网络延迟是最核心的网络性能指标。由于网络传输、网络包处理等各种因素影响,网络延迟不可避免,但过大的延迟会直接影响用户体验。
发现网络延时增大后,可以从路由、网络包的收发、网络包的处理,再到应用程序等,从各个层级分析网络延迟,待找到网络延时的来源层级后,再深入定位瓶颈所在。

NAT(network address translation) 网络地址转换也是一个可能导致网络延迟的因素。

NAT原理

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

NAT的实现

既可以在支持网络地址转换的路由器(NAT网关)中配置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或者源端口,主要用于多个内网ip共享访问一个公网ip,来访问外网资源的场景。
  • DNAT: 即源IP不变,只替换目的ip或端口。通过公网ip的不同端口,来访问内网的多种服务,同时隐藏后端服务器的真实ip地址。
  • 双向地址转换,接收到网络包时,执行DNAT,将目的IP转化为内网ip;发送网络包时,使用SNAT将源IP转化为外部IP。

如图是一个网络拓扑
当内网IP192.168.0.2访问外网百度时,发出的网络包,经过NAT网关时,会使用SNAT将源ip地址转化为NAT网关的ip地址,百度接收网络包时,该包的源IP为100.100.100.100
而百度返回的包在经过NAT网关时,则执行DNAT通过查找路由表将目的IP转化为内网的真实IP,即192.168.0.2

iptables与nat

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

要掌握iptables的原理和使用方法,其核心是弄清楚网络数据包通过netfilter时的工作流向,如下图:

tables

图中绿色方框即为表,用来管理链。linux中支持四种表,包括filter、nat、mangle和raw,其作用分别为:

  • filter: 用于过滤数据包
  • nat: 用于网络地址转换
  • mangle:用于修改分组数据
  • raw:用于原始数据包

chain

与table一期的白色方框即为链,用来管理具体的iptables规则,每个表中可以包含多条链。

NAT表为例,它内置了三条链:

  • prerouting, 用于路由判断前所执行的规则,比如对接收到的网络数据包进行DNAT
  • postrouting,用于路由判断后所执行的规则,比如对发送或者转发的数据包进行SNAT或者MASQUERADE
  • output:类似prerouting,只处理本机发送出去的包。

conntrack

灰色的conntrack,标识连接跟踪模块,他通过内核中的连接跟踪表(哈希表),记录了网络连接的状态,是iptables状态过滤(-m state)和nat的实现基础。
iptables的所有规则,都会放到这些表和链中,并按照图中的顺序和规则优先级顺序来执行。

[如何理解规则优先级?]

问题

问题1:Linux的NAT时给予内核的连接跟踪模块实现,保留了源IP、源端口、目的IP、目的端口之间的关系,多个内网IP地址的端口相同,但是IP不同,再nf_conntrack中对应不同的记录,所以MASQUERADE可以正常工作。

问题2:NAT方式所有流量都要经过NAT服务器,所以NAT服务器本身的软中断导致CPU负载、网络流量、文件句柄、端口号上限、nf_conntrack table full都可能是性能瓶颈

引用

1. 极客时间-如何优化nat性能
2. Netfilter-packet-flow.svg
2. linux系统日常管理
4. 记一次Docker/Kubernetes上无法解释的连接超时原因探寻之旅