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.

Let us explore the basic configuration methods for FRP proxy.
Before you can have this setup up and running, you need the following:
- A local server that is behind a firewall or NAT, e.g your laptop.
- 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:
- 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)
- 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
.

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.

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:
- Install posh-git on Windows – PowerShell environment for Git
- Install Kimai web-based time tracking application
- Configure KVM Networking With virsh, nmcli and brctl in Linux
- Faraday – Penetration Testing IDE & Vulnerability Management Platform
- Chezmoi – Securely Manage dotfiles across multiple machines