一、客户端下载
https://github.com/fatedier/frp/releases
下载,解压后,得到如下文件(windows示例)。其中 frps 为服务端,frpc为客户端。frps_full.ini为全量配置信息,可以自己阅读后,挑选需要的配置信息,写入frps.ini即可完成配置。
通常如果在本机配置服务端,则删除客户端的3个文件,如果配置客户端则删除服务端的3个文件。如下(Linux服务端示例)
二、配置frps.ini和frpc.ini文件(最重要)
我的网络情况:有公网IP,但不可能直接把一根网线都给Frps,需要先到路由器,然后路由器下连接Frps,这种情况下,如何实现我的电脑A或者外网访问我的电脑B呢?
首先,我已经把本地的动态IP地址映射到了阿里云的固定域名解析服务上。也就是说我已经可以直接通过域名访问本地IP地址。
一、连接内网windows远程桌面(极简)
1、frps.ini配置如下:
[common] bind_port = 7000
2、Frps服务器上,开放7000端口,开放3390端口。(windows在防火墙入站规则中设置)
3、在路由器上设置端口转发,将Frps的IP对应的7000端口 转发为域名 abcde.com 对应的7000端口上,将Frps的IP对应的3390端口 转发为域名 abcde.com 对应的3390端口上。
4、frpc.ini配置如下:
[common]
server_addr = abcde.com
server_port = 7000
[RDP]
type = tcp
local_ip = 192.168.1.5 # 我的电脑B的IP地址。
local_port = 3389
remote_port = 3390
5、在我的电脑B上开启远程桌面,确认3389端口已开启。
6、完成配置、端口开启、端口转发后,即可打开Frps服务端和客户端。出现sucess,既表示连接成功。
然后在外网通过 abcde.com:3390 既可连接内网中我的电脑B的远程桌面了。
7、上述配置数据最基本的极简式配置,为了安全性考虑,建议增加 token 和 oidc 设置等。
8、最后自建 frps 服务,虽然带宽畅通,但是如果要用做无人值守,还是需要安装向日葵,这样在出现问题后还有机会去修复。
二、更多配置内容
frp是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp, http, https, stcp 协议。
类型 | 描述 |
tcp | 单纯的 TCP 端口映射,服务端会根据不同的端口路由到不同的内网服务。 |
udp | 单纯的 UDP 端口映射,服务端会根据不同的端口路由到不同的内网服务。 |
http | 针对 HTTP 应用定制了一些额外的功能,例如修改 Host Header,增加鉴权。 |
https | 针对 HTTPS 应用定制了一些额外的功能。 |
stcp | 安全的 TCP 内网代理,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。 |
sudp | 安全的 UDP 内网代理,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。 |
xtcp | 点对点内网穿透代理,功能同 stcp,但是流量不需要经过服务器中转。 |
tcpmux | 支持服务端 TCP 端口的多路复用,通过同一个端口访问不同的内网服务。 |
1、TCP协议
我最常用的是tcp协议,因为无论是连接内网网页,还是远程桌面,还是SSH都可以用tcp协议。
#frps-配置
[common]
bind_port = 7000
#frpc-配置
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
[web]
type = tcp
local_ip = 127.0.0.1
local_port = 80
remote_port = 3395
记得配置打开端口和端口转发即可。
2、HTTP/HTTPS协议
http网页可以用HTTP协议,也可以用TCP协议。因为http协议的内网穿透,需要在服务端设置vhost_http_port,并且所有的http类型的客户端都将通过同一个vhost_http_port端口访问。同时需要在客户端设置custom_domains 二级域名。也就是说,http协议的解析,都是用通过服务端同一个端口,只是不同客户端的域名前缀不同。当然你要这样用还得开启阿里云的域名泛解析。
我的服务端在内网,显然没法正常使用这个协议。而且我也没开域名泛解析。
3、STCP/XTCP协议
STCP/XTCP协议,主要是解决TCP协议目前存在的问题:第一个是安全问题,端口暴露。第二个问题是网络问题,流量中转,网络延迟。
stcp协议主要解决安全问题,限制特定设备能够使用这个端口。但需要在发起请求的设备上也配置一个 frp 客户端。通过这个客户端带着密钥发起请求。
服务端:配置仍然同默认配置一致,直接运行即可
客户端 1:配置需要将 type 改为 stcp,并且增加一个 sk 字段。这里不需要远端端口,因为不公开
# frpc.ini
[common]
# 你的frp服务器的公网ip
server_addr = x.x.x.x
# 你的frp服务器的默认端口
server_port = 7000
[rdp]
type = stcp
# 只有 sk 一致的用户才能访问到此服务
sk = abcdefg
local_ip = 127.0.0.1
# 远程桌面的本地端口号
local_port = 3389
客户端 2:
# frpc.ini
[common]
# 你的frp服务器的公网ip
server_addr = x.x.x.x
# 你的frp服务器的默认端口
server_port = 7000
[rdp_visitor]
type = stcp
# stcp 的访问者
role = visitor
# 要访问的 stcp 代理的名字
server_name = rdp
# 只有 sk 一致的用户才能访问到此服务
sk = abcdefg
# 绑定本地端口用于访问 远程桌面 服务
bind_addr = 127.0.0.1
bind_port = 6000
此时,你在客户端 2,使用 127.0.0.1:6000 即可访问客户端 1 的远程服务。
xtcp 和 stcp 类似,主要是解决网络问题,实现点对点连接(p2p),流量不经过服务端。
服务端:配置需要增加一个 udp 端口 7001, (注意端口转发时协议类型选择udp)增加完之后就是如下
# frps.ini
[common]
bind_port = 7000
bind_udp_port = 7001
客户端 1:配置需要将 type 改为 xtcp 即可
客户端 2:配置需要将 type 改为 xtcp 即可
此时,你在客户端 2,使用同样的方式,以 127.0.0.1:6000 即可访问客户端 1 的远程服务。这种模式的好处是不需要消耗服务器的带宽和网速,延时也较低。不过该模式还在继续开发完善阶段,目前使用起来并不太稳定,很多时候会出现连不上的情况。并且与两端的路由器防火墙、DMZ、UPNP设置都有一些关系。一般公司网络都会有个DMZ区域,所以连接公司电脑,经常无法使用xtcp协议。
4、UDP协议
| UDP | TCP |
是否连接 | 无连接 | 面向连接 |
是否可靠 | 不可靠传输,不使用流量控制和拥塞控制 | 可靠传输,使用流量控制和拥塞控制 |
连接对象个数 | 支持一对一,一对多,多对一和多对多交互通信 | 只能是一对一通信 |
传输方式 | 面向报文 | 面向字节流 |
首部开销 | 首部开销小,仅8字节 | 首部最小20字节,最大60字节 |
适用场景 | 适用于实时应用(IP电话、视频会议、直播等) | 适用于要求可靠传输的应用,例如文件传输 |
TCP向上层提供面向连接的可靠服务 ,UDP向上层提供无连接不可靠服务。
虽然 UDP 并没有 TCP 传输来的准确,但是也能在很多实时性要求高的地方有所作为。
对数据准确性要求高,速度可以相对较慢的,可以选用TCP。
5、远程桌面的最佳选择(安全,稳定)
远程桌面不像文件传输,即便偶尔丢包又何妨?在windows8及以上(RDP8.0)的操作系统默认支持UDP,因此这里增加一条 sudp 隧道,转发本地 TCP 同端口的 UDP 数据到远程桌面服务器,使用以上配置即可解决远程桌面只能使用 TCP 传输数据的问题。判断远程桌面是否使用了 UDP 的方法如下:将远程桌面全屏,鼠标移动到最上方,会自动显示出远程桌面的连接栏,单击信号图标。
若启用udp,则弹框:与远程计算机连接的质量良好,并且已启用UDP。
若未启用udp,则弹框:与远程计算机连接的质量良好。
一个栗子:
#服务器端 frps.ini
[common]
#服务端启动端口
bind_port = 17777
#配置upd端口
bind_udp_port = 18888
#dashboard访问端口
dashboard_port = 17555
#dashboard访问账号
dashboard_user = admin
#dashboard访问密码
dashboard_pwd = 123456789dashboard_pwd
#token认证密码,客户端要相同
token = 123456789token
--------------------------------------------------------------------------
#客户端 frpc.ini
[common]
# 你的frp服务器的公网ip
server_addr = 8.210.210.60
# 你的frp服务器的默认端口
server_port = 17777
# token认证密码,客户端要相同
token = 123456789token
[rdp_11]
type = stcp
# 只有 sk 一致的用户才能访问到此服务
sk = 123456789sk
local_ip = localhost
# 远程桌面的本地端口号
local_port = 3389
[rdp_22]
type = sudp
# 只有 sk 一致的用户才能访问到此服务
sk = 123456789sk
local_ip = localhost
# 远程桌面的本地端口号
local_port = 3389
--------------------------------------------------------------------------
#登录端 frpc.ini
[common]
# 你的frp服务器的公网ip
server_addr = 8.210.210.60
# 你的frp服务器的默认端口
server_port = 17777
# token认证密码,客户端要相同
token = 123456789token
[rdp_11_visitor]
type = stcp
# stcp 的访问者
role = visitor
# 要访问的 stcp 代理的名字
server_name = rdp_11
# 只有 sk 一致的用户才能访问到此服务
sk = 123456789sk
# 绑定本地端口用于访问 远程桌面 服务
bind_addr = localhost
bind_port = 5000
[rdp_22_visitor]
type = sudp
# sudp 的访问者
role = visitor
# 要访问的 sudp 代理的名字
server_name = rdp_22
# 只有 sk 一致的用户才能访问到此服务
sk = 123456789sk
# 绑定本地端口用于访问 远程桌面 服务
bind_addr = localhost
bind_port = 5000
--------------------------------------------------------------------------
然后在本地用localhost:5000 或 127.0.0.1:5000 连接即可。优先用localhost:5000吧。
三、启动
1、windows下启动
管理员权限进入命令窗口,进入frp文件夹下,然后执行frps -c frps.ini &
(服务端)或frpc -c frpc.ini &
(客户端)。
2、windows下快速启动或自动启动
在 Frp 目录下新建一个文本,并改名为 start.bat,编辑这个 start.bat,在里面输入如下内容:
@echo off
:home
frpc -c frpc.ini
goto home
这样的话 Frp 在崩溃、异常退出进程后,将会自动重新启动,适用于无人值守。如果你想在 Frp 崩溃后直接退出,你可以输入以下内容:
@echo off
frpc -c frpc.ini
exit
双击这个 start.bat 文件,即可快速启动frp服务端或客户端。
如果需要开机启动,则利用windows的任务计划程序。
当然,也可以借助winsw 将frps程序转成windows的一个服务。
3、centos下启动
需要先把运行文件添加可执行权限。例如我的文件实在 root 文件夹中,我需要搭建 frp 服务端,那么待设置好服务端配置文件(frps.ini)后执行以下命令即可。
cd /root
chmod +x frps
nohup ./frps -c ./frps.ini &
执行成功后,会显示 frp 的进程号码。你可以通过命令来查看 frps 运行的进程编号。
ps -e | grep frps
4、centos下自动启动
centos7.0 以上的版本,服务都是基于 systemd 的方式进行管理的。frp 通过设置后也可以实现 systemd 的方式进行管理,这样我们就可以通过 systemctl 命令来进行服务的统一管理,同时通过这样的设置也可以将 frp 服务加入开机自启动。
1)、将 frp 设置成 linux 系统的服务,基于 systemd 方式管理
# 编写 frp service 文件,以 centos7 为例
vim /usr/lib/systemd/system/frps.service
# 内容如下
[Unit]
Description=frps daemon
After=syslog.target network.target
Wants=network.target
[Service]
Type=simple
#此处的路劲地址根据自己的实际放置的地址进行修改
ExecStart=/root/frp/frps -c /root/frp/frps.ini
Restart=always
RestartSec=1min
[Install]
WantedBy=multi-user.target
2)、将 frp 设置成开机自启动
systemctl enable frps
systemctl restart frps
5、mac下启动
1)新建frpc.plist文件
sudo vim ~/Library/LaunchAgents/frpc.plist
2)写入frpc.plist配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
<dict>
<key>Label</key>
<string>frpc</string>
<key>ProgramArguments</key>
<array>
<string>/Users/admin/software/frp_0.31.1_darwin_amd64/frpc</string>
<string>-c</string>
<string>/Users/admin/software/frp_0.31.1_darwin_amd64/frpc.ini</string>
</array>
<key>KeepAlive</key>
<true/>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
注意修改一下frpc所在的目录和配置文件的地址。
3)配置权限
sudo chown root ~/Library/LaunchAgents/frpc.plist
4)启动
sudo launchctl load -w ~/Library/LaunchAgents/frpc.plist
可在资源管理器中检查,看到frpc 的程序,运行用户是root,则已正常启动,可以正常使用。
问题,重启后以登陆用户运行,而非root用户(非root用户运行失效,无法正常使用)。因为mac电脑有SIP系统完整性保护策略,普通用户无法将服务永久加入root用户下(只能临时加入),所以重启后失效,要想让将服务加入root用户下,需要将mac彻底root去操作,而这不是最佳策略。
5)关闭当前登陆用户自动运行
launchct stop ~/Library/LaunchAgents/frpc.plist ,停止当前用户的Frpc程序,可以在资源管理器中检查。
launchctl unload -w ~/Library/LaunchAgents/frpc.plist ,前面不加 sudo ,就是以登陆用户的权限运行,关闭当前用户的自动启动。
6)制作root用户运行脚本文件,新建文件Frpc_start.command,如果每次开机都用,则放桌面,如果偶尔使用,则与Frpc程序放一起。脚本内容如下:
#!/bin/bash sudo launchctl load -w ~/Library/LaunchAgents/frpc.plist echo "Frp服务已启动"
然后在终端窗口中赋予执行权限 chmod +x 路径/Frpc_start.command ,然后每次开机需要使用Frpc服务,则双击该脚本,会提示让输入密码,输入密码后,即可root权限启动Frpc服务。
7)探索-mac下免root实现自动启动(失败)
利用 expect 实现执行 sudo 命令时自动输入密码,先安装expect ,expect 是Mac下的一个软件包,利用它可以很方便地在自动化流程中实现一些需要交互性的操作,我们直接通过brew就可以很方便地安装它。在终端中输入:brew install expect ,即可安装。(没安装brew 的参考 、、https://www.jianshu.com/p/d1ea8d40964e,brew国内的安装并不容易,expect的安装也不容易,主要问题还是下载源都是国外的)
然后,重写运行脚本:
#/usr/local/bin/expect
set timeout 3
set password 123456
spawn sudo chown root ~/Library/LaunchAgents/frpc.plist
spawn sudo launchctl load -w ~/Library/LaunchAgents/frpc.plist
expect "*asswor*"
send "$password\r"
interact
expect脚本需要expect Frpc_start.sh执行,而不是sh Frpc_start.sh,执行结果如下,呵呵哒,苹果这保护机制真是……,自动输入密码就强制在当前用户下执行,看来这个方法不行。(如果可行的话,还是可以在shell中嵌套expect脚本,然后添加到登录项,就可以实现自动开机运行,这个方案pass吧)
daveydeMacBook:~ davey$ expect /Users/honfo/Desktop/Frpc_start.sh
spawn sudo chown root ~/Library/LaunchAgents/frpc.plist
spawn sudo launchctl load -w ~/Library/LaunchAgents/frpc.plist
Password:
/Users/honfo/~/Library/LaunchAgents/frpc.plist: No such file or directory
daveydeMacBook:~ davey$
6、服务关闭
windows下关闭,直接关闭命令窗口就行,如果是自动启动,则在任务计划程序中停止。
centos7下关闭,查看 frp 进程号,然后 kill -9 进程号,即可。
mac下关闭,终端运行 sudo launchct stop ~/Library/LaunchAgents/frpc.plist
四、其他
服务端和客户端的管理界面,可以通过配置文件实现。
更多配置项的详情可以参考frps_full.ini 和 frpc_full.ini文件。
内网穿透异地组网,最好使用STCP、SUDP、XTCP安全协议。
windows远程桌面工具技巧
内网穿透连接多台windows桌面时,比如localhost:50、localhost:60,这时,用windows自带的远程桌面,连接localhost:50且保存密码,再连接localhost:60且保存密码,然后再连接localhost:50,则会引用localhost:60的账密,因为这两个桌面域名都是localhost,会被windows远程桌面认为是同一个。解决办法:
修改windows的hosts文件,C:\WINDOWS\system32\drivers\etc,在文末追加:
127.0.0.1 localhost1
127.0.0.1 localhost2
127.0.0.1 localhost3
需要几个追加几个。hosts的作用是建立域名与IP之间的关系,你在浏览器输入网址后,系统会先从hosts处寻找域名对应的IP,如果没有,系统会从指定的DNS服务器寻找,这样就避免了同一个域名的尴尬。
(完)