【网络层协议】NAT技术内网穿透
IP地址数量限制
我们知道,IP地址(IPv4)是一个4字节32位的整数,那么一共只有2^32也就是接近43亿个IP地址,而TCP/IP协议栈规定,每台主机只能有一个IP地址,这就意味着,一共只有不到43亿台主机能接入互联网吗?
实际上,由于一些特殊的IP地址(主机号全0代表网络号,主机号全1代表广播地址,127.*用于本地环回测试)的存在,IP地址实际数量要比这个数更小一些,并且IP地址并不是按主机台数分配的,每张网卡都需要配置一个或多个IP地址,这就导致了一个很尴尬的问题:IP地址不够用了!这时候有三种方式来解决:
- 动态分配IP地址:只给接入网络的设备分配IP地址,因此即使同一MAC地址的设备,每次接入网络分配到的IP地址也不一定是相同的。
- NAT(Net Address Transimision):也就是网络地址转换,这是我们今天要重点学习的。
- IPv6:这并不是IPv4的简单升级,两者是互不兼容的协议,用16字节128位的整数表示一个IP地址,理论上能够给沙漠中的每一粒沙子都分配一个IP地址,但目前尚未普及。
私有IP与公网IP
如果一个组织内部组建局域网,IP地址只用于局域网内通信,而不连接互联网,那么理论上可以使用任意的IP地址,但如果想要接入Internet,就必须遵守RFC 1918对于组建局域网的私有IP地址的限制:
- 10.*:前8位是网络号,共16,777,216个地址(大家在学校的时候,IP地址应该都是10开头的)
- 172.16.*到172.31.*:前12位是网络号,共1,048,576个地址
- 192.168.*:前16位是网络号,共65,536个地址(大家在家里的时候,IP地址应该都是192.168开头的)
- 包含在以上范围的,都成为私有IP,其余的则是公网IP
大家可能觉得奇怪,不是要讲解决IPv4地址数量不足的问题吗,怎么扯到了私有IP和公网IP了,事实上,这是NAT技术能解决地址数量不足的一个很关键的要素:如果私有IP地址只在局域网内使用,那么不同局域网就可以出现重复的私有IP了,那么可用的IP数量就大大增加了!
那么问题来了,局域网中的主机怎么和公网进行通信呢?所以NAT技术实际上做的就是:在子网内的主机需要与外网进行通信时,路由器将IP报文首部的IP地址进行替换,经过一次次路由,最终数据包中的源IP地址成为一个公网IP,可以在公网中访问目标公网IP了。
NAT技术
前面提到了路由器将IP报文首部的IP地址替换,那么这个替换过程长啥样呢?让我们接着往下学,首先了解一下关于路由器的一些相关知识:
- 一个路由器可以配置至少两个IP地址,一个WAN口(广域网接口)IP,一个或一个以上的LAN口(局域网接口)IP。
- 路由器LAN口连接的主机都从属于这个路由器的某个子网中。
- 子网内的主机IP地址不能重复,但不同路由器的子网间可以出现重复的IP地址。
- 每个家用路由器实际上又作为运营商路由器子网中的一个节点,并且这样的运营商路由器可能有很多级,最外层的出入口运营商路由器的WAN口IP就是一个公网IP了。
现在再回过头表述一下什么是NAT技术:子网主机需要和外网通信时,家路由器将IP报头首部的源IP地址替换为自己的WAN口IP,这样主机替换,最终数据包中的源IP地址称为一个公网IP。
所以现在我们也就大概能够理解为什么我们的宽带欠费后,运营商可以让我们上不了网了,因为我们的每台主机其实都是在内网中,要想访问公网,那就必须先通过NAT转化为公网IP,而运营商路由器识别出欠费,直接不帮我们进行NAT,也就自然断网了。
通过前面的学习,我们解决了一个问题:局域网内的主机如何向公网的服务器发送请求。但是还有一个很重要的问题:服务器要怎么把响应返回给服务器呢?
按照我们前面的说法,局域网中有那么多的内网主机发送到服务器的请求的IP都是相同的(出入口运营商服务器的WAN口IP),服务器返回请求的目的IP都是运营商出入口NAT路由器,那NAT路由器怎么判定要把数据包交给哪个局域网的主机呢?
这个时候NAPT(网络地址端口转换)闪亮登场了,NAT路由器在进行源IP替换时,会将报文的源IP+port与自己替换的WAN口IP+port的映射关系存到一张转化表里,这很重要,因为:内网IP在局域网中唯一,port在主机上唯一;公网IP在公网中唯一,port在路由器上唯一。两个唯一值存在一张表里,就意味着两者互为键值!建立起这张转换表后,公网就可以访问到内网了!
(这个关联表是由NAT服务器自动维护的,对于TCP,在建立连接时生成表项,断开连接后删除表项)
内网穿透
在学习了NAT技术后,我们就可以开始学习内网穿透了。首先,什么是内网穿透?其实内网穿透就是:一台局域网中的主机,通过一个在公网的主机,访问另一个局域网中的主机。
那么内网穿透的原理是什么呢?其实我们学习了NAT和NAPT后,就非常容易理解了:
当客户机与服务器建立好转换表后,只要服务器1能够给服务器2提供这样的服务:服务器2发来的某个端口的数据全部转发到客户机,就可以实现让服务器2通过公网访问客户机了。
内网穿透的价值在于,可以通过它实现远程办公/跨区域、部门的协作。那么为了更好地理解内网穿透的过程,接下来我们一起来做一个实验!部署实现一下内网穿透~
部署与测试内网穿透
首先,说一下我的实验环境:
- 客户机:Ubuntu 20.04虚拟机(VMware设置为NAT模式)
- 服务器1:阿里云服务器(因为我们需要公网IP)
- 服务器2:Windows上的xterminal(SSH客户端软件)
- 转发功能:通过frp实现的,因为它用起来很简单
frp下载:下载的是linux amd64
Release v0.58.1 · fatedier/frphttps://github.com/fatedier/frp/releases/tag/v0.58.1 简单讲讲实验步骤:
- 在客户机上部署、安装、配置frpc(frp的客户端),然后把本地ssh 22号端口映射到frps的xxx端口(如6000)
- 在云服务器1上部署配置frps(frp的服务器),设置让xxx端口(如7000)与客户机上的frpc进行通信
- 服务器2此时通过云服务器1的7000端口就能访问到客户机的ssh服务了!
我们下载好这个压缩包之后,解压就能得到:
其中frps和frpc分别是frp的服务器和客户端,而.toml文件则是对服务器/客户端的配置信息。
frpc.toml:
- serverAddr和serverPort分别是frps的IP和port
- localPort和remotePort表示将本机的22号端口(ssh专用)映射到frps主机的6000号端口(也可以自己设置)——其实就是frps服务器会将6000号端口收到的请求都转发到frpc的22号端口,收到应答后再转发回给请求方。
frps.toml:
- frps上的配置信息比较简单,只要设置好要与frpc进行通信的端口即可
启动frps:
启动frpc:
值得一提的是,我们直接运行frpc并不会使用.toml文件中的配置,必须加-c选项显式指定。
此时我们可以发现frps这边显示连接成功了(我还配置了nginx,不过步骤类似,所以只和大家说ssh的操作):
接下来我们通过Xterminal来访问云服务器的6000端口,如果和我们设想一样的话,应该就能ssh登录客户机:
可以看到,XTerminal启动后,直接就是在客户机的~下:
我们在这下面新建一个文件,可以看到确实多了个文本文件:
ok,本篇文章到这里也接近尾声了,最后再给大家梳理下流程:服务器1是一台云服务器,有自己的公网IP,服务器2是windows机器用的是内网IP,而客户机是虚拟机用的也是内网IP。frp为我们做的事情是:启动frps(服务器)后,启动frpc(客户端)与frps连接,此时由于内网主机主动通过NAT技术与公网主机建立了连接,那么通过NAPT技术我们就可以实现公网主机访问内网主机了,并且frps会把发到6000号端口的数据都转发到frpc的22号端口,接下来另一台内网主机(ssh客户端)就可以通过访问云服务器的6000号端口来ssh登录客户机了!