It is usually a big challenge for geeks who would love to access their local server over the internet. Don’t you worry no more, we shall be exploring a tool that can be used to expose your local server and services behind a firewall on NAT over the internet. In this article you’ll learn to expose a Local Server behind a NAT or firewall to the internet using FRP Proxy.

FRP proxy is a reverse proxy written in Golang that allows you forward a port of your local server behind a firewall or NAT to a public server.

FRP proxy currently supports TCP, UDP, HTTP and HTTPS protocols.

Expose Local Server behind a NAT or firewall to the internet using FRP
FRP Architecture

Let us explore the basic configuration methods for FRP proxy.

Before you can have this setup up and running, you need the following:

  1. A local server that is behind a firewall or NAT, e.g your laptop.
  2. A remote server with a public IP, e.g AWS EC2 instance.

Installation of FRP Proxy on Linux / macOS / FreeBSD

Let us jump into the installation part.

1. Download and extract FRP

Download the latest version of FRP from their Github repository. This should be downloaded on both the local and the public server.

Get the latest release Tag:

TAG=$(curl --silent "https://api.github.com/repos/fatedier/frp/releases/latest"|grep '"tag_name"'|sed -E 's/.*"([^"]+)".*/\1/'|sed 's/v//')

Download and extract the archive.

### Linux Intel 64-bit ###
wget https://github.com/fatedier/frp/releases/download/v${TAG}/frp_${TAG}_linux_amd64.tar.gz
tar xvf frp_${TAG}_linux_amd64.tar.gz
cd  frp_${TAG}_linux_amd64

### Linux ARM 64-bit ###
wget https://github.com/fatedier/frp/releases/download/v${TAG}/frp_${TAG}_linux_arm64.tar.gz
tar xvf frp_${TAG}_linux_arm64.tar.gz
cd frp_${TAG}_linux_arm64

### macOS Intel 64-bit ###
wget https://github.com/fatedier/frp/releases/download/v${TAG}/frp_${TAG}_darwin_amd64.tar.gz
tar xvf frp_${TAG}_darwin_amd64.tar.gz
cd frp_${TAG}_darwin_amd64

### macOS ARM 64-bit ###
wget https://github.com/fatedier/frp/releases/download/v${TAG}/frp_${TAG}_darwin_arm64.tar.gz
tar xvf frp_${TAG}_darwin_arm64.tar.gz
cd frp_${TAG}_darwin_arm64

### FreeBSD 64-bit ###
wget https://github.com/fatedier/frp/releases/download/v${TAG}/frp_${TAG}_freebsd_amd64.tar.gz
tar xvf frp_${TAG}_freebsd_amd64.tar.gz
cd frp_${TAG}_freebsd_amd64

The following files are in the extracted directory:

$ ls
frpc  frpc.toml  frps  frps.toml  LICENSE

At the public server, the frps and frps.toml file are needed.

2. Setup Public server

On the public server, we only need to set the bind_port under the [common] in the frps.toml file to 7000. This is the default port, you can also define your own port depending on your preference.

$ vim frps.toml
bind_port = 7000

3. Start FRP on public server

We need to start the service on the public server to allow connections from the local server.

The following command shall be used:

./frps -c ./frps.toml

You should see an output that the service is listening on the specified port:

$ ./frps -c ./frps.toml
2023/11/22 12:11:54 [I] [root.go:102] frps uses config file: ./frps.toml
2023/11/22 12:11:54 [I] [service.go:200] frps tcp listen on 0.0.0.0:7000
2023/11/22 12:11:54 [I] [root.go:111] frps started successfully

4. Configure FRP Client on local server

With FRP up and running on the Public server, the next step is to configure the local server.

Download and extract the package as covered in previous step.

For example, to expose ssh on our local server. The required files on the local server are frpc and frpc.toml.

Edit the frpc.toml file and add the following details:

  • Put the Public servers IP in the server_addr value and the port you defined in the Public server under the [common] section.
$ vim frpc.toml
serverAddr = "<PUBLIC_FRP_SERVER_IP>"
serverPort = 7000

[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000

In the above configuration, we have exposed port 22 of our local server to port 6000 of the public server.

We have also defined the protocol that we’re using, TCP.

We can also expose a web service running on your local server in the same configuration. You can add the webserver details just below the ssh configuration in the frpc.toml file.

In the example below, the webserver is running on port 80 of the local server and will be forwarded to port 8080 of the public server.

[[proxies]]
name = "web"
type = "http"
localPort = 80
customDomains = ["www.example.com"]

The following step is to start FRP service on the local server.

./frps -c ./frps.toml

You can now ssh to your local server using the following command:

ssh -oPort=6000 <username>@<PUBLIC_FRP_SERVER_IP>

You can also access the webserver running on the public server’s port 8080

http://<PUBLIC_FRP_SERVER_IP>:8080

You should also allow the respective ports on the remote server if you have a firewall configured.

5. Daemonize FRP service using Systemd

You might want to have FRP services on local and public server running as a service/daemon.

1) To daemonize frps service on the public server:

  1. Copy the frps file to /usr/bin
sudo cp frps /usr/bin

2. Copy the frps.service file in systemd folder to /etc/systemd/system.

sudo tee /etc/systemd/system/frps.service<<EOF
[Unit]
Description=frp server
Wants=network-online.target
After=network.target network-online.target

[Service]
ExecStart=/usr/bin/frps -c /etc/frp/frps.toml

[Install]
WantedBy=multi-user.target
EOF

3. Create folder called frp in /etc/ directory.

sudo mkdir -p /etc/frp

4. Copy frps.toml file to /etc/frp

sudo cp frps.toml /etc/frp

5. Reload daemon

sudo systemctl daemon-reload

6. Start frps service

