为什么要做内网穿透?
你的家庭宽带连接到ISP(Internet Service Provider,互联网服务提供商,移动、联通、电信等),可以简略的表示为下图所示:
一般来说,因为IPV4地址池有限,运营商并不会给你分配一个公网IP地址,会通过NAT(Network Address Translation)方式,使得一栋楼或者一个小区共用一个IP地址连接互联网,如下图。
这样就会导致一个问题,如果你想通过公用的IP,从外部访问你的电脑(内网主机或其他网络设备),就会出现无法连接的问题,因为NAT方式使用的是当前地址池里空闲的端口为你转换,而你并不知道现在使用的端口是什么,并且这个地址是不停在变的(除非运营商使用静态NAT表,外部端口和你的内部端口是对应的)。为了解决这个问题,就需要内网穿透技术了。
内网穿透也叫NAT穿透,进行 NAT 穿透是为了使具有某一个特定源 IP 地址和源端口号的数据包不被 NAT 设备屏蔽而正确路由到内网主机。内网穿透工具有很多,例如花生壳、Ngrok、Natapp、Frp等,本文将在有一个公网服务器的前提下,介绍如何使用Frp进行内网穿透。
frp内网穿透的原理
如下图:
- 服务端运行frps,监听外部连接。
- 启动frpc,frpc启动后会向frps注册,也就是内网主机会向公网服务器请求注册,建立一条虚拟连接。
- 外部客户端请求连接,查找是否有对应服务。
- frps告知frpc有新请求,需要建立连接,也就是公网服务器告知内网主机,需要建立连接。
- frps收到frpc的响应,建立新的连接。
- frps把frpc和请求连接的服务流量互相转发,将运行frps的服务器当成流量中转站,把内网主机的流量转发给外部客户端。
frp客户端的使用
从 https://github.com/fatedier/frp/releases 下载对应平台的软件,此处以Windows平台为例,下载 frp_x.xx.x_windows_amd64.zip
,解压后会获得如下文件:
frpc.exe
frpc.ini
frpc_full.ini
frps.exe
frps.ini
frps_full.ini
LICENSE
其中, frpc.exe,frpc.ini,frpc_full.ini
是内网客户端使用的程序及配置文件, frps.exe,frps.ini,frps_full.ini
是有公网ip的服务器使用的程序及配置文件,其中xxxx_full.ini
是完整的配置模板,可以根据需要自行探索,可以仅保留对应平台的应用和配置文件,下面我们将分别配置。
配置服务端程序
首先,连接你的公网服务器,复制frps.exe,frps.ini
到服务器,打开frps.ini
,修改初次建立连接使用的端口
[common]
bind_port = 7000
建议修改 bind_port
为其他端口,部分运营商会屏蔽7000端口。
在frps服务端目录打开控制台,运行
frps -c frps.ini
你将会看到控制台输出
2022/11/06 20:37:51 [I] [root.go:209] frps uses config file: frps.ini
2022/11/06 20:37:51 [I] [service.go:194] frps tcp listen on 0.0.0.0:7000
2022/11/06 20:37:51 [I] [root.go:218] frps started successfully
出现如上字样即为启动成功。
请在服务器防火墙开启对应端口,否则会连接失败
配置客户端程序
复制frpc.exe,frpc.ini
到需要内网穿透的内网主机,打开frpc.ini
,修改服务器地址以及添加内网服务
[common]
server_addr = 127.0.0.1
server_port = 7000
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
修改 server_addr
为你的有公网ip的服务器地址,修改 server_port
为 服务端 bind_port
的端口,下面示例的ssh服务的配置不需要的话可以删除。
下面我们尝试添加web服务的内网穿透配置。
确保你的web服务为开启状态,打开控制面板--程序--启用或关闭Windows功能,勾选Internet Information Services,确定,打开浏览器,输入 localhost
或 127.0.0.1
,你将看到如下界面,即为开启成功,默认页面在 C:/inetpub/wwwroot
内,可以修改为你自己的网页,具体IIS服务器的配置请百度。
下面我们将使这个页面对外网也可见,
修改frpc.ini
,添加如下配置:
[web]
#你的服务名称,请使用英文
type = tcp
#使用的协议
local_ip = 127.0.0.1
#本地地址
local_port = 80
#本地端口,web服务默认为80,可绑定其他端口
remote_port = 8866
#服务器端口,你从外网访问此web服务需要连接的端口,服务器的防火墙也需要开放此端口
在客户端目录打开控制台运行
frpc -c frpc.ini
出现类似如下输出,即配置成功,失败的话请检查客户端/服务器的防火墙配置。
2022/11/06 21:00:36 [I] [service.go:349] [dbdbc51112224443] login to server success, get run id [dbdbc51112224443], server udp port [0]
2022/11/06 21:00:36 [I] [proxy_manager.go:144] [dbdbc51112224443] proxy added: [web]
2022/11/06 21:00:36 [I] [control.go:181] [dbdbc51112224443] [web] start proxy success
此时使用任意电脑/手机浏览器访问 http://[你的服务器ip]:8866
,将看到和在内网主机访问localhost
一样的界面,此时,你已经会使用frp进行内网穿透了。
下面再举个例子,穿透远程桌面服务。
请保证你的远程桌面服务是开启的,打开设置--系统--远程桌面,查看“启用远程桌面“选项是否为开启状态。
Windows7以及其他版本在计算机属性--高级系统设置--远程--远程桌面,确保勾选的为”允许远程连接到此计算机“。
注意!需要确保你的电脑有登录密码以及有效的防火墙,才可开启远程桌面服务,如果你通过各种手段绕过了安全认证,这时暴露在外网是十分危险的!
修改frpc.ini
,添加如下配置:
[rdp]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
#你的公网服务器也需要开启11451端口
remote_port = 11451
保存,并在控制台运行
frpc -c frpc.ini
如看到
2022/11/06 21:00:36 [I] [control.go:181] [dbdbc51112224443] [rdp] start proxy success
即为穿透成功。
现在使用其他电脑,打开远程桌面程序,连接 [你的服务器ip]:11451
,输入你的用户名和密码即可连接。
部分情况下,将内网服务暴露在公网是十分危险的,请确保你的服务器和内网主机有合理的防火墙规则和安全控制,例如将remote_port设置为较高端口,使其不会被轻易扫描到,以及参考frpc_full.ini,配置访问控制等。
其他一些高级操作
隐藏控制台,使其后台运行
如果使用 frpc -c frpc.ini
命令运行程序,你需要时刻保持控制台窗口为打开状态,并且每次打开计算机都需要手动运行,十分不方便,这里我们使用另一个开源项目winsw,将其转换为服务即可,打开https://github.com/winsw/winsw/releases下载最新版程序,以转换客户端为服务为例。
新建文本文档,键入
<service>
<id>frpClient</id>
<name>frpClient</name>
<description>内网穿透服务</description>
<executable>frpc</executable>
<arguments>-c frpc.ini</arguments>
<onfailure action="restart" delay="60 sec"/>
<onfailure action="restart" delay="120 sec"/>
<logmode>reset</logmode>
</service>
其中
--id
为服务id,它在所有Windows服务中应该是独一无二的。
--name
为服务名称,也就是你在任务管理器,服务标签看到的名字。
--description
为服务介绍,也就是你在任务管理器,服务标签看到的服务描述。
--executable
为可执行文件的位置,如果winsw与frpc在同一目录,填写 frpc
即可。
--arguments
为可执行文件的执行参数,我们这里设置为 -c frpc.ini
指定frpc的配置文件。
--onfailure
为服务启动失败进行的操作,上述配置会导致服务在第一次故障后60秒内重新启动,在第二次故障后120秒内重新启动,action
有三个值,restart:重启服务,reboot:重启windows,none:不执行任何操作。
--logmode
为日志模式,每次启动清空日志重新记录。
具体配置请参考https://github.com/winsw/winsw/blob/v3/docs/xml-config-file.md
保存配置文件,将winsw.exe与配置文件命名为相同的名字,例如我命名为frpService.exe和frpService.xml,在frpService.exe目录以管理员权限打开控制台,执行 frpService.exe install
注册服务,执行frpService.exe start
启动服务,不出意外的话,同目录将会生成 frpService.out.log
(frp的控制台输出,可以看到frp的连接情况)与 frpService.wrapper.log
(winsw的日志,可以看到服务的启动情况)。后续可以打开Windows的服务管理,找到frpClient服务,配置其启动方式,实现开机启动。
开启frp的web控制台
如果你想实时关注frp服务端的运行情况,可以在 frpc.ini
加入如下配置:
#配置文件common标签下加入
admin_addr = 127.0.0.1
admin_port = 8899
#控制面板用户名
admin_user = admin
#控制面板密码
admin_pwd = admin
#配置文件末尾加入
[admin_ui]
type = tcp
#localport需要与common中的admin_port一致
local_port = 8899
#服务器防火墙也需要开启remote_port端口
remote_port = 7788
重启服务,浏览器访问 [你的服务器]:7788
,输入控制面板的账户密码,即可看到控制台,如下图:
服务端编辑 frps.ini
,在 common
标签下加入:
#dashboard端口、用户名、密码
dashboard_port = 99
dashboard_user = admin
dashboard_pwd = admin
浏览器访问 [你的服务器ip]:99
即可打开服务端仪表盘。
更多玩法,请参考官方文档自行探索。