使用 frp 工具实现内网穿透
1. frp 工具简介
frp 是一款高性能的反向代理应用,专注于内网穿透。它支持多种协议,包括 TCP/UDP、HTTP/HTTPS 等,提供了加密、压缩,身份认证,代理限速,负载均衡等众多能力。此外,还可以通过 xtcp 实现 P2P 通信。使用 frp,可以安全、便捷地将内网服务暴露到公网,通过拥有公网 IP 的节点进行中转。
frp 采用经典的 C/S 模式,将服务端部署在具有公网 IP 的机器上,客户端部署在内网或防火墙内的机器上,通过访问暴露在服务器上的端口,反向代理到处于内网的服务。

2. 配置拥有公网 IP 的服务器
2.1 下载 frp 安装包
首先,查看自己服务器 CPU 的信息,方便后面选择安装包
$ lscpu

根据操作系统(OS)和 CPU 的架构,选择相应的 frp 安装包,

这里选择 frp_0.53.2_linux_amd64.tar.gz,具体安装包的下载方式根据自己服务器的网络情况而定,
-
比如,直接在服务器上使用
wget工具 进行下载$ wget https://github.com/fatedier/frp/releases/download/v0.53.2/frp_0.53.2_linux_amd64.tar.gz -
或者先下载到自己的本机,再通过
scp工具上传到服务器$ scp D:\Users\borne\Downloads\Temp\frp_0.53.2_linux_amd64.tar.gz TC_born:/home/borne
将 frp_0.53.2_linux_amd64.tar.gz 压缩包解压到 /usr/local/ 目录下,得到下列文件,
frpc/frps:frp 的客户端(client)/ 服务器端(server)程序,需要放到内网服务 / 拥有公网 IP 的机器上;frpc/frps.toml:frp 的客户端程序(frpc)/ 服务器端程序(frps)的配置文件;

2.2 配置 frps.toml 文件
通过简单配置 TCP 类型的代理,使用户能够访问内网服务器。
部署 frps 并编辑 frps.toml 文件。以下是简化的配置,其中设置了 frp 服务器用于接收客户端连接的端口:
bindPort = 7000
注:
bindPort可自行设置成其他端口!
如果你使用的云服务商的主机绑定了安全组,需要手动登录服务器的云控制台,在网络安全组中将 7000 端口设置为进站出站的放行策略,才能在后续进行访问,具体过程,详见之前写过的一篇文章《如何开启服务器的自定义端口?》。
2.3 使用 systemd 管理 frp 服务
可以直接通过下面的命令去直接启动 frp 服务器或者客户端,
-
启动 frp 服务器
$ ./frps -c ./frps.toml -
启动 frp 客户端
$ ./frpc -c ./frpc.toml
注意:上面这种运行方式,一旦关闭终端相应的 frp 服务就会终止。
所欲对于类似 frp 这种需要在后台长期运行的服务,最好去结合其他工具,比如:systemd 和 supervisor 进行管理。
使用 systemd 工具来管理 frps 服务,包括启动、停止、配置后台运行和设置开机自启动,大致步骤如下,
-
在
/etc/systemd/system目录下创建一个frps.service文件,用于配置frps服务$ sudo vim /etc/systemd/system/frps.service写入内容,
[Unit] # 服务名称,可自定义 Description = frp server After = network.target syslog.target Wants = network.target [Service] Type = simple # 启动 frps 的命令,需修改为相应的 frps 的安装路径 ExecStart = /path/to/frps -c /path/to/frps.toml [Install] WantedBy = multi-user.target -
使用
systemd命令管理frps服务# 启动frp sudo systemctl start frps # 停止frp sudo systemctl stop frps # 重启frp sudo systemctl restart frps # 查看frp状态 sudo systemctl status frps -
设置
frps开机自启动$ sudo systemctl enable frps
通过上述步骤,可以轻松地使用 systemd 来管理 frps 服务,实现启动、停止、自动运行和开机自启动。

同理,也可以使用 systemd 来管理 frpc 服务,
[Unit]
# 服务名称,可自定义
Description = frp client
After = network.target syslog.target
Wants = network.target
[Service]
Type = simple
# 启动 frpc 的命令,需修改为相应的 frpc 的安装路径
ExecStart = /path/to/frpc -c /path/to/frpc.toml
[Install]
WantedBy = multi-user.target
3. 配置内网服务所在的机器
为了能够实现内网穿透,仿照前面 frps 的配置(拥有公网 IP 的服务器),同样的需要在内网服务所在的机器上部署 frpc 并编辑 frpc.toml 文件。
3.1 通过 SSH 访问内网机器
假设 frps 所在服务器的公网 IP 地址为 x.x.x.x。以下是简单的示例配置:
serverAddr = "x.x.x.x"
serverPort = 7000
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000
localIP和localPort配置为需要从公网访问的内网服务的地址和端口,比如:上面ssh服务的默认端口是22remotePort表示在 frp 服务端监听的端口,访问此端口的流量将被转发到本地服务的相应端口。
注意:服务器端除了
serverPort需要开放之外,remotePort也需要服务器的云控制台中进行开放。
配置完成后,启动服务端 frps 和 客户端 frpc ,
-
启动服务器

