FRP (Fast Reverse Proxy)是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。
Github仓库:https://github.com/fatedier/frp
官方文档介绍:frp/README_zh.md at dev · fatedier/frp · GitHub
除了开源的frp,常见的还有如下内网穿透/远控工具:
- TeamViewer:TeamViewer是国内外知名的远程控制、远程会议软件,额外提供文件上传下载等实用功能,比QQ远程协助好用。虽然个人版免费,但是现在TeamViewer商业化道路一去不复往,原来还爆出过漏洞;
- 向日葵:向日葵远控软件是贝锐科技旗下的产品,注册账户后可免费体验内网穿透功能;
- ToDesk:号称免费安全流畅的远程控制软件,用过一段时间,免费版体验还不错,只是会限速;
- Sakura frp:没用过,但是据说还不错,也是免费的,可以自行搜索了解。
今天主要介绍用FRP实现在外网远程桌面连接访问本地没有公网IP(内网)的Windows电脑。其中我的公网服务器上的操作系统为 CentOS 7
,希望被控的客户端为 Window 10
,控制端可以随意,可以在 Windows、Android 或 iOS 设备上使用远程桌面连接到 Windows 10 远程电脑。
注意两个前提:
- 需要拥有一台公网服务器 或 VPS 用于部署服务端进行服务转发。
- 希望被远程控制的电脑需要是 Windows专业版 以上(专业版,企业版,服务器版) 才行,Windows家庭版 ,教育版默认情况下可以远程连接别的电脑,但是不能被远程连接。
一.VPS安装配置FRP服务端(frps)
1.连接服务器
2.从官方下载地址下载最新版本的服务端
官方下载链接:https://github.com/fatedier/frp/releases
根据服务端和客户端平台不同,请按照下面对应关系下载:
- windows系统:32位系统下载frp_0.36.2_windows_386.zip,64位系统下载 frp_0.36.2_windows_amd64.zip,如果不知道系统多少位,请下载32位;
- mac系统:下载 frp_0.36.2_darwin_amd64.tar.gz;
- linux系统:32位系统下载 frp_0.36.2_linux_386.tar.gz,64位系统下载 frp_0.36.2_linux_amd64.tar.gz,不知道系统位数请下载32位的;
- 树莓派/路由器等:32位系统下载 frp_0.36.2_linux_arm.tar.gz,64位系统下载 frp_0.36.2_linux_arm64.tar.gz,如果不知道系统多少位请直接下载32位的。
找到对应的最新的版本进行下载:
鼠标右键,复制服务端软件的下载链接 ,在Xshell中粘贴地址,使用 wget
进行下载:
wget https://github.com/fatedier/frp/releases/download/v0.36.2/frp_0.36.2_linux_amd64.tar.gz
最后一行显示已经下载完成,可以查看一下:
可以看到,在根目录下确实存在下载文件,接着可以进行解压
3.解压
tar -xzvf frp_0.36.2_linux_amd64.tar.gz
4.配置文件
切换目录,进入解压后的目录:
cd frp_0.36.2_linux_amd64
编辑frps配置文件:
vi frps.ini
编辑配置文件如下,按【i】键编辑,按【Esc】键退出编辑,再按 :wq
退出并保存
[common]
bind_port = 7000
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = 123456
token = 12345678
bind_port 为客户端与服务端进行通信的端口,默认是7000,可以改成其他的
dashboard_user 、dashboard_userfrp管理后台用户名和密码,请改成自己的
token安全授权码,请改成更复杂的
dashboard_port 为frp管理后台端口,请按自己需求更改
配置好Dashboard后可以通过浏览器查看frp的状态以及代理统计信息展示
5.端口放行
注意在配置服务端以后需要在服务器的防火墙放行相应的端口:
firewall-cmd --zone=public --add-port=7000/tcp --permanent
firewall-cmd --zone=public --add-port=7500/tcp --permanent
放行以后没有完,需要重启防火墙(这里也是个巨坑,我开始没有重启防火墙导致端口一直未处于聆听状态进而导致服务不可用)
重启防火墙:
firewall-cmd --reload
验证新增加端口是否生效
firewall-cmd --zone=public --query-port=7000/tcp
firewall-cmd --zone=public --query-port=7500/tcp
验证出现 " Yes" 字样就表示放行成功了。
后期如果想更改端口,可以取消前面放行的端口,防火墙取消某一开放端口:
firewall-cmd --zone=public --remove-port=7500/tcp --permanent
附CentOS 防火墙常用命令 :
1.查看防火墙状态:
firewall-cmd --state
2.启动防火墙
systemctl start firewalld
3.关闭防火墙
systemctl stop firewalld
4.检查防火墙开放的端口
firewall-cmd --permanent --zone=public --list-ports
5.开放一个新的端口
firewall-cmd --zone=public --add-port=7750/tcp --permanent
6.重启防火墙
firewall-cmd --reload
7.验证新增加端口是否生效
firewall-cmd --zone=public --query-port=7750/tcp
8.防火墙开机自启动
systemctl enable firewalld.service
9.防火墙取消某一开放端口
firewall-cmd --zone=public --remove-port=7500/tcp --permanent
6.测试服务端
测试服务端是否能正常运行:
./frps -c frps.ini
7.访问面板
面板仅供参考,可用可不用。在浏览器地址栏输入:服务器IP:7500
回车,如果显示输入登录用户名和密码就说明面板可以成功访问。再输入上面配置的用户名和密码即可: admin/123456
浏览器打开"http://服务器IP:后台管理端口" ,输入用户名和密码可以查看连接状态:登陆可以看到如下界面:
二.电脑(windows10)安装配置FRP客户端(frpc)
1.下载frps客户端
2.解压后编辑配置文件
内网的电脑上安装同样版本的frp,安装方法同服务端一样。
客户端我们只需要关注这三个文件frps相关的文件,frps相关的是服务端文件,在客户端可以选择删除。
- frpc 客户端启动程序
- frpc.ini 客户端配置文件
- frpc_full.ini 客户端全量配置文件
首先配置一下 frpc.ini:
[common]
server_addr = 服务器IP
server_port = 7000
token = 12345678
`[RDP]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 7001`
- server_addr就是你公网服务器的IP。
- server_port服务端设置的端口。
- token安全授权 token,需与服务端设置的token一致。
- type为代理的类型,设置为tcp类型。
- local_ip为电脑在局域网中的内网 IP (如是本机,也可使用 127.0.0.1),即本地需要暴露到公网的服务地址。
- local_port为远程桌面的默认端口,本地需要暴露到公网的端口。
- remote_port为内网提供给外网访问的服务端口。
下面是我的配置文件:
[common]
server_addr = xx.xx.xx.xx
server_port = 7000
token = 12345678
tls_enable = true
`[RDP]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 7001`
每个服务的 remote_port 是远程访问时要用到的端口号,远端端口也要在服务器的防火墙和安全组里放行才能顺利访问的,如上面的 7001
remote_port 在服务器防火墙上进行放行:
firewall-cmd --zone=public --add-port=7001/tcp --permanent
firewall-cmd --reload
3.运行FRP客户端
把配置好的文件 frpc.ini 与程序 frpc.exe 复制到内网电脑上。
我这里复制到C盘根目录:
在该目录下右键运行 "Open in Windows Terminal" , 如果没有这个可以按住【Shift】健后点击鼠标右键,选择 "在此处打开Power Shell窗口",输入以下命令运行客户端:
./frpc -c frpc.ini
这时服务端也会出现相应提示:
对于一般的内网,应该会显示上述在 Power Shell 中成功 "start proxy success" 的字样,但是,学校的内网做了安全处理,导致我连接失败了。。。
由于我这内网的一些安全原因,如果不加上"tls_enable = true"进行加密传输,就会出现如下连接不上的错误:
这个错误搞了好久,终于在网上看到有人跟我遇到相同的报错了,他通过流里抓包分析,发现是他 "公司的防火墙应该是探测到了某些特征流量而触发了规则,导致frp认证的包被重置,于是服务端frp关闭了链接,而翻开源码,我们能看到再发送完认证信息后执行了ReadMsgInto
方法,因为连接已经关闭,所以我们就得到了EOF错误!究其原因,很有可能是这一段明文数据暴露了frp,然后导致被防火墙封杀。
那么如何解决login to server failed: EOF
的问题呢?
其实看了源代码就知道了,原来frp在v0.25.0版本后增加了一个客户端选项,支持了tls传输,也就是传说中的非对称加密,原来在frps初始化服务时,在内存中已经为我们生成了一个简易的TLS服务,简直完美!
开启的办法很简单,在客户端原来的[common]
配置中加入tls_enable = true
即可! "
因此,我猜测学校内网也是同样探测到了特征流量导致frp被阻断了,于是必须加上 tls_enable = true
加了这一行就成功了:
如果运行出现下面的错误,则很有可能是服务端的配置出了问题,例如服务器的端口未放行,frp服务未启动等等
三.远程桌面连接
1.打开Windows远程桌面连接
首先需要开启被连接的电脑 windows10 远程桌面。打开控制面板=>系统=>高级系统设置,切换到"远程",选择"允许远程连接到此计算机",并勾选身份验证选项,如下图所示:
(下图摘自网页)
2.从外部网络进行远程连接
现在我们在外网任意一台电脑,搜索并打开windows远程桌面程序:
输入 服务器IP:remote_port
例如:1.2.3.4:7001 (冒号是英文符号),就可以连接到内网的windows了。
在此过程中需要输入内网电脑的用户名和开机密码后才能进行远程操控。
由于没有截图,远程连接的过程使用的是网页的图片。
(下图摘自网页)
(下图摘自网页)
四.相关问题
1. 服务端启动报错 Exec format error
/frpc: cannot execute binary file: Exec format error
这是下载错文件了,下载的 FRP 与操作系统处理器架构不匹配,需要重新下载正确的文件。
可以使用 arch
、uname -a
等命令查看系统架构。如:
$ arch
# 输出
x86_64
FRP 版本与 Linux 系统处理器架构对比参考:
| FRP类型 | 处理器架构 | |----------|-------------| | 386 | X86架构 | | amd64 | amd架构 | | arm | arm架构 | | arm64 | 64位arm架构 | | mips | mips架构 | | mips64 | 64位mips架构 | | mipsle | mipsle架构 | | mips64le | 64位mipsle架构 |
2.无法远程
如果排除了其他原因,还是无法远程访问,我们需要对内网电脑的远程进行设置。右键点击「此电脑」-「属性」,找到「远程设置」,在「远程桌面」中勾选「允许远程连接到此计算机」,同时取消「仅允许运行使用网络级别身份验证的远程桌面的计算机连接」的勾选,然后点击「确定」。
(下图摘自网页)
最后,我们需要打开 Windows 防火墙给以上服务予以放行,在控制面板\所有控制面板项\Windows Defender 防火墙\允许的应用
中点击「更改设置」,然后在下面找到「远程桌面」和「远程桌面(webSocket)」并分别勾选上「专用」和「公用」。
(下图摘自网页)
3.服务端开机启动和后台运行
编辑 frps.service:
vi /etc/systemd/system/frps.service
(下图摘自网页)
编辑配置文件如下,按【i】键编辑,按【Esc】键退出编辑,再按 :wq
退出并保存
(下图摘自网页)
[Unit]
Description=frps daemon
After=syslog.target network.target
Wants=network.target
[Service]
Type=simple
ExecStart=/root/frp_0.36.2_linux_amd64/frps -c /root/frp_0.36.2_linux_amd64/frps.ini
Restart= always
RestartSec=1min
[Install]
WantedBy=multi-user.target
注意ExecStart中要配置成自己的路径
完成后,可以通过下面的命令进行控制frp服务端
启动frps:sudo systemctl start frps
打开开机自启动:sudo systemctl enable frps
重启应用:sudo systemctl restart frps
停止应用:sudo systemctl stop frps
查看应用的日志:sudo systemctl status frps
运行下面的命令启动并设置开机启动
systemctl start frps && systemctl enable frps
(下图摘自网页)
4.客户端开机启动及后台运行
cmd 命令提示符下启动 FRP 虽然简单便捷,但一直启动着一个黑色的 cmd 界面看上去并不完美,更为重要的是,还会因无意中的关闭导致中断而没有任何办法。
NSSM 是一个可以将指定脚本或可执行程序注册为 Windows 系统服务的小巧而优秀的工具。同类型工具还有winsw 和 easy-service 等。
我们这里介绍使用 NSSM 将 FRP 启动脚本注册为 Windows 系统服务的方法。
1、 下载:从官网下载 NSSM,地址为:https://nssm.cc/download。注意,window10 系统要下载 prerelease 版本。
2、 解压:解压下载的 zip 文件至本地目录,根据当前电脑系统类型选择 win32 位或 win64 位目录下的 nssm.exe
文件,打开 cmd 命令提示符进入到该文件所在目录。
3、 服务注册:在 cmd 命令行输入 ./nssm.exe install frpc
,回车,在弹出的对话框中,path 处选择启动frpc的脚本,然后点击Install service
注册服务。
提示: 启动 frpc 的批处理脚本可以建立在客户端所在目录下。例如上图Path路径下选择的 start.bat
文件,该文件是我自己建立的,新建一个文本文件,改后缀并命名为 start.bat
,其内容仅为一行命令: ./frpc -c frpc.ini
4、 服务启动:通过以上操作后,即可以在本地计算机服务列表中看到 frpc 服务。打开本地服务程序的方法为:按键 Win+R
,输入 services.msc
。
可以自己设置启动类型,我这里设置成 手动 ,在不需要远程的时候都是关闭状态,在出差或者离开学校之前再启动就行。
nssm
其他命令参考:
- 创建一个服务名称为 servicename 的服务
nssm install servicename - 启动创建的servername服务
nssm start servicename - 停止创建的servername服务
nssm stop servicename - 重新启动创建的servername服务
nssm restart servicename - 删除创建的servername服务
nssm remove servicename