网络地址转换NAT原理及应用

2023-11-10

 

这是做路由器的时候,学习网络地址转换Network Address Translation后的一些理解整理,主要通过实例和图表的方式展示了NAT的工作原理和每个阶段的状态。本文的NAT是基本于Linux下的iptables命令实现。

1 概述

1.1 简介

NAT英文全称是“Network Address Translation”,中文意思是“网络地址转换”,它是一个IETF(Internet Engineering Task Force, Internet工程任务组)标准,允许一个整体机构以一个公用IP(Internet Protocol)地址出现在Internet上。顾名思义,它是一种把内部私有网络地址(IP地址)翻译成合法网络IP地址的技术。因此我们可以认为,NAT在一定程度上,能够有效的解决公网地址不足的问题。

1.2 分类

NAT有三种类型:静态NAT(Static NAT)、动态地址NAT(Pooled NAT)、网络地址端口转换NAPT(Port-Level NAT)。

其中,网络地址端口转换NAPT(Network Address Port Translation)则是把内部地址映射到外部网络的一个IP地址的不同端口上。它可以将中小型的网络隐藏在一个合法的IP地址后面。NAPT与 动态地址NAT不同,它将内部连接映射到外部网络中的一个单独的IP地址上,同时在该地址上加上一个由NAT设备选定的端口号。

NAPT是使用最普遍的一种转换方式,在HomeGW中也主要使用该方式。它又包含两种转换方式:SNAT和DNAT。

(1)源NAT(Source NAT,SNAT):修改数据包的源地址。源NAT改变第一个数据包的来源地址,它永远会在数据包发送到网络之前完成,数据包伪装就是一具SNAT的例子。

(2)目的NAT(Destination NAT,DNAT):修改数据包的目的地址。Destination NAT刚好与SNAT相反,它是改变第一个数据懈的目的地地址,如平衡负载、端口转发和透明代理就是属于DNAT。

1.3 应用

NAT主要可以实现以下几个功能:数据包伪装、平衡负载、端口转发和透明代理。

数据伪装: 可以将内网数据包中的地址信息更改成统一的对外地址信息,不让内网主机直接暴露在因特网上,保证内网主机的安全。同时,该功能也常用来实现共享上网。

端口转发: 当内网主机对外提供服务时,由于使用的是内部私有IP地址,外网无法直接访问。因此,需要在网关上进行端口转发,将特定服务的数据包转发给内网主机。

负载平衡: 目的地址转换NAT可以重定向一些服务器的连接到其他随机选定的服务器。

失效终结: 目的地址转换NAT可以用来提供高可靠性的服务。如果一个系统有一台通过路由器访问的关键服务器,一旦路由器检测到该服务器当机,它可以使用目的地址转换NAT透明的把连接转移到一个备份服务器上。

透明代理: NAT可以把连接到因特网的HTTP连接重定向到一个指定的HTTP代理服务器以缓存数据和过滤请求。一些因特网服务提供商就使用这种技术来减少带宽的使用而不用让他们的客户配置他们的浏览器支持代理连接。

2 原理

2.1 地址转换

NAT的基本工作原理是,当私有网主机和公共网主机通信的IP包经过NAT网关时,将IP包中的源IP或目的IP在私有IP和NAT的公共IP之间进行转换。

如下图所示,NAT网关有2个网络端口,其中公共网络端口的IP地址是统一分配的公共 IP,为202.20.65.5;私有网络端口的IP地址是保留地址,为192.168.1.1。私有网中的主机192.168.1.2向公共网中的主机202.20.65.4发送了1个IP包(Dst=202.20.65.4,Src=192.168.1.2)。

当IP包经过NAT网关时,NAT Gateway会将IP包的源IP转换为NAT Gateway的公共IP并转发到公共网,此时IP包(Dst=202.20.65.4,Src=202.20.65.5)中已经不含任何私有网IP的信息。由于IP包的源IP已经被转换成NAT Gateway的公共IP,Web Server发出的响应IP包(Dst= 202.20.65.5,Src=202.20.65.4)将被发送到NAT Gateway。

