NAT原理
NAT技术可以重写IP数据包的源IP或者目的IP,被普遍地用来解决公网IP地址短缺的问题
它的主要原理就是,网络中的多台主机,通过共享同一个公网IP地址,来访问外网资源
同时,由于NAT屏蔽了内网网络,自然也就为局域网中的机器提供了安全隔离
既可以在支持网络地址转换的路由器(称为 NAT 网关)中配置NAT,也可以在Linux服务器中配置NAT
如果采用第二种方式,Linux服务器实际上充当的是“软”路由器的角色
NAT的主要目的,是实现地址转换。根据实现方式的不同,NAT可以分为三类
- 静态NAT,即内网IP与公网IP是一对一的永久映射关系
- 动态NAT,即内网IP从公网IP池中,动态选择一个进行映射
- 网络地址端口转换NAPT(Network Address and Port Translation)
即把内网IP映射到公网IP的不同端口上,让多个内网IP可以共享同一个公网IP地址
NAPT是目前最流行的NAT类型,在Linux中配置的NAT也是这种类型
而根据转换方式的不同,又可以把NAPT分为三类
- 第一类是源地址转换SNAT,即目的地址不变,只替换源IP或源端口
SNAT主要用于,多个内网IP共享同一个公网IP ,来访问外网资源的场景 - 第二类是目的地址转换DNAT,即源IP保持不变,只替换目的IP或者目的端口
DNAT主要通过公网IP的不同端口号,来访问内网的多种服务,同时会隐藏后端服务器的真实IP地址 - 第三类是双向地址转换,即同时使用SNAT和DNAT
当接收到网络包时,执行DNAT,把目的IP转换为内网IP
而在发送网络包时,执行SNAT,把源IP替换为外部IP
双向地址转换,其实就是外网IP与内网IP的一对一映射关系
所以常用在虚拟化环境中,为虚拟机分配浮动的公网IP地址
为了理解NAPT,画了一张图假设
- 本地服务器的内网IP地址为192.168.0.2
- NAT网关中的公网IP地址为100.100.100.100
- 要访问的目的服务器baidu.com的地址为123.125.115.110
那么SNAT和DNAT的过程,就如下图所示
- 当服务器访问baidu.com时,NAT网关会把源地址
从服务器的内网IP192.168.0.2替换成公网IP地址100.100.100.100,然后才发送给baidu.com - 当baidu.com发回响应包时,NAT网关又会把目的地址
从公网IP地址100.100.100.100替换成服务器内网IP192.168.0.2,然后再发送给内网中的服务器
iptables与NAT
Linux内核提供的Netfilter框架,允许对网络数据包进行修改(比如NAT)和过滤(比如防火墙)
在这个基础上iptables、ip6tables、ebtables等工具,又提供了更易用 的命令行接口
以便系统管理员配置和管理NAT、防火墙的规则
其中iptables就是最常用的一种配置工具
要掌握iptables的原理和使用方法
最核心的就是弄清楚,网络数据包通过Netfilter时的工作流向,下面这张图就展示了这一过程
在这张图中,绿色背景的方框,表示表(table),用来管理链
Linux支持4种表,包括filter(用于过滤)、nat(用于NAT)、mangle(用于修改分组数据)和raw(用于原始数据包)等
跟table一起的白色背景方框,则表示链(chain),用来管理具体的iptables规则
每个表中可以包含多条链,比如
- filter表中,内置INPUT、OUTPUT和FORWARD链
- nat表中,内置PREROUTING、POSTROUTING、OUTPUT等
当然也可以根据需要,创建自己的链
灰色的conntrack,表示连接跟踪模块
它通过内核中的连接跟踪表(也就是哈希表)
记录网络连接的状态,是iptables状态过滤(-m state)和NAT的实现基础
iptables的所有规则,就会放到这些表和链中,并按照图中顺序和规则的优先级顺序来执行
针对今天的主题,要实现NAT功能,主要是在nat表进行操作
而nat表内置了三个链
- PREROUTING,用于路由判断前所执行的规则,比如,对接收到的数据包进行DNAT
- POSTROUTING,用于路由判断后所执行的规则,比如,对发送或转发的数据包进行SNAT或MASQUERADE
- OUTPUT,类似于PREROUTING,但只处理从本机发送出去的包
SNAT
SNAT需要在nat表的POSTROUTING链中配置,常用两种方式来配置它
-
第一种方法,是为一个子网统一配置SNAT,并由Linux选择默认的出口IP
这实际上就是经常说的MASQUERADE$ 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
DNAT需要在nat表的PREROUTING或者OUTPUT链中配置
其中,PREROUTING链更常用一些(因为它还可以用于转发的包)
$ iptables -t nat -A PREROUTING -d 100.100.100.100 -j DNAT --to-destination 192.168.0.2
双向地址转换
双向地址转换,就是同时添加SNAT和DNAT规则,为公网IP和内网IP实现一对一的映射关系,即
$ 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转发功能
可以执行下面的命令,查看这一功能是否开启
如果输出的结果是1,就表示已经开启了IP转发
$ sysctl net.ipv4.ip_forwardnet.ipv4.ip_forward = 1
net.ipv4.ip_forward = 1
如果还没开启,可以执行下面的命令手动开启
$ sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
当然,为了避免重启后配置丢失,不要忘记将配置写入/etc/sysctl.conf文件中
$ cat /etc/sysctl.conf | grep ip_forward
net.ipv4.ip_forward=1
小结
NAT技术能够重写IP数据包的源IP或目的IP,所以普遍用来解决公网IP地址短缺的问题
它可以让网络中的多台主机,通过共享同一个公网IP地址,来访问外网资源
同时, 由于NAT屏蔽了内网网络,也为局域网中机器起到安全隔离的作用
Linux中的NAT ,基于内核的连接跟踪模块实现
所以,它维护每个连接状态的同时,也会带来很高的性能成本