frps+frpc内网穿透服务搭建记录

在 IPv4 地址池枯竭的当下,家庭宽带只能拥有 NAT 后的内网地址已经成了常态。找 ISP 软磨硬泡讨一个公网 IP 不失为一种方法,但这样做往往会把战线拉得很长。于是,花生壳 / Ngrok / frp 等内网穿透方案便显得十分合适。这些方案有的是开源项目,有的是商业服务。但是,它们的原理基本相——即让一个拥有公网 IP 的机器,“借”几个端口给没有公网 IP 的机器,从而让没有公网 IP 的机器上的服务能够对公网暴露。

frp的原理

在常规的情况下,服务器需要拥有公网 IP。IP 就如同门牌号,有了门牌号,别人才能找到你。客户端即便是处在 NAT 环境下,也能通过公网 IP 访问到服务器提供的服务。NAT 环境内的客户端发起的连接建立之后,NAT 网关便会对外打开一个端口来接收服务器返回的数据,并把接收到的数据转发给客户端。但是这个通讯,必须由 NAT 环境内的机器来发起。而提供服务的一方总是被动地等待传入连接的,因此 NAT 环境下的机器是无法对 NAT 环境外的机器提供服务的(这里暂时不考虑端口映射、DMZ、UDP 穿透等因素)。

如果用了 frp,那么处在 NAT 环境下的服务器也能对 NAT 环境外的机器提供服务了。这需要一台有公网 IP 的机器来做 frp 服务器。没有公网 IP 的应用服务器首先要告诉 frp 服务器:“我有一个服务运行在 A 端口,我想借你的 B 端口来对外开放这个服务。”frp 服务器答应了。于是应用服务器便和 frp 服务器建立起了一个长连接,这使得 frp 服务器可以随时发送数据给应用服务器(NAT 环境下,连接的建立只能是单向的;但连接建立后的通讯仍然可以是双向的)。frp 服务器还同时开始监听 B 端口上的传入连接。当有客户端想要访问应用服务器 A 端口上的服务时,它需要访问 frp 服务器的 B 端口。frp 服务器接到这个请求后,就通过刚才建立的那个长连接把请求转发给应用服务器,应用服务器处理完这个请求,把响应发送给了 frp 服务器,frp 服务器再次转发给客户端。整个流程就完成了。这就是 frp 的基本原理。

之前就在家里的路由器上尝试过搭建 frps 来提供内网穿透服务,但出于路由器系统更新后不再提供 frps 的软件包、以及家庭宽带连通性欠佳等因素,决定将 frps 转移到我的阿里云服务器上。那么,开始吧!

服务端(frps)

首先,从 GitHub 下载最新的 frp。frp 的官方地址是:https://github.com/fatedier/frp/releases。由于我的服务器系统是 CentOS 64 位,我需要下载后缀为 linux_amd64 的文件。

wget https://github.com/fatedier/frp/releases/download/v0.33.0/frp_0.33.0_linux_amd64.tar.gz

下载完成后解压文件:

tar -xzvf frp_0.33.0_linux_amd64.tar.gz

进入对应目录后,将可执行文件和配置文件复制到系统相应位置:

cp frps /usr/bin/frps
mkdir /etc/frp
cp frps.ini /etc/frp/frps.ini
cp systemd/frps.service /usr/lib/systemd/system/frps.service

重新加载 systemd 的服务项:

systemctl daemon-reload

在开启服务之前,需要对 frps 进行配置,frps 的配置文件位于 /etc/frp/frps.ini,如何配置可以参考:https://github.com/fatedier/frp/blob/master/README_zh.md。最后,启动服务并设置开机自启:

systemctl start frps
systemctl enable frps

如果启用了 Dashboard,在浏览器输入 http://[服务器地址]:[Dashboard端口]/,就能看到 frps 的 Dashboard 界面了。服务端的部署到此结束。

客户端(frpc)

首先在 https://github.com/fatedier/frp/releases 下载 frp,由于我使用的是 Windows 64 位的系统,我需要下载后缀为 windows_amd64 的文件。接着,再到 https://github.com/winsw/winsw/releases 下载 WinSW,下载后缀为 NET461 的文件即可。WinSW 可以把任何 EXE 文件打包成一个服务,从而免去了每次都要在命令行中打开的麻烦。解压 frp,和 WinSW 一起放在一个文件夹内。

配置 frpc.ini,如何配置可以参考 https://github.com/fatedier/frp/blob/master/README_zh.md。将 WinSW.NET461.exe 重命名为 frpc_service.exe。新建一个名为 frpc_service.xml 的文件,输入以下内容:

<service>
  <id>frpc</id>
  <name>FRPC</name>
  <description>This service runs frp client.</description>
  <executable>frpc.exe</executable>
  <arguments>-c frpc.ini</arguments>
  <logmode>rotate</logmode>
</service>

删除多余的文件,只留下以下几个文件:

把整个文件夹藏到 C:\Program Files\ 中,在文件夹中打开命令提示符,启动打包好的服务:

.\frpc_service.exe install
.\frpc_service.exe start

打开 service.msc,可以看到出现了一个新的服务,并且已经被设置为了开机自启:

为了让 frpc 能够在连接错误退出后重启,需要在恢复选项卡中设置自动重启:

如果启用了 Admin UI,在浏览器输入 http://localhost:[Admin UI端口]/,就能看到 frpc 的 Admin UI 界面了。客户端的部署到此结束。

接下来,就能体验 frp 的各种功能了!

参考文章

  1. CentOS 7 x64如何安装内网穿透工具frps服务器端