这时,NAT Gateway会将IP包的目的IP转换成私有网中主机的IP,然后将IP包(Des=192.168.1.2,Src=202.20.65.4)转发到私有网。对于通信双方而言,这种地址的转换过程是完全透明的。转换示意图如下。

如果内网主机发出的请求包未经过NAT,那么当Web Server收到请求包,回复的响应包中的目的地址就是私网IP地址,在Internet上无法正确送达,导致连接失败。

2.2 连接跟踪

在上述过程中,NAT Gateway在收到响应包后,就需要判断将数据包转发给谁。此时如果子网内仅有少量客户机,可以用静态NAT手工指定;但如果内网有多台客户机,并且各自访问不同网站,这时候就需要连接跟踪(connection track)。如下图所示:

在NAT Gateway收到客户机发来的请求包后,做源地址转换,并且将该连接记录保存下来,当NAT Gateway收到服务器来的响应包后,查找Track Table,确定转发目标,做目的地址转换,转发给客户机。

2.3 端口转换

以上述客户机访问服务器为例,当仅有一台客户机访问服务器时,NAT Gateway只须更改数据包的源IP或目的IP即可正常通讯。但是如果Client A和Client B同时访问Web Server,那么当NAT Gateway收到响应包的时候,就无法判断将数据包转发给哪台客户机,如下图所示。

此时,NAT Gateway会在Connection Track中加入端口信息加以区分。如果两客户机访问同一服务器的源端口不同,那么在Track Table里加入端口信息即可区分,如果源端口正好相同,那么在时行SNAT和DNAT的同时对源端口也要做相应的转换,如下图所示。

3 Linux下NAT实现

3.1 netfilter/iptables模块

netfilter/iptables(IP信息包过滤系统)是一种功能强大的工具,根据数据包过滤规则,对经过的网络数据包进行丢弃、改造、转发等处理。

netfilter组件也称为内核空间(kernelspace),是内核的一部分,由一些数据包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集。

iptables组件是一种工具,也称为用户空间(userspace),它主要用来向用户提供添加、修改、删除内核中数据过滤表的接口。

3.2 基于netfilter/iptables的NAT

netfilter/iptables中的数据包过滤表有三种:filter、nat和mangle。

filter 表用于一般的信息包过滤,它包含 INPUT 、 OUTPUT 和 FORWARD 链。

nat 表用于要转发的信息包,它包含 PREROUTING 、 OUTPUT 和 POSTROUTING 链。

如果信息包及其头内进行了任何更改,则使用 mangle 表。该表包含一些规则来标记用于高级路由的信息包,该表包含 PREROUTING 和 OUTPUT 链。

filter 表用来过滤数据包,我们可以在任何时候匹配包并过滤它们。Mangle不经常使用还在开发当中。我们下面主要介绍Nat表来实现NAT功能。

(1)用户使用iptables命令在用户空间设置NAT规则。通过使用用户空间iptables命令,可以构建用户自己的定制NAT规则。所有规则存储在内核空间的nat表中。根据规则所处理的信息包类型,将规则分组在链中。要做SNAT的信息包被添加到POSTROUTING链中。要做DNAT的信息包被添加到PREROUTING链中。直接从本地出站的信息包的规则被添加到OUTPUT 链中。

(2)内核空间接管NAT工作.做过NAT操作的数据包的地址就被改变了,当然这种改变是根据我们的规则进行的。属于一个流的包只会经过这个表一次。如果第一个包被允许做NAT或 Masqueraded,那么余下的包都会自动地被做相同的操作。也就是说,余下的包不会再通过这个表,一个一个的被NAT,而是自动地完成。这就是我们为什么不应该在这个表中做任何过滤的主要原因。PREROUTING 链的作用是在包刚刚到达防火墙时改变它的目的地址,如果需要的话。OUTPUT链改变本地产生的包的目的地址。下图是数据包穿越整个netfilter/iptables的流程图。

