文章目录
- 前言
- frp原理
- Windows服务端
- IP检验
- IP固定
- 软件下载
- 端口放行
- 端口映射
- 开机启动
- NAS客户端
- 端口查询
- 软件下载
- 端口检验
- 穿透测试
- 自启设置
- Ubuntu客户端
- 软件下载
- 后台启动
- 后记
前言
之前一直用花生壳远程控制一个服务器,但最近内网的网络策略似乎发生了变化,花生壳相关的域名都被屏蔽了。此时我恰好发现家里分配的宽带是公网IP(如果不是可以打电话申请一个),于是干脆选择自己动手丰衣足食了。
一开始我的想法是给家里的路由器刷完固件之后安装一个内网穿透工具,但是发现两个路由器都不行,一个是电信定制的,没有现成的刷机工具;另一个路由器内存太小了,就剩几十KB,没什么操作空间。
顺着这个思路,最好的解决方案似乎就是买一个大几百的高端路由器,但我实在是不想住在一个路由之家里面。此时又有某儿子吹风建议我可以买一个大几百的迷你主机,我都马上要下单了,才想起家里没有显示器,只能作罢。
正头痛之时,我突然看见才过了八岁生日的老电脑正在无事摸鱼,立即决定把它改造成内网穿透服务器,这样我不用再花钱,它可以有事做,可谓两全其美。
frp原理
frp(Fast Reverse Proxy)是一个高性能的反向代理应用,主要用于内网穿透场景,允许用户将内网服务暴露到公网上,从而实现外网用户对内网服务的访问。frp的原理基于以下关键概念:
- 反向代理:frp作为代理服务器,接收来自外网的连接请求,并将其转发到内网的服务器上。这样,外网用户可以直接通过frp服务器访问内网服务,而不需要直接连接到内网服务器。
- 端口映射:frp将外网用户请求的特定端口映射到内网服务器的对应端口。例如,如果内网服务器上运行了一个Web服务,监听80端口,frp可以将外网的80端口请求映射到内网服务器的80端口。
- 安全隧道:frp通过安全隧道传输数据,确保通信的安全性。它支持多种加密方式,如HTTPS、SSL等,以保护数据不被截获或篡改。
- 多协议支持:frp支持多种协议,包括HTTP、HTTPS、TCP、UDP、WebSocket等,这使得它可以用于多种不同的应用场景,如Web服务、文件传输、游戏服务器等。
- 服务端与客户端:frp由服务端(frps)和客户端(frpc)两部分组成。服务端运行在公网服务器上,负责接收外网请求并将其转发到内网客户端。客户端运行在内网服务器上,负责将服务端转发的请求传递给本地服务,并将本地服务的响应返回给服务端。
- 配置与控制:frp通过配置文件来指定服务端和客户端的行为,如监听的端口、映射规则、加密方式等。用户可以根据需要自定义配置,以适应不同的网络环境和需求。
通过这种方式,frp允许内网服务在不改变原有网络设置的情况下,通过公网服务器对外提供服务,从而实现了内网穿透的功能。
反向代理是一种网络技术,它可以帮助将客户端的请求转发到内部服务器,并将服务器的响应返回给客户端。通俗地说,就像是有一个中间人帮你去访问网站,然后再把网站的内容转发给你一样。
比如,你想访问某个网站,但是你不能直接连接到这个网站,而是要通过反向代理服务器。你向反向代理服务器发送请求,然后反向代理服务器会帮你去请求真正的网站,并将网站的内容返回给你。这样,你就可以间接地访问网站了,同时也可以帮助隐藏真实的服务器地址,提高安全性。
接下来我就记录一下在Windows服务端、NAS客户端以及Linux客户端使用frp实现内网穿透的一些步骤。
Windows服务端
IP检验
这一步要检验两个东西:一个是个人电脑的IP是否为公网IP,第二步是路由器的WAN口IP是否与公网IP相一致。
在电脑浏览器中打开公网IP检验网站,得到以下结果,确认为公网IP
打开路由器管理后台,发现WAN口IP并不是公网,而是内网IP
这时就要提一下我家的路由架构了,有一个带路由功能的光猫(天翼网关)作为主路由,还有一个华为路由(TC7206)作为子路由。
在家庭或企业网络中,通常会有一个主路由器连接到互联网服务提供商(ISP),并获得一个公网IP地址。子路由器(或二级路由器)则连接到主路由器,形成内网的一部分。在这种情况下,子路由器的WAN口IP地址通常是由主路由器分配的内网IP地址,而不是公网IP。
解决方案也很简单,让作为内网穿透的电脑连接作为主路由的光猫的WiFi即可,再看一下WAN口IP,舒服了。
IP固定
这里要介绍一下我家光猫与路由器的连接方式:光猫连接互联网服务提供商(ISP)的光纤网络,光猫LAN口接路由器的WAN口。因此,光猫和路由器及连接光猫的其他设备是一个网络,路由器和连接路由器的网络设备是另一个网络,两个网络相互独立互不影响,且光猫和路由都各自开启了DHCP。
- 光猫和路由器都是双网卡设备,一个WAN(Wide Area Network,广域网)接口,多个LAN(Local Area Network,局域网)接口,同时有DHCP服务器和拨号客户端
- DHCP(动态主机配置协议)是一种网络协议,它允许服务器向客户端自动分配IP地址和配置信息,不需要手动为每个设备配置IP地址、子网掩码、默认网关和DNS服务器等信息。
这样就带来了一个问题:当路由器重启时,DHCP服务也会重启。重启后,DHCP服务器可能不会保留之前的IP地址分配记录,而是重新开始分配IP地址。这可能导致某些设备获得不同的IP地址,尤其是当多个设备同时请求IP地址时,这就会为后文的IP端口映射带来麻烦,总不能每次一重启就把所有的端口映射重新设置一遍吧。
如果是连接路由器WiFi,其实固定IP这事还好,路由器自带根据MAC地址分配固定IP的功能。但是光猫并没有这么高级,所以只能先修改DHCP的范围,再在范围之外手动分配IP。
DHCP默认的分配范围是所有可能的IP,即2-255,我们将其的范围缩小到2-250,剩下的部分用来固定设备IP
按照以下操作步骤,将默认的自动获取IP地址
修改为使用下面的IP地址
设置哪个IP地址呢?为了向某爱国厂商致敬,就设一个251吧,具体参数可以参考路由器的网关设置部分
软件下载
进入frp下载页,选择最新版本的windows_amd64下载到本地。
解开压缩包,因为它作为服务端,所以删掉frpc
开头的两个文件,只保留frps
开头的两个文件。
打开frps.toml
这个配置文件,参考服务端详细配置说明,输入以下内容并保存:
# frps.toml
bindPort = 7000 # 服务端与客户端通信端口transport.tls.force = true # 服务端将只接受 TLS链接auth.token = "123" # 身份验证令牌,frpc要与frps一致# Server Dashboard,可以查看frp服务状态以及统计信息
webServer.addr = "0.0.0.0" # 后台管理地址
webServer.port = 7500 # 后台管理端口
webServer.user = "root" # 后台登录用户名
webServer.password = "admin" # 后台登录密码
执行.\frps -c .\frps.toml
启动服务,不知道为啥会有些乱码
此时已经可以在浏览器中打开网页
端口放行
为了让流量在开放的端口中畅行无阻,需要对Windows防火墙的规则进行修改。
Win10左下角搜索防火墙和网络设置
,点击高级设置
→入站规则
,下拉会发现frps在公用网络被ban得死死,直接右键取消禁用
再按以下步骤新增自定义的frp规则,开放特定端口
最后将防火墙改造如下
端口映射
做完上面这些步骤,如果我们输入公网IP:7500
,却仍然会提示网页无法打开,这是因为还差最后一步,没有将光猫端口与笔记本的端口做映射。
进入光猫管理页面,找到端口映射,按此添加7000等端口映射
路由器上的端口映射(Port Mapping)是一种网络地址转换(NAT)的技术,它允许将路由器的外部接口(通常连接到互联网的WAN口)的某个端口映射到内部网络的某台设备的特定端口上。这样,当外部的网络请求到达路由器的特定端口时,路由器会将这些请求转发到内部网络中相应的设备上。
刷新页面,完美打开
开机启动
在frp文件夹下新建start.bat可执行文件,输入以下内容
@echo off
:home
frps -c frps.toml
goto home
右键新建快捷方式
将快捷方式复制到C:\Users\【替换成你的用户名】\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
下,重启一下,即可实现开机自动运行内网穿透服务
NAS客户端
端口查询
第一步是查询NAS上有哪些服务对应的端口需要穿透
-
DSM服务
-
SSH服务
-
WebDAV服务
软件下载
进入frp下载页,选择最新版本的linux_amd64下载到本地。
解开压缩包,因为它作为服务端,所以删掉frps
开头的两个文件,只保留frpc
开头的两个文件。打开frpc.toml
这个配置文件,根据frp客户端配置 以及 访问内网机器中的相关说明,输入以下内容
# frpc.toml
transport.tls.enable = true # 从 v0.50.0版本开始,transport.tls.enable的默认值为 true
serverAddr = "1xx.xxx.xxx.xxx"
serverPort = 7000 # 公网服务端通信端口auth.token = "123" # 令牌,与公网服务端保持一致[[proxies]]
name = "NAS-http"
type = "tcp"
localIP = "127.0.0.1" # 需要暴露的服务的IP
localPort = 65000 # 将本地65000端口的服务暴露在公网的7001端口
remotePort = 7001[[proxies]]
name = "NAS-https"
type = "tcp"
localIP = "127.0.0.1" # 需要暴露的服务的IP
localPort = 65001 # 将本地65001端口的服务暴露在公网的7002端口
remotePort = 7002[[proxies]]
name = "NAS-SSH"
type = "tcp"
localIP = "127.0.0.1" # 需要暴露的服务的IP
localPort = 60001 # 将本地60001端口的服务暴露在公网的7022端口
remotePort = 7022[[proxies]]
name = "NAS-webdav"
type = "tcp"
localIP = "127.0.0.1" # 需要暴露的服务的IP
localPort = 5005 # 将本地5005端口的服务暴露在公网的7003端口
remotePort = 7003
端口检验
由于之前已经在NAS上部署了zerotier-one的docker环境,本着节约资源保护环境的原则,我决定直接把frp布到已有的环境中。
进入zerotier-one的docker环境,点击通过命令启动
并输入ash
进入终端,输入 cat /etc/issue
查看镜像类型
Alpine Linux 是一个轻量级的发行版,它使用musl libc 和 busybox,使用apk做包管理。
使用以下命令安装端口扫描工具nmap
apk update
apk add nmap
探测win服务端的端口是否打开,确认已打开
穿透测试
在docker文件夹中新建frp文件夹,将frpc
相关文件传进去,并编辑容器,建立存储空间的映射
按如下方式启动穿透服务
尝试在外网通过ssh user@1xx.xxx.xxx.xxx -p 7022
访问NAS的SSH服务,成功进入并查看文件内容
尝试在外网通过1xx.xxx.xxx.xxx:7001
访问NAS的DSM服务,访问失败,后台报如下错误
尝试了一堆解决方案未果,最后猜测是端口被之前安的花生壳应用占有了,也罢,反正能穿透就行
接下来测试webdav,首先下载raidrive软件,打开后做如下设置,注意要取消地址旁的勾选
连接瞬间成功,现在打开电脑多了一个网络位置
自启设置
查看容器设置,其每次开机都会自启动,并执行/entrypoint.sh
进入容器终端,查看文件内容
将其修改成以下内容,并重新启动容器
#!/bin/sh
set -eu if [ ! -e /dev/net/tun ]; then echo 'FATAL: cannot start ZeroTier One in container: /dev/net/tun not present.' exit 1
fi /usr/sbin/zerotier-one &
/frp/frp_0.57.0_linux_amd64/frpc -c /frp/frp_0.57.0_linux_amd64/frpc.toml
这里我们使用 & 将 zerotier-one 后台运行,这样它就不会阻塞脚本中的其他命令。注意,exec 命令会替换当前进程,因此如果使用 exec 启动进程,该进程会取代当前脚本的进程,导致后续的命令不会被执行。
查看进程,两个进程同时后台启动
查看日志,frp正常开启
接下来再设置每次NAS开机都会自启动docker
可以把docker关了之后,选中命令右键运行,测试一下能不能正常执行并查看结果
Ubuntu客户端
软件下载
跟上一部分下载一样的文件,在frpc.toml
文件中输入以下内容
# frpc.toml
transport.tls.enable = true # 从 v0.50.0版本开始,transport.tls.enable的默认值为 true
serverAddr = "1xx.xxx.xxx.xxx"
serverPort = 7000 # 公网服务端通信端口auth.token = "123" # 令牌,与公网服务端保持一致[[proxies]]
name = "Ubuntu-Gradio"
type = "tcp"
localIP = "127.0.0.1"
localPort = 7860
remotePort = 7007[[proxies]]
name = "Ubuntu-Gradioo"
type = "tcp"
localIP = "127.0.0.1"
localPort = 7861
remotePort = 7008[[proxies]]
name = "Ubuntu-SSH"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 7006
后台启动
- 安装screen
sudo apt-get update
sudo apt install screen
- 进入后台执行
screen -R frp
sudo chmod 777 frpc
./frpc -c ./frpc.toml
ctrl+A+D
退出,screen -R frp
进入查看
客户端全部配完后,进入端口号为7500的后台管理页面,欣赏一下劳动成果
后记
尽管上面的这一段流程看起来像是一个天才的一气呵成,但我必须承认,实情并非如此。这完全是一个菜鸡在设定好目标后,从自己半知不解的一点知识入手,靠着智谱、GPT3.5、Claude以及各种博客和论坛上的信息东凑西补踉踉跄跄尝试得来。
虽然听起来有些辛酸,但这个过程并不辛苦,我只是花一个周时间全身心投入,酣畅淋漓地通关了一场庞大的游戏。从一开始我就觉得我能通过这个游戏,而结局也确实如此,那些我初中高中从来没弄明白的路由器和光猫,大学里险些害我计网挂科的各种IP知识,在这场游戏中以一种全新的方式进入我脑海并扎根下来,这实在是一种神奇的体验。