一般在做透明代理时,当代理程序在发起到服务器的连接时,不改变客户机的源IP和源端口,若此时代理机器出口使用了SNAT,则无法建立同服务器的通信。
原因是:
在客户机同代理程序建立连接后,在系统的conntrack表中建立了无SNAT的会话。而当代理程序同服务器再发起连接时,需要做SNAT,但是按其五元组对conntrack表查询时,会找到无SNAT的会话,导致数据包不走nat表做SNAT策略。
解决方案:
conntrack表有zone的概念,即使相同的五元组可以将其绑定到不同的zone中,使得系统中可以存在相同五元组的会话,通过zone id来区分。
1、查看内核编译选项CONFIG_NF_CONNTRACK_ZONES是否开启。
2、设置iptable规则。
iptables -t raw -A OUTPUT -p tcp --dport 100 -j CT --zone 1
iptables -t raw -A PRETOUTING -p tcp --sport 100 -j CT --zone 1
上述两条规则,分别是对出口且目地端口100和入口且源端口为100的tcp数据包使用zone 1进行会话查找。而客户机方向则是出口且源端口100和入口且目地端口100,这里不需要对客户机的数据包进行iptables配置,可以保证当代理程序使用SO_ORIGINAL_DST属性获取真实的服务器IP时,可以在默认zone中查找到。