frp is a fast reverse proxy to help you expose a local server behind a NAT or firewall to the Internet. As of now, it supports TCP and UDP, as well as HTTP and HTTPS protocols, where requests can be forwarded to internal services by domain name.
frp also has a P2P connect mode.
- Development Status
- Architecture
- Example Usage
- Features
- Configuration Files
- Using Environment Variables
- Dashboard
- Admin UI
- Monitor
- Authenticating the Client
- Encryption and Compression
- Hot-Reloading frpc configuration
- Get proxy status from client
- Only allowing certain ports on the server
- Port Reuse
- Bandwidth Limit
- TCP Stream Multiplexing
- Support KCP Protocol
- Connection Pooling
- Load balancing
- Service Health Check
- Rewriting the HTTP Host Header
- Setting other HTTP Headers
- Get Real IP
- Require HTTP Basic Auth (Password) for Web Services
- Custom Subdomain Names
- URL Routing
- TCP Port Multiplexing
- Connecting to frps via HTTP PROXY
- Range ports mapping
- Client Plugins
- Server Manage Plugins
- Development Plan
- Contributing
- Donation
frp is under development. Try the latest release version in the master
branch, or use the dev
branch for the version in development.
The protocol might change at a release and we don't promise backwards compatibility. Please check the release log when upgrading the client and the server.
Firstly, download the latest programs from Release page according to your operating system and architecture.
Put frps
and frps.ini
onto your server A with public IP.
Put frpc
and frpc.ini
onto your server B in LAN (that can't be connected from public Internet).
- Modify
frps.ini
on server A and set thebind_port
to be connected to frp clients:
# frps.ini
[common]
bind_port = 7000
- Start
frps
on server A:
./frps -c ./frps.ini
- On server B, modify
frpc.ini
to put in yourfrps
server public IP asserver_addr
field:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
Note that local_port
(listened on client) and remote_port
(exposed on server) are for traffic goes in/out the frp system, whereas server_port
is used between frps.
- Start
frpc
on server B:
./frpc -c ./frpc.ini
- From another machine, SSH to server B like this (assuming that username is
test
):
ssh -oPort=6000 test@x.x.x.x
Sometimes we want to expose a local web service behind a NAT network to others for testing with your own domain name and unfortunately we can't resolve a domain name to a local IP.
However, we can expose an HTTP(S) service using frp.
- Modify
frps.ini
, set the vhost HTTP port to 8080:
# frps.ini
[common]
bind_port = 7000
vhost_http_port = 8080
- Start
frps
:
./frps -c ./frps.ini
- Modify
frpc.ini
and setserver_addr
to the IP address of the remote frps server. Thelocal_port
is the port of your web service:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[web]
type = http
local_port = 80
custom_domains = www.example.com
- Start
frpc
:
./frpc -c ./frpc.ini
-
Resolve A record of
www.example.com
to the public IP of the remote frps server or CNAME record to your origin domain. -
Now visit your local web service using url
http://www.example.com:8080
.
- Modify
frps.ini
:
# frps.ini
[common]
bind_port = 7000
- Start
frps
:
./frps -c ./frps.ini
- Modify
frpc.ini
and setserver_addr
to the IP address of the remote frps server, forward DNS query request to Google Public DNS server8.8.8.8:53
:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[dns]
type = udp
local_ip = 8.8.8.8
local_port = 53
remote_port = 6000
- Start frpc:
./frpc -c ./frpc.ini
- Test DNS resolution using
dig
command:
dig @x.x.x.x -p 6000 www.google.com
Expose a Unix domain socket (e.g. the Docker daemon socket) as TCP.
Configure frps
same as above.
- Start
frpc
with configuration:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[unix_domain_socket]
type = tcp
remote_port = 6000
plugin = unix_domain_socket
plugin_unix_path = /var/run/docker.sock
- Test: Get Docker version using
curl
:
curl http://x.x.x.x:6000/version
Browser your files stored in the LAN, from public Internet.
Configure frps
same as above.
- Start
frpc
with configuration:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[test_static_file]
type = tcp
remote_port = 6000
plugin = static_file
plugin_local_path = /tmp/files
plugin_strip_prefix = static
plugin_http_user = abc
plugin_http_passwd = abc
- Visit
http://x.x.x.x:6000/static/
from your browser and specify correct user and password to view files in/tmp/files
on thefrpc
machine.
- Start
frpc
with configuration:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[test_https2http]
type = https
custom_domains = test.example.com
plugin = https2http
plugin_local_addr = 127.0.0.1:80
plugin_crt_path = ./server.crt
plugin_key_path = ./server.key
plugin_host_header_rewrite = 127.0.0.1
plugin_header_X-From-Where = frp
- Visit
https://test.example.com
.
Some services will be at risk if exposed directly to the public network. With STCP (secret TCP) mode, a preshared key is needed to access the service from another client.
Configure frps
same as above.
- Start
frpc
on machine B with the following config. This example is for exposing the SSH service (port 22), and note thesk
field for the preshared key, and that theremote_port
field is removed here:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[secret_ssh]
type = stcp
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22
- Start another
frpc
(typically on another machine C) with the following config to access the SSH service with a security key (sk
field):
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[secret_ssh_visitor]
type = stcp
role = visitor
server_name = secret_ssh
sk = abcdefg
bind_addr = 127.0.0.1
bind_port = 6000
- On machine C, connect to SSH on machine B, using this command:
ssh -oPort=6000 127.0.0.1
xtcp is designed for transmitting large amounts of data directly between clients. A frps server is still needed, as P2P here only refers the actual data transmission.
Note it can't penetrate all types of NAT devices. You might want to fallback to stcp if xtcp doesn't work.
- In
frps.ini
configure a UDP port for xtcp:
# frps.ini
bind_udp_port = 7001
- Start
frpc
on machine B, expose the SSH port. Note thatremote_port
field is removed:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[p2p_ssh]
type = xtcp
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22
- Start another
frpc
(typically on another machine C) with the config to connect to SSH using P2P mode:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[p2p_ssh_visitor]
type = xtcp
role = visitor
server_name = p2p_ssh
sk = abcdefg
bind_addr = 127.0.0.1
bind_port = 6000
- On machine C, connect to SSH on machine B, using this command:
ssh -oPort=6000 127.0.0.1
Read the full example configuration files to find out even more features not described here.
Full configuration file for frps (Server)
Full configuration file for frpc (Client)
Environment variables can be referenced in the configuration file, using Go's standard format:
# frpc.ini
[common]
server_addr = {{ .Envs.FRP_SERVER_ADDR }}
server_port = 7000
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = {{ .Envs.FRP_SSH_REMOTE_PORT }}
With the config above, variables can be passed into frpc
program like this:
export FRP_SERVER_ADDR="x.x.x.x"
export FRP_SSH_REMOTE_PORT="6000"
./frpc -c ./frpc.ini
frpc
will render configuration file template using OS environment variables. Remember to prefix your reference with .Envs
.
Check frp's status and proxies' statistics information by Dashboard.
Configure a port for dashboard to enable this feature:
[common]
dashboard_port = 7500
# dashboard's username and password are both optional,if not set, default is admin.
dashboard_user = admin
dashboard_pwd = admin
Then visit http://[server_addr]:7500
to see the dashboard, with username and password both being admin
by default.
The Admin UI helps you check and manage frpc's configuration.
Configure an address for admin UI to enable this feature:
[common]
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = admin
Then visit http://127.0.0.1:7400
to see admin UI, with username and password both being admin
by default.
When dashboard is enabled, frps will save monitor data in cache. It will be cleared after process restart.
Prometheus is also supported.
Enable dashboard first, then configure enable_prometheus = true
in frps.ini
.
http://{dashboard_addr}/metrics
will provide prometheus monitor data.