单IP做NAT支持的最大连接数问题

单IP做NAT支持的最大连接数问题

根据我的理解:TCP有65535个端口,UDP有65535个端口。各自是独立的。

 

和一些做NAT的老师接触,谈起NAT的问题,大多数都是自己用Linux使用iptables来搞定的,在具体谈到地址池的时候,发现很多老师都习惯将1个C网络NAT到一个单独的IP地址上,如果有N个C类地址,那就需要写N条iptables规则,当然这样做的好处是用户的源地址永远不会变,便于事件的追查等,当问到为什么非要把1个C映射到一个IP地址上时,大家的回答都是:怕一个地址的端口数量不够,导致连接数不够。

想想也是,TCP/IP的端口数是16位的,最大也就支持65535个端口,难道单个IP地址做NAT的最大连接数就是65535?

我们知道,Linux做NAT的时候,将NAT前后的IP地址及端口都记录在/proc/net/ip_conntrack里,通过查找这个文件,可以推断出某个报文NAT前后的IP地址及端口,也就是所谓的一个连接。

下面我们来看一个实际的例子【1】:

处于同一子网内的主机A、B,IP地址分别为:192.168.1.2、192.168.1.3,他们使用TCP协议,使用相同的源端口访问不同目的IP地址的web服务,看看NAT前后的IP地址及端口:

1
2
tcp     
6 431994 ESTABLISHED src=192.168.1.3 dst=121.194.0.206 sport=7777
dport=80 src=121.194.0.206 dst=60.16.128.110 sport=80 dport=7777
[ASSURED] use=1
tcp     
6 431983 ESTABLISHED src=192.168.1.2 dst=60.215.128.148 sport=7777
dport=80 src=60.215.128.148 dst=60.16.128.110 sport=80 dport=7777
[ASSURED] use=1

从上面可以看出,NAT之后只是把数据包的源地址修改了,都改成60.16.128.110,他们的源端口依然不变。

我们继续看另外一个例子【2】:

同样是以上两台主机,同时TCP协议访问同一主机的web服务:

1
2
tcp     
6 431997 ESTABLISHED src=192.168.1.3 dst=121.194.0.206 sport=6666
dport=80 src=121.194.0.206 dst=60.16.128.110 sport=80 dport=6666
[ASSURED] use=1
tcp     
6 431990 ESTABLISHED src=192.168.1.2 dst=121.194.0.206 sport=6666
dport=80 src=121.194.0.206 dst=60.16.128.110 sport=80 dport=60121
[ASSURED] use=1

从结果可以看出,有一个连接的源端口号被修改成60121了。

比较上面两个例子,不难看出,识别一个连接只需5元组即可:

协议、源地址、源端口、目的地址、目的端口

对于【1】的两个连接,NAT前后的5元组为:

NAT前:

TCP、192.168.1.3、7777、121.194.0.206、80

TCP、192.186.1.2、7777、60.215.128.148、80

NAT后:

TCP、60.16.128.110、7777、121.194.0.206、80

TCP、60.16.128.110、7777、60.215.128.148、80

将内网地址修改成功网地址后,五元组中的目的地址不一致,可以区分两个连接,无需修改 源端口。

对于【2】的两个连接,NAT前的五元组为:

TCP、192.168.1.3、6666、121.194.0.206、80

TCP、192.168.1.2、6666、121.194.0.206、80

如果NAT服务器只是简单的将源地址替换成一个IP地址,则两个连接的五元组完全一致,无法区分两个连接,所以NAT后将其中一个连接的源端口做了相应的修改:

TCP、60.16.128.110、6666、121.194.0.206、80

TCP、60.16.128.110、60121、121.194.0.206、80

这样,两个连接的源端口不同,仍然可以区分两个连接。

从上面的分析,可以得出如下结论:

NAT支持最大连接数主要看可以产生多少个不重复的5元组。

因此单个IP地址做NAT支持的最大连接数是多少呢?

协议× 源地址×源端口×目的地址×目的端口 =  2 * 1 * 2^16 * 2^32 * 2^16 = 3.68934881e+019 个连接(理想状态)

最差的情况,所有的用户都访问同一个IP地址的同一协议的同一端口,则:

协议×源地址×源端口×目的地址×目的端口 =  1 * 1 * 2^16 * 1 * 1 = 65536个连接(最糟糕情况)。