利用Linux构建一台千兆级的NAT服务器(4)

构建一台大容量的NAT服务器
Ippen Yang
(ippen@21cn.com)

1.前言
本文档主要描述如何利用Linux构建一台能力比较强的NAT服务器,并发连接数大约16万,流量200M-300M,如果你需要一个流量更高的NAT设备,请考虑购买专业厂商的设备。

2.许可协议
本文的许可协议遵循GNU Free Document License。协议的具体内容请参见。在遵循GNU Free Document License的基础上,可以自由地转载或发行本文,但请保留本文的完整性。

3.准备工作
CentOS 4.6光盘一套(4张CD)

PC服务器一台,P4 CPU,速度越快越好,256M内存(有没听错?没错! 256M内存就够了,如果资金充裕,可以用512M;如果你用1G内存,那叫浪费),2G或以上的硬盘(可以用CF电子盘)

两个高性能千兆网卡,到目前为止,我测试过几种网卡,Intel的PCI-X服务器网卡,Intel的PCI服务器网卡,Marvell PCI-E,3COM,前面三种网卡都不错,反而是3COM的网卡不行。

网卡最好用两个不同的接口,我现在用的主板,通常都是一张PCI-X网卡,一张PCI-E网卡,这样能避免内部接口速度影响转发效率

4.安装
首先安装CentOS,如果考虑编译内核,安装时记住要安装开发工具,因为要调整系统内核模块的一些参数,要编译系统模块。安装时要注意,不要建立交换区,切记!!!原因后面解释
安装完成后,运行setup,在system service中将不需要用的程序全部停止,基本上只需要保留ssh,iptables,network,snmpd,syslog几个,设置完后重新启动服务器。
编辑/etc/sysctl.conf,查找行“net.ipv4.ip_forward = 0”,然后将这行按下面的内容进行更改,原文件中没有的内容请自己添加
# Controls IP packet forwarding
net.ipv4.ip_forward = 1
net.ipv4.netfilter.ip_conntrack_max = 262144
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 300
net.ipv4.route.max_size=2097152
net.ipv4.tcp_window_scaling=1
kernel.shmmax=268435456
kernel.shmall=268435456

 

编辑/etc/rc.local如下:

编辑/root/nat如下:

# eth0 is internet interface
# eth1 is intranet interface
INCOMING=eth0
OUTGOING=eth1
ip addr add 222.222.222.8 dev $OUTGOING
ip addr add 222.222.222.9 dev $OUTGOING
ip addr add 222.222.222.10 dev $OUTGOING
ip addr add 222.222.222.11 dev $OUTGOING
IPPOOL=222.222.222.8-222.222.222.11

iptables -t nat -F
iptables -t nat -A POSTROUTING -s 内部IP地址/子网 -o $OUTGOING -j SNAT --to $IPPOOL

iptables-save -c >/etc/sysconfig/iptables
 

注意,这里假定互联网IP是222.222.222.8-222.222.222.11(上面黑色字体),请用真正使用的IP范围将黑色字体替换。内网地址也请根据实际环境变更。这个脚本只是NAT用,如果需要增加安全策略,请参考其它的iptables的脚本。
如果服务器的CPU是双核的,编辑/etc/grub.conf
#boot=/dev/sda1
default=1
timeout=1
#splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS-4 i386 (2.6.9-34.ELsmp)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.9-34.ELsmp ro root=LABEL=/
        initrd /boot/initrd-2.6.9-34.ELsmp.img

title CentOS-4 i386-up (2.6.9-34.EL)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.9-34.EL ro root=LABEL=/
        initrd /boot/initrd-2.6.9-34.EL.img
 


将服务器调整为单核方式运作,为什么?之前与CU的高手讨论过这个问题,也进行过测试,单核方式下运行的NAT效率的确比双核高,也更稳定,所以只用单核,不过现在只能买到双核的CPU,只好浪费一点了。

5.高级配置

由于linux系统内部的一些参数在NAT环境中并不合理,因此在一些情况下需要作些修改,由于涉及内核,建议不熟悉的朋友忽略这个部分。

这部分的调整对系统的优化有限,如果你的并发连接数不是非常高,也可以忽略这个部分。

首先下载linux的内核源文件,请上下载,下载后解包到硬盘中。

系统调整主要是三个默认的参数,参数buckets、ip_conntrack_max和tcp_timeout_established。

参数tcp_timeout_established 位于文件net/ipv4/netfilter/ip_conntrack_proto_tcp.c中,用vi打开文件,查找
unsigned long ip_ct_tcp_timeout_established = 5 DAYS;  

