免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 74472 | 回复: 118
打印 上一主题 下一主题

[网络管理] 构建一台大容量的NAT服务器 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-07 21:36 |只看该作者 |倒序浏览
构建一台大容量的NAT服务器
Ippen Yang
(
ippen@21cn.com)


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

2.许可协议
本文的许可协议遵循GNU Free Document License。协议的具体内容请参见http://www.gnu.org/copyleft/fdl.html。在遵循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如下:

#!/bin/sh

touch /var/lock/subsys/local
/root/nat



编辑/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的内核源文件,请上http://mirror.be10.com下载,下载后解包到硬盘中。


系统调整主要是三个默认的参数,参数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的论坛(http://bbs.chinaunix.net)发帖子。发邮件给我的话,就要有点耐心等回复了


感谢

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


[ 本帖最后由 ippen 于 2008-7-7 23:38 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-07-07 21:36 |只看该作者
其实这个帖子去年就写好了,因一些个人原因,一直没有发布,现在将做过的测试总结一下,希望能帮助有需要的TX

[ 本帖最后由 ippen 于 2008-7-7 21:39 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2008-07-07 22:01 |只看该作者
谢谢 ippen 的激情奉献!
不过我对里面的几个地方有些疑问,还请多指教 ^_^

1、盲目加大 net.ipv4.netfilter.ip_conntrack_max 会有副作用吗?
经过测试发现,如果 iptables 里面加了过多规则的话,max 数量过大,连接数非常多的时候会造成内存溢出,不知道 ippen 是否遇到过?

2、修改 buckets 数量是否有效,是否有副作用?
代码里如果 > 1GB 就分配一定数量的 buckets,(我的内核 2.6.23 是 16384)
这个改大会减少 hash 表碰撞,但是过大会有多大用处不是很清楚,不知会不会溢出(内存小于 1GB 的时候也赋值为 8192)
另外不知道内核为什么在内存 > 1GB 的时候写死,而不是根据内存继续算下去

3、不知道 ippen 兄是否用 sar 观察过每秒的包数

4、不知道当时测试时 iptables 的规则数量有多少,除了 NAT 以外是否还做了繁重的过滤工作


去年 ippen 兄写了一篇关于 iptables 不能完美支持双 CPU 的贴子,从中就提到了大负载状况的 NAT 架设,一直很感兴趣,今日又见此大作,万分高兴:)

[ 本帖最后由 platinum 于 2008-7-7 22:03 编辑 ]

论坛徽章:
1
2015元宵节徽章
日期:2015-03-06 15:50:39
4 [报告]
发表于 2008-07-07 23:00 |只看该作者
又长见识了,测试一把

论坛徽章:
0
5 [报告]
发表于 2008-07-07 23:32 |只看该作者
原帖由 platinum 于 2008-7-7 22:01 发表
谢谢 ippen 的激情奉献!
不过我对里面的几个地方有些疑问,还请多指教 ^_^

1、盲目加大 net.ipv4.netfilter.ip_conntrack_max 会有副作用吗?
经过测试发现,如果 iptables 里面加了过多规则的话,max 数 ...

哈哈,platinum兄的记性真好

对于platinum兄的问题,我尽量回答,因为有些问题我也是同样存在疑问的

1.加大 net.ipv4.netfilter.ip_conntrack_max 确实会有副作用,规则过多造成内存溢出的问题我遇到过,控制这个值的大小能避免内存溢出。目前这个数值是经过我测试,认为设备能够承受的,实际使用中也能到达这个最大值,系统也是正常的。
2.修改buckets的大小作用似乎不明显,增大一些,系统的稳定性要好一点,副作用目前还没发现。源代码里,内存〉1GB,将buckets写死为8192(centos 4.6内核),我也不知道是什么原因,也想找个高手了解一下。我推断可能是一个系统设计的考虑,即Linux不只是用作网络用途,所以要保留内存给其他应用,和限制网络部分使用内存量,基于我的使用方式,完全只作为网络设备使用,让网络占大部分内存应该是可行的。当然,只是我的猜测而已,希望有高手能回答这个问题。
3.sar没有用过
4.目前使用的NAT服务器,大约有50条规则,30条在forward表,20条在postrouting表,主要都是针对ip地址的accept和drop,设备只做nat,没有其他繁重的过滤工作

补充一点,上面提到的这些参数,都是通过实际使用总结出来的,现在nat服务器仍然在运行。在实际使用中,服务器达到的最大值是:320Mb/s的nat流量,最大并发连接数26万,这个数值在应用中基本上维持了2个月,系统基本稳定,但后来我认为这个数值过分接近极限,出现突发流量时会出现假死现象,所以将流量和并发连接数下调了。
现在在nat系统中,唯一不好处理的就是突发小包冲击,容易导服务器cpu过高,出现假死现象。

有空看能不能找到当时最大值的MRTG图贴给大家看看

[ 本帖最后由 ippen 于 2008-7-7 23:41 编辑 ]

论坛徽章:
5
IT运维版块每日发帖之星
日期:2015-08-06 06:20:00IT运维版块每日发帖之星
日期:2015-08-10 06:20:00IT运维版块每日发帖之星
日期:2015-08-23 06:20:00IT运维版块每日发帖之星
日期:2015-08-24 06:20:00IT运维版块每日发帖之星
日期:2015-11-12 06:20:00
6 [报告]
发表于 2008-07-08 06:18 |只看该作者
首先感谢IPPER的大作。但是我也有如下疑问:

1、并发连接数大约16万。这个测试过吗?外网的地址池配置了几个地址啊?
2、后来IPPER说最大并发连接数达到26万,这个又是怎么计算出来的哦。

论坛徽章:
0
7 [报告]
发表于 2008-07-08 11:53 |只看该作者
学习中。。。。。。

以前参考过这篇文章
http://www.wallfire.org/misc/netfilter_conntrack_perf.txt

论坛徽章:
0
8 [报告]
发表于 2008-07-08 12:06 |只看该作者
原帖由 ippen 于 2008-7-7 21:36 发表
构建一台大容量的NAT服务器
Ippen Yang
(ippen@21cn.com)

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


对于大容量NAT服务器,发表一下个人看法,仅供大家拍砖。

1、主要思路还是加大hash表容量,缩短连接超时时间等等——因为剩下的就是优化hash表的建立、查找算法等等了,但是这些不是使用者做的,希望Netfilter的开发团队在性能方面下点功夫(曾经我有想过,利用网络访问的亲和性的特性,加一个cookie表,不过一直没有时间来尝试);

2、Netfilter对于大容量,例如楼主说的16W,表现确实不太好。因为连接跟踪的效率的确不咋样,再加上NAT,雪上加霜。快速解决方法之一就是提升硬件配置。唉……

3、我用双/多CPU(核),想过一个网卡绑死一个CPU(因为中断亲和性的问题),不知能不能进一步提升效率。想过,但是还没有试过。

3、个人认为,像BSD那样,NAT不依赖于连接跟踪的实现而单独实现,也就是说,单使用NAT,不使用连接跟踪,只有想用的时候再用,我想肯定会大大提升NAT的转发效率的。

4、网上有很多对比Linux/BSD/Windows做网关时的网络性能的,我认为大都不太公平——因为Linux是使用了连接跟踪的,单是开这一项,性能下降30%-40%(在我的测试环境中)。

[ 本帖最后由 独孤九贱 于 2008-7-8 12:07 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2008-07-08 13:25 |只看该作者
问一下九贱兄
对于 TCP 来说,超时就意味着不再维护它的 seq,这里就不说了,说说 UDP
如果 udp 的 timeout 设置过小,的确 conntrack 表不会有过多 udp 信息存留,但对于 NAT 有什么负面影响吗?
换言之,netfilter 的 timeout 判断时间小于实际 app 的时间的话,netfilter 会不会判断失误而惘做处理?

[ 本帖最后由 platinum 于 2008-7-8 13:32 编辑 ]

论坛徽章:
0
10 [报告]
发表于 2008-07-08 14:42 |只看该作者
参看一下,看各位讨论~~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP