FRP搭建内网穿透服务指南

  有时候,我们回家了想要访问公司电脑上的一些资料,或者远程到公司的电脑,再或者访问公司内网的网页服务,但是我们并不知道公司的网络地址,也不知道如何访问局域网中的服务;这时候我们就需要用到一个叫内网穿透的工具了,世面上有很多类似的工具,其中大部分都是需要收费的,这里我们介绍一款成本较低、开源的软件Frp。

介绍

  Frp是一款开源的高性能的反向代理软件,专注于内网穿透,它支持多种协议,包括TCP、UDP、HTTP、HTTPS 等;通过frp,我们可以很方便的将内网的服务暴露到公网,通过有公网IP的服务器节点进行中转,例如Linux的ssh或者windows的远程控制服务;而世面上的很多内网穿透软件也是基于Frp开发的。

  Frp是一种典型的C/S架构,其大致流程如下图所示:

流程架构

截至本文发稿时,frp最新版本为0.60.0。

  通过流程图发现,我们前期需要完成以下准备工作:

  域名的话,可以去万网注册一个,选一些不常用的,如vip或者fun等,一年也就一包烟的价格。

域名注册

  下面是准备一台公网IP的服务器,如果是电信的小伙伴,且家里有闲置电脑,可以百度一下:电信公网IP申请,然后自行打电话跟客服小姐姐说一下,记得千万不要说是因为家里的监控摄像头需要公网IP,也千万不要去为难人家小姐姐说去投诉说公网IP是我们的权利。

  如果拿到了公网IP,就可以在路由器里面进行端口映射,这一步主要针对的是那些动手能力强外加脸皮厚的童鞋;但是如果你不想自己动手并且嫌麻烦的话,阿里云新推出的99计划,助力广大的开发者和企业上云,开发者可享99一年的服务器折扣权益,而且重点来了新老同享优惠,是的,你没看错,不会再出现老用户下单时价格突然暴涨的情况了,新老用户下单都统一价格:

服务器购买

服务端

  首先我们进行服务端的安装,在frp的release页面下载程序,一般使用Linux服务器选择amd版本进行下载即可,这里笔者以自己手上安装的Ubuntu Server为例:

1
2
wget https://github.com/fatedier/frp/releases/download/v0.60.0/frp_0.60.0_linux_amd64.tar.gz
tar -zxcf frp_0.60.0_linux_amd64.tar.gz

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

  解压后的文件夹得到四个文件,分别是服务端和客户端的运行程序和配置文件,带s的是服务器运行的,带c的是客户端运行的程序:

1
2
3
4
|- frps
|- frps.toml
|- frpc
|- frpc.tom

  因为是在服务端,我们编辑frps.toml文件,加入以下配置:

1
2
3
4
5
6
7
8
bindPort = 7000
vhostHTTPPort = 7000
auth.token = "your token"

webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "frp"
webServer.password = "frp"

auth.token是服务端和客户端的认证token,需要一致,frp的配置文件有很多,这里只列举了常用的几个配置。

  7000端口就是frp监听的主端口,我们所有的连接访问都是需要通过这端口,而webServer的7500端口是控制面板的访问端口;我们新建一个run.sh文件,加入以下内容,让frp能够在后台启动:

1
nohup ./frps -c ./frps.toml > /dev/null 2>&1 &

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

  给run.sh启动权限并运行即可;我们的服务端启动后,访问7500可能并不能直接看到页面,需要在安全组里面将两个端口添加进去。

放开端口

  在浏览器打开7500端口就可以看到我们的管理后台界面了,在这个界面上我们可以看到启动的Frp服务器的信息、链接数量等等。

管理界面

客户端

  我们上面服务端部署好了,就可以来部署我们客户端的服务了,主要以下面四种场景作为案例,看下每个场景的客户端代码是如何部署的。

临时文件服务器

  第一个案例就是临时的文件服务器,我们在工作或者生活中,偶尔需要发送个保密的文件资料给朋友,有时候又不想通过微信(懂得都懂),百度网盘速度又太慢,这个时候就可以利用我们自己的frp服务器做中转,在本地电脑上搭建一个临时的文件服务器。

  还是下载上面release页面的frp压缩包,我们这个时候就需要修改frpc.toml客户端的配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
serverAddr = "your domain"
serverPort = 7000
auth.token = "your token"

[[proxies]]
name = "file-static"
type = "tcp"
remotePort = 7810
transport.useEncryption = true
transport.useCompression = true
transport.bandwidthLimit = "10MB"
[proxies.plugin]
type = "static_file"
localPath = "your path"
httpUser = "frp"
httpPassword = "frp"

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

  将上面的serverAddr地址换成自己服务器的地址和token,localPath这里就是本地电脑的文件夹的路径,需要注意的是,Windows的写法和Linux的路径写法都是不一样的;这里笔者的电脑用的是windows,就填写D:/software;同样的,windows的启动命令和linux也不一样,需要用到反斜杠:

1
.\frpc.exe -c .\frpc.toml

  这样我们在浏览器打开7810端口就可以看到我们本地的文件列表了:

静态文件服务器

注意开放服务器的7810端口,避免访问不到的情况。

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

转发ssh服务

  我们经常在公司内网有一些服务器,想要在家里或者出差的时候通过ssh服务来远程访问,虽然可以通过向日葵等工具使用界面访问,但是有时候不是很稳定;而且视频传输,容易有卡顿的情况,这时候frp就能很好的派上用处了;我们知道ssh的默认端口都是22端口,通过frp直接转发22端口就行了。

  在内网的服务器上创建如下配置文件:

1
2
3
4
5
6
7
8
9
10
serverAddr = "your domain"
serverPort = 7000
auth.token = "your token"

[[proxies]]
name = "linux-ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 7820

  这样,我们访问的时候可以通过[your domain]:7820的方式,使用任意你喜欢的ssh工具来进行访问;这里笔者推荐一款超好用,颜值超高的ssh工具Termius

  但是这种方式相当于是直接将公网的7820端口映射到了远程服务器的22端口,我们都知道端口直接暴露在公网,会存在一定的风险性,很容易被网络攻击扫描到,因此我们需要一种更安全的方式;frp提供了stcp类型的代理,这里的s也是secret的意思,本质上还是tcp连接。

  我们继续修改上面服务器上的frpc.toml文件,添加以下配置:

1
2
3
4
5
6
7
8
9
10
11
serverAddr = "your domain"
serverPort = 7000
auth.token = "your token"

[[proxies]]
name = "linux-ssh"
type = "stcp"
localIP = "127.0.0.1"
localPort = 22
# 加入secretKey,一致的用户才能访问此服务
secretKey = "abcdefg"

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

  然后回到我们本地计算机,创建一个访问者的配置文件:

1
2
3
4
5
6
7
8
9
10
11
serverAddr = "your domain"
serverPort = 7000
auth.token = "your token"

[[visitors]]
name = "local-visitor"
type = "stcp"
serverName = "linux-ssh"
secretKey = "abcdefg"
bindAddr = "127.0.0.1"
bindPort = 6000

  serverName和上面proxies中的name保持一致,secretKey也要一致,在本地启动frp服务后,在Termius中,我们就可以添加访问地址了;不过这次是我们本地的地址,直接是通过127.0.0.1:6000访问即可,没有暴露任何服务器的端口。

SSH服务

代理web服务

  代理web服务是我们最常见,也是经常需要用到的服务,比如我们在公司内部有某个网站,我们希望在公网也能访问到这个网站;通过frp我们可以将这个网站暴露到公网中访问。又或者经常开发小程序的同学,肯定遇到过这样的需求,我们在公司内部项目上开发好了小程序的代码,想要给领导或者测试预览一下小程序,但是恰好他不在公司内部,小程序的码访问不了,这时也可以通过frp将服务器的端口暴露到公网上面。

  我们编辑frpc.tome文件,将内网的ip、端口以及自定义域名添加进去:

1
2
3
4
5
6
7
8
9
10
11
12
serverAddr = "your domain"
serverPort = 7000
auth.token = "your token"

[[proxies]]
name = "com-sd-http"
type = "http"
localIP = "127.0.0.1"
localPort = 7860
customDomains = ["frpsd.xxx.xxx"]
transport.useEncryption = true
transport.useCompression = true

这里需要确保自定义域名已经正确解析到了阿里云服务器上,否则将无法访问。

  这时,我们打开网址http://frpsd.xxx.xxx:7000就可以正常访问到内网127.0.0.1:7860上的服务了。

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

