目录

  1. 相关概念
    1. 防火墙
  2. netfilter/iptables
  3. iptables基础
    1. 规则
      1. 匹配条件
      2. 处理动作
    2. 链和表的关系
    3. 数据经过防火墙的流程
  4. iptables命令
    1. 查看对应表的规则
    2. 查看指定表的指定链的规则
      1. 显示IP地址
      2. 显示行号
      3. 精确计数
    3. 增加规则
      1. 插入规则
      2. 追加规则
    4. 删除规则
      1. 根据规则的编号删除规则
      2. 根据具体匹配条件与动作删除规则
    5. 修改规则
      1. 指定默认策略
    6. 保存规则
    7. 规则匹配
      1. 源地址
      2. 目的地址
      3. 协议类型
      4. 网卡接口
      5. 扩展匹配
        1. tcp
        2. –tcp-flags
        3. multiport
        4. iprange
        5. string
        6. time
        7. connlimit
        8. limit

相关概念

防火墙

从逻辑上讲。 防火墙可以分为主机防火墙和网络防火墙。

  • 主机防火墙:主要针对单个主机进行防护。

  • 网络防火墙:往往处于网络入口边缘,针对网络入口进行防护,服务于防火墙背后的本地局域网。

网络防火墙和主机防火墙并不冲突,可以理解为,网络防火墙主外(集体),主机防火墙主内(个人)。

从物理上讲,防火墙可以分为硬件防火墙和软件防火墙。

  • 硬件防火墙:在硬件级别实现部分防火墙功能,另一部分功能基于软件实现,性能高,成本高。
  • 软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙,性能低,成本低。

netfilter/iptables

iptables不是真正的防火墙,我们可以把它理解为一个客户端代理,用户通过iptables,将用户的安全设定执行到对应的“安全框架”中,这个“安全框架”才是真正的防火墙,这个框架的名字叫netfilter。

netfilter才是防火墙真正的安全框架(framework),netfilter位于内核空间。
iptables其实是一个命令行工具,位于用户空间,我们用这个工具操作真正的框架。

netfilter/iptables(下文中简称iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火墙解决方案,完成包过滤、封包重定向和网络地址转换(NAT)等功能。

netfilter是Linux操作系统核心层内部的一个数据包处理模块。它具有以下功能:

  1. 网络地址转换(Network Address Translate)。
  2. 数据包内容修改。
  3. 数据包过滤的防火墙功能。

iptables基础

规则

iptables是按照规则办事的。规则(rule)就是网络管理员预定义的条件,规则一般定义为“如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTP和SMTP)等。
当数据包与规则匹配时,iptables就会根据规则所定义的方法来处理这些数据包,如放行(accept)、拒绝(reject)和丢弃(drop)等。配置防火墙的主要工作就是添加、修改和删除这些规则。

当客户端访问服务器的web服务时,客户端发送报文到网卡,而tcp/ip协议栈是属于内核的一部分,所以,客户端的信息会通过内核的TCP协议传输到用户空间中的web服务中,而此时,客户端报文的目标终点为web服务所监听的套接字(IP:Port)上,当web服务需要响应客户端请求时,web服务发出的响应报文的目标终点则为客户端。这个时候,web服务所监听的IP与端口发而变成了原点,netfilter才是真正的防火墙,它是内核的一部分,所以,如果我们想要防火墙起作用,则需要在内核中设置关卡,所有进出的报文都必须通过这些关卡,经过检查后,符合放行条件的才能放行,符合阻拦条件的则需要被阻拦,于是就出现了input关卡和output关卡,而这些关卡在iptables中称为“链”。


报文的流向:
到达本机某进程的报文:prerouting -> input。
由本机转发的报文:prerouting -> forward -> postrouting。
由本机的某进程发出的报文(通常为响应报文):output -> postrouting。

匹配条件

匹配条件分为基本匹配条件与扩展匹配条件。

  • 基本匹配条件:源地址Source IP,目标地址 Destination IP。
  • 扩展匹配条件:源端口 Source Port,目标端口 Destination Port。

处理动作

  • accept:允许数据包通过。
  • drop:直接丢弃数据包,不给任何回应消息。
  • reject:拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息。
  • snat:源地址转换,解决内网用户用同一个公网地址上网的问题。
  • masquerade:是snat的一种特殊形式,适用于动态的、临时会变的ip上。
  • dnat:目标地址转换。
  • redirect:在本机做端口映射。
  • log:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是除了记录以外不对数据包做任何操作,仍然让下一条规则去匹配。

