Frp (fast reverse proxy) is an open-source tunneling tool: a server with a public IP runs frps, machines behind NAT run frpc, and the two keep a persistent connection. Traffic hitting ports on the public server is forwarded through that connection to internal services. Typical use case: exposing a web service or SSH on your home machine to the outside world.
Configuration files use TOML (frps.toml / frpc.toml; the INI format is deprecated since v0.52+).
Server side (frps)
Unpack the frp release on your public server and edit frps.toml:
bindPort = 7000 # port frpc connects to
auth.token = "a long random secret" # client must use the same value
webServer.addr = "0.0.0.0" # built-in dashboard
webServer.port = 7500
webServer.user = "admin"
webServer.password = "dashboard password"
vhostHTTPPort = 8080 # entry port for HTTP proxies, enable as needed
Run it under systemd, /etc/systemd/system/frps.service:
[Unit]
Description = frp server
After = network.target
[Service]
Type = simple
ExecStart = /opt/frp/frps -c /opt/frp/frps.toml
Restart = on-failure
RestartSec = 5
[Install]
WantedBy = multi-user.target
sudo systemctl enable --now frps
Remember to open ports 7000 (frpc connection), 7500 (dashboard), and any proxy ports in your cloud provider’s security group — this is the most common cause of “it doesn’t connect”.
Client side (frpc)
On the internal machine, edit frpc.toml:
serverAddr = "server public IP"
serverPort = 7000
auth.token = "same secret as the server"
# Plain TCP: map internal port 22 to server port 6022
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6022
# HTTP site: served on vhostHTTPPort, routed by domain
[[proxies]]
name = "web"
type = "http"
localPort = 3000
customDomains = ["app.example.com"]
Start it:
frpc -c frpc.toml
Now ssh -p 6022 user@server-ip reaches the internal machine, and http://app.example.com:8080 opens internal port 3000 in a browser.
On Linux, run the client under systemd too (same unit file as above with frps replaced by frpc). On Windows, install with winget install fatedier.frp and schedule frpc -c frpc.toml to run at startup via Task Scheduler.
Troubleshooting
- login to server failed: token in login doesn’t match token in configuration — the
auth.tokenvalues differ, or the client is hitting a different frps instance. - Port unreachable — check whether the proxy registered in
frps.logfirst, then the cloud security group and system firewall (ufw/firewalld). - HTTP proxy returns 404 — the
customDomainsmust resolve to the server IP, and requests must hitvhostHTTPPort, notremotePort. - Need HTTPS — put nginx in front of frps for TLS termination, or use frp’s
https2httpplugin.