可能是目前最全的讲 NAT 的文章

对于 NAT,你想知道的,可能包括以下几点:

  • NAT 是啥

  • 为啥需要 NAT

  • NAT 的分类

  • NAT 是怎么实现的

  • NAT 有什么问题

  • 防火墙与 NAT

01 NAT 是啥

NAT,全称叫 Network Address Translation,网络地址转换/翻译,简单讲就是能将私有地址和公有地址进行转换的一个技术。NAT 功能通常会被集成到路由器、防火墙、或独立的 NAT 设备中。

02 为啥需要 NAT

为什么需要转换私有地址和公有地址,以及什么是私有地址和公有地址?

我们知道,由于历史原因,IPv4 地址起初设计的时候,长度只有 32 位,所以只能提供大约 40 亿个地址。这造成了 IPv4 地址的耗尽危机。虽然后面 IPv6 地址被设计出来,能够提供更多的 IP 地址。

但 IPv4 和 IPv6 并不兼容,IPv4 向 IPv6 迁移也并不容易。在迁移的这段时间内,急需一些替代技术来缓解 IPv4 地址的稀缺。NAT 就是其中一种,另外还有 CIDR。

理论上,每个 IP 地址代表了 Internet 上的一个设备,但有一些地址被保留,用作私有的 IP 地址,如下面的三段:

From             To
10.0.0.0         10.255.255.255
172.16.0.0        172.31.255.255
192.168.0.0        192.168.255.255

私有地址只用于局域网内部通信,与之对应的就是公有地址。理论上,私有地址不应该在互联网被看到,而公有地址正恰好相反。由于互联网上有通信需求的设备众多,所以公有地址就显得格外稀缺而珍贵,这个时候,如果说能将私有地址在不同的私有网络中重复使用,那将大大缓解公有地址的使用耗尽。

NAT 就是提出来为私有网络服务的。在私有网络中的主机使用私有 IP 地址,当需要与外部 Internet 通信时,网关路由器执行 NAT 功能,将私有 IP 地址转为公有地址。这就可以缓解设备对公有 IP 地址的需求。

03 NAT 的分类

NAT 从概念上说很简单,就是进行私有地址和公有地址的转换,但是怎么转换的,一对一,还是多对一?不同的方法对公网 IP 地址的节省都不一样,根据使用公网 IP 地址数量的不同, NAT 分为以下三类:

① 静态 NAT

这个是最基本的,一对一 NAT,就是静态配置一个私有地址对应一个公网地址,但是问题也很明显,基本没有缓解对公网 IP 地址的使用。

内网 IP外网 IP
192.168.1.10219.152.168.222
192.168.1.11219.152.168.223
192.168.1.12219.152.168.224

② 动态 NAT

也叫地址池 NAT,网关路由器维护一个动态变化的 NAT 地址池,当有私网设备要访问公网时,会得到一个临时的公有 IP 地址,若该设备在一定时间内没有和公网通信,这个临时地址就会被释放,给其他设备用,有关它的 IP 映射关系也会从 NAT table 中删除。

通常来说,一个局域网中只有少数设备处于开机状态,且有访问外网的需求,动态 NAT 就非常适用,它可以极大减少公有 IP 地址的分配和使用。但这样还不够,公有地址分配还是相对较多,且管理上不够灵活,所以就有了下面这种方式。

NAPT

全称叫 Network Address and Port Translation,网络地址和端口转换,它比前面的方式多利用了 Port 层面的信息进行转换,可以实现多对一,即多个私有地址映射一个公有地址的需求,更能节省地址且管理更灵活。

其实更为准确的理解应该是 IP + session 的转换,session 是更为通用的一种说法,指代的是能够对不同类型的数据进行标识的特定字段,比如 TCP/UDP 报文,session=port,ICMP 报文,session=ICMP Indentifier。下面显示一个带 IP+端口号的 NAT 表:

内网 IP外网 IP
192.168.1.10:5566219.152.168.222:9200
192.168.1.11:80219.152.168.222:9201
192.168.1.12:4465219.152.168.222:9202

可以看到,只用了一个 公网 IP,即可完成三个内网 IP 的转换。

以上方法是根据使用公网 IP 地址数量进行分类,也有一种分类是根据 NAT 的数据流向进行分类,将 NAT 分为:

  • SNAT :数据流从私网访问公网,到达 NAT 网关进行 SNAT,根据配置的 NAT 表,将数据包的 src_ip 改为对应的公网地址,如果 port 有记录,也要相应修改

  • DNAT :数据流从公网访问私网,由于不知道私网地址,所以数据包的 dst_ip 是 NAT 网关对外的公网地址,到达 NAT 网关进行 DNAT,同理将数据包 dst_ip 改为对应的私网地址,同样 port 有记录也做修改

04 NAT 是怎么实现的

啰嗦这么多,想必大家应该都知道 NAT 是怎么实现的了,无非就是网关设备或者专用 NAT 设备维护一个 NAT 映射表来完成 NAT 的转换工作,这个过程我们重点注意两点:

  • 连接跟踪

  • checksum 修改

在 NAT 网关收到响应包的时候,它是如何知道要传给内部的具体哪个主机呢?这里主要用到的技术就是连接跟踪。

在 NAT 网关收到内部主机的请求包之后,会做 SNAT ,然后把本次连接记录保存到一个连接跟踪表(Track Table)里,当收到响应包之后,就可以根据 Track table 确定目标主机,然后做 DNAT,转发给主机。

