iptables之xtables_addons浅度解析
xtables_addons 1.46的几个特性是比较有意思,本文不会列出所有的特性,仅仅针对少数几个来分析。也不会给出太具体的配置,因为这些配置都可以从manual上得到或者被google到,以下所写的都是自己的一些想法。
SYSRQ target:
机器死了,特别是置于机架上的网关死了,搬来一个显示器和USB键盘赶紧插上,看看发生了什么,悲剧的是,什么也没有显示。毕竟此时可能已经kernel panic了,USB键盘识别早就失效了,按下什么键都不会触发显示器显示信息。像个刑侦人员丢了犯罪现场一样的苦闷!记住,即使kernel panic了,中断还是可以响应的,且网络处理中断处在softirq上下文中,因此如果此时网卡收到了数据包,还是会执行诸如PREROUTING上的HOOK function的(如果kernel不是panic得很严重的话,大多数情况是这样~~)。xtables_addons支持了SYSRQ target,可以远程触发sysrq,这样只要有网线插着,并且设置了SYSRQ规则,80%的情况下,插上显示器就能看到犯罪现场。
然而SYSRQ target是很危险的,如果有人远程发送了一个reboot或者shutdown命令,你就哭吧!因此SYSRQ target设置了很多安全参数,比如密码,摘要等;由于Linux不建议内核侦听珍贵的TCP端口资源,所以这个target的执行不能依赖任何用户态执行的服务,故而仅仅可以使用UDP来发送sysrq键。
Stateless NAT target
以前,在Linux上配置一个Stateless NAT要累死人,70%人都搞不定这个,因为需要使用tc工具进行超级繁琐的配置,而Stateful NAT仅仅转换一个IP地址却需要动用耗资的ip_conntrack,使得Linux一直不能像Cisco那样工作。如今xtables_addons支持了Stateless NAT,Linux也可以配置轻量级的NAT了。虽然说是类似Cisco的配置,却还不一样。Cisco的ip nat命令可以配置出两类NAT,一类是基于pool的,另一类是static的,然而它俩并不是并列的关系,区别在于:
pool nat:和inside/outside接口有关,也就是和一个流的方向有关,类似Linux的ip_conntrack,系统中的映射表只有碰到流头时才开始创建,因此反方向的连接将不会匹配到acl;
static nat:系统直接建立一个映射,因此在两个方向均可以匹配,类似下面的规则:
ip nat outside source static 1.1.1.1 2.2.2.2
如果有数据包从inside到outside方向,且destination为2.2.2.2(而非规则中指定的source 1.1.1.1),它也会将数据包的destination转为1.1.1.1,上述规则实际上建立了以下两个映射:
1>目标为2.2.2.2的,目标转为1.1.1.1
2>源为1.1.1.1的,源转为2.2.2.2
对于pool nat则不会这么转,因为它匹配不到类似下面的acl:
access-list 100 permit 1.1.1.1 0.0.0.0,
系统中既然没有建立映射,因此反向进来的数据包将不会查找到需要转换的映射条目。
IPMARK target
该target可以基于进入包的IP地址动态的计算需要打上的mark,而无需在数据包进来之前显式配置一大堆的mark规则,如果算法精妙的话(无非就是对IP地址,掩码进行位运算),一条规则可以替代数百条规则。
condition match
condition是一个match,初看它无非就是一个match,一个布尔值,实际上,其精妙之处在于该值可以在procfs中动态配置,比如以下的需求:拥有两个默认网关,GW1,GW2,如果GW1掉电了,就走GW2,GW1又恢复了,抢占。我们可以配置如下的Policy routing:
ip rule add fwmark 100 tab G1
ip rule add fwmark 200 tab G2
ip route add 0.0.0.0/0 via G1_addr tab G1
ip route add 0.0.0.0/0 via G2_addr tab G2
iptables -t mangle -A PREROUTING -m condition --condition GW1 -j MARK --set-mark 100
iptables -t mangle -A PREROUTING -m condition --condition GW2 -j MARK --set-mark 200
规则以上就完全确定了,接下来就根据GW1/2的状态来操作/proc/net/nf_condition/GW1和/proc/net/nf_condition/GW2两个文件了,如果文件中写入1,那么match匹配,写入0则不匹配。cron脚本(或者不用cron这种轮询机制,某种notify机制可能更好,网络层的监控手段太多了!)可以如下:
if GW1断电; then
ech0 0>/proc/net/nf_condition/GW1;
fi
...
另外如果和GWX是直连的话,还可以通过iface这个新的match来匹配端口状态。condition技术结合iptables的statistic match,可以很酷的实现基于流的或者基于包的路由负载均衡功能。
总结:iptables非常强大,几乎可以实现任何功能,你只需要在PREROUTING上挂一个function,就可以实现你自己的协议栈,最后该function返回一个STOLEN即可。iptables强大的表象背后是Netfilter设计的精妙,好像一座城市5个城门,任何数据包进出协议栈都要接受检查,进来需要检查,出去也要检查,协议栈外面就两条路,一条是链路层,另一条是用户态,在这些关卡上,被哨位劫持是很正常的,他会安排另一条路让你通过协议栈,或者发现你比较可疑直接扣押或者干掉...NF_STOLEN改为NF_HIJACK岂不更好!