41-案例篇:如何优化NAT性能(上)





NAT原理

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

既可以在支持网络地址转换的路由器(称为 NAT 网关)中配置NAT,也可以在Linux服务器中配置NAT
如果采用第二种方式,Linux服务器实际上充当的是“软”路由器的角色

NAT的主要目的,是实现地址转换。根据实现方式的不同,NAT可以分为三类

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

NAPT是目前最流行的NAT类型,在Linux中配置的NAT也是这种类型
而根据转换方式的不同,又可以把NAPT分为三类

  1. 第一类是源地址转换SNAT,即目的地址不变,只替换源IP或源端口
    SNAT主要用于,多个内网IP共享同一个公网IP ,来访问外网资源的场景
  2. 第二类是目的地址转换DNAT,即源IP保持不变,只替换目的IP或者目的端口
    DNAT主要通过公网IP的不同端口号,来访问内网的多种服务,同时会隐藏后端服务器的真实IP地址
  3. 第三类是双向地址转换,即同时使用SNAT和DNAT
    当接收到网络包时,执行DNAT,把目的IP转换为内网IP
    而在发送网络包时,执行SNAT,把源IP替换为外部IP

双向地址转换,其实就是外网IP与内网IP的一对一映射关系
所以常用在虚拟化环境中,为虚拟机分配浮动的公网IP地址

为了理解NAPT,画了一张图假设

  1. 本地服务器的内网IP地址为192.168.0.2
  2. NAT网关中的公网IP地址为100.100.100.100
  3. 要访问的目的服务器baidu.com的地址为123.125.115.110

那么SNAT和DNAT的过程,就如下图所示
41-案例篇:如何优化NAT性能(上)

  1. 当服务器访问baidu.com时,NAT网关会把源地址
    从服务器的内网IP192.168.0.2替换成公网IP地址100.100.100.100,然后才发送给baidu.com
  2. 当baidu.com发回响应包时,NAT网关又会把目的地址
    从公网IP地址100.100.100.100替换成服务器内网IP192.168.0.2,然后再发送给内网中的服务器



iptables与NAT

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

其中iptables就是最常用的一种配置工具
要掌握iptables的原理和使用方法
最核心的就是弄清楚,网络数据包通过Netfilter时的工作流向,下面这张图就展示了这一过程
41-案例篇:如何优化NAT性能(上)

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

跟table一起的白色背景方框,则表示链(chain),用来管理具体的iptables规则
每个表中可以包含多条链,比如

  1. filter表中,内置INPUT、OUTPUT和FORWARD链
  2. nat表中,内置PREROUTING、POSTROUTING、OUTPUT等

当然也可以根据需要,创建自己的链

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

iptables的所有规则,就会放到这些表和链中,并按照图中顺序和规则的优先级顺序来执行

针对今天的主题,要实现NAT功能,主要是在nat表进行操作
而nat表内置了三个链

  1. PREROUTING,用于路由判断前所执行的规则,比如,对接收到的数据包进行DNAT
  2. POSTROUTING,用于路由判断后所执行的规则,比如,对发送或转发的数据包进行SNAT或MASQUERADE
  3. OUTPUT,类似于PREROUTING,但只处理从本机发送出去的包



SNAT

SNAT需要在nat表的POSTROUTING链中配置,常用两种方式来配置它

  1. 第一种方法,是为一个子网统一配置SNAT,并由Linux选择默认的出口IP
    这实际上就是经常说的MASQUERADE

    $ iptables -t nat -A POSTROUTING -s 192.168.0.0/16 -j MASQUERADE
    
    
  2. 第二种方法,是为具体的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 ,基于内核的连接跟踪模块实现
所以,它维护每个连接状态的同时,也会带来很高的性能成本


上一篇:zxing生成二维码输出在页面


下一篇:【学无止境】WIFI 6 AX200 无线网卡 连接 华为Q2S路由器