多个规则形成链。

链

把具有相同功能的规则的集合叫做“表”,所以,不同功能的规则,我们可以放置在不同的表中进行管理。
iptables为我们定义了4种表。

  • filter表: 负责过滤功能,防火墙;内核模块:iptables_filter。
  • nat表:network address translation,网络地址转换功能;内核模块:iptable_nat。
  • mangle表:拆解报文,做出修改,并重新封装;iptable_mangle。
  • raw表:关闭nat表启用的连接追踪机制;iptable_raw。

链和表的关系

每个链中的规则都存在哪些表。
prerouting的规则可以存在于:raw表、mangle表、nat表。
input的规则可以存在于:mangle表、filter表。
forward的规则可以存在于:mangle表、filter表。
output的规则可以存在于:raw表、mangle表、nat表、filter表。
postrouting的规则可以存在于:mangle表、nat表。

链中规则的执行优先级:
raw表 > mangle表 > nat表 > filter表


表

数据经过防火墙的流程

iptables命令

查看对应表的规则

1
iptables -t [表名] -L

-t,指定要操作的表;省略“-t”时,默认操作filter表。
-L,表示列出规则。

查看指定表的指定链的规则

1
iptables -t [表名] -L [链名]

查看filter表中INPUT链的规则

1
iptables -vL INPUT

-v,查看详细信息。

pkts:对应规则匹配到的报文个数。
bytes:对应匹配到报文包的大小总和。
target:规则对应的target,往往表示对应的“动作”,即规则匹配完成后需要采取的措施。
prot:表示规则对应的协议,是否只针对某些协议应用此规则。
opt:表示规则对应的选项。
in:表示数据包由哪个接口(网卡)流入,我们可以设置通过哪块网卡流入的报文需要匹配当前规则。
out:表示数据包由哪个接口(网卡)流出,我们可以设置通过哪块网卡流出的报文需要匹配当前规则。
source:表示规则对应的源头地址。可以是一个IP,也可以是一个网段。
destination:表示规则对应的目的地址。可以是一个IP,也可以是一个网段。

显示IP地址

1
iptables -nvL INPUT

-n,表示不对IP地址进行名称反解,直接显示IP地址。

显示行号

1
iptables -nvL INPUT --line-numbers

–line-numbers,显示行号。

(policy ACCEPT 26381 packets, 2993K bytes)
policy ACCEPT表示图中INPUT的链的默认动作为ACCEPT。默认接收通过INPUT的所请求。
packets表示当前链默认策略匹配到的包的数量。
bytes表示当前链默认策略匹配到的所有的包的大小总和。

精确计数

1
iptables -nvxL INPUT

-x,精确计数。

增加规则

主机A的IP地址为:10.211.55.11
主机B的IP地址为:10.211.55.2

插入规则

给主机A的filter表的INPUT链插入一条规则,拒绝接受所有从主机B发送的数据。

1
iptables -t filter -I [行号] INPUT -s 10.211.55.2 -j DROP

-t,指定表;不使用-t时,默认操作filter表。
-I,表示插入到哪条链。(默认第一个,有行号n的话,插入第n行)
-s,指明匹配条件的源地址。
-j,表示当匹配条件被满足时,所对应的动作。(DROP 丢弃)

ping测试,没有通过,规则起作用。

追加规则

给主机A的filter表的INPUT链追加一条规则,接受所有从主机B发送的数据。

1
iptables -t filter -A INPUT -s 10.211.55.2 -j ACCEPT

-t,指定表;不使用-t时,默认操作filter表。
-A,表示追加到哪条链。(最后一个)
-s,指明匹配条件的源地址。
-j,表示当匹配条件被满足时,所对应的动作。(ACCEPT 接受)

ping测试,依旧没有通过,规则没有起作用。

给主机A的filter表的INPUT链插入一条规则,接受所有从主机B发送的数据。

1
iptables -t filter -I INPUT -s 10.211.55.2 -j ACCEPT

ping测试,通过,规则起作用。

规则的顺序很重要,如果报文被前面的规则匹配到,iptables则会对报文执行对应的动作,即使后面的规则也能匹配到当前的报文,也没有机会对报文执行相应的动作。

删除规则

根据规则的编号删除规则

查看filter表中INPUT链中的规则。

1
iptables --line -vnL INPUT

删除第3条规则。

1
iptables -D INPUT 3

-D,表示删除指定链中的某条规则。

根据具体匹配条件与动作删除规则

删除源地址为10.211.55.2,动作为ACCEPT的规则。

