【性能】如何优化 NAT 性能?

【性能】如何优化 NAT 性能?,第1张

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

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

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

其中,iptables 就是最常用的一种配置工具。要掌握 iptables 的原理和使用方法,最核心的就是弄清楚,网络数据包通过 Netfilter 时的工作流向。

熟悉 iptables 中的表和链后,我们以 NAPT 的三个分类为例,来具体解读一下:

在使用 iptables 配置 NAT 规则时,Linux 需要转发来自其他 IP 的网络包,所以你 千万不要忘记开启 Linux 的 IP 转发功能 。

Linux 中的 NAT ,基于内核的连接跟踪模块实现。所以,它维护每个连接状态的同时,也会带来很高的性能成本,对网络性能有一定影响。

那么,碰到 NAT 性能问题时,我们又该怎么办呢?

SystemTap  是 Linux 的一种动态追踪框架,它把用户提供的脚本,转换为内核模块来执行,用来监测和跟踪内核的行为。关于它的原理,你暂时不用深究,这里你只要知道怎么安装就可以了。

# yum   -y  install systemtap kernel-devel

# yum info  systemtap 

我们之前使用 tcpdump 抓包的方法,找出了延迟增大的根源。那么今天的案例,我们仍然可以用类似的方法寻找线索。不过,现在换个思路,因为今天我们已经事先知道了问题的根源——那就是 NAT。

回忆一下 Netfilter 中,网络包的流向以及 NAT 的原理,你会发现,要保证 NAT 正常工作,就至少需要两个步骤:

这个脚本,跟踪内核函数 kfree_skb() 的调用,并统计丢包的位置。

文件保存好后,执行下面的 stap 命令,就可以运行丢包跟踪脚本。

这里的 stap,是 SystemTap 的命令行工具:

#  man 1 perf-record

###############################################################

-a, --all-cpus

          System-wide collection from all CPUs (default if no target is specified).

-g

          Enables call-graph (stack chain/backtrace) recording

#################################################################

在 perf report 界面中,输入查找命令 / 然后,在d出的对话框中,输入 nf_hook_slow;最后再展开调用栈,就可以得到下面这个调用图:

不过,你可能还是很好奇,连接跟踪表里,到底都包含了哪些东西?这里的东西,又是怎么刷新的呢?

实际上,你可以用 conntrack 命令行工具 ,来查看连接跟踪表的内容。

# yum provides conntrack

# yum  -y install conntrack-tools

#  yum info   conntrack-tools

#  conntrack -L -o extended | wc -l

#  conntrack -L -o extended | awk '/^.*tcp.*$/ {sum[$6]++} END {for(i in sum) print i, sum[i]}'

#  conntrack -L -o extended | awk '{print $7}' | cut -d "=" -f 2 | sort | uniq -c | sort -nr | head -n 10

因为NAT 基于 Linux 内核的连接跟踪机制来实现,所以在分析 NAT 性能问题时,我们可以先从 conntrack 角度来分析,比如用 systemtap、perf 等,分析内核中 conntrack 的行文;然后,通过调整 netfilter 内核选项的参数,来进行优化。

其实,Linux 这种通过连接跟踪机制实现的 NAT,也常被称为有状态的 NAT,而维护状态,也带来了很高的性能成本。

所以,除了调整内核行为外,在不需要状态跟踪的场景下(比如只需要按预定的 IP 和端口进行映射,而不需要动态映射),我们也可以使用无状态的 NAT (比如用 tc 或基于 DPDK 开发),来进一步提升性能。

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

https://time.geekbang.org/column/article/83189

案例篇:如何优化 NAT 性能?(下)

https://time.geekbang.org/column/article/83520

1. 配置IP地址

1.1 正确配置学校分配的IP使能正常上网

1) 按学校分配的IP地址配置好Linux主机

[~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0

| DEVICE=eth0 |

| BOOTPROTO=none |

| HWADDR=00:1E:90:13:E0:25 |

| IPADDR=10.3.10.19|

| NETMASK=255.255.255.0|

| GATEWAY=10.3.10.254 |

| ONBOOT=yes |

| TYPE=Ethernet|

| DNS1=211.64.120.2|

| DEFROUTE=yes |

| DOMAIN=168.96.1.1|

2) 重起网卡

[~]# servie network restart

note: 经过以上的配置, Linux主机应该能够正常上网了!

1.2 新增eth0别名设备eth0:0

