上一篇文章我们说了一些iptables/netfilter的基础知识,本文我们来介绍一下iptables的规则编写。Iptables的规则可以概括的分为两个方面:1、报文的匹配条件;2、匹配到后的处理动作。其中匹配条件分为基本匹配条件和扩展匹配条件,处理动作分为内建处理机制和自定义处理机制。这里需要注意的一点是,自定义处理机制(自定义链)不在内核中所以报文是不会经过自定义链的,它只能被内建机制引用即当做处理的子目标。
Iptables说白了就是一个规则管理工具,用于生成、检查和自动实现规则。规则和链都有自己的计数器,用于统计被匹配到的报文数。一般链上都有默认策略,默认的默认策略是允许所有,如果我们要阻挡某报文就定义阻止策略就可以,类似黑名单;也可以更改默认默认策略,改为拒绝所有,然后开放我们想要开放的内容,类似白名单。因为5个链工作在内核之上所以策略一旦启用将立即生效,但不会永久有效,想要永久有效需要写到配置文件之中。接下来我们看看iptables的命令结构:
iptables的基本语法格式:
iptables [-t 表名] 命令选项 [链名] [条件匹配] [-j 目标动作或跳转]
说明:表名、链名用于指定 iptables命令所操作的表和链(我们上篇博客中提到的四表五链),命令选项用于指定管理iptables规则的方式(比如:插入、增加、删除、查看等;条件匹配用于指定对符合什么样 条件的数据包进行处理;目标动作或跳转用于指定数据包的处理方式(比如允许通过、拒绝、丢弃、跳转(Jump)给其它链处理。
iptables命令的管理控制选项: -A 在指定链的末尾添加(append)一条新的规则 -D 删除(delete)指定链中的某一条规则,可以按规则序号和内容删除 -I 在指定链中插入(insert)一条新的规则,默认在第一行添加 -R 修改、替换(replace)指定链中的某一条规则,可以按规则序号和内容替换 -L 列出(list)指定链中所有的规则进行查看 -E 重命名用户定义的链,不改变链本身 -F 清空(flush) -N 新建(new-chain)一条用户自己定义的规则链 -X 删除指定表中用户自定义的规则链(delete-chain) -P 设置指定链的默认策略(policy) -Z 将所有表的所有链的字节和数据包计数器清零 -n 使用数字形式(numeric)显示输出结果 -v 查看规则表详细信息(verbose)的信息 -V 查看版本(version) -h 获取帮助(help)
防火墙处理数据包的四种方式:
ACCEPT 允许数据包通过 DROP 直接丢弃数据包,不给任何回应信息 REJECT 拒绝数据包通过,必要时会给数据发送端一个响应的信息。 LOG在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则
上文也提到iptables写的规则无法永久生效,以下两种方法可以解决这个问题:
iptables-save > /etc/sysconfig/iptables service iptables save
它能把规则自动保存在/etc/sysconfig/iptables中。
当计算机启动时,rc.d下的脚本将用命令iptables-restore调用这个文件,从而就自动恢复了规则。
接下来我们看通过一些具体案例深入了解一下iptables的使用:
-L:list,列出指定链上的所有规则; -n: numeric,以数字格式显示地址和端口号,即不反解; -v: verbose,详细格式,显示规则的详细信息,包括规则计数器等; -vv: -vvv: --line-numbers: 显示规则编号; -x: exactly,显示计数器的精确值 pkts bytes target prot opt in out source destination pkts: 被本规则所匹配到的包个数; bytes:被本规则所匹配到的所包的大小之和; target: 处理目标 (目标可以为用户自定义的链) prot: 协议 {tcp, udp, icmp} opt: 可选项 in: 数据包流入接口 out: 数据包流出接口 source: 源地址 destination: 目标地址;
在规则匹配中分为:
通用匹配
[!] -s, --src, --source IP|Network:检查报文中的源IP地址;叹号表示取反,以下几个都可以使用 -d, --dst, --destination:检查报文中的目标IP地址; -p, --protocol:检查报文中的协议,即ip首部中的protocols所标识的协议;tcp、udp或icmp三者之一; -i, --in-interface:数据报文的流入接口;通常只用于PREROUTING, INPUT, FORWARD链上的规则; -o, --out-interface:检查报文的流出接口;通常只用于FORWARD, OUTPUT, POSTROUTING链上的规则;
扩展匹配:使用iptables模块实现的进一步检查
隐式扩展:就是在通用匹配的基础上使用-p指定了协议类型,则-m选项指明模块就可以省略
tcp: --dport PORT[-PORT] #可以指定连续端口,但不能指定离散端口,UDP也一样 --sport --tcp-flags LIST1 LIST2 LIST1: 要检查的标志位; LIST2:在LIST1中出现过的,且必须为1标记位;而余下的则必须为0; 例如:--tcp-flags syn,ack,fin,rst syn --syn:用于匹配tcp会话三次握手的第一次; udp: --sport --dport icmp: --icmp-types 8: echo request 0:echo reply [[email protected] ~]# iptables -I INPUT 1 -s 192.168.1.103 -d 192.168.1.109 -p tcp -m tcp --dport 80 -j DROP #这里的-m tcp可以省略所以就叫做隐式扩展 [[email protected] ~]# iptables -I INPUT 1 -s 192.168.1.103 -d 192.168.1.109 -p tcp --dport 22 -j ACCEPT
显式扩展:必须使用-m指明了扩展模块,使用rpm -ql iptables查看到的诸如/lib64/xtables/libxt_iprange.so的模块完成的功能
multiport: 多个离散端口的同时匹配;--dports, --sports, --ports,最多同时指定15个端口 iprange:地址范围的匹配(不适于写为网络地址);--src-range, --dst-range string: 字符串匹配;--string, --algo {kmp|bm}, --hex-string "HEX_STRING":HEX_STRING为编码成16进制格式的字串;#algorithms是算法的意思,kmp|bm是两种编码算法 time: 基于时间进行匹配;--datestart, --datestop, --timestart, --timestop, --weekdays connlimit: 做连接数限制,对每IP能够发起并发连接数作匹配;--limit-above limit: 做速率匹配,令牌桶算法;--limit, --limit-burst#空闲突发访问量的限制
这是我对以上几种扩展的演示结果,大家看看能否从中看出对应的iptables命令是什么呢。
附ICMP类型表:
在讲接下来的扩展匹配条件之前我们有必要说一下TCP的有限状态机,有限状态机是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
以上这三幅图已经详细的描述了TCP三次握手和四次挥手以及有限状态机,我就不再进行解释了。我们知道IP协议是无状态的,当有很多个IP与我们的主机连接时我们如何判断某个连接来自哪个IP呢?这就需要netfilter在内存中保存一张表记录跟踪了每个连接的信息,不过这个空间如果被打满那么之后的请求就会被拒绝,所以高并发的时候慎用。
connection template:连接追踪模板,用于记录各连接及相关状态;基于IP实现,与是否为TCP协议无关;通过倒计时的方式删除条目;
记录连接的状态:
NEW: 新建立的连接,连接追踪模板中无相应的条目时,客户端第一次发出的请求; ESTABLISHED:NEW状态之后,边距追踪模板中的条目删除之前所进行的通信过程,都称为ESTABLISHED; RELATED:相关联的连接,如ftp协议的命令连接与数据连接即为相关联的连接; INVALIED: 无法识别的状态;
我们说了这么多的原理,是为了说明iptables中state扩展的,这个扩展有一个大大用处就是阻止反弹式木马,反弹式木马是什么大家可以自行去了解,我们简单的说一下就是它可以从主机防火墙某个以开放的监听端口当做Client端口去连接远程主机以实现控制被攻陷的肉鸡。比如80端口的出去的连接必须是对Client请求的响应而不能是NEW连接。
这个是我使用state模块完成的功能:能够使用ssh登录和yum功能的网络epel源,开放http、https、ftp服务(被动连接,需要安装一个ftp模块)。就这几个启用连接追踪功能,带状态检测的包过滤防火墙就完成了一大堆功能。
好了我们的filter表就说到这里了,接下来我们说一下nat表。NAT叫做网络地址转换,说白了就是把IP首部中的原地址或者目标地址更改一下以达到通往目的地的效果。早期发明NAT是为了在网络中隐藏自己真实的IP,以实现一定的安全保护功能,后来当IPv4地址耗尽时,无心插柳,解决了IPv4地址紧缺的问题。NAT大致分为四种情况:源地址转换、目标地址转换、端口转换,全地址转换。
源地址转换:将内网地址通过NAT Server转换为公网地址访问互联网 目标地址转换:将互联网访问NAT Server的公网地址转换内部Server的私有地址 端口转换:在目标地址转换的基础上将互联网访问NAT Server的端口转换成内部Server真正监听的端口 全地址转换:就是同时做源地址和目标地址转换,类似于代理服务器,但与之又不相同。
上面的拓扑图中192.168.1.0/24网段是外网地址,192.168.80.0/24网段是内网地址。
源地址转换测试:
目标地址转换测试:
OK,我们的iptables/netfilter的基础应用就说到这里了,iptables主要是工作在网络层,那么在linux中还有有个叫tcp_wrapper的控制工具组件,它他利用一些tcp_wrapper的库完成在传输层对数据的过滤,有兴趣的朋友可以去了解一些,我就不再过多的介绍了。如有错误敬请指正。