(3)NAT工作步骤:

DNAT:若包是被送往PREROUTING链的,并且匹配了规则,则执行DNAT或REDIRECT目标。为了使数据包得到正确路由,必须在路由之前进行DNAT。

路由:内核检查信息包的头信息,尤其是信息包的目的地。

处理本地进程产生的包:对nat表OUTPUT链中的规则实施规则检查,对匹配的包执行目标动作。

SNAT:若包是被送往POSTROUTING链的,并且匹配了规则,则执行SNAT或MASQUERADE目标。系统在决定了数据包的路由之后才执行该链中的规则。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

网络地址转换NAT原理及应用 的相关文章

  • 闪亮:动态更改选项卡名称

    我正在开发一个应该处理多种语言的闪亮应用程序 我设法动态翻译应用程序的几乎所有元素 具体取决于selectInput选择语言 然而 困难的事情 仍然是navbarPage选项卡以及tabPanels在我的页面内 我不能改变他们的名字 我尝试
  • 需要解释“~0”与“2**64”(带和不带“使用整数”)

    我编写了一些测试程序打印的值 0 and 2 64 usr bin perl use warnings use strict use integer print 0 n print 2 64 n Without use integer程序输
  • 如何动态添加值到 I18n?

    我的 Rails 应用程序中有很多 yml 我想将其中一些放在其他服务中 以便我可以从多个地方调用它 此调用的响应将是一个哈希值 en test text1 hi english text2 mambo number num es test
  • 旋转、缩放和平移 2D 坐标?

    我目前正在开发一个项目 尝试使用 Python 成像库创建希尔伯特曲线 我创建了一个函数 它将通过每次迭代生成曲线的新坐标 并将它们放入各种列表中 然后我希望能够移动 旋转和缩放 我想知道是否有人可以给我一些提示或方法来做到这一点 因为我完
  • Shiny 允许用户选择要显示的绘图输出

    我有一个闪亮的应用程序 我的服务器功能如下所示 shinyServer function input output session filedata lt reactive infile lt input file1 if is null
  • 字符串和标签本地化和全球化的最佳实践[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我是一个拥有 20 多名开发人员的团队的成员 每个开发人员都在一个单独的模块上工作 大约 10 个模块 在每个模块中 我们可能至少有 50 个
  • 如何将控制台输出写入文本文件

    我是编程新手 我在网页上搜索了这个问题的答案 并尝试了很多可能性 但没有成功 我目前已成功将电位计连接到我的树莓派并在控制台上获取值 但我不知道如何将这些值保存到文本文件中 这是我的代码 usr bin python import spid
  • 我的代码在输出前面打印一个新行[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我正在编写代码 但遇到了问题 我的代码在输出前面打印了一个新行 我想避免这种情况 这是我的代码 if movieName
  • 将scala生成的数据写入文本文件

    我希望有人可以提供帮助 我是 scala 新手 并且在将输出写入文本文件时遇到一些问题 我有一个数据表 并且编写了一些代码来一次读取一行 执行我想要它执行的操作 现在我需要它将该行写入文本文件 例如 我有下表的数据类型 名称 日期 goX
  • int(x[base]) 如何工作?

    以下代码的输出是 int 12 5 O P 7 int 0 5 O P 0 int 10 2 O P 2 我无法理解这一点 Python 文档中说 base 部分是可选的 即它可能需要一个或两个参数 第一个参数必须是一个在引号内具有 int
  • 防止 LISP 中的终端输出

    我想运行一个函数 但不让它在终端中输出结果 例如 set A B 正常返回B在控制台中如下所示 gt gt gt set A B B gt gt gt A B 我不希望它返回任何东西 我仍然希望该函数能够完成它应该做的事情 只是默默地 gt
  • 如何获取按输入顺序排序的 python Counter 输出?

    我一直在努力获取计数 频率 然后制作它的图形表示 我在用Counter班级来自collections使用Python 我想要的输出Counter按照先到对象的顺序 例如 offset a b c a b b b c c c c c coun
  • Swift - 将数组写入文本文件

    我从一个包含几千行纯文本的文件中读入 myArray 原生 Swift myData String stringWithContentsOfFile myPath encoding NSUTF8StringEncoding error ni
  • 你能帮助解释我的 svn diff 输出吗?

    我正在使用 SVN DIFF 比较两个文件夹 一个在分支中 一个在主干中 目的是确定更改列表 然后我对分支中的文件进行了一些更改 但输出显示我已经在主干中修改了它们 为什么会出现这种情况 有没有更好的命令来获取我正在寻找的结果 我现在使用的
  • 如何将Matlab命令的输出重定向到文件? [复制]

    这个问题在这里已经有答案了 我想将 Matlab 命令的输出重定向或复制到文件中 我怎样才能做到这一点 就我而言 我想使用 UNIX 工具比较两个大型结构diff 示例 我可以在 Matlab 中执行此操作 gt gt s1 s1 a 32
  • Magento,翻译验证错误消息

    我已经成功创建了原型验证的新规则 现在我需要翻译错误消息 位置 Javascript 中的字符串 但是 我只能翻译所有消息 我的新自定义消息似乎无法翻译 我该如何改变这个 也许你需要一个jstranslator xml里面的文件etc fo
  • django 翻译:msgfmt:找不到命令

    我已经使用 wiki 脚本 webfaction 安装了 OSQA 现在我想编译一个消息文件 但出现以下错误 django msgfmt command not found 命令 输出 ls apache2 bin lib osqa osq
  • Ansible 输出格式选项

    是否有一个选项可以使用 ansible 而不是任何其他脚本 来格式化 ansible 输出 例如 name Show version sudo true hosts web front end tasks name Create yum c
  • 更改 Qt 中的语言环境

    我尝试使用 QLocale 和 setDefault 函数更改区域设置 但似乎不起作用 以下是使用 C 本地化库和 QLocale 更改语言环境的示例 对于 C 本地化库 它似乎可以工作 但对于 QLocale setDefault 函数调
  • Django:如何为应用程序添加中文支持

    我正在尝试将中文添加到我用 Django 编写的应用程序中 但我确实遇到了困难 我花了半天时间尝试了不同的方法 但没有成功 我的应用程序支持几种语言 这是设置 py file TIME ZONE Europe Dublin LANGUAGE

随机推荐

  • LeetCode 18. 四数之和

    文章目录 1 排序 双指针 2 对上面代码加剪枝 题目链接 https leetcode cn problems 4sum 1 排序 双指针 class Solution using ll long long public vector
  • Linux使用4g模块拨号上网

    imux6ull 串口连接移远的4g模块EC200N 使用pppd拨号上网 1 设置内核支持pppd 打开pppd下的所有项 编译内核 Device Drivers gt Network device support gt PPP poin
  • Git出现无法同步问题的解决方式

    在我们使用git同步至github服务器上去时 可能会出现 the request URL returns error 403 Forbbidden while accessing 权限不够 此项目为私有 没有权限 输入用户名和密码 或远程
  • 高级面向对象技术

    封装 三种方式 工厂函数模式 构造函数模式 构造函数模式和原型结合 工厂函数模式代码示例 function factory name var obj new Object obj name name obj sayName function
  • 9_1 ArrayList 初始化 (elementData.getClass() != Object[].class)

    第一个知识点 数组也有自己 class 表示维度 Lxxx表示数组的元素类型 package 集合类 ArrayList类 import java util ArrayList import java util Arrays public
  • 实现高效的并行计算:使用Fork/Join框架和并行流

    要实现高效的并行计算 可以使用Java中的Fork Join框架和并行流 这两个工具都是Java提供的用于并行处理任务的机制 可以充分利用多核处理器的能力 1 Fork Join框架 Fork Join框架是Java中用于并行任务处理的一个
  • 有向图邻接矩阵c语言编程,邻接矩阵有向图(一)之 C语言详解

    本章介绍邻接矩阵有向图 在 图的理论基础 中已经对图进行了理论介绍 这里就不再对图的概念进行重复说明了 和以往一样 本文会先给出C语言的实现 后续再分别给出C 和Java版本的实现 实现的语言虽不同 但是原理如出一辙 选择其中之一进行了解即
  • vue-i18n 的使用

    一 安装 安装 Vue i18n 插件 您可以使用以下命令进行安装 npm install vue i18n next save 安装 npm install vue i18n next save legacy peer deps adde
  • 微软Kinect:谁还要控制器?

    体感控制游戏 Kinect谁还要控制器 这是XBoxKinect系统背后最重要的思想 微软的新玩具在10天内卖出了100万台 记者陈赛简单说 Kinect是嵌入XBox的三个小镜头 一个RGB摄像头 一个红外投影仪和一个远程感应器 这些镜头
  • 火狐浏览器插件

    All in one sidebar 侧栏控制 Firebug 在浏览网页的同时 具备丰富开发的功能 LastPass 在线密码管理器 gtranslator 翻译 Xmarks 书签 ColorZilla 颜色复制 Adblock Plu
  • 北京大学肖臻老师《区块链技术与应用》公开课笔记20——ETH中GHOST协议篇

    北京大学肖臻老师 区块链技术与应用 公开课笔记 以太坊GHOST协议 对应肖老师视频 click here 全系列笔记请见 click here About Me 点击进入我的Personal Page BTC系统中出块时间为10min 而
  • AntdPro项目前端测试的探索

    测试规范 测试工具的选择 在本项目中以 ant design pro 项目为测试项目 测试工具最终选型为 jest javascript的常用测试框架 enzyme 支持react的jest测试库 react test renderer 快
  • ftp服务器收集信息,用VBScript收集系统信息并上传到ftp空间

    之前无聊整理出来了一份这个东西 因为在单位给新入职的员工配电脑时 需要登记一遍设备 可每次总要查感觉挺麻烦 结果下面的这份VBS脚本就诞生了 只可惜这个脚本做好了却没派上用场哎 这个脚本的功能是运行后自动将查询到的计算机相关信息记录到一个文
  • 详解 Neo4J 出现问题

    项目启动报错提示如下错误 org springframework data mapping PropertyReferenceException No property selectMenuPage found for type Menu
  • 传输层--UDP协议

    传输层的功能 传输层一个很重要的功能就是复用和分用 应用层不同进程的报文通过不同端口向下交到传输层 再往下就共用网络层提供的服务 具体功能 1 传输层是为应用进程之间提供端到端的逻辑通信 网络层是为主机之间提供逻辑通信 2 传输层要对收到的
  • 使用mysql

    使用mysql 语句来解决复杂逻辑问题 select id SUBSTRING INDEX name 1 from test where parent SUBSTRING INDEX使用方法 name字段 是标识符 1代表是第一个出现的 U
  • Python pyi文件

    当用nn conv2d 函数的时候 发现它内部其实是调用的F conv2d 而F conv2d 的定义是在 init pyi文件里 那么 pyi到底是什么文件呢 pyi文件是Python 的存根文件 用于代码检查时的类型提示 pyi文件是P
  • linux下执行shell脚本调用sql文件,传输到远程服务器

    1 编写sql 2 编写shell shell里用sqlplus调用sql文件生成csv文件 还要编写对端服务器的相关信息 3 将写好的sql和shell文件传输到linux服务器上 4 切换到文件存放目录下 使用以下命令执行shell s
  • Elasticsearch删除文档

    根据id删除 例如删除id为110的文档 DELETE ffbf doc 110 返回信息 index ffbf type doc id 110 version
  • 网络地址转换NAT原理及应用

    这是做路由器的时候 学习网络地址转换Network Address Translation后的一些理解整理 主要通过实例和图表的方式展示了NAT的工作原理和每个阶段的状态 本文的NAT是基本于Linux下的iptables命令实现 1 概述