iptables的原理与简单应用
1. 什么是防火墙?
在计算机体系中,防火墙是基于预定安全规则来监视和控制传入和传出网络流量的网络安全系统。该计算机流入流出的所有网络通信均要经过此防火墙。防火墙对流经它的网络通信进行扫描,这样能够过滤掉一些攻击,以免其在目标计算机上被执行。防火墙还可以关闭不使用的端口。而且它还能禁止特定端口的流出通信,封锁特洛伊木马。最后,它可以禁止来自特殊站点的访问,从而防止来自不明入侵者的所有通信。
根据其表现形式可以分为软件防火墙和硬件防火墙,其优缺点如下:
硬件防火墙:拥有经过特别设计的硬件及芯片,性能高、成本高(当然硬件防火墙也是有软件的,只不过有部分功能由硬件实现,所以硬件防火墙其实是硬件+软件的方式);
软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙,性能比硬件防火墙低、成本低。
其中软件防火墙又在不同的OS上具有不同的程序实现,在windows
会有系统自带的windows defender
在linux中经过了netfilter、iptables、firewall
等多个版本迭代。其中最为经典的就是iptables这一款防火墙,通过对其的学习可以有效的帮助我们理解主机防火墙的基本原理。
1.1 netfilter和iptables的关系
Netfilter是由Rusty Russell提出的Linux 2.4内核防火墙框架,该框架既简洁又灵活,可实现安全策略应用中的许多功能,如数据包过滤、数据包处理、地址伪装、透明代理、动态网络地址转换(Network Address Translation,NAT),以及基于用户及媒体访问控制(Media Access Control,MAC)地址的过滤和基于状态的过滤、包速率限制等。Iptables/Netfilter的这些规则可以通过灵活组合,形成非常多的功能、涵盖各个方面,这一切都得益于它的优秀设计思想。
Netfilter是Linux操作系统核心层内部的一个数据包处理模块,它具有如下功能:
- 网络地址转换(Network Address Translate)
- 数据包内容修改
- 以及数据包过滤的防火墙功能
Netfilter平台中制定了数据包的五个挂载点(Hook Point,我们可以理解为回调函数点,数据包到达这些位置的时候会主动调用我们的函数,使我们有机会能在数据包路由的时候改变它们的方向、内容),这5个挂载点分别是PRE_ROUTING
、INPUT
、OUTPUT
、FORWARD
、POST_ROUTING
。
Netfilter所设置的规则是存放在内核空间中的,而iptables是一个应用层的应用程序,它通过Netfilter放出的接口来对存放在内核空间中的 XXtables(Netfilter的配置表)进行修改。这个XXtables由表tables、链chains、规则rules组成,iptables在应用层负责修改这个规则文件,类似的应用程序还有firewalld(CentOS7默认防火墙)。
所以Linux中真正的防火墙是Netfilter,但由于都是通过应用层程序如iptables或firewalld进行操作,所以我们一般把iptables或firewalld叫做Linux的防火墙。
注意:以上说的iptables都是针对IPv4的,如果IPv6,则要用
ip6tables
,至于用法应该是跟iptables
是一样的。
Linux系统运行时,内存分内核空间和用户空间,内核空间是Linux内核代码运行的空间,它能直接调用系统资源,用户空间是指运行用户程序的空间,用户空间的程序不能直接调用系统资源,必须使用内核提供的接口“system call”。*
2.iptables的基本概念
2.1 链的概念
iptables开启后,数据报文从进入服务器到出来会经过5道关卡,分别为Prerouting(路由前)、Input(输入)、Outpu(输出)、Forward(转发)、Postrouting(路由后)
对于五链的解释如下:
- INPUT链:当接收到防火墙本机地址的数据包(入站)时,应用此链中的规则;
- OUTPUT链:当防火墙本机向外发送数据包(出站)时,应用此链中的规则;
- FORWARD链:当接收到需要通过防火墙发送给其他地址的数据包(转发)时,应用此链中的规则;
- PREROUTING链:(互联网进入局域网)在对数据包作路由选择之前,应用此链中的规则,如DNAT;
- POSTROUTING链:(局域网出互联网)在对数据包作路由选择之后,应用此链中的规则,如SNAT。
以上链中,前路由和后路由链仅在服务器作为网络边界时有用,在现在的网络环境中几乎不会将服务器直接摆放到公网上去,在服务器前会有一堆安全设备。所以我们需要关心的就是INPUT
和OUTPUT
链。
每一道关卡中有多个规则,数据报文必须按顺序一个一个匹配这些规则,这些规则串起来就像一条链,所以我们把这些关卡都叫“链”。规则的匹配顺序是从上到下依次匹配,最后会匹配到默认规则。这一点与路由交换中的ACL访问控制列表一致。
那么此时就可以理解为,针对于不同的数据流向会匹配到不同的链,那么对于数据的动作则取决于对应匹配链内的规则。
2.2 表的概念
虽然每一条链上有多条规则,但有些规则的作用(功能)很相似,多条具有相同功能的规则合在一起就组成了一个“表”,iptables提供了四种“表”:
-
filter表
:主要用于对数据包进行过滤,根据具体的规则决定是否放行该数据包(如DROP、ACCEPT、REJECT、LOG),所谓的防火墙其实基本上是指这张表上的过滤规则,对应内核模块iptables_filter; -
nat表
:network address translation
,网络地址转换功能,主要用于修改数据包的IP地址、端口号等信息(网络地址转换,如SNAT、DNAT、MASQUERADE、REDIRECT)。属于一个流的包(因为包的大小限制导致数据可能会被分成多个数据包)只会经过这个表一次,如果第一个包被允许做NAT或Masqueraded,那么余下的包都会自动地被做相同的操作,也就是说,余下的包不会再通过这个表。对应内核模块iptables_nat; -
mangle表
:拆解报文,做出修改,并重新封装,主要用于修改数据包的TOS(Type Of Service,服务类型)、TTL(Time To Live,生存周期)指以及为数据包设置Mark标记,以实现Qos(Quality Of Service,服务质量)调整以及策略路由等应用,由于需要相应的路由设备支持,因此应用并不广泛。对应内核模块iptables_mangle; -
raw表
:是自1.2.9以后版本的iptables新增的表,主要用于决定数据包是否被状态跟踪机制处理,在匹配数据包时,raw表的规则要优先于其他表,对应内核模块iptables_raw。
对于我们日常主机防护中起到关键作用的其实就是filter
表,因为我们大多数时候就是在做数据包的准入过滤和IP地址封堵这样的操作。 我们最终定义的防火墙规则,都会添加到这四张表中的其中一张表中。
2.3 表链的关系
5条链(即5个关卡)中,并不是每条链都能应用所有类型的表,事实上除了Ouptput链能同时有四种表,其他链都只有两种或三种表:
前面说过,数据报文必须按顺序匹配每条链上的一个一个的规则,但其实同一类(即属于同一种表)的规则是放在一起的,不同类的规则不会交叉着放,按上边的规律,每条链上各个表被匹配的顺序为:raw→mangle→nat→filter。
数据包通过防火墙的流程可总结为下图:
2.4 规则的概念
iptables规则主要包含“条件&动作”,即匹配出符合什么条件(规则)后,对它采取怎样的动作。
匹配条件:基于数据五元组(源目端口、源目IP、协议类型)
- S_IP:source ip,源ip
- S_PORT:source port,源端口
- D_IP: destination ip,目标ip
- D_PORT: destination port,目标端口
- TCP/UDP:第四层(传输层)协议
处理的动作:
- ACCEPT:允许数据包通过;
- DROP:直接丢弃数据包,不回应任何信息,客户端只有当该链接超时后才会有反应;
- REJECT:拒绝数据包,会给客户端发送一个数据包被丢弃的响应的信息;
- SNAT:S指Source,源NAT(源地址转换)。在进入路由层面的route之后,出本地的网络栈之前,改写源地址,目标地址不变,并在本机建立NAT表项,当数据返回时,根据NAT表将目的地址数据改写为数据发送出去时候的源地址,并发送给主机。解决私网用户用同一个公网IP上网的问题;
- MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的IP上;
- DNAT:D指Destination,目的NAT,解决私网服务端,接收公网请求的问题。和SNAT相反,IP包经过route之前,重新修改目标地址,源地址不变,在本机建立NAT表项,当数据返回时,根据NAT表将源地址修改为数据发送过来时的目标地址,并发给远程主机。可以隐藏后端服务器的真实地址;
- REDIRECT:在本机做端口映射;
- LOG:在
/var/log/messages
文件中记录日志信息,然后将数据包传递给下一条规则。
除去最后一个LOG,前几条规则匹配数据包后,该数据包不会再往下继续匹配了,所以编写的规则顺序极其关键。
3.iptables命令操作
对于防火墙的使用就是对于五链四表的增删改查
3.1 查看iptables
命令格式:iptables [选项] [参数]
常用选项:
选项 | 功能 |
---|---|
-L | 默认查看所有链上的规则列表,可以后跟链名指定查询某一条链 |
-t | 前面-L 不是列出所有链的规则列表吗?为什么没有PREROUTING和POSTROUTING链呢?因为有默认参数-t ,t是table的缩写,意思是指定显示哪张“表”中的规则(前面说过iptables有四种表),iptables -L 其实就相当于iptables -t filter -L ,即相当于你查看的是“filter”表中的规则。而根据前面的讲解,filter表只可用于INPUT、FORWARD、OUTPUT三条链中,这就是为什么iptables -L 不显示PREROUTING链和POSTROUTING链 |
-n | numeric的缩写,numeric意思是数字的,数值的,意思是指定源和目标地址、端口什么的都以数字/数值的方式显示,否则默认会以域名/主机名/程序名等显示,该选项一般与-L 合用,因为单独的-n 是没有用的(没有-L 列表都不显示,所以用-n 就没有意义了)。 |
-v | 输出更加详细的信息 |
-x | 加了-v 后,Policy那里变成了“(policy ACCEPT 0 packets, 0 bytes)”,即多了过滤的数据包数量和字节数,其中的字节数,如果数据大了之后,会自动转换单位,比如够KB不够MB,它会显示“xxxk”,够了MB它显示“MB”,但单位转换之后,就不完全精确了,因为它没有小数,如果还是想要看以“字母”即“byptes”为单位查看的话,加个-x 就行了,“x”来自于“exact”,意思是“精确的;准确的”,不取首字母应该是太多选项首字母是e了。 |
–line-numbers | 添加列表序号,可以简写为--line |
正经人的查看方式:
#统一查询所有链的filter表
[root@blackstone ~]# iptables -xnvL --line
#过滤输出OUTPUT链的filter表
[root@blackstone ~]# iptables -xnvL OUTPUT --line
Chain OUTPUT (policy ACCEPT 3709 packets, 374788 bytes)
num pkts bytes target prot opt in out source destination
当然此时是空的,来解释解释这些参数的含义:
- Chain INPUT: INPUT链上的规则,同理,后面的“Chain FORWARD”、“Chain OUTPUT”分别是FORWARD链和OUTPUT链上的规则;
- (policy ACCEPT): 表示默认策略是接受,即假如我没设置,那就是允许,只有我设置哪个不允许,才会不允许,示例中是安装iptables后的默认规则,由于默认是ACCEPT,你规则也设置为ACCEPT按道理来说是没什么意义的,因为你不设置也是ACCEPT呀,但事实上,是为了方便修改为REJECT/DROP等规则,说白了就是放在那,要设置的时候我们就可以直接修改;
- num 显示规则的编号
- pkts: packets,包的数量;
- bytes: 流过的数据包的字节数;
- prot: protocol,协议;
- opt: option,选项;
- in: 入站网卡;
- out: 出站网卡。
- source: 源地址(ip(可以是网段)/域名/主机名)
- destination: 目标地址(ip(可以是网段)/域名/主机名)
- 末列: 一些额外的信息
- target: 英文意思是“目标”,但该列的值通常是动作,比如ACCEPT(接受)、REJECT(拒绝)等等,但它确实可以是“目标”,比如我们创建 一条链
iptables -N July_filter
,然后在INPUT链上添加一条规则,让它跳转到刚刚的新链-A INPUT -p tcp -j July_filter
,再用iptables -L
查看,可以看到target此时已经是真正的“target(July_filter)”而不再是动作了
3.2 添加规则
我们可以向某条链中的某个表的最前面添加记录(我们叫“插入”,会用到-I
选项,I表示Insert),也可以向某条链中的某个表的最后面添加记录(我们叫“追加”,会用到-A
选项,A表示Append),熟悉vi/vim
的童鞋会对这个“I”和“A”感觉到熟悉,因为在vi/vim
的命令模式下,按I
是在光标所行的行首插入,按A
是在光标所在行的行尾插入,跟这个在表头跟表尾插入非常像。
之所以有向前添加和向后添加,是因为如果前面规则的是丢弃或拒绝,那么后面的规则是不会起作用的;而如果前面的是接受后面的是丢弃或拒绝,则接受之后后面的丢弃或拒绝也是不会生效的。
向INPUT链的filter表中添加一条规则:
iptables -t filter -I INPUT -s 192.168.2.0/24 -j ACCEPT
-
-t
: 是指定插入到哪个表中,不写的话默认为“filter”表; -
-I
: 指定插入到哪条链中,并且会在该链指定表(在这里是filter表)中的最前面插入(I:Input),如果用-A
则是在最后插入(A:Append)。 -
-s
: 匹配源ip,s: source,源。 -
-j
: jump,跳转的意思,后面可指定跳转的target(目标),比如自定义的链,当然更多的是跳转到“action(动作)”中,比如ACCEPT、DROP、REJECT等等。 -
连起来的意思是允许192.168.2.0/24网段的主机访问本机
测试:
[root@blackstone ~]# iptables -t filter -I INPUT -s 192.168.2.0/24 -j ACCEPT
[root@blackstone ~]# iptables -nvxL INPUT --line
Chain INPUT (policy ACCEPT 1 packets, 76 bytes)
num pkts bytes target prot opt in out source destination
1 64 4096 ACCEPT all -- * * 192.168.2.0/24 0.0.0.0/0
可以看到已经有数据包匹配到这条规则了,再次执行或看到我们的ssh命令传输产生的流量被此条规则匹配了。
当然还可以使用的规则参数有:-p 指定协议、-d指定目的地址、-i指定数据进入网卡、-o指定数据出向网卡。
3.3 删除iptables中的记录
3.3.1 根据编号删除
iptables -t filter -D INPUT 2
示例:
[root@blackstone ~]# iptables -nvxL INPUT --line
Chain INPUT (policy ACCEPT 1 packets, 76 bytes)
num pkts bytes target prot opt in out source destination
1 18 1152 ACCEPT all -- * * 192.168.2.0/24 0.0.0.0/0
2 4 256 ACCEPT all -- * * 192.168.2.0/24 0.0.0.0/0
3 81 5208 ACCEPT all -- * * 192.168.2.0/24 0.0.0.0/0
[root@blackstone ~]# iptables -t filter -D INPUT 1
[root@blackstone ~]# iptables -nvxL INPUT --line
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 10 640 ACCEPT all -- * * 192.168.2.0/24 0.0.0.0/0
2 81 5208 ACCEPT all -- * * 192.168.2.0/24 0.0.0.0/0
删除后,所有规则的序号都会-1
,此时我们需要注意重新删除时的编号变动。
3.3.2 根据条件删除:
iptables -t filter -D INPUT -s 192.168.2.0/24 -j ACCEPT
示例:
[root@blackstone ~]# iptables -nvxL INPUT --line
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 10 640 ACCEPT all -- * * 192.168.2.0/24 0.0.0.0/0
2 81 5208 ACCEPT all -- * * 192.168.2.0/24 0.0.0.0/0
[root@blackstone ~]# iptables -t filter -D INPUT -s 192.168.2.0/24 -j ACCEPT
[root@blackstone ~]# iptables -nvxL INPUT --line
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 87 5592 ACCEPT all -- * * 192.168.2.0/24 0.0.0.0/0
[root@blackstone ~]# iptables -t filter -D INPUT -s 192.168.2.0/24 -j ACCEPT
[root@blackstone ~]# iptables -nvxL INPUT --line
Chain INPUT (policy ACCEPT 6 packets, 384 bytes)
num pkts bytes target prot opt in out source destination
这里由于失误多写了几条相同的规则进去,在匹配删除时,单次只能删除一条记录。算是一个小发现。正常在写的时候,不会出现两条一样的记录。
3.3.3 强制清空
iptables -F
强制清空所有表链中的规则,生产环境慎用。
3.4 修改iptables
事实上用“替换”来描述会更好一点,因为所谓的修改其实就是把整个规则替换成新的规则:
iptables -t filter -R INPUT 1 -s 192.168.2.0/24 -j ACCEPT
其中的-R
就是replace,即替换的意思,整句命令意思是从INPUT链中的filter表中替换编号为1的规则,编号1后面的就是要替换的新规则。
修改策略:
iptables -P FORWARD DROP
#-P: policy,即策略。整个意思是把FORWARD链的默认规则设置为DROP,iptables [-t table] -P chain target这个命令,可以根据不同的表,设置不同的限制
iptables -t raw -P OUTPUT ACCEPT
iptables -t filter -P OUTPUT DROP
3.5 规则的备份与还原
默认的 iptables 防火墙规则会立刻生效,但如果不保存,当计算机重启后所有的规则都会丢失,所以对防火墙规则进行及时保存的操作是非常必要的。
iptables 软件包提供了两个非常有用的工具,我们可以使用这两个工具处理大量的防火墙规则。这两个工具分别是 iptables-save 和 iptables-restore,使用该工具可以实现防火墙规则的保存与还原。这两个工具的最大优势是处理庞大的规则集时速度非常快。
CentOS 7 系统中防火墙规则默认保存在 /etc/sysconfig/iptables 文件中,使用 iptables-save 将规则保存至该文件中可以实现保存防火墙规则的作用,计算机重启后会自动加载该文件中的规则。如果使用 iptables-save 将规则保存至其他位置,可以实现备份防火墙规则的作用。当防火墙规则需要做还原操作时,可以使用 iptables-restore 将备份文件直接导入当前防火墙规则。
备份:
#保存在默认文件夹中(保存防火墙规则):
iptables-save > /etc/sysconfig/iptables
#保存在其他位置(备份防火墙规则):
iptables-save > 文件名称
恢复:
iptables-restore < 文件名称
注意,导入的文件必须是使用 iptables-save工具导出来的才可以。
示例:备份当前配置,进行配置清除,在重新恢复出来防火墙的配置
#1.开始备份当前配置
[root@blackstone ~]# iptables-save > beifenfw.bak
[root@blackstone ~]# iptables -nvxL INPUT --line
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 66 4224 ACCEPT all -- * * 192.168.2.0/24 0.0.0.0/0
#2.当前配置清空
[root@blackstone ~]# iptables -F
[root@blackstone ~]# iptables -nvxL INPUT --line
Chain INPUT (policy ACCEPT 6 packets, 384 bytes)
num pkts bytes target prot opt in out source destination
#3.配置还原
[root@blackstone ~]# iptables-restore < beifenfw.bak
[root@blackstone ~]# iptables -nvxL INPUT --line
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 6 384 ACCEPT all -- * * 192.168.2.0/24 0.0.0.0/0
有了这样的操作,我们就可以建立一套完整的规则库,在不同的业务环境中启用不同的规则,可以做到快速高效的iptables规则部署。
4.ipables的扩展
4.1 tcp 扩展
-p tcp -m tcp --sport
用于匹配tcp协议报文的源端口,可以使用冒号指定一个连续的端口范围(-p protocol,
-m:match,指匹配的模块,很多人可能以为是module的缩写,其实是match的缩写,
–sport: source port);
-p tcp -m tcp --dport用于匹配tcp协议报文的目标端口,可以使用冒号指定一个连续的端口范围(
–dport 80:88
#示例如下
#1.output链中拒绝目的地址为192.168.1.146,协议为tcp,源端口为22的连接
iptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp --sport 22 -j REJECT
#2.input链中添加tcp协议,目的端口22-25,源地址为192.168.1.146的数据包为拒绝动作
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport 22:25 -j REJECT
4.2 multiport扩展模块
-p tcp -m multiport --sports
用于匹配报文的源端口,可以指定离散的多个端口号,端口之间用”逗号”隔开;
-p tcp -m multiport --dports
用于匹配报文的目标端口,可以指定离散的多个端口号,端口之间用”逗号”隔开:
例如:
#限制tcp协议的目标端口为22,80到88,源地址为192.168.2.0/24的通信数据
iptables -t filter -I INPUT -s 192.168.2.0/24 -p tcp -m multiport --dports 23,80:88 -j REJECT
测试:
无法访问80端口,但是我们的ssh正常使用。
查看匹配情况如下:
4.3 iprange扩展模块
使用iprange扩展模块可以指定”一段连续的IP地址范围”,用于匹配报文的源地址或者目标地址。iprange扩展模块中有两个扩展匹配条件可以使用:
--src-range
(匹配源地址范围)
--dst-range
(匹配目标地址范围)
iptables -t filter -I INPUT -m iprange --src-range 192.168.1.127-192.168.1.146 -j DROP
这条扩展可以用于对于一段连续的IP地址进行封堵。
4.4 string扩展模块
该模块可以对请求内的敏感字段进行过滤,在关键时刻可以充当敏感字waf。防御一些基于敏感字段的攻击。
iptables -t filter -I INPUT -m string --algo bm --string "attackword" -j REJECT
-m string
:表示使用string模块
--algo bm
:表示使用bm算法来匹配index.html中的字符串,“algo”是“algorithm”的缩写,另外还有一种算法叫“kmp”,所以--algo
可以指定两种值,bm或kmp,貌似是bm算法速度比较快。
测试效果:
1.敏感字段出现在URL中:
查看它的网络连接:
2.敏感字段出现在useragent中时:
出现敏感字段
3.敏感字段出现在post传参的请求体中
后端代码
<?php
$key = $_POST['key'];
var_dump($key);
phpinfo();
正常请求:
敏感字段:
4.5 connlimit模块
使用connlimit扩展模块,可以限制每个IP地址同时链接到server端的链接数量,注意:我们不用指定IP,其默认就是针对”每个客户端IP”,即对单IP的并发连接数限制。
限制22端口(ssh默认端口)连接数量上限不能超过2个;
iptables -t filter -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
在CentOS6中可对--connlimit-above
取反:
iptables -t filter -I INPUT -p tcp --dport 22 -m connlimit ! --connlimit-above 2 -j REJECT
表示连接数量只要不超过两个就允许连接,至于超过两个并不一定不允许连接,这得看默认策略是ACCEPT还是DROP或REJECT,又或者有其它规则对它进行限制。
在CentOS7中有一个叫--connlimit-upto
的选项,它的作用跟! --connlimit-above
一样,不过这种用法还是比较少用的。
配合--connlimit-mask
来限制网段:
iptables -t filter -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 --connlimit-mask 24 -j REJECT
示例:测试ssh多终端连接
iptables -t filter -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
可以看到,连接到第二个就没动静了。说明这样的限制是起了作用的。
4.6 limit扩展模块
limit模块是限速用的,用于限制“单位时间内流入的数据包的数量”。可以说是专治各种dos攻击。
示例配置:
#每6秒放行一下ping包(因为1分钟是60秒,所以1分钟10个包,就相当于每6秒1个包):
iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT
–limit`后面的单位除了minute,还可以是second、hour、day
--limit-burst
: burst是爆发、迸发的意思,在这里是指最多允许一次性有几个包通过,要理解burst,先看以下的“令牌桶算法”。
令牌桶算法:
有一个木桶,木桶里面放了5块令牌,而且这个木桶最多也只能放下5块令牌,所有报文如果想要出关入关,都必须要持有木桶中的令牌才行,这个木桶有一个神奇的功能,就是每隔6秒钟会生成一块新的令牌,如果此时,木桶中的令牌不足5块,那么新生成的令牌就存放在木桶中,如果木桶中已经存在5块令牌,新生成的令牌就无处安放了,只能溢出木桶(令牌被丢弃),如果此时有5个报文想要入关,那么这5个报文就去木桶里找令牌,正好一人一个,于是他们5个手持令牌,快乐的入关了,此时木桶空了,再有报文想要入关,已经没有对应的令牌可以使用了,但是,过了6秒钟,新的令牌生成了,此刻,正好来了一个报文想要入关,于是,这个报文拿起这个令牌,就入关了,在这个报文之后,如果很长一段时间内没有新的报文想要入关,木桶中的令牌又会慢慢的积攒了起来,直到达到5个令牌,并且一直保持着5个令牌,直到有人需要使用这些令牌,这就是令牌桶算法的大致逻辑。
看完了“令牌桶算法”,其实--limit
就相当于指定“多长时间生成一个新令牌”,而--limit-burst
则用于指定木桶中最多存放多少块令牌。
示例测试:
[root@blackstone ~]# iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT
[root@blackstone ~]# iptables -t filter -I INPUT -s 192.168.2.0/24 -p tcp -m tcp --dport 22:80 -j ACCEPT
#设定默认动作为丢弃
[root@blackstone ~]# iptables -t filter -P INPUT DROP
#查看规则
[root@blackstone ~]# iptables -xnvL INPUT
此处最好使用linux带的ping,看的效果更好
我们看到序列号连续到第五次就开始中断,中断时间大约为6秒,符合我们的推断。可能会遇到另一种情况就是第五个响应和第七个响应之间相差很少短,这是由于令牌在第0秒的时候就已经开始刷新了,故在第七个数举包处会生成新的令牌,供数据包使用。并且默认的令牌数就是5个,可以通过--limit-burst
进行修改,比如:
[root@blackstone ~]# iptables -nvxL INPUT --line
Chain INPUT (policy DROP 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 907 64040 ACCEPT tcp -- * * 192.168.2.0/24 0.0.0.0/0 tcp dpts:22:80
2 0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 10/min burst 8
3 272 149830 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "attackworld" ALGO name bm TO 65535 reject-with icmp-port-unreachable
4.7 icmp扩展模块
ping是使用icmp协议的,假设要禁止所有icmp协议的报文进入本机(根据前面所说,我们可以省略用-m icmp
来指定使用icmp模块,因为不指定它会默认使用-p
指定的协议对应的模块):
iptables -t filter -I INPUT -p icmp -j REJECT
如果按照这样的操作进行禁用,会导致两个结果,第一我们的icmp请求包将永远收不到返回包,第二我们将永远收不到别人的请求包。但是通常我们的需求就是我要ping别人,但是我不允许别人ping我。到这里就一定需要使用icmp扩展模块对icmp进行一个更加细粒度的控制。
很明显上边的规则不是我们想要的,我们想要的一般都是允许本机ping别人,不允许别人ping本机
解决方案:
iptables -t filter -I INPUT -p icmp --icmp-type 8/0 -j REJECT
--icmp-type 8/0
用于匹配报文type为8,code为0时才会被匹配到,至于会是type和code,这是icmp协议的知识。
其实上边的命令还可以省略code(即把“8/0”写成“8”即可,省略掉“/0”,原因是type=8的报文中只有code=0一种,所以我们不写默认就是code=0,不会有其它值):
iptables -t filter -I INPUT -p icmp --icmp-type 8 -j REJECT
除了能用type/code来匹配icmp报文,还可以使用icmp的描述名称来匹配:
iptables -t filter -I INPUT -p icmp --icmp-type "echo-request" -j REJECT
--icmp-type "echo-request"
的效果与icmp --icmp-type 8/0
或icmp --icmp-type 8
的效果完全一样(你可能发现了,icmp协议的描述“echo-request”其实是“echo request”,只不过我们用于作为匹配条件时,要把空格换成横杠)。
说白了就是将对面发送过来的icmp请求包给禁用了,此时我们出去的包不受影响,对端发来的icmp响应包同样不受影响。就达到了上面的效果。
测试:
[root@blackstone ~]# iptables -t filter -I INPUT -p icmp --icmp-type 8 -j REJECT
[root@blackstone ~]# ping 192.168.2.159
PING 192.168.2.159 (192.168.2.159) 56(84) bytes of data.
64 bytes from 192.168.2.159: icmp_seq=1 ttl=64 time=0.309 ms
64 bytes from 192.168.2.159: icmp_seq=2 ttl=64 time=0.662 ms
64 bytes from 192.168.2.159: icmp_seq=3 ttl=64 time=0.360 ms
^C
--- 192.168.2.159 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2005ms
rtt min/avg/max/mdev = 0.309/0.443/0.662/0.157 ms
#对端测试
┌──(root💀kali)-[~]
└─# ping 192.168.2.169
PING 192.168.2.169 (192.168.2.169) 56(84) bytes of data.
From 192.168.2.169 icmp_seq=1 Destination Port Unreachable
From 192.168.2.169 icmp_seq=2 Destination Port Unreachable
From 192.168.2.169 icmp_seq=3 Destination Port Unreachable
^C
--- 192.168.2.169 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2055ms
效果达到。
5.总结
通过以上对于iptables的学习,我们知道了对于主机数据包过滤的一种强力的解决方案。
要掌握好iptables就需要理解五链四表、规则的概念。链是基于netilter这款内核模块提供的五个挂载点(prerouting、postrouting、input、output、fword)而提供的应用层概念。理解的白话一点就是主机上的五种数据流经方向。那么每个连都会对应一套完整的匹配规则,规则从上到下按顺序匹配,同时配置有一套默认规则用于处理"漏网之鱼"。而规则过于繁多并且种类不一,为了对其进行统一管理,便有了我们的四表用于对规则进行集中分类。且不同的分类具有不同的优先级,其优先级依次是:raw→mangle→nat→filter 。但是我们在日常使用中更加侧重于filter表的使用,以达到准入控制和数据过滤的作用。
然后就是对于iptables的基本操作包括记录的增删改查,防火墙备份还原,以及对于其一些扩展功能的实现。
在安全学习中,十分有用的几个模块有iprangle用于范围封堵、string用于关键字过滤、connlimit用于扫描器过滤、limit用于反制dos攻击、当然,tcp的扩展可以用于对扫描器的详细过滤。
以上就是iptabes的基础内容了。