1
iptables -D INPUT -s 10.211.55.2 -j ACCEPT

删除指定表中的所有规则。

1
iptables -t [表名] -F

修改规则

修改规则中的动作从DROP改为REJECT。

1
iptables -t filter -R INPUT 1 -s 10.211.55.2 -j REJECT

-R INPUT 1,表示修改INPUT链中的第1条规则。

必须指定源地址,否则修改规则中的源地址会自动变为0.0.0.0/0(此IP表示匹配所有网段的IP地址)。

ping测试。

指定默认策略

修改filter表INPUT链中的默认规则,从ACCEPT改为DROP。

1
iptables -t filter -P INPUT DROP

-P INPUT DROP,将表中INPUT链的默认策略改为DROP。

保存规则

1
iptables-save

规则匹配

源地址

1
2
iptables -t filter -I INPUT -s 192.168.1.111,192.168.1.112 -j DROP
iptables -t filter -I INPUT -s 192.168.1.0/24 -j DROP

-s,用于匹配报文的源地址,可以同时指定多个源地址,每个IP地址用逗号隔开,也可以指定一个网段。

1
iptables -t filter -I INPUT ! -s 192.168.1.0/24 -j ACCEPT

!,用于匹配条件取反。
上面的规则匹配的是,只要源地址不是192.168.1.0/24网段的就会执行接受动作。

目的地址

1
2
iptables -t filter -I INPUT -d 192.168.1.111,192.168.1.112 -j DROP
iptables -t filter -I INPUT -d 192.168.1.0/24 -j DROP

-d,用于匹配报文的目的地址,可以同时指定多个目的地址,每个IP地址用逗号隔开,也可以指定一个网段。

协议类型

1
2
iptables -t filter -I INPUT -p tcp -s 192.168.1.111,192.168.1.112 -j DROP
iptables -t filter -I INPUT -p udp -s 192.168.1.0/24 -j DROP

-p,用于匹配报文的协议类型,可以匹配的协议类型tcp、udp、udplite、icmp、esp、ah、sctp等。

网卡接口

1
iptables -t filter -I INPUT -p icmp -i enth4 -j DROP

-i,用于匹配报文要从哪个网卡接口流入本机。由于匹配条件只是用于匹配报文流入的网卡,所以在OUTPUT链与POSTROUTING链中不能使用此选项。

1
iptables -t filter -I INPUT -p icmp -O enth4 -j DROP

-o,用于匹配报文要从哪个网卡接口流出本机。由于匹配条件只是用于匹配报文流入的网卡,所以在INPUT链与PREROUTING链中不能使用此选项。

扩展匹配

tcp

1
iptables -t filter -I OUTPUT -d 192.168.1.111 -p tcp -m tcp --sport 22 -j REJECT

-p,指定协议。
-m,指定扩展模块。
–sport,source-port,指定源端口。

1
iptables -t filter -I INPUT -s 192.168.1.111 -p tcp -m tcp --dport 22:25 -j REJECT

-p,指定协议。
-m,指定扩展模块。
–dport,destination-port,指定目的端口。
22:25,表示22、23、24、25端口。

1
iptables -t filter -I INPUT -s 192.168.1.111 -p tcp -m tcp --dport 80: -j REJECT

80:,表示80端口到之后的所有的端口(直到65535)。

1
iptables -t filter -I INPUT -s 192.168.1.111 -p tcp -m tcp --dport :22 -j REJECT

:22,表示从0端口到22端口。

–tcp-flags

–tcp-flags,指的就是tcp头中的标志位,可以匹配tcp报文的头部的标志位,然后根据标识位的实际情况实现访问控制的功能。

1
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN -j REJECT

匹配到第一次握手的报文。

1
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN,ACK -j REJECT

匹配到第二次握手的报文。

还可以用ALL表示SYN,ACK,FIN,RST,URG,PSH。

1
2
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags ALL SYN -j REJECT
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags ALL SYN,ACK -j REJECT

–syn选项,匹配tcp第一次握手。

1
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --syn -j REJECT

multiport

tcp模块中的–sport或者–dport可以指定一个连续的端口范围,但是无法同时指定多个离散的、不连续的端口。

multiport模块中的–sports扩展条件可以同时指定多个离散的源端口。
multiport模块中的–dports扩展条件可以同时指定多个离散的目的端口。

1
iptables -t filter -I INPUT -s 192.168.1.111 -p tcp -m multiport --dport 22,36,80 -j DROP

multiport模块只能用于tcp协议和udp协议,配合-p tcp或者-p udp使用。

