1.简介
CONNMARK是NF框架中一个很有用的特性。它实现了往链接跟踪记录上打标记的方法。一旦某个链接被打上一个标记,则该标记同样会应用到该链接的RELATED连接上。因此,如果你给FTP的链接打上了标记,则该标记同样会被记录在FTP的数据连接ftp-data上。
所有Linux下的工具(比如Qos或路由)只能够在数据包上打标记。因此,更有用的是,CONNMARK能够将链接跟踪上的标记记录在数据包上,反之亦然。因此,CONNMARK可以用在Qos或路由上已建链接的管理。更多关于CONNMARK的信息可以在NF的网站上找到。2.6.12以上版本的内核都支持该模块。
2.示例
一个简单的例子
以下是iptables命令行配置的规则:
iptables -A POSTROUTING -t mangle -j CONNMARK --restore-mark iptables -A POSTROUTING -t mangle -m mark ! --mark 0 -j ACCEPT iptables -A POSTROUTING -p tcp --dport 21 -t mangle -j MARK --set-mark 1 iptables -A POSTROUTING -p tcp --dport 80 -t mangle -j MARK --set-mark 2 iptables -A POSTROUTING -t mangle -j CONNMARK --save-mark
这几条规则的处理流程如下:
- 重新保存CONNMARK上的标记。实际上,该条规则只是只是简单的将链接跟踪上记录的CONNMARK值赋给数据包上的MARK。 TC是从数据包的MARK读取标记。
- 如果数据包上已经有了MARK,则直接接受该数据包,不需要匹配下面的规则了。
-
我们给协议为TCP并且目的端口为21的数据包打上标记,标记值为1.
- 我们给协议为TCP并且目的端口为80的数据包打上标记,标记值为2.
-
我们将数据包上记录的标记值保存到该数据包对应的链接跟踪上,以后属于该链接的所有数据包都会使用该标记值。随后属于该链接的数据包会经过第1条规则时,规则会将链接上记录的标记值重新保存到数据报上,这就是–-restore-mark的功能。
一个完整的例子
如果你想实现的更加具体(或者使用复杂的过滤器,--原文:imbricated filters),你可以将规则按照精确的程度进行排序:
iptables -A POSTROUTING -t mangle -j CONNMARK --restore-mark iptables -A POSTROUTING -t mangle -m mark ! --mark 0 -j ACCEPT iptables -A POSTROUTING -m mark --mark 0 -p tcp --dport 21 -t mangle -j MARK --set-mark 1 iptables -A POSTROUTING -m mark --mark 0 -p tcp --dport 80 -t mangle -j MARK --set-mark 2 iptables -A POSTROUTING -m mark --mark 0 -t mangle -p tcp -j MARK --set-mark 3 iptables -A POSTROUTING -t mangle -j CONNMARK --save-mark
我们使用-m mark –mark 0来避免一个带标记的数据包被重复打标记。作者这样解释个人认为应该是单独就这一条规则来说的。
第二条规则是可选的,但是它可以保证所有和一条已建链接相关的数据包都只被检测一次,避免被后数据包还要经过后面的几条规则。
3.相关提示
Connmark处理入口的数据包
如果你使用的是一条进入系统的规则,你在PREROUTING点的规则链上通过CONNMARK重新保存数据包的mark值。因此可以这样配置规则:
iptables -A PREROUTING -t mangle -j CONNMARK --restore-mark
修改过的ip_conntrack文件
加载了CONNMARK模块之后,文件/proc/net/ip_conntrack显示的每一条记录上都包含了链接的标记,即mark字段:
tcp 6 432000 ESTABLISHED src=62.212.98.117 dst=XXX.XXX.XXX.XXX sport=35027 dport=22 src=217.15.82.6 dst=62.212.98.117 sport=22 dport=35027 [ASSURED] use=1 mark=0
udp 17 24 src=127.0.0.1 dst=127.0.0.1 sport=1024 dport=53 [UNREPLIED]
src=127.0.0.1 dst=127.0.0.1 sport=53 dport=1024 use=1 mark=0
使用ip_conntrack计数
可以很容易的通过以下规则替代规则iptables -A POSTROUTING -t mangle -m mark ! –mark 0 -j ACCEPT:
iptables -A POSTROUTING -t mangle -m mark --mark 1 -j ACCEPT iptables -A POSTROUTING -t mangle -m mark --mark 2 -j ACCEPT ...
使用上面的规则配置之后,就可以通过命令iptables -L POSTROUTING -t mangle -v给出每条规则的详细计数。同上所述,它也会统计RELATED链接的计数。
不过仍然有一个问题,因为我们前面没有特意去关注一个链接的第一个数据包。因此,有必要增加加关于设置--set-mark和ACCEPT规则的计数。
以上简单的介绍了CONNMARK,其实还包括MARK和mark模块的用法和功能。下一篇文章我们将从内核的源码分析这三个模块的实现。