使用frp进行内网映射

首先我们应先分清什么是内网映射和什么是内网转发和端口映射与端口转发

内网映射:指使处于nat4状态下,由于nat的物理特性使得无法主动为外部提供服务,提供服务时并不能将所需要的内网上面的某个地址与端口转发到一个可控的外网地方的地方与端口上面。

首先我们的家庭宽带会获得一个为100.64.1.2的用于上网的地址,此时的上网地址并不是公网,但是由于有nat服务器所以可以用于上网,nat部分看我另外一其文章。

对于外部来说是必须要一个公网地址来用于全球(不对,有GFW的存在所以能不能全球取决于你的ip有没有被墙)通信的,此时运营商使用的是117.2.3.6用于提供给100.64.1.2进行通信,也就是实际上一台家庭(防止杠精,如果你家有多条nat宽带那确实可以使用100.64.1.2作为末端ip,但是家庭还要接路由器)路由器如果要上网至少要被nat封装2次,第一次在路由器中将192.168.123.0/24的数据封装在100.64.1.2中,在把100.64.1.2的数据封装在117.2.3.6中,这才完成了通信。

对于上述流程来说将存在一个问题就是,如果192.168.123.61想提供服务对方使用,那么他的端口就应该与117.2.3.6进行绑定,但是nat的特性是仅支持由nat内向nat外提供服务,也就是如果你想把192.168.123.61:5666映射到公网上面那么你就必须要先把100.64.1.2对应的192.168.123.61:56666的数据给转发到117.2.3.6上面,但是由于多层nat的原因,从最开始的192.168.123.61:5666已经变成了117.2.3.6:2632,但是这不是最担心的,因为不管怎么样,似乎我们看到了最终的对应关系,即192.168.123.61:56666对应外网地址117.2.3.6:2632,但是此时应注意nat4的特性,即只有建立了映射关系的数据才会被发送到内网里面,所以192.168.123.61:56666对应的外网地址117.2.3.6:2632只能与119.3.6.5:6359对应的192.168.1.6:6359进行通信,而其他地址是不能进行通信的,综上所述,nat4在目前的环境中以不再具有互联网的互联互通的特性了,还是得加强ipv6的部署。

所以我们需要使用frp之类的工具来将内网上面的数据先转发到一个可控的公网上面,其他人再访问这个可控公网来实现数据通信。此时内网是主动发起的连接,所以在tcp keep的保持下,就算是nat网也可以稳定的连接。具体的原理下面会讲解。

 

那么内网转发呢?

内网转发实际就是上图中对方服务器的部分

此时你的路由器获得的是119.3.6.5的ip,一般认为这个公网ip属于可控的,因为你获得已经是全球上网的ip了,对于这个ip的使用权,从《中华人民共和国民法典》上面来说,运营商已暂时租赁给了你,那你就可以使用该ip在符合法律范围的情况做任何事,当然端口转发也包含在其中。使用你可以将192.168.1.6:6359给转发到119.3.6.5:6359上面,具体转发流程在路由器上面操作就行。

端口映射其实跟内网映射一样,只是内网映射一般指映射多个端口,而端口映射一般都是单个端口,当然啦,这个只是叫法不同,意思都是一样的。

而端口转发呢,就是指将一个内网ip生成的socket连接转发到外部ip上面,再由外部的设备从端口池里面选一个用于通信,当然这个步骤可以自动建立,也可以人为操作。

例:192.168.123.61:2663可以对应119.3.6.5:2963,也可以是192.168.123.61:2663对应119.3.6.5:2663,2种端口转发,人为指定内网ip的某个端口与外部ip的某个端口的绑定关系。

注意:端口绑定的端口不一定非要与内网相同,也可以不同。

以上简要解释一下网络知识,然后就可以开始部署frp了

首先frp的客户端与服务端都是一个文件夹里面,frps是服务端在公网里面运行,frpc是客户端在内网里面运行。

先下载frp文件,这里使用wget下载

wget https://cdn.10086.fund:23350/frp_0.36.2_linux_amd64.tar.gz

然后解压,注意此时的路径,下面用的到

