Best Practice with FRP
FRP is a tool for reverse proxy. By using FRP, we can easily expose service in local network to public internet. Though the official documents provides some configurations for specific condition, it can still be confusing for new users. Thus I would like to record how I use it.
Installation
FRP doesn’t provide any installation script, maybe because it’s quite easy to run under command. But FRP does provided systemd configs, thus we can manage FRP service though systemd.
Download latest tarball from FRP Binary and unpack it, then execute following command to install on Linux with systemd:
1 | on frp client |
Configration
You may notice that we use frpc@.service rather than frpc.service, this is a kind of systemd grammar. We can append extra string after @, and systemd will use the config file with the same name.
SSH
Client
Add config file
/etc/frp/ssh.ini
Local sshd listens at
127.0.0.1:22
and we would like to access it through<server ip>:7022
. Multiple client can make use of the same server with different tag[ssh]
and differentremote_port
.1
2
3
4
5
6
7
8
9
10[common]
server_addr = <ip or domain>
server_port = 7000
token = <password>
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 7022Enable and start service
1
2systemctl enable frpc@ssh
systemctl start frpc@ssh
Server
Add config file
/etc/frp/ssh.ini
1
2
3
4[common]
bind_addr = 0.0.0.0
bind_port = 7000
token = <password>Enable and start service
1
2systemctl enable frps@ssh
systemctl start frps@ssh
Http service with Nginx
Under this condition, we have a http service in local network and would like to access it through Nginx.
Client
Add config file
/etc/frp/http.ini
Suppose we have a local http server listening at
http://127.0.0.1:80
1
2
3
4
5
6
7
8
9[common]
server_addr = <ip or domain>
server_port = 7000
token = <password>
[http_service]
type = http
local_port = 80
custom_domains = <bound doamin>Enable and start service
1
2systemctl enable frpc@http
systemctl start frpc@http
Server
Add config file
/etc/frp/http.ini
In this config, FRP server will listen at
0.0.0.0:7000
, and the exposed http service will listen at127.0.0.1:7080
. The limitation is that 1 server can only serve 1 client if you don’t use the locations, while FRP can not rewrite URL path as this work should belong to Nginx.1
2
3
4
5
6[common]
bind_addr = 0.0.0.0
bind_port = 7000
proxy_bind_addr = 127.0.0.1
vhost_http_port = 7080
token = <password>Enable and start service
1
2systemctl enable frps@http
systemctl start frps@httpAdd Nginx location
1
2
3
4
5
6
7
8location / {
proxy_redirect off;
proxy_pass http://127.0.0.1:7080/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
Https service with Nginx
Under this condition, we have a https service in local network and would like to access it through Nginx. You may ask: Why use https for internal service? Well, sometimes this can happen and we can not change, such as Proxmox VE, it only supports https for web service, and it’s hard to switch to http.
Client
Add config file
/etc/frp/https.ini
Suppose we have a local https service
https://127.0.0.1:443
1
2
3
4
5
6
7
8
9[common]
server_addr = <ip or domain>
server_port = 7000
token = 'password'
[proxmox]
type = https
local_port = 443
custom_domains = <bound domain>Enable and start service
1
2systemctl enable frpc@https
systemctl start frpc@https
Server
Add config file
/etc/frp/https.ini
In this config, FRP server will listen at
0.0.0.0:7000
, and the exposed https service will listen at127.0.0.1:7443
. The limitation is that 1 server can only serve 1 client if you don’t use the locations, while FRP can not rewrite URL path as this work should belong to Nginx.1
2
3
4
5
6[common]
bind_addr = 0.0.0.0
bind_port = 7000
proxy_bind_addr = 127.0.0.1
vhost_https_port = 7443
token = <password>Enable and start service
1
2systemctl enable frps@https
systemctl start frps@httpsAdd Nginx location
1
2
3
4
5
6
7
8
9
10
11
12location / {
proxy_ssl_server_name on;
proxy_ssl_name $host;
proxy_ssl_verify off;
proxy_pass https://127.0.0.1:7443;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header cookie $http_cookie;
proxy_set_header Proxy-Connection "";
proxy_http_version 1.1;
}