sudo systemctl start frps.service

Check service status after starting:

$ systemctl status frps
 frps.service - frp client
     Loaded: loaded (/etc/systemd/system/frps.service; disabled; preset: disabled)
    Drop-In: /usr/lib/systemd/system/service.d
             └─10-timeout-abort.conf
     Active: active (running) since Wed 2023-11-22 12:26:56 UTC; 4s ago
   Main PID: 3860 (frps)
      Tasks: 5 (limit: 4520)
     Memory: 8.1M
        CPU: 150ms
     CGroup: /system.slice/frps.service
             └─3860 /usr/bin/frps -c /etc/frp/frps.toml

Nov 22 12:26:56 fed39.mylab.io systemd[1]: Started frps.service - frp client.
Nov 22 12:26:56 fed39.mylab.io frps[3860]: 2023/11/22 12:26:56 [I] [root.go:102] frps uses config file: /etc/frp/frps.toml
Nov 22 12:26:56 fed39.mylab.io frps[3860]: 2023/11/22 12:26:56 [I] [service.go:200] frps tcp listen on 0.0.0.0:7000
Nov 22 12:26:56 fed39.mylab.io frps[3860]: 2023/11/22 12:26:56 [I] [root.go:111] frps started successfully

2) Running frpc service using systemd on local server (client)

  1. Copy frpc file to /usr/bin
sudo cp frpc /usr/bin

2. Create folder called frp in /etc/ directory.

sudo mkdir -p /etc/frp

3. Copy frpc.toml file to /etc/frp

sudo cp frpc.toml /etc/frp

4. Create systemd service

sudo tee /etc/systemd/system/frpc.service<<EOF
[Unit]
Description=frp client
Wants=network-online.target
After=network.target network-online.target

[Service]
ExecStart=/usr/bin/frpc -c /etc/frp/frpc.toml

[Install]
WantedBy=multi-user.target
EOF

5. Reload daemon

sudo systemctl daemon-reload

6. Start frpc service

sudo systemctl start frpc.service

Confirm service is in running state:

$ systemctl status frpc
 frpc.service - frp client
     Loaded: loaded (/etc/systemd/system/frpc.service; disabled; preset: disabled)
    Drop-In: /usr/lib/systemd/system/service.d
             └─10-timeout-abort.conf
     Active: active (running) since Wed 2023-11-22 12:30:55 UTC; 7s ago
   Main PID: 3943 (frpc)
      Tasks: 4 (limit: 4520)
     Memory: 1.8M
        CPU: 17ms
     CGroup: /system.slice/frpc.service
             └─3943 /usr/bin/frpc -c /etc/frp/frpc.toml

Nov 22 12:30:55 fed39.mylab.io systemd[1]: Started frpc.service - frp client.
Nov 22 12:30:55 fed39.mylab.io frpc[3943]: 2023/11/22 12:30:55 [I] [root.go:139] start frpc service for config file [/etc/frp/frpc.toml]
Nov 22 12:30:55 fed39.mylab.io frpc[3943]: 2023/11/22 12:30:55 [I] [service.go:299] [e789d0803f5eef73] login to server success, get run id [e789d0803f5eef73]
Nov 22 12:30:55 fed39.mylab.io frpc[3943]: 2023/11/22 12:30:55 [I] [proxy_manager.go:156] [e789d0803f5eef73] proxy added: [test-tcp]
Nov 22 12:30:55 fed39.mylab.io frpc[3943]: 2023/11/22 12:30:55 [I] [control.go:173] [e789d0803f5eef73] [test-tcp] start proxy success

6. Monitor FPS using Dashboard

There are two UI interfaces.

Server Admin UI

FPS has its own dashboard that can be configured to view the stats and metrics.

To activate you need to add the details below in the frps.toml file of the Public server.

$ sudo vim /etc/frp/frps.toml
webServer.addr = "127.0.0.1"
webServer.port = 7500
# dashboard's username and password are both optional
webServer.user = "admin"
webServer.password = "admin"
# Enable metrics with Prometheus
enablePrometheus = true

You can specify the username and password to the details of your choice. The address can be set to Server IP for external access.

Setting webServer.addr = "0.0.0.0" means listen on all interfaces.

Additionally, you can use HTTPS port by using your domains wildcard or normal SSL certificate:

webServer.port = 7500
# dashboard's username and password are both optional
webServer.user = "admin"
webServer.password = "admin"
webServer.tls.certFile = "server.crt"
webServer.tls.keyFile = "server.key"

Restart the FRP server service.

sudo systemctl restart frps.service

You can open the dashboard by visiting http://[serverAddr]:7500 to see the dashboard, with username and password both being admin.

frp server ui

When metrics is enabled,http://{dashboard_addr}/metrics will provide prometheus monitor data.

Client Admin UI

The Client Admin UI helps you check and manage frpc’s configuration. You need to edit client configuration and set an address for admin UI to enable this feature:

$ sudo vim /etc/frp/frpc.toml
webServer.addr = "127.0.0.1"
webServer.port = 7400
webServer.user = "admin"
webServer.password = "admin"

Setting webServer.addr = "0.0.0.0" means listen on all interfaces.

Restart FRP Client service

sudo systemctl restart frpc

Now visit http://clientip:7400 to see admin UI, with username and password both being admin.

frp client ui

You can now run FRP as a daemon. This helps if you want to run the service in the background, and also for management purposes.

Visit FRP Github documentation pages to learn more about this amazing project.

Conclusion

We have successfully installed FRP proxy and configured it. This is a tool that can be very useful to system administrators who wish to access their locally hosted services through the internet. If this post has been useful to you, feel free to share and comment.

More articles to read on our website:

LEAVE A REPLY

Please enter your comment!
Please enter your name here