0%

iptables使用教程02

5. 常用扩展

5.1 iprange扩展模块

使用iprange扩展模块可以指定”一段连续的IP地址范围”,用于匹配报文的源地址或者目标地址。

1
2
3
iptables -t filter -I INPUT -m iprange --src-range 192.168.1.127-192.168.1.146 -j DROP
iptables -t filter -I OUTPUT -m iprange --dst-range 192.168.1.127-192.168.1.146 -j DROP
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
2
3
4
5
6
7
8
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --timestart 09:00:00 --timestop 19:00:00 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 443 -m time --timestart 09:00:00 --timestop 19:00:00 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --weekdays 6,7 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --monthdays 22,23 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80  -m time ! --monthdays 22,23 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --timestart 09:00:00 --timestop 18:00:00 --weekdays 6,7 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --weekdays 5 --monthdays 22,23,24,25,26,27,28 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --datestart 2017-12-24 --datestop 2017-12-27 -j REJECT

5.4 connlimit扩展模块

使用connlimit扩展模块,可以限制每个IP地址同时链接到server端的链接数量,注意:我们不用指定IP,其默认就是针对”每个客户端IP”,即对单IP的并发连接数限制。

–connlimit-above:单独使用此选项时,表示限制每个IP的链接数量。

–connlimit-mask:此选项不能单独使用,在使用–connlimit-above选项时,配合此选项,则可以针对”某类IP段内的一定数量的IP”进行连接数量的限制

1
2
3
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 20 --connlimit-mask 24 -j REJECT
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 10 --connlimit-mask 27 -j REJECT

5.5 limit扩展模块

limit模块是对”报文到达速率”进行限制的。如果我想要限制单位时间内流入的包的数量,就能用limit模块。

–limit-burst:类比”令牌桶”算法,此选项用于指定令牌桶中令牌的最大数量。

–limit:类比”令牌桶”算法,此选项用于指定令牌桶中生成新令牌的频率,可用时间单位有second、minute 、hour、day。

1
2
3
#如下两条规则需配合使用
iptables -t filter -I INPUT -p icmp -m limit --limit-burst 3 --limit 10/minute -j ACCEPT
iptables -t filter -A INPUT -p icmp -j REJECT

5.6 udp扩展

udp扩展模块能用的匹配条件比较少,只有两个,就是–sport与–dport,即匹配报文的源端口与目标端口。

1
2
3
iptables -t filter -I INPUT -p udp -m udp --dport 137 -j ACCEPT
iptables -t filter -I INPUT -p udp -m udp --dport 137:157 -j ACCEPT
#可以结合multiport模块指定多个离散的端口

5.7 icmp扩展

ICMP协议的全称为Internet Control Message Protocol,翻译为互联网控制报文协议,它主要用于探测网络上的主机是否可用,目标是否可达,网络是否通畅,路由是否可用等。

ping命令使用的就是icmp协议。

–icmp-type:匹配icmp报文的具体类型

1
2
3
4
5
iptables -t filter -I INPUT -p icmp -m icmp --icmp-type 8/0 -j REJECT
iptables -t filter -I INPUT -p icmp --icmp-type 8 -j REJECT
iptables -t filter -I OUTPUT -p icmp -m icmp --icmp-type 0/0 -j REJECT
iptables -t filter -I OUTPUT -p icmp --icmp-type 0 -j REJECT
iptables -t filter -I INPUT -p icmp --icmp-type "echo-request" -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
2
iptables -I INPUT -s 192.168.1.111,192.168.1.118 -j DROP
iptables -A INPUT -j DROP

7. 自定义链

当默认链中的规则非常多时,不方便我们管理。

7.1 新建

1
2
3
4
5
iptables -N IN_WEB

iptables -nvL
Chain IN_WEB (0 references)
pkts bytes target prot opt in out source destination

7.2 添加规则

1
2
3
4
5
6
7
iptables -I IN_WEB -s 1.1.1.2 -j REJECT


iptables -nvL IN_WEB
Chain IN_WEB (0 references)
pkts bytes target prot opt in out source destination
0 0 REJECT all -- * * 1.1.1.2 0.0.0.0/0 reject-with icmp-port-unreachable

7.3 增加引用

现在,自定义链中已经有了一些规则,但是目前,这些规则无法匹配到任何报文,因为我们并没有在任何默认链中引用它。

1
2
3
4
5
6
7
iptables -I INPUT -p tcp -j IN_WEB


iptables -nvL INPUT
Chain INPUT (policy ACCEPT 7813 packets, 5921K bytes)
pkts bytes target prot opt in out source destination
7614 5907K IN_WEB tcp -- * * 0.0.0.0/0 0.0.0.0/0

之前的示例中,我们使用”-j”选项指定动作,而此处,我们将”动作”替换为了”自定义链”

7.4 修改

1
iptables -E IN_WEB WEB

7.5 删除

