1. 概念
1.1 iptables是什么?
iptables 其实不是真正的防火墙,只是用户通过iptables将特定的规则设置到对应的安全框架中,这个框架的名字叫 netfilter。
Netfilter是 Linux 内核中进行数据包过滤,连接跟踪(Connect Track),网络地址转换(NAT)等功能的主要实现框架;该框架在网络协议栈处理数据包的关键流程中定义了一系列钩子点(Hook 点),并在这些钩子点中注册一系列函数对数据包进行处理。这些注册在钩子点的函数即为设置在网络协议栈内的数据包通行策略,换句话说就是,这些函数可以决定内核是接受还是丢弃某个数据包,函数的处理结果决定网络数据包的“命运”。
在用户态层面,根据不同的协议类型,为上层用户提供了不同的系统调用工具,比如我们常用的针对IPv4协议iptables,IPv6 协议的ip6tables,针对ARP协议的arptables,针对网桥控制的ebtables,针对网络连接追踪的conntrack等。
不同的用户态工具在内核中有对应的模块进行实现,而底层都需要调用 netfilter hook API 接口进行实现。同时也发现,之前提到的iptables,Linux防火墙工具其实也是 netfilter 框架中的一个组件。
从图中我们可以看到,Netfilter 框架采用模块化设计理念,并且贯穿了 Linux 系统的内核态和用户态。
1.2 iptables的作用?
- 连接追踪
- 网络地址转换
- 数据包内容修改
- 以及数据包过滤的防火墙功能
1.3 iptables基本概念
链:
防火墙的作用就在于对经过的报文匹配”规则”,然后执行对应的”动作”,所以,当报文经过这些关卡的时候,则必须匹配这个关卡上的规则,但是,这个关卡上可能不止有一条规则,而是有很多条规则,当我们把这些规则串到一个链条上的时候,就形成了 "链"。
表:
我们把具有相同功能的规则的集合叫做 "表"。
1.3.1 数据包经过防火墙流程
1.3.2 四种表的作用
表名 | 作用 | 对应模块 |
filter | 负责过滤功能 | iptables_filter |
nat | 网络地址转换功能 | iptables_nat |
mangle | 拆解报文,修改,重新封装 | iptables_mangle |
raw | 关闭nat表上启用的连接追踪机制 | iptables_raw |
1.3.3 链到表的对应关系
规则链 | 可存放的表 | 说明 |
PREROUTING | raw,mangle,nat | |
INPUT | mangle,filter | centos7中还有nat表,centos6中没有 |
FORWARD | mangle,filter | |
OUTPUT | raw,mangle,nat,filter | |
POSTROUTING | mangle,nat |
1.3.4 表到链的对应关系
表名 | 规则链 | 说明 |
raw | PREROUTING,OUTPUT | |
mangle | 任意链 | |
nat | PREROUTING,OUTPUT,POSTROUTING | centos7中还有INPUT,centos6中没有) |
filter | INPUT,FORWARD,OUTPUT |
1.3.5 表的优先级
当4张 "表" 处于听一条 "链" 的时候,执行的优先级如下:
raw -> mangle -> nat -> filter
1.3.6 规则的概念
规则:
根据指定的匹配条件来尝试匹配每个包流经此处的报文,一旦匹配成功,则由规则后面指定的处理动作进行处理。
1.3.7 常用处理动作
处理动作在iptables中被称为target(这样说并不准确,我们暂且这样称呼),动作也可以分为基本动作和扩展动作。
此处列出一些常用的动作,之后的文章会对它们进行详细的示例与总结:
ACCEPT:允许数据包通过。
DROP:直接丢弃数据包,不给任何回应信息,这时候客户端会感觉自己的请求泥牛入海了,过了超时时间才会有反应。
REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息。
SNAT:源地址转换,解决内网用户用同一个公网地址上网的问题。
MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip上。
DNAT:目标地址转换。
REDIRECT:在本机做端口映射。
LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配。
2. 规则查询
iptables为我们预定义了4张表,它们分别是raw表、mangle表、nat表、filter表,不同的表拥有不同的功能。
在实际操作iptables的过程中,是以”表”作为操作入口的,下面我们就结合具体命令,和返回结果来学习如何查看iptables规则。
2.1 字段的含义
字段名 | 含义 | |
pkts | 对应规则匹配到的报文的个数 | |
bytes | 对应匹配到的报文包的大小总和 | |
target | 表示规则对应的”动作” | |
prot | 表示规则对应的协议 | |
opt | 表示规则对应的选项 | |
in | 表示数据包由哪个接口(网卡)流入 | |
out | 表示数据包将由哪个接口(网卡)流出 | |
source | 表示规则对应的源头地址 | |
destination | 表示规则对应的目标地址 |
2.2 查询命令
查看iptables规则命令:
iptables -t 表名 -nvL
查看所有表规则,并且显示规则的序号:
iptables --line-numbers -t 表名 -L
参数介绍:
-t 选项指定要操作的表,省略”-t 表名”时,默认表示操作filter表。
-L 表示列出规则,即查看规则。
-v 表示显示更详细的信息(更多字段)。
–line-numbers 表示显示规则的序号。
3. 规则管理
下面我们再来了解一下,iptables规则的增删改等命令。
3.1 添加规则
- 在指定表的指定链的尾部添加一条规则
示例:iptables -t filter -A INPUT -s 192.168.1.146 -j DROP
- 在指定表的指定链的首部添加一条规则
示例:iptables -t filter -I INPUT -s 192.168.1.146 -j ACCEPT
- 在指定表的指定链的指定位置添加一条规则
示例:iptables -t filter -I INPUT 5 -s 192.168.1.146 -j DROP
注意:
添加规则时,规则的顺序非常重要。
3.2 修改规则
使用-R选项时要同时指定对应的链以及规则对应的序号,并且规则中原本的匹配条件不可省略。
命令语法:iptables -t 表名 -R 链名 规则序号 规则原本的匹配条件 -j 动作
示例:iptables -t filter -R INPUT 3 -s 192.168.1.146 -j ACCEPT
注意:
如果使用-R选项修改规则中的动作,那么必须指明原规则中的原匹配条件。
3.3 删除规则
- 按照规则序号删除规则
示例:iptables -t filter -D INPUT 3
- 按照具体匹配条件与动作删除规则
示例:iptables -t filter -D INPUT -s 192.168.1.146 -j DROP
- 删除指定表的所有规则
示例:iptables -t filter -F
- 删除指定表指定链的所有规则
示例:iptables -t filter -F INPUT
注意:
如果没有保存规则,删除规则时请慎重。
3.4 保存规则
使用如下方法保存规则 : iptables-save > /etc/sysconfig/iptables
从指定的文件载入规则 : iptables-restore < /etc/sysconfig/iptables
4. 匹配规则条件总结
4.1 基本匹配条件
匹配选项 | 示例 | 说明 |
-s | iptables -t filter -I INPUT -s 192.168.1.111,192.168.1.118 -j DROP iptables -t filter -I INPUT -s 192.168.1.0/24 -j ACCEPT iptables -t filter -I INPUT ! -s 192.168.1.0/24 -j ACCEPT | 用于匹配报文的源地址,可以同时指定多个源地址,每个IP之间用逗号隔开,也可以指定为一个网段。 |
-d | iptables -t filter -I INPUT -d 192.168.1.111,192.168.1.118 -j DROP iptables -t filter -I INPUT -d 192.168.1.0/24 -j ACCEPT iptables -t filter -I INPUT ! -d 192.168.1.0/24 -j ACCEPT | 用于匹配报文的目标地址,可以同时指定多个目标地址,每个IP之间用逗号隔开,也可以指定为一个网段。 |
-p | iptables -t filter -I INPUT -p tcp -s 192.168.1.146 -j ACCEPT iptables -t filter -I INPUT ! -p udp -s 192.168.1.146 -j ACCEPT | 用于匹配报文的协议类型,可以匹配的协议类型tcp、udp、udplite、icmp、esp、ah、sctp等(centos7中还支持icmpv6、mh) |
-i | iptables -t filter -I INPUT -p icmp -i eth4 -j DROP iptables -t filter -I INPUT -p icmp ! -i eth4 -j DROP | 用于匹配报文是从哪个网卡接口流入本机的,由于匹配条件只是用于匹配报文流入的网卡,所以在OUTPUT链与POSTROUTING链中不能使用此选项。 |
-0 | iptables -t filter -I OUTPUT -p icmp -o eth4 -j DROP iptables -t filter -I OUTPUT -p icmp ! -o eth4 -j DROP | 用于匹配报文将要从哪个网卡接口流出本机,于匹配条件只是用于匹配报文流出的网卡,所以在INPUT链与PREROUTING链中不能使用此选项。 |
4.2 拓展匹配条件
匹配选项 | 示例 |
tcp扩展模块 | 作用:连续的端口范围 -p tcp -m tcp –sport: 用于匹配tcp协议报文的源端口,可以使用冒号指定一个连续的端口范围 -p tcp -m tcp –dport: 用于匹配tcp协议报文的目标端口,可以使用冒号指定一个连续的端口范围 |
示例: iptables -t filter -I INPUT -d 192.168.1.146 -p tcp -m tcp --sport 22 -j REJECT iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport 22:25 -j REJECT iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport :22 -j REJECT iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport 80: -j REJECT | |
作用:匹配报文的tcp头的标志位 –tcp-flags -syn | |
示例: iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN -j REJECT iptables -t filter -I OUTPUT -p tcp -m tcp --sport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN,ACK -j REJECT iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags ALL SYN -j REJECT iptables -t filter -I OUTPUT -p tcp -m tcp --sport 22 --tcp-flags ALL SYN,ACK -j REJECT iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --syn -j REJECT | |
multiport扩展模块 | 作用:不连续的端口 -p tcp -m multiport –sports: 用于匹配报文的源端口,可以指定离散的多个端口号,端口之间用”逗号”隔开 -p udp -m multiport –dports: 用于匹配报文的目标端口,可以指定离散的多个端口号,端口之间用”逗号”隔开 |
示例: iptables -t filter -I INPUT -d 192.168.1.146 -p udp -m multiport --sports 137,138 -j REJECT iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 80:88 -j REJECT iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 22,80:88 -j REJECT | |
iprange扩展模块 | 作用:连续的IP地址 –src-range :源地址IP范围 –dst-range :目的地址IP范围 |
示例: iptables -t filter -I INPUT -m iprange --src-range 192.168.1.127-192.168.1.146 -j DROP | |
string扩展模块 | 作用: –algo:指定对应的匹配算法,可用算法为bm、kmp,此选项为必需选项。 –string:指定需要匹配的字符串 |
示例: iptables -t filter -I INPUT -p tcp --sport 80 -m string --algo bm --string "OOXX" -j REJECT iptables -t filter -I INPUT -p tcp --sport 80 -m string --algo bm --string "OOXX" -j REJECT | |
time扩展模块 | 作用: –timestart:用于指定时间范围的开始时间,不可取反 –timestop:用于指定时间范围的结束时间,不可取反 –weekdays:用于指定”星期几”,可取反 –monthdays:用于指定”几号”,可取反 –datestart:用于指定日期范围的开始日期,不可取反 –datestop:用于指定日期范围的结束时间,不可取反 |
示例: 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 | |
connlimit拓展模块 | 作用: –connlimit-above:单独使用此选项时,表示限制每个IP的链接数量。 –connlimit-mask:此选项不能单独使用,在使用–connlimit-above选项时,配合此选项,则可以针对”某类IP段内的一定数量的IP”进行连接数量的限制。 |
示例: 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 | |
limit拓展模块 | 作用: –limit-burst:类比”令牌桶”算法,此选项用于指定令牌桶中令牌的最大数量,上文中已经详细的描述了” 令牌桶”的概念,方便回顾。 –limit:类比”令牌桶”算法,此选项用于指定令牌桶中生成新令牌的频率, 可用时间单位有second、minute 、hour、day。 |
示例: 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. (UDP & ICMP)拓展
匹配选项 | 示例 |
udp扩展模块 | 作用:连续的端口范围 –sport:匹配udp报文的源地址 –dport:匹配udp报文的目标地址 |
示例: 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 | |
icmp扩展模块 | 作用: –icmp-type:匹配icmp报文的具体类型 |
示例: 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 |
6. 链接追踪
概念:
iptables 使用stat模块可实现“连接追踪”机制。
连接追踪,即对数据包的连接进行记录,被记录后的链接不用每次都匹配iptables,从而提高效率。
优点:
- 端口安全,连接追踪功能可以只放行回应我们的数据包。
- 提高效率,不用每个包都匹配iptables规则
使用方法:
iptables -I INPUT -m state --state RELATED,ESTABLISHERD
报文状态 | 解释 |
NEW | 连接中的第一个包,状态就是NEW,我们可以理解为新连接的第一个包的状态为NEW。 |
ESTABLISHED | 我们可以把NEW状态包后面的包的状态理解为ESTABLISHED,表示连接已建立。 |
RELATED | 详细解释看下文。 |
INVALID | 如果一个包没有办法被识别,或者这个包没有任何状态,那么这个包的状态就是INVALID,我们可以主动屏蔽状态为INVALID的报文。 |
UNTRACKED | 报文的状态为untracked时,表示报文未被追踪,当报文的状态为Untracked时通常表示无法找到相关的连接。 |
RELATED 状态解释:
RELATED:从字面上理解RELATED译为关系,但是这样仍然不容易理解,我们举个例子。
比如FTP服务,FTP服务端会建立两个进程,一个命令进程,一个数据进程。
命令进程负责服务端与客户端之间的命令传输(我们可以把这个传输过程理解成state中所谓的一个”连接”,暂称为”命令连接”)。
数据进程负责服务端与客户端之间的数据传输 ( 我们把这个过程暂称为”数据连接” )。
但是具体传输哪些数据,是由命令去控制的,所以,”数据连接”中的报文与”命令连接”是有”关系”的。
那么,”数据连接”中的报文可能就是RELATED状态,因为这些报文与”命令连接”中的报文有关系。
(注:如果想要对ftp进行连接追踪,需要单独加载对应的内核模块nf_conntrack_ftp,如果想要自动加载,可以配置/etc/sysconfig/iptables-config文件)
7. 黑白名单机制
将INPUT链的默认策略设置为DROP,默认拒绝所有报文,只放行特定的报文。 (白名单)
iptables -P INPUT DROP
8. 自定义链
iptables 自带的默认链虽然已经可以满足我们的需要了,但是如果我们有很多条规则的时候,管理起来就很不方便。
我们可以根据不同的任务创建不同的自定义链,便于分开管理。
使用方法:
创建一个自定义链:
iptables -t filter -N IN_WEB
在自定义链中添加规则:
iptables -t filter -I IN_WEB -s 192.168.1.139 -j DROP
在默认的链中引用自定义链
iptables -I INPUT -p tcp --dport 80 -j IN_WEB
9. 网络防火墙
#如果想要iptables作为网络防火墙,iptables所在主机开启核心转发功能,以便能够转发报文。
#使用如下命令查看当前主机是否已经开启了核心转发,0表示未开启,1表示已开启 cat /proc/sys/net/ipv4/ip_forward
#使用如下两种方法均可临时开启核心转发,立即生效,但是重启网络配置后会失效。
方法一:echo 1 > /proc/sys/net/ipv4/ip_forward
方法二:sysctl -w net.ipv4.ip_forward=1
#使用如下方法开启核心转发功能,重启网络服务后永久生效。 配置/etc/sysctl.conf文件
(centos7中配置/usr/lib/sysctl.d/00-system.conf文件),在配置文件中将 net.ipv4.ip_forward设置为1
#由于iptables此时的角色为"网络防火墙",所以需要在filter表中的FORWARD链中设置规则。
#可以使用"白名单机制",先添加一条默认拒绝的规则,然后再为需要放行的报文设置规则。
#配置规则时需要考虑"方向问题",针对请求报文与回应报文,考虑报文的源地址与目标地址,源端口与目标端口等。
#示例为允许网络内主机访问网络外主机的web服务与sshd服务。
iptables -A FORWARD -j REJECT iptables -I FORWARD -s 10.1.0.0/16 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -d 10.1.0.0/16 -p tcp --sport 80 -j ACCEPT
iptables -I FORWARD -s 10.1.0.0/16 -p tcp --dport 22 -j ACCEPT
iptables -I FORWARD -d 10.1.0.0/16 -p tcp --sport 22 -j ACCEPT
#可以使用state扩展模块,对上述规则进行优化,使用如下配置可以省略许多"回应报文放行规则"。
iptables -A FORWARD -j REJECT
iptables -I FORWARD -s 10.1.0.0/16 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -s 10.1.0.0/16 -p tcp --dport 22 -j ACCEPT
iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
10. 动作总结
动作,就是iptables规则匹配到数据包后应该干什么。
最常见的动作有ACCEPT、DROP、REJECT等。其实动作也有对应的选项。
10.1 动作REJECT
使用–reject-with选项,可以设置提示信息,当对方被拒绝时,会提示对方为什么被拒绝。
示例:iptables -I INPUT 2 -j REJECT --reject-with icmp-host-unreachable
当不设置任何值时,默认值为icmp-port-unreachable。
选项 | 提示 | 说明 |
icmp-net-unreachable | ||
icmp-host-unreachable | ||
icmp-port-unreachable | ||
icmp-proto-unreachable | ||
icmp-net-prohibited | ||
icmp-host-pro-hibited | ||
icmp-admin-prohibited |
10.2 动作LOG
使用LOG动作,可以将符合条件的报文的相关信息记录到日志中,但当前报文具体是被”接受”,还是被”拒绝”,都由后面的规则控制,换句话说,LOG动作只负责记录匹配到的报文的相关信息,不负责对报文的其他处理,如果想要对报文进行进一步的处理,可以在之后设置具体规则,进行进一步的处理。
LOG动作也有自己的选项:
-log-level 选项,可以指定日志级别,可用级别有emerg,alert,crit,error,warning,notice,info,debug。
-log-prefix 选项, 可以给记录到的相关信息添加”标签”之类的信息,以便区分各种记录到的报文信息。
示例:
iptables -I FORWARD -p tcp --dport 22 -m state --state NEW -j LOG --log-level 7 --log-prefix "LINKLOG"
10.3 动作SNAT
配置SNAT,可以隐藏网内主机的IP地址,也可以共享公网IP,访问互联网,如果只是共享IP的话,只配置如下SNAT规则即可。
示例:
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 公网IP
10.4 动作DNAT
配置DNAT,可以通过公网IP访问局域网内的服务。
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 公网端口 -j DNAT --to-destination 私网IP:端口号
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 8080 -j DNAT --to-destination 10.1.0.1:80
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 公网IP
10.5 动作MASQUERADE
如果公网IP是动态获取的,不是固定的,则可以使用MASQUERADE进行动态的SNAT操作,如下命令表示将10.1网段的报文的源IP修改为eth0网卡中可用的地址。
示例:
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE
10.6 动作REDIRECT
在本机进行目标端口映射时可以使用REDIRECT动作。
示例:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
配置完成上述规则后,其他机器访问本机的80端口时,会被映射到8080端口。
内容主要参考朱双印老师写的,自行记录方便查阅。