fatedier/frp: exposing a LAN service through NAT with frps and frpc
A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.
At a glance
- What is it?
- frp is a Go reverse proxy that publishes TCP, UDP, HTTP and HTTPS services sitting behind NAT or a firewall. It is a two-binary design with a self-hosted server, and the documentation is explicit that a v2 rewrite is in progress and will not be compatible with v1.
- Who is it for?
- Adopt frp if you control a host with a public IP and need to publish TCP, UDP, HTTP or HTTPS services from a private network, and if you can live with the v1 configuration surface. Skip it if you need the v2 architecture described in the README, which the project says will not be compatible with version 1, or if a managed tunnel already covers your case.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The NAT problem frp is built to remove
A service running on a laptop, a lab machine or an internal host usually has no routable address. Port forwarding on the router works until the router changes, the ISP uses carrier-grade NAT, or the host moves between networks. frp addresses that by inverting the direction of the connection: the machine inside the private network dials out to a server that does have a public address, and the server forwards inbound traffic back down that established connection.
The README states the scope plainly: frp exposes a local server behind a NAT or firewall to the Internet, supporting TCP and UDP as well as HTTP and HTTPS, with requests forwarded to internal services by domain name. It also offers a P2P connect mode. The intended user is someone who runs their own public-facing host and wants a general-purpose tunnel rather than a single-protocol tool. Because the client initiates the connection, no inbound firewall rule is needed on the private side.
Two binaries, one control connection: how frps and frpc actually move traffic
The repository splits into client/ and server/ packages with cmd/frps and cmd/frpc as the entry points, and the Makefile builds them as separate tagged binaries. frps runs on the host with the public address. frpc runs next to the service you want to publish. The client opens a long-lived connection to the server, and each proxy entry in the client configuration is registered over that connection.
Several mechanisms sit on top of that base. TCP stream multiplexing lets many logical streams share one connection, and the README lists KCP and QUIC as alternative transport protocols alongside connection pooling. For HTTP and HTTPS, the server can route by domain name, which is how multiple internal web services can share a single public port; the README also documents URL routing, custom subdomain names, rewriting the Host header, and TCP port multiplexing. Authentication is handled with a token or with OIDC, and TLS is available for the tunnel itself. Observability is built in: a server dashboard, a client admin UI with dynamic proxy management, and a Prometheus endpoint. The dependency list in go.mod confirms the shape of this, with quic-go, kcp-go, yamux, go-oidc and the Prometheus client all present.
Building frp from source and publishing your first SSH port
The README does not walk through a binary install; it points at the GitHub releases page, and the repository also carries dockerfiles/ for container builds. The Makefile is the documented path from a checkout to working binaries. It builds the server and the client with the frps and frpc targets, which invoke go build against cmd/frps and cmd/frpc and write the results into bin/:
makeThat target runs env, fmt, web and build in sequence, and build depends on frps and frpc. If you would rather skip the web asset step, the Makefile defines a NOWEB_TAG that is applied when web/frps/dist or web/frpc/dist is missing, and the vet and gotest targets pass that tag through.
Once you have the binaries, the README's example usage section begins with accessing a computer in a LAN network via SSH. The server side needs a bind port before anything can connect, and the client side declares the tunnel that maps a port on the public host to the local SSH daemon. The README documents the client configuration options, including serverAddr, serverPort, and proxy entries with name, type, localIP, localPort and remotePort; the exact values are yours to choose.
After the client registers, connecting to the remote port on the public host reaches SSH on the private machine. Configuration can also come from environment variables, and the README documents splitting configuration across several files, which matters once you have more than a handful of proxies. For web services, the HTTP and HTTPS proxy types replace the raw port mapping with domain-based routing, and the README notes that frpc configuration can be hot-reloaded rather than requiring a restart. The README also documents requiring HTTP basic auth for web services, restricting the ports a server will accept, and setting per-proxy bandwidth limits, all of which are worth deciding on before the tunnel is reachable from the internet.
Where frp gets awkward: v1 limits, v2 promises and the compatibility floor
The most important constraint is stated by the project itself. The README says the maintainer is working on version 2, that it will not be compatible with version 1, and that the complexity of v2 was much higher than anticipated, so work continues on the current version in the meantime. Anyone planning a long-lived deployment on frp v1 should read that as a signal about where engineering effort is going, not as a guarantee about when the break arrives.
There is also a version-skew risk between your own frps and frpc. The Makefile defines FRP_COMPAT_FLOOR_VERSION ?= 0.61.0 and FRP_COMPAT_BASELINE_COUNT ?= 8, and exposes e2e-compatibility and e2e-compatibility-floor targets that run hack/run-e2e-compatibility.sh against those versions. That suite exists because mixed-version pairs are a real failure mode; if you upgrade the server and leave clients behind, you are in the territory those targets were written to cover.
Operationally, frp is a self-hosted tunnel, which means the public host is yours to secure. The README documents token and OIDC authentication, TLS, port restrictions on the server, and bandwidth limits per proxy, but none of those are on by default in a minimal configuration. A frps reachable on the internet with a weak or absent token is an open relay into whatever the clients expose. The feature set is wide, and each option you skip is a decision you are making rather than a default the project makes for you.
frp compared with a WireGuard-based tunnel
The obvious alternative is to build the same capability from a VPN such as WireGuard, which the go.mod file shows frp already depends on for its VirtualNet feature. The difference is in what each exposes. A VPN puts the private machine on a routable network segment: once the tunnel is up, anything listening on the private host is reachable by its tunnel address, and you manage reachability with routes and firewall rules.
frp works at the proxy layer instead. You declare individual proxies by name, type and port, and the server publishes exactly those. That is narrower by design. It means you do not have to reason about routing tables or address allocation, and it means a compromised client cannot reach anything you did not declare. It also means every new service needs a new proxy entry and, in most setups, a client reload. If your goal is full network-level access to a private subnet, a VPN is the more direct tool. If your goal is publishing a specific set of services on specific ports and domains, frp's model produces a smaller attack surface and a configuration file that reads like an inventory. The README's P2P mode and SSH tunnel gateway sit between the two approaches, but the core split remains: proxy-level exposure versus network-level access.
Licence, upgrades and what maintenance actually costs
frp is licensed under Apache-2.0, a permissive licence that allows commercial use and modification, with the usual obligations around preserving notices and stating changes. That is a summary of the identifier, not legal advice; read the LICENSE file in the repository if the distinction matters to your organisation.
The last push to the default branch was on 2026-08-14, and v0.71.0 was released the same day, following v0.70.1 on 2026-07-23 and v0.70.0 on 2026-07-11. Releases are frequent enough that pinning a version is worthwhile. The upgrade cost is not just downloading a new binary: the compatibility targets in the Makefile imply that server and client versions need to be considered together, and the README's note about hot-reloading frpc configuration means client changes can often be applied without dropping the tunnel, while server changes cannot. Budget for testing a version pair in a staging environment before moving production clients, and check the release notes for the version you are moving to rather than assuming the configuration format is unchanged.
Editorial conclusion
Adopt frp if you control a host with a public IP and need to publish TCP, UDP, HTTP or HTTPS services from a private network, and if you can live with the v1 configuration surface. Skip it if you need the v2 architecture described in the README, which the project says will not be compatible with version 1, or if a managed tunnel already covers your case. Before deploying, verify the frps and frpc versions you pair, because the Makefile runs a compatibility suite against a baseline version floor of 0.61.0.
Frequently asked questions
What is FRP (Fast Reverse Proxy)?
It is a reverse proxy that exposes a local server behind a NAT or firewall to the Internet, supporting TCP, UDP, HTTP and HTTPS. The client connects out to a server you run on a public address, and the server forwards inbound requests back through that connection. A P2P connect mode is also offered.
What is the FRP code?
The project is fatedier/frp, written in Go under the Apache-2.0 licence, with the server and client in the server/ and client/ packages and binaries built from cmd/frps and cmd/frpc. You obtain it from the GitHub releases page or build it yourself with the Makefile.
Does fatedier/frp work on Windows?
The repository ships a Makefile.cross-compiles target and release archives, and the documentation does not restrict supported platforms, so the frps and frpc binaries can be built or downloaded for Windows. The README's examples use shell commands, so on Windows you would run the equivalent binaries directly rather than through those scripts.
Is frp free to use?
Yes. The repository is licensed under Apache-2.0, which permits commercial use and modification subject to the licence's notice requirements. The project also accepts sponsorship, which the README describes as funding ongoing development.
Can I run frp in Docker?
The repository contains a dockerfiles/ directory alongside the Makefile and package.sh, so container images are part of the project's build story. The README itself does not document a Docker workflow, so check the files in that directory for the current entry points and configuration paths.
Community notes