使用 frp 进行内网穿透

在开发移动应用的时候,通常会在 PC 端开启 API 服务,然后在手机上调试,这时候 debug 和更新代码就变得异常繁琐,如果能把 PC 的服务端口映射到公网上,那就会方便许多。

所谓的内网穿透,就是绕过内网,将端口暴露到公网,这样无论在那里,就可以连接内网系统。还有一种比较方便的应用就是买一个树莓派,将树莓派里的服务,例如博客,接口,内容管理系统等连接到公网,这样比在云计算商买要便宜很多,当然考虑到稳定性,这里只建议个人服务这么做。

之前有一款叫 ngrock 的穿透软件,用起来比较方便,但是之后版本它闭源了,这里推荐使用 frp,它的功能还是蛮强大的,它的中文文档: https://github.com/fatedier/frp/blob/master/README_zh.md

这里先介绍一种场景,就是通过自定义域名访问部署于内网的 web 服务。frp 是用 Go 语言写的,主要就两个可执行文件,frps 是用于 server 端的,而 frpc 是用于客户端的。 要进行内网穿透,这里需要有一台能够公网访问的服务器,可以在云计算厂商买最便宜的,然后将 frps 部署到服务器,把它当作一个桥梁,PC 端服务通过公网服务器连接到公网。 下面是部署过程:

  1. 在公网服务器部署 frps 主要是修改 frps.ini 配置文件:
    # frps.ini
    [common]
    bind_port = 7000
    vhost_http_port = 8080

    这里的 bind_port 是 PC 连接公网服务器的端口,而 vhost_http_port 是暴露到公网的端口,启动服务:

    ./frps -c ./frps.ini

    frp 还提供了 systemd 启动文件,systemd 文件的内容:

[Unit]
Description=Frp Server Service
After=network.target

[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/usr/bin/frps -c /etc/frp/frps.ini

[Install]
WantedBy=multi-user.target

我们把 frps 拷贝到 /usr/bin 目录,将配置文件拷贝到 /etc/frp 目录,最后将这个 systemd unit 配置文件拷贝到 /etc/systemd/system 目录下,启动服务:

sudo service frps start

通过 sudo service frps status 即可查看运行状态:

frps

注:如果服务器开启了防火墙,务必开放相应的 TCP 和 UDP 协议端口

  1. 在 PC 端运行 frpc

修改 frpc.ini 配置文件:

# frpc.ini
[common]
server_addr = x.x.x.x      # 这里是公网服务器的地址
server_port = 7000    # 对应于 frps 配置文件里的 bind_port

[web]
type = http     # PC 端的服务协议
local_port = 80   # PC 端服务端口
custom_domains = www.yourdomain.com  # 公网访问域名,这个域名的 DNS 是解析到公网服务器的 IP 地址,即这里的 server_addr 

启动客户端:

./frpc -c ./frpc.ini

通过浏览器访问 http://www.yourdomain.com:8080 即可访问到处于内网机器上的 web 服务。 这里需要注意的是各个端口的配置,假设我们在 PC 机开启一个临时 wordpress 服务,并穿透到公网 80 端口,那么配置如下:

PC 机:

php -S 0.0.0.0:3000   # PC 开启 wordpress 博客服务

公网服务器 frps.ini

[common]
bind_port = 7000
vhost_http_port = 80

PC 配置文件 frpc.ini:

[common]
server_addr = x.x.x.x      # 这里是公网服务器的地址
server_port = 7000 

[web]
type = http 
local_port = 3000
custom_domains = www.yourdomain.com  # 域名