FRP是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

前言

因为公司属于良心型公司,几乎不加班。于是乎,不爱加班的我天天回家便各种躺平。但是出于程序猿的自我危机感,还是决定回家后稍微蹦跶下吧。其实早在毕业前就想蹦跶了,但是因为写(~比~)毕(~较~)设(~懒~)所以没行动起来。

至于为何会自己在家捣鼓起FRP,这就需要去问我精致的广东男孩同事甲
具体起因是因为我的title是云计算工程师,然后又想折腾点东西,便选择了折腾Cloud比较常用的管理云平台中多个主机上的容器化的应用的工具 -- k8s

因为部署k8s我需要linux系统,就装了台Ubuntu 20.04虚拟机;因为虚拟机所在宿主机不好用,便配置了虚拟机ssh环境和mac上的远程终端工具Termius,让我可以在mac上操作虚拟机;因为我想在公司使用mac能ssh处在家中内网环境的虚拟机,便要做VPN代理或者内网穿透;因为甲建议内网穿透或者找收费内网穿透服务,那肯定自己做内网穿透啊,于是甲给我推荐了FRP ~_~。

为什么会是FRP

通过在具有公网 IP 的节点上部署 frp 服务端,可以轻松地将内网服务穿透到公网,同时提供诸多专业的功能特性,这包括:

  • 客户端服务端通信支持 TCP、KCP 以及 Websocket 等多种协议。
  • 采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间。
  • 代理组间的负载均衡。
  • 端口复用,多个服务通过同一个服务端端口暴露。
  • 多个原生支持的客户端插件(静态文件查看,HTTP、SOCK5 代理等),便于独立使用 frp 客户端完成某些工作。
  • 高度扩展性的服务端插件系统,方便结合自身需求进行功能扩展。
  • 服务端和客户端 UI 页面。

以上内容来自FRP官方文档简介,经过整个部署过程和使用体验,frp确实具有这些功能特性,同时最重要的特性便是部署是真的简单,甚至可以说是无脑,具体见下文。

开始部署FRP

根据官网教程去github release页面下载了最新版本的linux amd64 二进制文件。下载后便是解压了,然后将解压的文件夹拷入阿里云公网服务器(xxx.xxx.xxx.xxx)和内网虚拟机(192.168.3.54)内了。

scp -r frp_0.37.0_linux_amd64/ hh@192.168.3.54:/home/hh/
scp -r frp_0.37.0_linux_amd64/ root@xxx.xxx.xxx.xxx:/root/

然后ssh进入公网服务器内,将刚拷入的frp_0.37.0_linux_amd64的文件夹中内frpc相关文件删除,因为frpc为客服端文件,也就是我们虚拟机该跑的东西。

cd /root/frp_0.37.0_linux_amd64
rm -rf frpc*
cd systemd
rm -rf frpc*

删除公网服务器内多余的frp文件后,配置frpc.ini,设置了 frp 服务器用户接收客户端连接的端口,内容如下:

[common]
bind_port = 7000

开始配置systemd 服务。使用systemd的原因是为了服务可以常驻在服务器内,开机后服务也会自动启动。

首先建需要用到的配置和脚本命令软链接到它该在的地方,注意软链接时必须用绝对路径。

cd /root/frp_0.37.0_linux_amd64
ln -s /root/frp_0.37.0_linux_amd64/frps /usr/bin/frps
sudo mkdir -p /etc/frp/
ln -s /root/frp_0.37.0_linux_amd64/frps.ini /etc/frp/frps.ini
ln -s /root/frp_0.37.0_linux_amd64/systemd/frps.service /lib/systemd/system/frps.service

软链接都做完后,便可以载入systemd服务设置开机自启,并启动它了。

sudo systemctl daemon-reload
sudo systemctl enable frps.service
sudo systemctl start frps.service

到这里公网服务器部分的frp便部署好了。然后便是按照上面操作配置内网虚拟机的frpc。

# 删除grps
cd /home/hh/frp_0.37.0_linux_amd64
rm -rf frps*
cd systemd
rm -rf frps*

# 配置frpc.ini 内容如下:
[common]
server_addr = xxx.xxx.xxx.xxx
server_port = 7000

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000



# 进行软链接
ln -s /home/hh/frp_0.37.0_linux_amd64/frpc /usr/bin/frpc
sudo mkdir -p /etc/frp/
ln -s /home/hh/frp_0.37.0_linux_amd64/frpc.ini /etc/frp/frpc.ini
ln -s /home/hh/frp_0.37.0_linux_amd64/systemd/frpc.service /lib/systemd/system/frpc.service

# 载入systemd服务
sudo systemctl daemon-reload
sudo systemctl enable frpc.service
sudo systemctl start frpc.service

到这里FRP便部署好了,下面便可以开始测试了

内网穿透测试

FRP部署好后,测试还是很简单的,只需使用ssh,看是否能连接公网服务器的公网IP 6000端口,命令如下:

ssh -oPort=6000 hh@xxx.xxx.xxx.xxx

然后很不幸的是连接失败,猜测是内网虚拟机可能无法连接公网服务器7000端口。

先进入到内网虚拟机中查看frpc.service的状态

sudo systemctl status frps.service

2021/07/07 22:02:14 [W] [service.go:104] login to server failed: dial tcp xxx.xxx.xxx.xxx:7000: connect: connection timed out
dial tcp xxx.xxx.xxx.xxx:7000: connect: connection timed out

发现输出果然显示无法连接公网IP 7000端口,使用telnet xxx.xxx.xxx.x 7000进行验证发现确实无法连接,应该是公网服务防火墙没有开放7000端口的原因,使用以下命令进行开发,顺带把6000端口一并开放:

firewall-cmd --zone=public --add-port=7000/tcp --permanent
firewall-cmd --zone=public --add-port=6000/tcp --permanent
firewall-cmd --reload

因为我的公网服务器是阿里云的,配置有安全组规则,所以去阿里云控制台修改了下安全组规则,对6000,7000端口进行暴露,然后再进行测试。

ssh -oPort=6000 hh@xxx.xxx.xxx.xxx




Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.8.0-59-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

156 updates can be installed immediately.
0 of these updates are security updates.
To see these additional updates run: apt list --upgradable

Your Hardware Enablement Stack (HWE) is supported until April 2025.
Last login: Thu Jul  8 00:37:26 2021 from 192.168.3.55
hh@ubuntu:~$

测试完成,到此FRP部署正式完成,内网穿透完成,完结撒花✿✿ヽ(°▽°)ノ✿。

后记

后续遇到的问题

  1. 多台内网服务器需要对外网暴露时,不允许有proxy名重复。也就是frpc.ini文件中的[ssh],不能全部都叫[ssh],否则会出现[ssh] start error: proxy name [ssh] is already in use错误,可以换个名字,例如[ssh_r4b]
Last modification:August 24th, 2021 at 09:06 pm