网络

网络延迟是最核心的网络性能指标。由于网络传输、网络包处理等各种因素的影响,网络延迟不可避免。

在发现网络延迟增大的情况后,可以先从路由、网络包的收发、网络包的处理,再到应用程序等,从各个层级分析网络延迟,等到找出网络延迟的来源层级后,再深入定位瓶颈所在。

可能导致网络延迟的因素,即网络地址转换(Network Address Translation),缩写为 NAT。

NAT

NAT 技术可以重写 IP 数据包的源 IP 或者目的 IP,被普遍地用来解决公网 IP 地址短缺的问题

NAT主要原理就是,网络中的多台主机,通过共享同一个公网 IP 地址,来访问外网资源。同时,NAT 屏蔽了内网网络,为局域网中的机器提供了安全隔离。

  • 支持网络地址转换的路由器(NAT网关)中配置NAT
  • Linux服务器中配置NAT,Linux服务器充当软路由器(NAPT)

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. 双向地址转换,即同时使用 SNATDNAT。当接收到网络包时,执行 DNAT,把目的 IP 转换为内网 IP;而在发送网络包时,执行 SNAT,把源 IP 替换为外部 IP。

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

示例

  • 本地服务器内网IP地址(192.168.0.2)
  • NAT网关公网IP地址(100.100.100.100)
  • 目标服务器baidu.com公网IP地址(123.125.115.110)

那么 SNAT 和 DNAT 的过程,就如下图所示:

image

  1. 本地服务器访问baidu.com时,NAT网关会把源地址从(192.168.0.2)改成(100.100.100.100)然后把请求发送给baidu.com
  2. baidu.com发送响应时,NAT网关把目的地址从(100.100.100.100)改成(192.168.0.2)然后把响应发送给本地服务器

iptables与NAT

Linux 内核提供的 Netfilter 框架,允许对网络数据包进行修改(比如 NAT)和过滤(比如防火墙)。

在这个基础上,iptables、ip6tables、ebtables 等工具,又提供了更易用的命令行接口,以便系统管理员配置和管理 NAT、防火墙的规则。

要掌握 iptables 的原理和使用方法,最核心的就是弄清楚网络数据包通过 Netfilter 时的工作流向,如下图所示。

image

绿色的方框表示表(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表中进行操作,其中内置了3个链:

  • PREROUTING:用于路由判断前执行的规则,如,对接收到的数据进行DNAT
  • POSTROUTING:用于路由判断后执行的规则,如,对发送或者转发的数据包进行SNATMASQUERADE
  • OUTPUT:类似PREROUTING,但是只处理本机发送出去的包

SNAT

SNAT需要在nat表的POSTROUTING链中配置,常用如下两种方式:

  1. 为一个子网统一配置 SNAT,并由 Linux 选择默认的出口 IP,即MASQUERADE(为多个内网IP地址提供共享的出口IP)

    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 转发功能

sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

# 手动启动

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

# 保存在配置中

cat /etc/sysctl.conf | grep ip_forward
net.ipv4.ip_forward=1
上次修改: 12 June 2020