-
启动客户端

-
启动客户端后,服务器与客户端之间建立了连接

使用以下命令通过 SSH 访问内网机器,假设用户名为 test:
$ ssh -o Port=6000 test@x.x.x.x

3.2 通过 RDP 远程桌面访问内网机器
关于 RDP,百科中有这样一段介绍,
远程桌面协议(英语:Remote Desktop Protocol,缩写:RDP)是一个多通道(multi-channel)的协议,让用户(客户端或称“本地电脑”)连上提供微软终端服务的电脑(服务端或称“远程电脑”)。大部分的 Windows 都有客户端软件。其他操作系统例如 Linux、FreeBSD、Mac OS X,也有对应的客户端软件
由于 RDP 远程桌面访问的通用性,所以下面重点说一下如何基于 frp 实现通过 RDP 远程桌面访问内网机器。
3.2.1 Linux 客户端
对于 Linux,首先在内网机器上通过 netstat 查询,xrdp 服务的 IP 地址和端口号,

然后,同样通过 frp 客户端(frpc)配置文件(frpc.toml),配置 xrdp 服务,
[[proxies]]
name = "xrdp"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3389
remotePort = 6001
注意,对于不同的服务通常需要配置不同的 remotePort,否则会出现错误,

3.2.2 Windows 客户端
下载针对 Windows 的 frp 客户端(frp_0.53.2_windows_amd64.zip),解压后得到下列文件,

同样也是配置 frpc.toml 文件,
[[proxies]]
name = "RDP"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3389
remotePort = 6002
然后,在 Windows Powershell 窗口中运行 frpc 客户端,即可
$ \path\to\frpc.exe -c \path\to\frpc.toml

和在 Linux 中使用 systemd 或 supervisor 管理 frp 服务一样,为了方便 frp 后续的使用,在 Windows 中同样也进行类似的处理,将可执行文件打包成系统服务,然后让服务在后台自动运行。
在 Windows 中使用 WinSW 来打包服务,大致流程如下,
-
获取
WinSW.exe或WinSW.zip,然后将其放置到 frp 服务所在目录下,可将其重命名为WinSW_frpc.exe
-
在当前目录下,创建
WinSW_frpc.exe的配置文件WinSW_frpc.xml<service> <id>frpc</id> <name>frpc</name> <description>frp client</description> <executable>frpc.exe</executable> <arguments>-c frpc.toml</arguments> <onfailure action="restart" delay="60 sec"/> <onfailure action="restart" delay="120 sec"/> <logmode>reset</logmode> </service> -
在 Windows Powershell 窗口中运行
WinSW_frpc.exe install [options]来安装服务
-
在 Windows Powershell 窗口中运行
WinSW_frpc.exe start来启动服务
此时,从 Windows 的服务管理中,可以发现已经能够查找到 frpc 服务,

为了方便文件传输,也可以在 Windows frpc 客户端中配置 ssh 服务,基本原理和前面提到的在 Linux frpc 中配置 ssh 服务类似,但是由于 Windows 的特殊性也有些不同的地方,大致流程如下,具体详见这篇文章
-
需要在 Windows 可选功能中添加 OpenSSH 服务器和客户端

-
在 Windows 服务 中设置
OpenSSH Authentication Agent和OpenSSH SSH Server启动类型为自动,并立即启用
-
在 Windows 防火墙对 OpenSSH 进行放行,勾选专用和公用

注意:SSH 登录的用户名可以在
C:\Users\下去找,密码的话就和通过 RDP 进行访问时用的密码相同。
4. 可能遇到的问题
4.1 查看服务器端口是否成功开放
可以使用 nmap 工具检测服务器端口号,
$ nmap -Pn IP地址 -p 端口号

也可以使用 telnet 工具
$ telnet IP地址 端口号
假设服务器的 IP 地址是 x.x.x.x ,使用 telnet 测试出现以下内容说明服务器的该端口开放,
Trying x.x.x.x...
Connected to x.x.x.x.
Escape character is '^]'.
Connection closed by foreign host.
注意:不管是
nmap工具也好,telnet工具也罢,都只能检测服务器自身(比如:防火墙)对端口的控制,检测不到云服务商的主机绑定的安全组是否开放了端口。对于一台没有配置防火墙的服务器,无论安全组配置如何,用这两个工具检测的任意端口的结果都显示的是开放状态,所以一定别忘了要在安全组也开放相应端口。
4.2 查询内网服务的地址和端口号
比如通过 netstat 查询 ssh 服务的 IP 地址和端口号,
$ netstat -nltp | head -n 2 && netstat -nltp | grep -i ssh
结果如下:

5. 写在最后
这不快放寒假了吗,想着在家里的时候也能用上学校的机器,于是便有了上面这一系列的折腾,嗯,希望能用上。
留下评论