原来的tcp_timeout_established是5天,这个数值太大了,很容易造成内存过度占用,导致系统死机,将其改为如下,
unsigned long ip_ct_tcp_timeout_established = 5 MINS;  


参数buckets、ip_conntrack_max位于文件net/ipv4/netfilter/ip_conntrack_core.c中,用vi打开文件,查找如下的一段代码,可以看出,系统默认的buckets数值是内存数的1/16384,ip_conntrack_max是buckets的8倍,即时你有大于1G的内存,buckets也只是8192。

/* Idea from tcp.c: use 1/16384 of memory.
On i386: 32MB

* machine has 256 buckets.
>= 1GB machines have 8192 buckets. */

if (hashsize) {

ip_conntrack_htable_size = hashsize;

} else {

ip_conntrack_htable_size

= (((num_physpages << PAGE_SHIFT) / 16384)

/ sizeof(struct list_head));

if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))

ip_conntrack_htable_size = 8192;

if (ip_conntrack_htable_size < 16)


ip_conntrack_htable_size = 16;

}
 

调整可以在这段代码后面直接对buckets和ip_conntrack_max赋值即可

/* Idea from tcp.c: use 1/16384 of memory.
On i386: 32MB

* machine has 256 buckets.
>= 1GB machines have 8192 buckets. */

if (hashsize) {

ip_conntrack_htable_size = hashsize;

} else {

ip_conntrack_htable_size

= (((num_physpages << PAGE_SHIFT) / 16384)

/ sizeof(struct list_head));


if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))

ip_conntrack_htable_size = 8192;

if (ip_conntrack_htable_size < 16)

ip_conntrack_htable_size = 16;

}

ip_conntrack_htable_size = 32768;

ip_conntrack_max = 8 * ip_conntrack_htable_size;
 

参数改好后,编译modules,然后用编译后产生的文件ip_conntrack.ko代替系统中的同名文件(位于/lib/modules/2.6.9……),重新启动即可。

调整内核参数buckets的效果不是特别明显,在初始测试中,使用默认的buckets数值,但并发连接数到12.8万时,CPU的使用率有明显上升,稳定性变差,调整buckets数值后并发连接数能到16万,但流量上升不多,所以对系统编译不熟悉的朋友不必考虑这个方法,增加一台服务器就是了。

常见问题

Q.服务器空载时速度很快,但一加载流量就有明显的丢包,并且只有几兆流量,但实际流量远远不止几兆

A.请检查网线以及交换机端口、linux服务器网卡端口的全双工、半双工状态,用ethertool,这个现象非常明显和常见,通常都是全双工、半双工匹配问题。

Q.我的网内有2千用户,要什么样的服务器才能正常运作?

A.其实完全不必关心又多少用户,关键是系统的并发连接数,系统并发连接数最好不要超过16万并发连接数,超过了系统会有些不稳定,所以建议连接数高的用户采用增加服务器的方式。
目前的优化只能到这个程度了,如果有更好的优化方案,我会第一时间高诉各位的。

Q.使用更快的CPU和更大的内存能否提高并发连接数?

A.开始我也这样认为,但实际测试中,发现这个观点完全错误,NAT使用的内存量比较固定,我监测的结果,基本上在200M左右,所以在开始建议大家买的内存也是256M而已,更快的CPU对NAT是有帮助,但随着并发连接数的增加,NAT的效率越来越低,反而效果更差。

Q.是否一定要将互联网IP设置到OUT网卡上?

A.不一定,但这样设置,NAT服务器的CPU利用率会明显降低,强烈建议这样配置。

Q.为什么不使用交换区?

A.这个服务器只是用于NAT,不是代理服务器,为了提高NAT转发速率,就要完全避免读写硬盘,而物理内存使用完了后,系统就会使用交换区来存储数据,整个服务器速度就会被拖慢,直至死机。因此在这里完全不要使用交换区。

Q.其他linux版本能否使用?

A.Sure,推荐CentOS主要是方便不熟悉Linux系统的朋友,避免朋友们盲目地找不同的linux版本测试。这里仍然强调一下,使用2.6的内核,不要使用2.4内核,2.6的内核能查看并发连接数,并且NAT效率比2.4高。

Q.为什么我的NAT服务器不行?

A.这个问题很复杂,我现在回答不了^_^,请上CU的论坛发帖子。发邮件给我的话,就要有点耐心等回复了

感谢

所有在CU的朋友,特别是Platinum和JohnBull,给我提出很多有用的参考意见。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyjsdg.html