tar -xzfv frp_0.36.2_linux_amd64.tar.gz

这里建议使用pwd命令查看当前的绝对路径

cd frp_0.36.2_linux_amd64

进入frp文件夹

使用ls命令查看当前文件夹下面的文件

我们需要先配置的是frps对应的服务端

使用nano进行编辑

nano frps.ini

编辑命令如下

[common]
bind_port = 23360
token = 12345678

我们只需要更改bind_port的端口号就行了,更改之后客户端将通过这个端口号与服务端进行通信。这里需要将你设置的端口号进行放行,否则无法运行。
token = 12345678 是指将12345678用于服务器与客户端的身份校验中,双方都要配置这个参数,且值一样才能进行端口映射

然后我们先让服务运行起来


./frpsc -c /data/wwwroot/default/frp_0.25.0_linux_amd64/frpc.ini

显然你们需要更改文件对应的路径才对,当然你们能允许frps命令就意味着里面在当前的文件夹下。
如果返回以下内容就监听成功了

如果你想要一直运行到结束在命令后面加上&即可


./frpsc -c /data/wwwroot/default/frp_0.25.0_linux_amd64/frpc.ini &

服务器重新开机后将不在进行运行该服务。

然后你需要重启后还能稳定运行,那你需要先了解一下systemctl服务的原理,这里,你也可以看看别人的文章:NAS 篇十一:小白上手教程,自建Frp内网穿透,实现外网访问nas设备

先进入systemctl的目录

cd /lib/systemd/system/

在这个目录下有很多的开机自启进程,不要更改任何一个命令的参数

使用nano新建一个命令,名字随便

nano frp.service

反正名称结尾是service,并且于其他文件名不冲突就行

然后要写入一些内容

[Unit]
Description=fraps service
After=network.target syslog.target
Wants=network.target
[Service]
Type=simple
ExecStart=/root/frp/frps -c /root/frp/frps.ini
[Install]
WantedBy=multi-user.target

然后一行一行的解释
[Unit] 这个是单元的开头属于固定格式

Description=fraps service 这个是命令的名称自己取一个就行了

After=network.target syslog.target 这个是当前 Unit 运行必须满足的条件,否则会报启动失败 意思是你得先加载网络单元才能运行

Wants=network.target 这个意思是与当前 Unit 配合的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败 意思是他只需要这个单元就能运行而不需要其他的单元,当然其他软件有没有就跟这个没关系了。

[Service] 区块用来 Service 的配置,只有 Service 类型的 Unit 才有这个区块

Type=simple Type:定义启动时的进程行为。它有以下几种值。

Type=simple:默认值

ExecStart=/data/wwwroot/default/frp_0.25.0_linux_amd64/frps -c /data/wwwroot/default/frp_0.25.0_linux_amd64/frps.ini 这里是启动命令的地方,就是运行什么命令的意思 注意这里应该是使用绝对路径来启用frps命令,并使用frpc.ini的配置文件

[Install] 通常是配置文件的最后一个区块,用来定义如何启动,以及是否开机启动

WantedBy=multi-user.target 这里指的是运行在多用户模式

以上的内容是我从别人博客抄下来的,加了点自己的看法,细节看他的博客Systemd 入门教程:命令篇
启动模式部分看:修改debian默认运行级别
保存退出以后,可以尝试运行一下

systemctl start frp

注意这里运行的frp应该跟你创建的文件名一样才能运行。

systemctl enable frp

这里设置成开机自启,这样重启以后服务就可以自动运行了
接下来看看客户端
在客户端上面打开frpc.ini进行配置

[common]
server_addr = 121.89.240.205
server_port = 23360
token = 12345678
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
[test]
type = tcp
local_ip = 192.168.123.61
local_port = 3389
remote_port = 6001
custom_domains = test.10086.fund