[~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0:0

| # eth0:0 必须要用''括起来: 'eth0:0' |

| DEVICE='eth0:0'|

| ONBOOT=yes |

| BOOTPROTO=static |

| IPADDR=192.168.50.1|

| NETMASK=255.255.255.0 |

| USERCTL=no |

1.3 配置后 查看一下是否配置成功:

[~]# ifconfig

| eth0 Link encap:Ethernet HWaddr 00:1E:90:13:E0:25 |

| inet addr:10.3.10.19 Bcast:10.3.10.255 Mask:255.255.255.0 |

| inet6 addr: fe80::21e:90ff:fe13:e025/64 Scope:Link|

| UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1|

| RX packets:187685 errors:0 dropped:0 overruns:0 frame:0 |

| TX packets:137327 errors:0 dropped:0 overruns:0 carrier:0 |

| collisions:0 txqueuelen:1000 |

| RX bytes:134816893 (128.5 MiB) TX bytes:56066393 (53.4 MiB) |

| Interrupt:27 Base address:0xa000 |

| eth0:0Link encap:Ethernet HWaddr 00:1E:90:13:E0:25 |

| inet addr:192.168.50.1 Bcast:192.168.50.255 Mask:255.255.255.0 |

| UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1|

| Interrupt:27 Base address:0xa000 |

2. 配置路由

由于在配置网卡接口时, 已自动配置一定的路由, 所以我们只需查看一下其信息, 验证其

是否已经被正确配置:

[root ~]$ route

Kernel IP routing table

Destination Gateway Genmask Flags Metric RefUse Iface

192.168.50.0* 255.255.255.0 U 0 00 eth0

10.3.10.0 * 255.255.255.0 U 1 00 eth0

link-local * 255.255.0.0 U 1002 00 eth0

default 10.3.10.254 0.0.0.0 UG0 00 eth0

3. 配置NAT

1) 新建nat.sh脚本文件并保存在 /usr/local/nat/ 目录下:

[~]# cat /usr/local/nat/nat.sh

| #!/bin/bash |

| # 0. 设定你的参数值|

| EXIF='eth0' # 这个是对外的网卡接口, 可能是'ppp0'等 |

| EXNET='192.168.50.0/24' # 这个是对内的网段|

| # 底下如无需要, 请不要改动了! |

| # 1. 启动routing等 |

| echo 1 >/proc/sys/net/ipv4/ip_forward |

| /sbin/iptables -F |

| /sbin/iptables -X |

| /sbin/iptables -Z |

| /sbin/iptables -F -t nat |

| /sbin/iptables -X -t nat |

| /sbin/iptables -Z -t nat |

| /sbin/iptables -P INPUT ACCEPT |

| /sbin/iptables -P OUTPUT ACCEPT |

| /sbin/iptables -P FORWARD ACCEPT |

| /sbin/iptables -t nat -P PREROUTING ACCEPT|

| /sbin/iptables -t nat -P POSTROUTING ACCEPT |

| /sbin/iptables -t nat -P OUTPUT ACCEPT|

| # 2. 载入模组 |

| /sbin/modprobe ip_tables 2>/dev/null |

| /sbin/modprobe ip_nat_ftp 2>/dev/null|

| /sbin/modprobe ip_nat_irc 2>/dev/null|

| /sbin/modprobe ip_conntrack 2>/dev/null |

| /sbin/modprobe ip_conntrack_ftp 2>/dev/null |

| /sbin/modprobe ip_conntrack_irc 2>/dev/null |

| # 3. 启动ip伪装 |

| /sbin/iptables -t nat -A POSTROUTING -o $EXIF -s $EXNET -j MASQUERADE |

2) 增加可执行权限

[~]# chmod +x /usr/local/nat/nat.sh

4. 大功告成

1) Linux主机配置完成, 现在只需重新启动一下刚才的配置:

[~]# servie network restart

[~]# /usr/local/nat/nat.sh

2) 为了使得开机即可运行, 可在 /etc/rc.d/rc.local 文件加入相应的命令:

[~]# echo "/usr/local/nat/nat.sh" >>/etc/rc.d/rc.local

5. 配置客户机(可以是windows或linux等其它系统)

1. network 设定需要为: 192.168.50.0

2. broadcast 设定需要为: 192.168.50.255

3. netmask 设定需要为 255.255.255.0

4. IP 设定需要为 192.168.50.1 ~ 192.168.50.254 之一, 且『不能重复』

5. Gateway 或者要设定为你的 Linux 的对内 IP , 以我的例子来说, 就是

192.168.50.1

6. DNS 的设定: 这个最容易出错了, DNS 设定需要是 ISP 给你的 DNS

IP, 如果不知道的话, 可以填入 168.95.1.1 或者是

139.175.10.20 这一个 SeedNet 的 DNS 即可!千万不要设定为 192.168.1.2


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/7205982.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-02
下一篇2023-04-02

发表评论

登录后才能评论

评论列表(0条)

    保存