5. 常用扩展
5.1 iprange扩展模块
使用iprange扩展模块可以指定”一段连续的IP地址范围”,用于匹配报文的源地址或者目标地址。
1 | iptables -t filter -I INPUT -m iprange --src-range 192.168.1.127-192.168.1.146 -j DROP |
5.2 string扩展模块
使用string扩展模块,可以指定要匹配的字符串,如果报文中包含对应的字符串,则符合匹配条件。
–algo:用于指定匹配算法,可选的算法有bm与kmp,此选项为必须选项,我们不用纠结于选择哪个算法,但是我们必须指定一个。
–string:用于指定需要匹配的字符串。
1 | iptables -t filter -I INPUT -p tcp --sport 80 -m string --algo bm --string "OOXX" -j REJECT |
5.3 time扩展模块
我们可以通过time扩展模块,根据时间段区匹配报文,如果报文到达的时间在指定的时间范围以内,则符合匹配条件。
–timestart:用于指定时间范围的开始时间,不可取反
–timestop:用于指定时间范围的结束时间,不可取反
–weekdays:用于指定”星期几”,可取反
–monthdays:用于指定”几号”,可取反
–datestart:用于指定日期范围的开始日期,不可取反
–datestop:用于指定日期范围的结束时间,不可取反
1 | iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --timestart 09:00:00 --timestop 19:00:00 -j REJECT |
5.4 connlimit扩展模块
使用connlimit扩展模块,可以限制每个IP地址同时链接到server端的链接数量,注意:我们不用指定IP,其默认就是针对”每个客户端IP”,即对单IP的并发连接数限制。
–connlimit-above:单独使用此选项时,表示限制每个IP的链接数量。
–connlimit-mask:此选项不能单独使用,在使用–connlimit-above选项时,配合此选项,则可以针对”某类IP段内的一定数量的IP”进行连接数量的限制
1 | iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT |
5.5 limit扩展模块
limit模块是对”报文到达速率”进行限制的。如果我想要限制单位时间内流入的包的数量,就能用limit模块。
–limit-burst:类比”令牌桶”算法,此选项用于指定令牌桶中令牌的最大数量。
–limit:类比”令牌桶”算法,此选项用于指定令牌桶中生成新令牌的频率,可用时间单位有second、minute 、hour、day。
1 | #如下两条规则需配合使用 |
5.6 udp扩展
udp扩展模块能用的匹配条件比较少,只有两个,就是–sport与–dport,即匹配报文的源端口与目标端口。
1 | iptables -t filter -I INPUT -p udp -m udp --dport 137 -j ACCEPT |
5.7 icmp扩展
ICMP协议的全称为Internet Control Message Protocol,翻译为互联网控制报文协议,它主要用于探测网络上的主机是否可用,目标是否可达,网络是否通畅,路由是否可用等。
ping命令使用的就是icmp协议。
–icmp-type:匹配icmp报文的具体类型
1 | iptables -t filter -I INPUT -p icmp -m icmp --icmp-type 8/0 -j REJECT |
5.8 state扩展
我们为了让”提供服务方”能够正常的”响应”我们的请求,于是在主机上开放了对应的端口(80, 22),开放这些端口的同时,也出现了问题,别人利用这些开放的端口,”主动”的攻击我们,他们发送过来的报文并不是为了响应我们,而是为了主动攻击我们。
对于state模块的连接而言,”连接”其中的报文可以分为5种状态,报文状态可以为NEW、ESTABLISHED、RELATED、INVALID、UNTRACKED。
- 怎样判断报文是否是为了回应之前发出的报文?
我们只要放行状态为ESTABLISHED的报文即可,因为如果报文的状态为ESTABLISHED,那么报文肯定是之前发出的报文的回应,如果你还不放心,可以将状态为RELATED或ESTABLISHED的报文都放行,这样,就表示只有回应我们的报文能够通过防火墙,如果是别人主动发送过来的新的报文,则无法通过防火墙。
6. 黑白名单
当链的默认策略设置为ACCEPT时,如果对应的链中没有配置任何规则,就表示接受所有的报文,如果对应的链中存在规则,但是这些规则没有匹配到报文,报文还是会被接受。
链的默认策略为ACCEPT时,链中的规则对应的动作应该为DROP或者REJECT,表示只有匹配到规则的报文才会被拒绝,没有被规则匹配到的报文都会被默认接受,这就是”黑名单”机制。
当链的默认策略设置为DROP时,如果对应的链中没有配置任何规则,就表示拒绝所有报文,如果对应的链中存在规则,但是这些规则没有匹配到报文,报文还是会被拒绝。
当链的默认策略设置为DROP时,链中的规则对应的动作应该为ACCEPT,表示只有匹配到规则的报文才会被放行,没有被规则匹配到的报文都会被默认拒绝,这就是”白名单”机制。
6.1 默认DROP的问题
在对应的链中没有设置任何规则时,这样使用默认策略为DROP是非常不明智的,因为管理员也会把自己拒之门外,即使对应的链中存在放行规则,当我们不小心使用”iptables -F”清空规则时,放行规则被删除,则所有数据包都无法进入,这个时候就相当于给管理员挖了个坑,所以,我们如果想要使用”白名单”的机制,最好将链的默认策略保持为”ACCEPT”,然后将”拒绝所有请求”这条规则放在链的尾部,将”放行规则”放在前面,这样做,既能实现”白名单”机制,又能保证在规则被清空时,管理员还有机会连接到主机,示例如下。
1 | iptables -I INPUT -s 192.168.1.111,192.168.1.118 -j DROP |
7. 自定义链
当默认链中的规则非常多时,不方便我们管理。
7.1 新建
1 | iptables -N IN_WEB |
7.2 添加规则
1 | iptables -I IN_WEB -s 1.1.1.2 -j REJECT |
7.3 增加引用
现在,自定义链中已经有了一些规则,但是目前,这些规则无法匹配到任何报文,因为我们并没有在任何默认链中引用它。
1 | iptables -I INPUT -p tcp -j IN_WEB |
之前的示例中,我们使用”-j”选项指定动作,而此处,我们将”动作”替换为了”自定义链”
7.4 修改
1 | iptables -E IN_WEB WEB |
7.5 删除
1 | iptables -X WEB |
因为有引用, 无法删除
1 | iptables -D INPUT 1 |
因为有规则, 无法删除
1 | iptables -F WEB |
8. 网络防火墙(filter表forward链)
网络防火墙的职责就是”过滤并转发”,要想”过滤”,只能在INPUT、OUTPUT、FORWARD三条链中实现,要想”转发”,报文则只会经过FORWARD链(发往本机的报文才会经过INPUT链)
iptables的角色变为”网络防火墙”时,规则只能定义在FORWARD链中。
8.1 用例
上图中的主机A充当了”外部网络主机”的角色,A主机的IP地址为192.168.1.147,我们使用主机A访问内部网络中的主机C,但是需要主机B进行转发,主机B在转发报文时会进行过滤,以实现网络防火墙的功能。
8.2 配置
要配置转发,则需在FORWAED链中定义规则,所以,我们应该在filter表中的FORWARD链中配置规则。
1 | iptables -nvL FORWARD |
当iptables作为”网络防火墙”时,在配置规则时,往往需要考虑”双向性”,也就是说,我们为了达成一个目的,往往需要两条规则才能完成。每次配置规则时都要考虑”双向”的问题, 可以考虑加下面的规则, 以后只加单向就可以了。
1 | iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT |
9. 动作
之前用到的ACCEPT与DROP都属于基础动作。使用-j可以指定动作,比如-j ACCEPT, -j DROP, -j REJECT
9.1 REJECT
REJECT动作的常用选项为–reject-with
使用–reject-with选项,可以设置提示信息,当对方被拒绝时,会提示对方为什么被拒绝。
可用值如下
icmp-net-unreachable
icmp-host-unreachable
icmp-port-unreachable,
icmp-proto-unreachable
icmp-net-prohibited
icmp-host-pro-hibited
icmp-admin-prohibited
当不设置任何值时,默认值为icmp-port-unreachable。
9.2 LOG
使用LOG动作,可以将符合条件的报文的相关信息记录到日志中,但当前报文具体是被”接受”,还是被”拒绝”,都由后面的规则控制,换句话说,LOG动作只负责记录匹配到的报文的相关信息,不负责对报文的其他处理,如果想要对报文进行进一步的处理,可以在之后设置具体规则,进行进一步的处理。
9.3 SNAT(NAT表)
9.3.1 NAT介绍
内部网络的报文发送出去时,报文的源IP会被修改,也就是源地址转换:Source Network Address Translation,缩写为SNAT。
外部网络的报文响应时,响应报文的目标IP会再次被修改,也就是目标地址转换:Destinationnetwork address translation,缩写为DNAT。
整个过程被称为SNAT还是DNAT,取决于整个过程的前半段使用了SNAT还是DNAT。
9.3.2 操作
1 | iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 2.2.2.2 |
如上图所示,上图中的规则表示将来自于10.1.0.0/16网段的报文的源地址改为公网IP地址(2.2.2.2)。
“-t nat”表示操作nat表,我们之前一直在灌输一个概念,就是不同的表有不同的功能,filter表的功能是过滤,nat表的功能就是地址转换,所以我们需要在nat表中定义nat规则。
“-A POSTROUTING”表示将SNAT规则添加到POSTROUTING链的末尾,在centos7中,SNAT规则只能存在于POSTROUTING链与INPUT链中,在centos6中,SNAT规则只能存在于POSTROUTING链中。
为什么SNAT规则必须定义在POSTROUTING链中,我们可以这样认为,POSTROUTING链是iptables中报文发出的最后一个”关卡”,我们应该在报文马上发出之前,修改报文的源地址,否则就再也没有机会修改报文的源地址了。
如果只是用于配置SNAT的话,我们并不用手动的进行DNAT设置,iptables会自动维护NAT表,并将响应报文的目标地址转换回来。
9.4 DNAT(NAT表)
公司只有一个公网IP,但是公司的内网中却有很多服务器提供各种服务,我们对外宣称,公司的公网IP上既提供了web服务,也提供了windows远程桌面,不管是访问web服务还是远程桌面,只要访问这个公网IP就行了,我们利用DNAT,将公网客户端发送过来的报文的目标地址与端口号做了映射,将访问web服务的报文转发到了内网中的C主机中,将访问远程桌面的报文转发到了内网中的D主机中。
1 | iptables -t nat -I PREROUTING -d 2.2.2.2 -p tcp --dport 3389 -j DNAT --to-destination 10.1.0.6:3389 |
“-t nat -I PREROUTING”表示在nat表中的PREROUTING链中配置DNAT规则,DNAT规则只配置在PREROUTING链与OUTPUT链中。
“-d 2.2.2.2 -p tcp –dport 3389”表示报文的目标地址为公司的公网IP地址,目标端口为tcp的3389号端口,而我们知道,windows远程桌面使用的默认端口号就是3389,当外部主机访问公司公网IP的3389号端口时,报文则符合匹配条件。
“-j DNAT –to-destination 10.1.0.6:3389”表示将符合条件的报文进行DNAT,也就是目标地址转换,将符合条件的报文的目标地址与目标端口修改为10.1.0.6:3389,”–to-destination”就是动作DNAT的常用选项。
那么综上所述,当外网主机访问公司公网IP(2.2.2.2)的3389时,其报文的目标地址与端口将会被映射到10.1.0.6:3389上。
理论上只要完成上述DNAT配置规则即可,但是在测试时,只配置DNAT规则后,并不能正常DNAT,经过测试发现,将相应的SNAT规则同时配置后,即可正常DNAT,于是我们又配置了SNAT。
1 | iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 2.2.2.2 |
9.5 MASQUERADE
当我们拨号网上时,每次分配的IP地址往往不同,不会长期分给我们一个固定的IP地址,如果这时,我们想要让内网主机共享公网IP上网,就会很麻烦,因为每次IP地址发生变化以后,我们都要重新配置SNAT规则,这样显示不是很人性化,我们通过MASQUERADE即可解决这个问题,MASQUERADE会动态的将源地址转换为可用的IP地址,其实与SNAT实现的功能完全一致,都是修改源地址。
只不过SNAT需要指明将报文的源地址改为哪个IP,而MASQUERADE则不用指定明确的IP,会动态的将报文的源地址修改为指定网卡上可用的IP地址。
1 | iptables -t nat -I POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 2.2.2.2 |
可以把MASQUERADE理解为动态的、自动化的SNAT,如果没有动态SNAT的需求,没有必要使用MASQUERADE,因为SNAT更加高效。
9.6 REDIRECT
使用REDIRECT动作可以在本机上进行端口映射
比如,将本机的80端口映射到本机的8080端口上
1 | iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080 |
经过上述规则映射后,当别的机器访问本机的80端口时,报文会被重定向到本机的8080端口上。
REDIRECT规则只能定义在PREROUTING链或者OUTPUT链中。