今天看到一个很好的iptables教程,对这个东西的理解又深了一步。

(教程在http://www.cublog.cn/u2/66903/showart_1802022.html

首先是源地址转换之后的返回包问题。原来用SNAT的时候不知道从外网返回内网的状态包是怎么被放行的,当时猜肯定有一个地方会记录连出去的SNAT信息。其实这个是 在/proc/net/ip_conntrack中逐行记录的。为了进一步说明,做了一个实验,环境如下:

机器A双网卡,外网IP为58.31.81.73,内网IP为192.168.0.1,且为内网网关。

内网机器B,IP为192.168.0.2。

机器A用iptables对外网网卡进行MASQUERADE设置(暂且理解为动态的SNAT吧),这样机器B通过机器A访问外网时将进行192.168.0.2到5 8.31.81.73的源地址转换。

从机器B访问地址66.249.89.99,在机器A上得到下面一条记录:

tcp      6 119 SYN_SENT src=192.168.0.2 dst=66.249.89.99 sport=37904 dport=80 packets=1 bytes=60 [UNREPLIED] src=66.249.89.99 dst=58.31.81.73 sport=80 dport=37904 packets=0 bytes=0 mark=0 secmark=0 use=2

这表示发起从192.168.0.2到66.249.89.99的连接,同时期望收到从66.249.89.99到58.31.81.73的返回包。SYN_SENT 表示当前状态为SYN已发送,UNREPLIED表示还没有收到回复。当收到回复时就可以依据这条记录将返回包返回192.168.0.2了。

关于ip_conntrack还有一点要说的是table full问题。这个问题是说ip_conntrack这个表满了怎么办。这个表是有上限的,在/proc/ sys/net/ipv4/ip_conntrack_max中可以看到。另外在/proc/sys/net/ipv4/netfilter下有各种timeout的 设置。这里就不细说了,下面两个链接可以参阅:

http://rackerhacker.com/2008/01/24/ip_conntrack-table-full-dropping-packet/

http://salogs.com/2010/03/%E8%A7%A3%E5%86%B3-linux-nat-ip_conntrack-table-full-%E7%9A%84%E6%96%B9%E6%B3%95/

其次是外网使用内网服务的问题。要完成这个任务,需要考虑DNAT,FORWARD和提供服务的服务器的路由问题。这个在教程的第二个例子里说的很详细,建议读一下。