
你既可以在支持网络地址转换的路由器(称为 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
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)