1
2
iptables -X WEB
#iptables: Too many links.

因为有引用, 无法删除

1
2
3
iptables -D  INPUT 1
iptables -X WEB
# iptables: Directory not empty.

因为有规则, 无法删除

1
2
3
4
iptables -F WEB
iptables -X WEB

# 删除成功

8. 网络防火墙(filter表forward链)

网络防火墙的职责就是”过滤并转发”,要想”过滤”,只能在INPUT、OUTPUT、FORWARD三条链中实现,要想”转发”,报文则只会经过FORWARD链(发往本机的报文才会经过INPUT链)

1

iptables的角色变为”网络防火墙”时,规则只能定义在FORWARD链中。

8.1 用例

1

上图中的主机A充当了”外部网络主机”的角色,A主机的IP地址为192.168.1.147,我们使用主机A访问内部网络中的主机C,但是需要主机B进行转发,主机B在转发报文时会进行过滤,以实现网络防火墙的功能。

8.2 配置

要配置转发,则需在FORWAED链中定义规则,所以,我们应该在filter表中的FORWARD链中配置规则。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
iptables -nvL FORWARD
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination


# 添加默认拒绝
iptables -A FORWARD -j REJECT


# 添加转发规则
iptables -I FORWARD -s 1.1.0.0/16 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -I FORWARD -d 1.1.0.0/16 -p tcp -m tcp --sport 80 -j ACCEPT


iptables -nvL FORWARD
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 0.0.0.0/0 1.1.0.0/16 tcp spt:80
0 0 ACCEPT tcp -- * * 1.1.0.0/16 0.0.0.0/0 tcp dpt:80
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable

当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
2
3
4
5
6
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 2.2.2.2

iptables -t nat -nvL POSTROUTING
Chain POSTROUTING (policy ACCEPT 357 packets, 21639 bytes)
pkts bytes target prot opt in out source destination
0 0 SNAT all -- * * 10.1.0.0/16 0.0.0.0/0 to:2.2.2.2

如上图所示,上图中的规则表示将来自于10.1.0.0/16网段的报文的源地址改为公网IP地址(2.2.2.2)。

  1. “-t nat”表示操作nat表,我们之前一直在灌输一个概念,就是不同的表有不同的功能,filter表的功能是过滤,nat表的功能就是地址转换,所以我们需要在nat表中定义nat规则。

  2. “-A POSTROUTING”表示将SNAT规则添加到POSTROUTING链的末尾,在centos7中,SNAT规则只能存在于POSTROUTING链与INPUT链中,在centos6中,SNAT规则只能存在于POSTROUTING链中。

  3. 为什么SNAT规则必须定义在POSTROUTING链中,我们可以这样认为,POSTROUTING链是iptables中报文发出的最后一个”关卡”,我们应该在报文马上发出之前,修改报文的源地址,否则就再也没有机会修改报文的源地址了。

  4. 如果只是用于配置SNAT的话,我们并不用手动的进行DNAT设置,iptables会自动维护NAT表,并将响应报文的目标地址转换回来。

9.4 DNAT(NAT表)

公司只有一个公网IP,但是公司的内网中却有很多服务器提供各种服务,我们对外宣称,公司的公网IP上既提供了web服务,也提供了windows远程桌面,不管是访问web服务还是远程桌面,只要访问这个公网IP就行了,我们利用DNAT,将公网客户端发送过来的报文的目标地址与端口号做了映射,将访问web服务的报文转发到了内网中的C主机中,将访问远程桌面的报文转发到了内网中的D主机中。

1
2
3
4
5
6
7
iptables -t nat -I PREROUTING -d 2.2.2.2 -p tcp --dport 3389 -j DNAT --to-destination 10.1.0.6:3389


iptables -t nat -vnL PREROUTING
Chain PREROUTING (policy ACCEPT 2 packets, 68 bytes)
pkts bytes target prot opt in out source destination
0 0 DNAT tcp -- * * 0.0.0.0/0 2.2.2.2.146 tcp dpt:3389 to:10.1.0.6:3389
  1. “-t nat -I PREROUTING”表示在nat表中的PREROUTING链中配置DNAT规则,DNAT规则只配置在PREROUTING链与OUTPUT链中。

  2. “-d 2.2.2.2 -p tcp –dport 3389”表示报文的目标地址为公司的公网IP地址,目标端口为tcp的3389号端口,而我们知道,windows远程桌面使用的默认端口号就是3389,当外部主机访问公司公网IP的3389号端口时,报文则符合匹配条件。

  3. “-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上。

  4. 理论上只要完成上述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
2
3
4
iptables -t nat -I POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 2.2.2.2

# MASQUERADE的对比
iptables -t nat -I POSTROUTING -s 10.1.0.0/16 -o 网卡名字 -j MASQUERADE

可以把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链中。

给作者打赏,可以加首页微信,咨询作者相关问题!