FRP代理内网的stable diffusion服务

  不过需要注意的是,网页和接口暴露到公网服务有一定风险,注意权限及账号验证。frp支持通过简单的HTTP Basic Auth来验证用户,用户需要通过用户名和密码才能访问服务,我们通过添加httpUserhttpPassword字段来添加验证:

1
2
3
4
5
6
7
8
9
10
11
12
serverAddr = "your domain"
serverPort = 7000
auth.token = "your token"

[[proxies]]
name = "com-sd-http"
type = "http"
localIP = "127.0.0.1"
localPort = 7860
customDomains = ["frpsd.xxx.xxx"]
httpUser = "abc"
httpPassword = "abc"

  这样我们访问web服务后,会弹出一个登录框,要求我们输入账号密码才能进入。

穿透Windows远程控制

  Windows远程控制相信不少小伙伴都使用过,如果在内网使用自带的Windows远程控制软件,我们可以很流畅很方便的的控制远程电脑,但是在外网就很难访问到内网中的Windows了;这里使用的连接方式也是frp的stcp类型,只不过将端口改到了3389;我们在远程被控端的电脑上创建如下配置文件:

1
2
3
4
5
6
7
8
9
10
serverAddr = "your domain"
serverPort = 7000
auth.token = "your token"

[[proxies]]
name = "windows-mstsc"
type = "stcp"
localIP = "127.0.0.1"
localPort = 3389
secretKey = "abcd"

  在我们本地控制端的电脑,同样写入配置文件,启动一个frp的程序:

1
2
3
4
5
6
7
8
9
10
11
serverAddr = "your domain"
serverPort = 7000
auth.token = "your token"

[[visitors]]
name = "mstsc-visitor"
type = "stcp"
serverName = "windows-mstsc"
secretKey = "abcd"
bindAddr = "127.0.0.1"
bindPort = 8090

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

需要注意的是,这里的serverName和secretKey字段都要和上面受控端的name和secretKey保持一直,

  我们打开Windows远程,输入127.0.0.1:8090就可以远程上我们的目标计算机了。

Windows远程

  另外说个小技巧,有一些Linux发行版带有图形界面,比如笔者常用的Ubuntu,也是能够支持Windows的远程软件来连接的,在系统设置中打开远程登录选项即可。

Windows远程Ubuntu系统

Ubuntu客户端设置开机启动

  在一些Linux的受控端上,我们希望frp能够做到重启或者断电后开机自启动,这里笔者以家里的一台Ubuntu24为例子,看下如何让frp开机启动;在新的Ubuntu发行版上已经没有rc.local文件了,我们需要自己新建一个:

1
sudo vim /etc/systemd/system/rc-local.service

  写入如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=/etc/rc.local Compatibility
ConditionPathExists=/etc/rc.local

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
SysVStartPriority=99

[Install]
WantedBy=multi-user.target

  激活上面创建的rc-local.service:

1
sudo systemctl enable rc-local.service

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

  创建/etc/rc.local文件:

1
sudo vim /etc/rc.local

  写入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# 开机启动的命令
nohup /home/software/frp/frpc -c /home/software/frp/frpc-ssh.toml > /dev/null 2>&1 &

exit 0

  这样我们就实现了frp的开机启动。

总结

  本文我们总结了frp常见的几种使用场景,frp在实际使用中,确实能够帮助笔者解决很多网络上的问题,解决了笔者在远程办公、远程调试、远程控制等场景下的不少问题;在办公中,让笔者能够轻松穿越地域限制,访问家庭网络中的各种影音、文档资源;回到家中,通过搭建安全高效的反向代理隧道,也能够直接连接到公司远程服务器上,让笔者能够流畅的调试、部署项目,极大地提升了工作效率。总而言之,frp以其强大的功能和灵活的部署方式,极大地丰富了我们的网络操作手段,为远程工作与学习带来了极大的便利,绝对是摸鱼听歌、居家办公的不二利器。

参考

Github
文档地址
ubuntu 20.04 没有rc.local文件的解决方法

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里


本网所有内容文字和图片,版权均属谢小飞所有,任何媒体、网站或个人未经本网协议授权不得转载、链接、转贴或以其他方式复制发布/发表。如需转载请关注公众号【前端壹读】后回复【转载】。