iprange

在不使用任何扩展模块下,可以使用-s或者-d即匹配报文的源地址和目的地址,而且在指定IP地址时,可以同时指定多个IP地址,每个IP地址之间用逗号隔开;但是,-s或者-d选项不能一次性地指定一段连续的IP地址范围。

iprange可以指定一段连续的IP地址范围。

1
2
iptables -t filter -I INPUT -m iprange --src-range 192.168.1.111-192.168.1.146 -j DROP
iptables -t filter -I INPUT -m iprange --dst-range 192.168.1.111-192.168.1.146 -j DROP

–src-range,源地址范围。
–dst-range,目的地址范围。

string

string扩展模块,可以指定要匹配的字符串,如果报文中包含对应的字符串,则符合匹配规则。

1
iptables -t filter -I INPUT -m string --algo bm --string "Hello World" -j ACCEPT

–algo,用于指定匹配算法,可选算法有bm和kmp,必须选项,所以不用纠结选择哪个算法,但是必须指定一个。
–string,用于指定需要匹配的字符串。

time

time扩展模块,可以根据时间段匹配报文,如果报文到达的时间在规定时间范围以内,则符合匹配条件。

1
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --timestart 09:00:00 --timestop 18:00:00 -j REJECT

–timestart,指定开始时间。
–timestop,指定结束时间。

1
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --weekdays 6,7 -j REJECT

–weekdays,指定每个星期的具体哪一天,可以同时指定多个,用逗号隔开。

1
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --monthdays 22,23 -j REJECT

–monthdays,指定每个月的哪一天。

1
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --datestart 2018-12-01 --datestop 2018-12-25 -j REJECT

–datestart,日期开始。
–datestop,日期结束。

–weekdays和–monthdays可以使用“!”取反,其他选项不可以。

connlimit

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

1
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT

–conlimit-above 2,表示限制每个IP的链接数量上限为2。
-p tcp –dport 22,限制每个客户端IP的ssh并发链接数量不能高于2。

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

–connlimit-mask 24,表示某个C类网段。mask表示掩码;24转换成点分十进制就是255.255.255.0。
所以,上面的规则表示,一个最多包含254个IP的C类网络中,同时最多只能有2个ssh客户端连接到当前服务器。

limit

limit扩展模块,可以对报文到达的速率进行限制(限制单位时间内流入的包的数量)。

1
iptables -t filter -I INPUT -p icmp -m limit 10/minute -j ACCEPT

–limit 10/minute -j ACCEPT,表示每分钟最多放行10个包,相当于每6秒最多放行一个包。

ping测试。

配置的规则没有起作用,ping请求的速率完全没有发生任何变化。
这是因为,上面的规则每6秒放行一个包,那么iptables就会计时,每6秒一个轮次,到第6秒时,到达的报文就会匹配到对应的规则,执行ACCEPT。
那么,在第6秒之前到达的包,则无法被上述规则匹配到。
之前总结过,报文会匹配链中的每条规则,如果没有任何一条规则匹配到,则匹配默认动作(链的默认策略)。INPUT链的默认策略是ACCEPT。

我们有两种方法修改。一是,修改INPUT链的默认策略;二是,再增加一条规则。

1
iptables -t filter -A INPUT -p icmp -j REJECT

ping测试。

前5个ping包没有受到限制,之后的ping包已经开始受到规则的限制。

limit模块采用令牌桶算法。
上面的情况可以这样想象,有一个木桶,木桶里放了5块令牌,而且这个木桶最多也只能放下5块令牌,所有报文如果想要出关入关,必须要持有木桶中的令牌才行。这个木桶每隔6秒钟就会产生一块新的令牌,如果此时,木桶的令牌不足5块,那么新生成的令牌就会放在木桶中,超过5块,新生成的令牌就会被丢弃。如果此时有5个报文想要入关,那么这5个报文就会去木桶里找令牌,正好一人一个,快乐地入关了。此时木桶空了,再想有报文想要入关已经没有对应的令牌可以使用,只好等待6秒,新的令牌生成,报文拿着新生成的令牌入关。如果很长一段时间没有新的报文想要入关,木桶里的令牌又会慢慢积攒起来,直到到达5个令牌,直到有人使用它。

–limit,用于指定多长时间生成一个新的令牌。
–limit-brust,用于指定木桶中最多存放几个令牌。


上面的例子表示,令牌桶最多放3个令牌,每分钟生成10个令牌。

–limit,可以选择的时间单位有多种,如 /second、/minute、/hour、/day。