这里的common是连接服务器的相关信息
server_addr填服务器的ip
server_port填你在服务器里面设置的bind_port的端口
记得把token带上不然会报错
[ssh]是名称这个可以随意
type = tcp是内网连接的类型,这里监听的是tcp的端口
local_ip这里填写的是内网的ip
local_port这里填写的是内网的端口号
remote_port这里填写的是想在外部服务器上面访问的端口号,这个端口号应该在外部服务器上面进行放行,而不是在内网服务器上面放行,这里需要注意。
custom_domains = test.10086.fund 这里可以使用域名访问内部192.168.123.61的连接,当然由于这里的远程连接是6001发起的,所以如果想要连接得在远程连接什么输入test.10086.fund:6001有端口号才行
如果有多个,后面就继续就行了。
例如

[common]
server_addr = 121.89.240.205
server_port = 23360
token = 12345678
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
custom_domains = test.10086.fund
[test]
type = tcp
local_ip = 192.168.123.61
local_port = 3389
remote_port = 6001

服务器的连接信息只用写一次,要映射的端口就按需填写,记得remote_port是在外网上面进行放行与使用的就行。
以上配置完了,运行一下吧。

frpc -c /data/wwwroot/default/frp_0.25.0_linux_amd64/frpc.ini

那没什么问题你会看到以下提示

第一个框里面是服务端的监听端口,以后的转发都会通过这个端口来完成,这个既是管理,也是转发的端口
第二个框是监听ssh的端口号
第三个框对于第二个ssh的端口号返回了一个成功那就没问题了
第四第五同上
到这里就快结束了,下面我会对frp如何完成内网映射进行说明。
首先是服务器部分
在运行frps后使用了frps.ini已经设置好的23360端口,此时23360端口将会进行监听

此时我们可以看到23360端口的管理部分已经监听好了,只要你记得端口放行就行。
接下来看看客户端的端口使用情况

此时我们可以看到192.168.123.61的内网使用了21230端口监听了服务端的23600端口,我前面提过nat4只能由内部发往外部,这里作为服务端的23600就可以被成功的监听。
当然对于服务器来说,内网的ip和端口号也会发生改变

由于我内网使用的是公网宽带,所以路由器支持upnp服务,所以客户端的内网与外网的端口号不变,在nat4中,一般都会进行变化。
那么双方都完成了启动工作,接下来就是访问的原理了

此时我们可以看到在服务端上面已经具备了6000与6001的端口,那么访问试一下,看到底是怎么完成的映射


这里我使用了公司宽带访问6000端口,那么我跟服务器的6000端口之间已经建立的连接。

对于客户端来说,他的外部访问只需要跟服务器完成连接就行了,所有的数据转发都会走23600来完成
此时我们可以看到仅多了一个来自127.0.0.1的连接,这里的连接是由端口号生成一个端口用于访问内网对应服务端口的,这里我对内网6000使用的是ssh,所以内网建立的是22端口。
这里23392会把从22访问到的数据通过21230发给服务器的23360管理端口,23360再把数据发给我的公司电脑的19225来完成了本次的建立连接。

这里可能会有一个疑问我解答一下

公司电脑的19225是怎么来的?
公司电脑的ip访问服务器的23360时,会随机使用一个未被占用的外部端口来完成,这里使用的是19225来访问服务器的23360。
为什么只用23360来传输数据?
这里由于建立的连接只能由客户端发起,任何由服务器发起向客户端的连接都会被运营商取消,所以能与服务器建立几个连接取决于客户端配置,目前只能使用一个端口建立连接。
为什么只用23360就够了,客户端不是映射了2个端口吗?
在服务器上面有监听客户端申请的2个端口就是没问题的,对于外部来说端口映射就是把你想要从外部ip+端口访问的数据发给内部而已,那么对于内部来说到底建立几个连接并不受外部影响。上面已经说过了,客户端只申请建立一个管理端口,那么从外部访问的数据就只会通过客户端与服务器建立的那一个端口进行操作。
为什么只用一个23360就可以完成管理、监听、数据传输?
这个是因为服务器的流量要走23360管理端口才能到达内部,那么客户端的对应端口收到数据后就会解析数据内容并在客户端内生成对应的socket来模拟客户端自己访问自己再把自己的数据通过管理端口发给服务器完成通信流程。

made by qwe

点赞

发表回复

必填项已用 * 标注

百度已收录