【网络层协议】NAT技术内网穿透

news/2025/3/28 21:14:59/

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登录客户机了!


http://www.ppmy.cn/news/1583290.html

相关文章

HTML应用指南:利用GET请求获取猫眼电影日票房信息——以哪吒2为例

2025年春节档期,国产动画电影《哪吒之魔童闹海》(以下简称《哪吒2》)以颠覆性的叙事风格与工业化制作水准震撼登场,不仅刷新了中国动画电影的票房纪录,更成为全球影史现象级作品。影片凭借春节档期的爆发式开局、持续5…

从零开始实现 C++ TinyWebServer 网络服务器 WebServer详解

文章目录 WebServer 运行流程1. 服务器初始化2. 服务器启动3. 处理新连接4. 处理读事件5. 处理写事件6. 连接超时处理7. 服务器关闭 WebServer 类构造函数析构函数实现 InitSocker() 函数实现 SetFdNonBlock() 函数实现 InitEventMode() 函数实现 start() 函数实现 AddClient()…

stm32第六天继电器

一:继电器 1.继电器的工作原理 继电器是一个电控开关,工作原理基于电磁感应,继电器包括一个电磁线圈和一组触点。常用于控制高电流或高电压的电路,例如自动控制原理,电力系统和自动化设备中,由于可靠性和电…

Linux -- 进程间通信(IPC)-- 进程间通信、管道、system V 共享内存、system V 消息队列、责任链模式 、system V 信号量

一、什么是进程间通信 1.进程间通信的目的 数据传输:一个进程需要将它的数据发送给另一个进程。资源共享:多个进程之间共享同样的资源。通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发…

初识HTTP

HTTP 概念:HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则 HTTP 协议特点: 1.基于TCP协议:面向连接,安全 2.基于请求-响应模型的:一次请求对应一次响应 3.HTTP协议是无状态的协议:对于事务处理没有…

TCP粘包原因分析以及解决方案

一、TCP粘包简介 使用TCP 协议进行数据传输时,多个数据包被连续存储于缓存中,在对数据包进行读取时由于无法确定发送方的发送边界,而采用某一估测值大小来进行数据读取,使得发送方发送的若干个数据包到接收方接收时粘成一包&…

自然语言处理(11:RNN(RNN的前置知识和引入)

系列文章目录 第一章 1:同义词词典和基于计数方法语料库预处理 第一章 2:基于计数方法的分布式表示和假设,共现矩阵,向量相似度 第一章 3:基于计数方法的改进以及总结 第二章 1:word2vec 第二章 2:word2vec和CBOW模型的初步实现 第二章 3:CBOW模型…

在 PostgreSQL 中设置调试环境以更好地理解 OpenSSL API

1. 概述 本文将介绍如何设置一个 gdb 调试环境,以深入了解 TLS 连接并更好地理解 PostgreSQL 中使用的 OpenSSL API。 2. 使用调试符号构建 OpenSSL 首先,检出 OpenSSL 源代码并切换到您想要使用的版本。在本例中,我想使用 OpenSSL 3.0.2 …