frp

What is frp?

frp is a fast reverse proxy that allows you to expose a local server located behind a NAT or firewall to the Internet. It currently supports TCP and UDP, as well as HTTP and HTTPS protocols, enabling requests to be forwarded to internal services via domain name.

frp also offers a P2P connect mode.

Development Status

frp is currently under development. You can try the latest release version in the master branch, or use the dev branch to access the version currently in development.

We are currently working on version 2 and attempting to perform some code refactoring and improvements. However, please note that it will not be compatible with version 1.

About V2

The complexity and difficulty of the v2 version are much higher than anticipated. I can only work on its development during fragmented time periods, and the constant interruptions disrupt productivity significantly. Given this situation, we will continue to optimize and iterate on the current version until we have more free time to proceed with the major version overhaul.

The concept behind v2 is based on my years of experience and reflection in the cloud-native domain, particularly in K8s and ServiceMesh. Its core is a modernized four-layer and seven-layer proxy, similar to envoy. This proxy itself is highly scalable, not only capable of implementing the functionality of intranet penetration but also applicable to various other domains.

In addition, I envision frp itself becoming a highly extensible system and platform, similar to how we can provide a range of extension capabilities based on K8s.

Finally, we acknowledge that the current design of modules such as configuration management, permission verification, certificate management, and API management is not modern enough.

We sincerely appreciate your support for frp.

Architecture

Example Usage

To begin, download the latest program for your operating system and architecture from the Release page.

Next, place the frps binary and server configuration file on Server A, which has a public IP address.

Finally, place the frpc binary and client configuration file on Server B, which is located on a LAN that cannot be directly accessed from the public internet.

Some antiviruses improperly mark frpc as malware and delete it. This is due to frp being a networking tool capable of creating reverse proxies. Antiviruses sometimes flag reverse proxies due to their ability to bypass firewall port restrictions. If you are using antivirus, then you may need to whitelist/exclude frpc in your antivirus settings to avoid accidental quarantine/deletion. See issue 3637 for more details.

Access your computer in a LAN network via SSH

  1. Modify frps.toml on server A by setting the bindPort for frp clients to connect to:

    # frps.toml
    bindPort = 7000
    
  2. Start frps on server A:

    ./frps -c ./frps.toml
    
  3. Modify frpc.toml on server B and set the serverAddr field to the public IP address of your frps server:

    # frpc.toml
    serverAddr = "x.x.x.x"
    serverPort = 7000
    [[proxies]]
    name = "ssh"
    type = "tcp"
    localIP = "127.0.0.1"
    localPort = 22
    remotePort = 6000
    
  4. Start frpc on server B:

    ./frpc -c ./frpc.toml
    
  5. To access server B from another machine through server A via SSH (assuming the username is test), use the following command:

    ssh -oPort=6000 test@x.x.x.x
    

Multiple SSH services sharing the same port

This example implements multiple SSH services exposed through the same port using a proxy of type tcpmux.

  1. Deploy frps on a machine with a public IP and modify the frps.toml file. Here is a simplified configuration:

    bindPort = 7000
    tcpmuxHTTPConnectPort = 5002
    
  2. Deploy frpc on the internal machine A with the following configuration:

    serverAddr = "x.x.x.x"
    serverPort = 7000
    [[proxies]]
    name = "ssh1"
    type = "tcpmux"
    multiplexer = "httpconnect"
    customDomains = ["machine-a.example.com"]
    localIP = "127.0.0.1"
    localPort = 22
    
  3. Deploy another frpc on the internal machine B with the following configuration:

    serverAddr = "x.x.x.x"
    serverPort = 7000
    [[proxies]]
    name = "ssh2"
    type = "tcpmux"
    multiplexer = "httpconnect"
    customDomains = ["machine-b.example.com"]
    localIP = "127.0.0.1"
    localPort = 22
    
  4. To access internal machine A using SSH ProxyCommand:

    ssh -o 'proxycommand socat - PROXY:x.x.x.x:%h:%p,proxyport=5002' test@machine-a.example.com
    
  5. To access internal machine B, the only difference is the domain name:

    ssh -o 'proxycommand socat - PROXY:x.x.x.x:%h:%p,proxyport=5002' test@machine-b.example.com
    

Accessing Internal Web Services with Custom Domains in LAN

  1. Modify frps.toml and set the HTTP port for vhost to 8080:

    # frps.toml
    bindPort = 7000
    vhostHTTPPort = 8080
    
  2. Start frps:

    ./frps -c ./frps.toml
    
  3. Modify frpc.toml and set serverAddr to the IP address of the remote frps server. Specify the localPort of your web service:

    # frpc.toml
    serverAddr = "x.x.x.x"
    serverPort = 7000
    [[proxies]]
    name = "web"
    type = "http"
    localPort = 80
    customDomains = ["www.example.com"]
    
  4. Start frpc:

    ./frpc -c ./frpc.toml
    
  5. Visit your local web service using url http://www.example.com:8080.

Forward DNS query requests

  1. Modify frps.toml:

    # frps.toml
    bindPort = 7000
    
  2. Start frps:

    ./frps -c ./frps.toml
    
  3. Modify frpc.toml and set serverAddr to the IP address of the remote frps server:

    # frpc.toml
    serverAddr = "x.x.x.x"
    serverPort = 7000
    [[proxies]]
    name = "dns"
    type = "udp"
    localIP = "8.8.8.8"
    localPort = 53
    remotePort = 6000
    
  4. Start frpc:

    ./frpc -c ./frpc.toml
    
  5. Test DNS resolution using the dig command:

    dig @x.x.x.x -p 6000 www.google.com
    

Features

Configuration Files

Since v0.52.0, we support TOML, YAML, and JSON for configuration. Please note that INI is deprecated and will be removed in future releases. New features will only be available in TOML, YAML, or JSON. Users wanting these new features should switch their configuration format accordingly.

Using Environment Variables

Environment variables can be referenced in the configuration file, using Go's standard format:

# frpc.toml
serverAddr = "{{ .Envs.FRP_SERVER_ADDR }}"
serverPort = 7000
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = {{ .Envs.FRP_SSH_REMOTE_PORT }}

Split Configures Into Different Files

You can split multiple proxy configs into different files and include them in the main file.

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000
includes = ["./confd/*.toml"]

Load balancing

Load balancing is supported by group. This feature is only available for types tcp, http, tcpmux now.

# frpc.toml
[[proxies]]
name = "test1"
type = "tcp"
localPort = 8080
remotePort = 80
loadBalancer.group = "web"
loadBalancer.groupKey = "123"

[[proxies]]
name = "test2"
type = "tcp"
localPort = 8081
remotePort = 80
loadBalancer.group = "web"
loadBalancer.groupKey = "123"

Connections to port 80 will be dispatched to proxies in the same group randomly. For type tcp, remotePort in the same group should be the same.

Service Health Check

Health check feature can help you achieve high availability with load balancing. Add healthCheck.type = "tcp" or healthCheck.type = "http" to enable health check.

# frpc.toml
[[proxies]]
name = "test1"
type = "tcp"
localPort = 22
remotePort = 6000
healthCheck.type = "tcp"
healthCheck.timeoutSeconds = 3
healthCheck.maxFailed = 3
healthCheck.intervalSeconds = 10