NAT(Network Address Translation,网络地址转换)是一种 L3 网络层的 IP 地址转换技术,由 IETF 定义标准,最初用于缓解 IPv4 公网地址紧缺的问题。现在广泛被应用于公网 IP(全球唯一可寻址 IP 地址)和私网 IP(10、172、192 网段)之间的转换。
除了解决公网 IP 地址紧缺的问题之外,NAT 技术还常用于支撑以下网络功能:
NAT GW 的基本原理是在转发 IP 数据包时,对其 srcIP/dstIP 甚至是 srcPort/dstPort 进行编辑和转换。
从 IP 映射关系上,可以细分为:
从 IP 编辑和转换类型上,可以细分为:
如上图所示,NAT GW 具有对外和对内的 2 类网络端口:
如果此时 NAT GW 已经配置了私网网段和公网 IP 地址之间的动态 NAT 规则,那么当私网中的 ClientA 192.168.1.2 向公网中 Web Server 202.20.65.4 发送了 1 个 IP Packet(srcIP=192.168.1.2、dstIP=202.20.65.4)时会执行以下 NAT 行为。
动态 NAT 技术需要依赖 Connection Track(连接跟踪)功能来维护动态的地址映射表,它使得 “回程包“ 知道应该转发给哪个私网 IP 地址。如下图所示:
NAPT(Network Address Port Translation)用于实现将一个公网 IP 地址映射到多个私网 IP 上。如下图所示。
NAT GW 的 Connection Track 还用于支持 NAPT 技术,
NAT Server,顾名思义是一台服务器角色,可以主动接受公网 Client 的请求,并转发到后端私网 IP 地址。实现的原理和上述一致,区别在于由于应用场景的不同,所以 NAT Table Entries 的创建时机不同。
NAT 穿透是一种特殊的应用场景,顾名思义就是 “绕过 NAT GW“,实现两个网络间的 P2P(点到点)直接通信。NAT 穿透在多种场景中有用,例如:
Linux iptables NAT 转发操作需要在 filter 表中 FORWARD 链中允许,并且打开 Kernel ip_forwarding 转发功能。
另外,由于 iptables 会主动维护 NAT Table,所以在使用 iptables 配置时往往只需要配置 SNAT 或 DNAT 即可 “回包“,而无需为一个数据流同时创建 2 条规则。同时,Linux iptables 在 Kernel 中会将 Netfilter 和 ConnTrack 组合支撑会话跟踪功能。
SNAT 作用于 Egress 流量,所以在 iptables 的 POSTROUTING 链生效。出站路径为:APP => TCP/IP stack 路由子系统 => filter:OUTPUT => nat:POSTROUTING => 出站。
$ iptables -t nat -I POSTROUTING -s 192.168.0.0/24 -o eth1 -j SNAT --to 198.51.100.3
在动态 NAT 场景中,还需要使用 IP 地址伪装模式(MASQUERADE),这是一种动态 SNAT 技术,通常用于家庭网络或移动网络。
$ iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
DNAT 作用于 Ingress 流量,所以在 PREROUTING 链中生效。
$ iptables -t nat -I PREROUTING -p tcp -d 198.51.100.3 --dport 80 -j DNAT --to 192.168.0.2
NAPT 通常和 DNAT 一起使用,例如:将本机公网 IP 的 2222 端口映射到虚拟机内网 IP 的 22 端口。
$ iptables -t nat -A PREROUTING -d 210.14.67.127 -p tcp --dport 2222 -j DNAT --to-dest 192.168.188.115:22
# 测试。
$ ssh [email protected] -p 2222