使用 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
服务的默认端口是22
remotePort
表示在 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. 写在最后
这不快放寒假了吗,想着在家里的时候也能用上学校的机器,于是便有了上面这一系列的折腾,嗯,希望能用上。
留下评论