一、客户端下载

https://github.com/fatedier/frp/releases

image.png

下载,解压后,得到如下文件(windows示例)。其中 frps 为服务端,frpc为客户端。frps_full.ini为全量配置信息,可以自己阅读后,挑选需要的配置信息,写入frps.ini即可完成配置。

image.png

通常如果在本机配置服务端,则删除客户端的3个文件,如果配置客户端则删除服务端的3个文件。如下(Linux服务端示例)

image.png

二、配置frps.ini和frpc.ini文件(最重要)

我的网络情况:有公网IP,但不可能直接把一根网线都给Frps,需要先到路由器,然后路由器下连接Frps,这种情况下,如何实现我的电脑A或者外网访问我的电脑B呢?

首先,我已经把本地的动态IP地址映射到了阿里云的固定域名解析服务上。也就是说我已经可以直接通过域名访问本地IP地址。

image.png

一、连接内网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,既表示连接成功。

image.png

然后在外网通过 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协议

内网穿透神器 frp 之进阶配置——stcp 及 p2p 模式

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协议。

image.png

4、UDP协议

 UDPTCP
是否连接无连接面向连接
是否可靠不可靠传输,不使用流量控制和拥塞控制可靠传输,使用流量控制和拥塞控制
连接对象个数支持一对一,一对多,多对一和多对多交互通信只能是一对一通信
传输方式面向报文面向字节流
首部开销首部开销小,仅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的任务计划程序。

image.png

当然,也可以借助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.cnblogs.com/x1you/p/12506405.htmlhttps://blog.csdn.net/qq_38963450/article/details/106153037https://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服务器寻找,这样就避免了同一个域名的尴尬。

(完)

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