「NAT」- Network address translation

  CREATED BY JENKINSBOT

原理简述

NAT,网络地址转换,用于重写数据包中的 源地址 或 目的地址,用于解决地址短缺的问题。它的主要原理是,在网络中的多台主机,通过共享同个公网地址来访问外网资源。同时,由于 NAT 屏蔽了内网网络,自然也就为局域网中的机器提供了安全隔离。

网络地址转换的分类

根据实现方式的不同,网络地址转换可以分为三类:
1)静态 NAT,即内网 IP 与公网 IP 是一对一的永久映射关系;
2)动态 NAT,即内网 IP 从公网 IP 池中,动态选择一个进行映射;
3)网络地址端口转换 NAPT(Network Address and Port Translation),即把内网地址映射到公网地址的不同端口上,让多个内网地址可以共享同个公网地址

网络地址端口转换的分类

根据转换方式的不同,我们又可以把网络地址端口转换分为三类:
1)地址转换,SNAT:目的地址不变,只替换源地址或源端口。这是我们常用的模式。
2)地址转换,DNAT:源地址保持不变,只替换目的地址或者目的端口
3)双向地址转换,即同时使用 SNAT 和 DNAT 规则。当接收到网络包时,执行 DNAT,把目的地址转换为内网地址;而在发送网络包时,执行 SNAT,把源地址替换为外部地址

iptables 与 NAT

Linux 内核提供的 Netfilter 框架,允许对网络数据包进行修改(比如 NAT)和过滤(比如防火墙)。在这个基础上,iptables、ip6tables、ebtables 等工具,又提供了更易用的命令行接口,以便系统管理员配置和管理 NAT、防火墙的规则。

网络数据包的工作流向

绿色背景的方框,表示表(table),用来管理链,支持 4 种表:filter(用于过滤)、nat(用于 NAT)、mangle(用于修改分组数据)、raw(用于原始数据包)

跟 table 一起的白色背景方框,则表示链(chain),用来管理具体的 iptables 规则。每个表中可以包含多条链,比如:
1)filter 表中,内置 INPUT、OUTPUT 和 FORWARD 链;
2)nat 表中,内置 PREROUTING、POSTROUTING、OUTPUT 等

灰色的 conntrack,表示连接跟踪模块。它通过内核中的连接跟踪表(也就是哈希表),记录网络连接的状态,是 iptables 状态过滤(-m state)和 NAT 的实现基础。

实现 NAT 功能

这需要在 nat 表进行操作。而 nat 表内置了三个链:
1)PREROUTING,用于路由判断前所执行的规则,比如,对接收到的数据包进行 DNAT。
2)POSTROUTING,用于路由判断后所执行的规则,比如,对发送或转发的数据包进行 SNAT 或 MASQUERADE。
3)OUTPUT,类似于 PREROUTING,但只处理从本机发送出去的包。

SNAT,修改源地址,即在数据包发送出去时修改地址:

// 由 Linux 选择默认的出口 IP

# iptables -t nat -A POSTROUTING -s 192.168.0.0/16 -j MASQUERADE

// 指定具体的 IP 地址配置 SNAT

# iptables -t nat -A POSTROUTING -s 192.168.0.2 -j SNAT --to-source 100.100.100.100

DNAT,修改目的地址,即要在数据包收到时进行修改,以进行路由决策和处理:

// 由 Linux 选择默认的出口 IP

# iptables -t nat -A PREROUTING -d 100.100.100.100 -j DNAT --to-destination 192.168.0.2

// 也可以在OUTPUT链中配置???

双向地址转换,同时添加 SNAT 和 DNAT 规则:

# iptables -t nat -A POSTROUTING -s 192.168.0.2 -j SNAT --to-source 100.100.100.100
# iptables -t nat -A PREROUTING -d 100.100.100.100 -j DNAT --to-destination 192.168.0.2

另外,在使用 iptables 配置 NAT 规则时,Linux 需要转发来自其他 IP 的网络包,所以需要开启 Linux 的 IP 转发功能:

# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

参考文献

Wikipedia/Network address translation
41 | 案例篇:如何优化 NAT 性能?(上)