为什么要做内网穿透?

你的家庭宽带连接到ISP(Internet Service Provider,互联网服务提供商,移动、联通、电信等),可以简略的表示为下图所示:
isp.png
一般来说,因为IPV4地址池有限,运营商并不会给你分配一个公网IP地址,会通过NAT(Network Address Translation)方式,使得一栋楼或者一个小区共用一个IP地址连接互联网,如下图。
nat.png
这样就会导致一个问题,如果你想通过公用的IP,从外部访问你的电脑(内网主机或其他网络设备),就会出现无法连接的问题,因为NAT方式使用的是当前地址池里空闲的端口为你转换,而你并不知道现在使用的端口是什么,并且这个地址是不停在变的(除非运营商使用静态NAT表,外部端口和你的内部端口是对应的)。为了解决这个问题,就需要内网穿透技术了。
内网穿透也叫NAT穿透,进行 NAT 穿透是为了使具有某一个特定源 IP 地址和源端口号的数据包不被 NAT 设备屏蔽而正确路由到内网主机。内网穿透工具有很多,例如花生壳、Ngrok、Natapp、Frp等,本文将在有一个公网服务器的前提下,介绍如何使用Frp进行内网穿透。

frp内网穿透的原理

如下图:
frp.png

  1. 服务端运行frps,监听外部连接。
  2. 启动frpc,frpc启动后会向frps注册,也就是内网主机会向公网服务器请求注册,建立一条虚拟连接。
  3. 外部客户端请求连接,查找是否有对应服务。
  4. frps告知frpc有新请求,需要建立连接,也就是公网服务器告知内网主机,需要建立连接。
  5. frps收到frpc的响应,建立新的连接。
  6. 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服务器的配置请百度。


iis.png

下面我们将使这个页面对外网也可见,
修改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服务,配置其启动方式,实现开机启动。
service.png

开启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 ,输入控制面板的账户密码,即可看到控制台,如下图:
adminui.png

服务端编辑 frps.ini ,在 common 标签下加入:

#dashboard端口、用户名、密码
dashboard_port = 99
dashboard_user = admin
dashboard_pwd = admin

浏览器访问 [你的服务器ip]:99 即可打开服务端仪表盘。

更多玩法,请参考官方文档自行探索。