内网穿透 | FRP 使用教程
唠唠闲话
FRP 的两个实践:
- 不使用 VPN 直接访问校园网内网(TODO)
- 将内服务映射到公网,灵活访问和管理内网服务:「Nginx 双域名管理内网服务」
内网穿透简介
互联网上两个不同的主机进行通信首先需要知道对方 IP。根据 IP 协议,只有分配了公网 IP 的设备才能在互联网上通信和传输数据。而中国人口/设备众多,分配到的 IPv4 资源又少,因此绝大部分情况是通过路由器/交换机转换公网 IP 后才上网。
位于路由器/交换机后的设备一般是内网设备,分配的IP地址以 192.168/172.16/10.0 开头,属于内网 IP。要让内网设备对外提供服务,就需要进行内网穿透。
常见穿透工具包括:Ngrok, FRP, ZeroTier 等,本文介绍 FRP 的使用。
相关阅读
利用frp工具实现内网穿透、随时随地访问内网服务
frp 内网穿透教程
内网穿透系列:ZeroTier技术初级
FRP 简介
FRP 是什么
frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。
基本原理
如上图所示:
- 在带有公网 ip 的云服务器上部署 frp 的服务端 frps
- 在需要穿透的内网服务器上部署 frp 的客户端 frpc
- 每个客户端都会有一个配置文件用于和服务器连接
- 公网服务器充当代理服务器,用户访问 公网ip + 端口号时,公网服务器的 frps 服务会根据端口号,自动转发到对应的内网服务器上,从而访问到内网服务
FRP 配置及使用
教程使用 v0.52.3
,配置文件为 .toml
格式,旧版教程参见 旧版 一节。
下载 FRP
访问 frp 发行地址,根据系统选择下载:
一般的 Linux 系统为 amd 架构,不确定可以通过输入 arch
命令查看,如果返回 x86_64 则为 amd 架构。
命令行的下载方式:
1 | wget -c https://github.com/fatedier/frp/releases/download/v0.52.3/frp_0.52.3_linux_amd64.tar.gz |
将服务端和客户端分开,方便管理:
1 | cd frp_0.52.3_linux_amd64 |
其中 server
文件夹放到公网服务器,client
文件夹放到内网服务器。
配置服务端
以下是一个简单的配置文件,参数见注释,完整的配置文件见 frps_full_example
1 | bindAddr = "0.0.0.0" |
这里有几个参数需要根据需要手动修改:
bindPort
:frp 服务端监听的端口,也即服务入口,建议修改auth.token
:授权码,这个授权码之后在客户端还会用到webServer.port
:监控流量页面的端口,建议修改webServer.user
:监控流量页面的用户名webServer.password
:监控流量页面的密码log.to
:日志文件路径,根据需要修改
其中 auth.token
可通过 pwgen -s 32 1
生成,这是连接服务用的密钥,安全考虑务必修改。
服务端自启动
将 server
目录上传到公网服务器,创建 frps.server
文件:
1 | cd /lib/systemd/system |
内容编写如下:
1 | [Unit] |
其中 ExecStart
填写 frps 的实际路径和配置文件路径。
编写完成后,执行
1 | sudo systemctl enable frps |
后续如果更改了配置文件,执行下边命令重启服务:
1 | sudo systemctl daemon-reload |
通常,我们可以通过下边命令查看服务状态
1 | sudo systemctl status frps # 查看服务状态 |
客户端配置
将 client
目录上传到内网服务器,如下编辑 frpc.toml
,参数见注释。
1 | serverAddr = "公网IP地址" |
其中 serverAddr
为公网服务器的 IP,其他内容与服务端配置文件保持一致。此外,对于需要添加服务,比如 ssh 穿透,在 frpc.toml
中添加相应 proxies
字段,比如
1 | [[proxies]] |
客户端的自启动类似配置。
监控设置
默认地,通过 IP + 端口访问监控页面。如果有域名可以在 Nginx 中添加如下配置:
1 | server{ |
其中 your_domain
为你的域名,7000
为服务端的 webServer.port
端口。
心跳设置
如果不设置心跳,frp 创建的连接可能在间隔较长时间后会断开,重新连接需刷新几次才能成功。为了避免这种情况的出现,可以在服务端输入 crontab -e
,添加定时任务
1 | * * * * * curl localhost:8080 --max-time 5 >/dev/null 2>&1 |
这里创建了一个 curl 请求,定时访问服务器的 8080
,而该 8080 端口穿透为内网服务,这样每分钟就会发送一次心跳,避免连接断开。
客户端 toml
文件添加相应的 proxies
字段:
1 | [[proxies]] |
FRP 配置及使用 | 旧版
以下为 0.49.0 版本的配置,使用 .ini
文件,新版使用 .toml
文件。
下载 FRP
服务端和客户端使用的都是同一份文件,只是配置文件和启动文件不同。因此只需要下载一份文件,并按类型分成两份。
下载地址:https://github.com/fatedier/frp/releases
服务器是 x86_64 架构,因此下载 linux_amd64 版本,如下图
通过命令行下载并解压:
1 | wget -c https://github.com/fatedier/frp/releases/download/v0.49.0/frp_0.49.0_linux_amd64.tar.gz |
查看目录:
1 | . |
这些文件分成两部分。
- 客户端,也即内网的服务器,需要 frpc 和 frpc.ini
- 服务端,也即公网的服务器,需要 frps 和 frps.ini
- 剩下的两个文件用于查看支持的所有配置项,可以不用管
将两类文件分别打包
1 | mkdir client server |
配置服务端
将 server
目录上传到公网服务器,如下编辑 frps.ini,参数见注释。
1 | [common] |
其中授权码可以用 pwgen
命令来生成,这个授权码之后在客户端还会用到。
1 | sudo apt install pwgen -y |
运行服务:
1 | ./frps -c frps.ini |
打开服务器的 7500 端口,即 dashboard_port
的设置值,输入设置的账户和密码,登录后即可看到 frp 的状态。
服务端自启动
把 frps 添加为系统服务,这一来当系统重启时,Frps 服务会自动启动,并且不需要手动再次启动。
将 frps, frps.ini
文件放到系统目录下,比如
1 | sudo mv frps /usr/bin/ # frps 可执行文件 |
然后新建文件:frps.service,内容如下:
1 | [Unit] |
这里 ExecStart
的路径要和 frps 的路径一致。
将文件复制到自启服务项:
1 | sudo cp frps.service /usr/lib/systemd/system/ |
设置自启动,并启动服务
1 | systemctl enable frps # 允许自启动 |
客户端配置
服务端配置后,就可以配置客户端了。
将 client
目录上传到内网服务器,如下编辑 frpc.ini,参数见注释。
1 | [common] |
第一处 common
是公共配置,第二处 overleaf
是需要映射的服务,可以根据服务命令,但注意不能与已有服务名称重复。(比如在多台服务器上配置 [ssh]
的穿透,则给服务器命名 [ssh-1]
、[ssh-2]
避免冲突)
同样地,本地执行 ./frpc -c frpc.ini
即可启动客户端。
P.S. 建议使用 tmux 在后台启动服务
1 | tmux new -s frpc |