如果是存在端口转换的情况,即 NAPT,那么需要在 Track table 里加入端口信息区分,这样来回的 NAT 转换也就不会有问题。

图片来源ref1

checksum 的修改就是很自然的,源目的 IP (NAPT 还有端口)改变了,包头中有关联的字段也要相应改变,其中关联的就是 checksum 字段。

checksum 字段存在于 IP 头部和 TCP/UDP 头部(UDP 头部是可选的),IP 头部 checksum 的校验范围只在头部,TCP/UDP checksum 则包括一个伪首部+TCP/UDP header + TCP/UDP payload,伪首部就包含了 IP 地址信息,所以当 IP 改变了,IP 头部和 TCP/UDP 头部(如果有)的 checksum 都需要相应改变。

另外,还需要注意的是,其他的一些协议,比如说 ICMP、FTP、DNS 等,它们的数据中如果有携带 IP 和 TCP port 信息的,也需要修改 checksum 的字段。

05 NAT 有什么问题

看很多资料上,罗列了好几种 NAT 的问题,比如说 “违反 IP 的体系结构、分层原则,网关设备变重等等”,这些问题在我看来有点鸡蛋里挑骨头,要减缓公网 IP 地址的使用,这是必然的做法。

要说问题,可能就在于两点:

1)从性能上来说,地址转换增加了延迟,这个也有点挑,对于高性能的应用来说,能直接转必然也不会考虑 NAT。

2)有些嵌入 IP 地址或端口的应用可能工作会比较麻烦。典型的比如 FTP,它的 payload 中会嵌入一些 IP 地址和端口号的信息,这种情况下除了需要 NAT 转换表负责转换包头的 IP 和端口字段外,还需要额外的程序来处理 payload 中关联的字段,就会给网关设备带来更加繁重的处理压力。

06 NAT 与防火墙

NAT 将网络划分为内部网络和外部网络这个特性,基本就是实现一个防火墙的功能了。它隐藏了主机自己的真实 IP,仅通过端口复用来与外网通信。所以我们也看到,Linux系统实现的内部防火墙 iptables 中就有 NAT 的实现。

下面就来看看 iptables 中的 NAT 是如何做到防护的。

我们都知道,iptables 有 4 表 5 链的防护体系,NAT 就是其中的一张表,它可以作用在 PREROUTING、OUTPUT、POSTROUTING 这 3 条链上(有些系统还包含INPUT 链,不是必须的),如下图所示:

其中,SNAT 因为要负责转换出本机的包,所以是作用在 OUTPUT 和 POSTROUTING 两条链上,OUTPUT 负责从本机发出的包的 NAT,POSTROUTING 负责非本机转发的包的 NAT(也就是经过 FORWARD 链转发的包);

而 DNAT 则是负责转换进入主机的包,所以作用在 PREROUTING 链上。

通过 iptables 的命令,我们可以配置下面的 SNAT 和 DNAT 命令来实现地址的转换。

1. 首先配置 SNAT,我们配到 POSTROUTING 链上:

iptables -t nat -A POSTROUTING -s 10.10.0.0/16 -j SNAT --to-source 公网IP

这条命令的意思是将来自 10.10.0.0/16 网段的报文的源地址改为公司的公网 IP 地址。

  • -t nat:表示 NAT 表

  • -A POSTROUTING:表示将该条规则添加到 POSTROUTING 链的末尾,A 就是 append。

  • -j SNAT:表示使用 SNAT 动作

  • --to-source:表示将报文的源 IP 修改为哪个公网 IP 地址

2. 然后配置 DNAT,配到 PREROUTING 链上:

iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 公网端口 -j DNAT --to-destination 私网IP:端口号

这条命令的意思是将来自公网IP:端口号的报文的目的地址改为私网IP:端口,可以看到这里多了端口的信息。原因是要区分公网访问的是私网的那个服务,所以需要明确到端口层级,才能精确送到客户端。而 SNAT 不需要端口信息也可以完成正确转发。

  • -I PREROUTING:表示将该条规则插入到 PREROUTING 的首部,I 就是 insert

  • --to-destination:表示将报文的目的 IP:端口修改为哪个私网IP:端口

06 总结

NAT 的分类,现在主要的应用都是 NAPT

SNAT、DNAT,NAT 与防火墙的实现

IPv6 也有 NAT 的版本,叫 NAT6,为什么 IPv6 也需要 NAT 呢?大家可以思考一下。

参考:

https://www.cnblogs.com/dongzhuangdian/p/5105844.html

http://www.zsythink.net/archives/1764


后台回复“加群”,带你进入高手如云交流群

推荐阅读:

什么是物联网?这里有你需要了解的一切

网络通信中的几种握手

【趣图】程序员一乐!

Kubernetes的架构为什么是这个样的?

任何人都能看得懂的网络协议之ARP

用好你的网络瑞士军刀netcat

一次Linux系统被攻击的分析过程

Linux下删除大量文件效率对比

130 个相见恨晚的神器网站

分享20个Linux命令小贴士与技巧

一文带你彻底理解文件系统

5G与Wi-Fi6空口技术对

牛逼的Linux性能剖析—perf

HTTPS 的 7 次握手以及 9 倍时延

一文搞定 UDP 和 TCP 高频面试题!


喜欢,就给我一个“在看”


10T 技术资源大放送!包括但不限于:云计算、虚拟化、微服务、大数据、网络、Linux、Docker、Kubernetes、Python、Go、C/C++、Shell、PPT 等。在公众号内回复「1024」,即可免费获取!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值