iptables的CONNMARK与MARK
Posted on January 24, 2012
iptables的CONNMARK与MARK是用于给数据连接和数据包打标记的两个target。一直没搞明白二者的区别。直到昨天花了不少时间解决openwrt下多路合并时工行网银登录问题,才大致弄清这两个target的用法。
两者的区别在于,同样是打标记,但CONNMARK是针对连接的,而MARK是针对单一数据包的。
这么说大家肯定还是不明白。但回想一下,这两种机制一般都要和ip rule中的fwmark联用,实现对满足某一类条件的数据包的策略路由。所以问题的关键在于两点:
1. 对连接打了标记,只是标记了连接,没有标记连接中的每个数据包。标记单个数据包,也不会对整条连接的标记有影响。二者是相对独立的。
2. 路由判定(routing decision)是以单一数据包为单位的。或者说,在netfilter框架之外,并没有连接标记的概念。或者说,ip命令只知道MARK, 而不知道CONNMARK是什么。
所以写相关的iptables规则,关键在于:给所有要进行ip rule匹配的单一数据包打上标记。方法一般有二:用MARK直接打,或者用CONNMARK –restore-mark把打在连接上的标记转移到数据包上。
理解了这些,要解决相关的问题就心里有数了。就比如网银登录的问题吧,在使用openwrt多拨时登录工行网银时,由于使用了多个IP,服务器检测到所认为有安全问题,就会阻止用户登录。解决思路是,由于网银用https协议,对相应的443端口做一些处理。让所有目的端口为443的outgoing包只走一条线路就行了。到iptables规则中,就是对这些包只打一种标记咯。假设打0×01吧。相应的规则像下面这样写:
# 第一个outgoing的包(tcp SYN),打上标记
iptables -t mangle -A PREROUTING -p tcp --dport 443 -m conntrack --ctstate NEW \
-j MARK --set-mark 0x01
# routing decision时,会选择与0x01标记对应的那条路由。
# 然后,我们把这个包上的标记(0x01)转存到与之对应的连接上。--save-mark功能就在于此。
iptables -t mangle -A POSTROUTING -m conntrack --ctstate NEW -j CONNMARK --save-mark
# 这条连接后续的包,都用--restore-mark命令,把连接上的标记(上一条命令保存的)
# 再打到每个单一数据包上。
iptables -t mangle -A PREROUTING -i br-lan -m conntrack --ctstate ESTABLISHED,RELATED \
-j CONNMARK --restore-mark
# 至此,所有(目的端口为443的outgoing包)对应连接上的每一个数据包都打上了0x01标记,
# 可以被正确地路由。
This entry was posted in
iptables,
Linux by
morfast. Bookmark the
permalink.