iptables与firewalld防火墙
众所周知,相较于企业内网,外部的公网环境更加恶劣,罪恶众生。在公网与内网之间充当保护屏障的防火墙虽然有软件和硬件之分,但主要功能都是依据策略对穿越防火墙的流量进行过滤。防火墙策略可以基于流量的源目地址、端口号、协议、应用等信息来定制,然后防火墙使用预先定制的策略监控出入的流量,若流量与某一条策略规则相匹配,则执行相应的处理,反之则丢弃。
在RHEL5/6系统中,使用的是iptables防火墙,而从RHEL7系统开始,firewalld防火墙正式取代了iptables防火墙。但其实iptables和firewalld都不是真正的防火墙,它们只是用来定义防火墙策略的防火墙管理工具而已,或者说,它们只是一种服务。
- iptables:iptables服务会把配置好的防火墙策略交由内核层面的netfilter网络过滤器来处理
- firewalld:firewalld服务会把配置好的防火墙策略交由内核层面的nftable包过滤框架来处理
两者各有优劣,但在防火墙策略的配置思路上是保持一致的。实际使用中可以任选一款将其学透,基本就可以满足日常的工作需求了。
iptables
四表五链
说起iptables,经常会说到四表五链,那究竟什么是表什么是链呢?
iptables由表(tables)、链(chains)和规则(rules)组成。在iptables的架构中,表是最高级别的组织单位,它们包含了不同的功能,如过滤(filter)、网络地址转换(NAT)、修改数据包(mangle)和原始数据包处理(raw)。每张表下包含多条链,这些链中又包含了多条规则,即具体的处理指令。简而言之,表是链的容器,而链是规则的容器。
规则(rules):规则是存储在内核空间的数据包过滤表中的预定义条件,规则指定了如何处理满足特定条件的数据包。规则包括一个或多个条件以及要采取的动作(target),如果满足条件,就执行对应的动作。防火墙会按照从上到下的顺序来读取配置的规则,在找到匹配项后就立即结束匹配工作并去执行匹配项中定义的动作。如果在读取完所有的规则之后都没有匹配项,就执行默认的动作
链(chains):iptables中的链包括INPUT、OUTPUT、FORWARD、PREROUTING和POSTROUTING。这些链会在数据包处理的不同阶段被调用,例如INPUT链负责处理流入的数据包,OUTPUT链负责处理流出的数据包,而FORWARD链则负责处理转发的数据包。
| 链 | 说明 |
|---|---|
| PREROUTING | 在进行路由选择前处理数据包 |
| INPUT | 处理流入的数据包 |
| OUTPUT | 处理流出的数据包 |
| FORWARD | 处理转发的数据包 |
| POSTROUTING | 在进行路由选择后处理数据包 |
- 表(tables):iptables支持四张内建表,filter、nat、mangle和raw。其中,filter表是默认表。用于一般的过滤功能,nat表用于网络地址转换,mangle表用于对特定数据包的修改,而raw表则用于设置不再让iptables做数据包的链接跟踪处理,以提高性能。
| 表 | 说明 | 包含链 |
|---|---|---|
| filter | 用于过滤数据包 | INPUT、FORWARD、OUTPUT |
| nat | 用于网络地址转换 | PREROUTING、POSTROUTING、OUTPUT |
| mangle | 用于修改数据包的服务类型、TTL、并且可以配置路由实现QOS内核模块 | PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD |
| raw | 决定数据包是否被状态跟踪机制处理 | OUTPUT、PREROUTING |


安装iptables
说明
CentOS6或更早版本中默认已安装iptables,在CentOS7/8中,如果要使用iptables,需要先安装并关闭firewalld防火墙
1 | systemctl stop firewalld |
命令详解
命令格式
iptables [-t 表名] [子命令] [链名] [条件] [-j 动作]
| 参数 | 说明 |
|---|---|
[-t 表名] |
指定表名,不指定默认为filter表 |
[子命令] |
定义对规则做何操作,例如添加规则、删除规则 |
[链名] |
指定要操作的链名,不指定默认指定表内的所有链 |
[条件] |
设置匹配标准 |
[-j 动作] |
指定处理动作,例如ACCEPT,DROP等 |
说明
[子命令]、[链名]、[动作]使用大写字母,其余使用小写字母
以下为常用子命令
| 子命令 | 说明 |
|---|---|
-P |
设置默认策略 |
-F |
清空规则链 |
-L |
查看规则链 |
-A |
在规则链的末尾加入新规则 |
-I chain [rulenum] |
在规则链的头部加入新规则 |
-D chain [rulenum] |
删除某一条规则 |
-n |
地址和端口的以数字形式输出 |
-v |
详细模式 |
--line-numbers |
查看规则时,同时显示规则在链中的序号 |
以下为常用的条件匹配参数
| 条件 | 说明 |
|---|---|
-s |
匹配来源地址IP/MASK,加叹号“!”表示除这个IP外 |
-d |
匹配目标地址 |
-i 网卡名称 |
匹配从这块网卡流入的数据 |
-o 网卡名称 |
匹配从这块网卡流出的数据 |
-p |
指定协议类型,例如:tcp、udp、icmp |
--dport num |
匹配目标端口号 |
--sport num |
匹配源端口号 |
-m |
用于提供更多的匹配参数,例如:-m state --state ESTABLISHED,RELATED-m tcp --dport 22-m multiport --dports 80,8080-m icmp --icmp-type 8 |
以下为常用的动作
| 动作 | 说明 |
|---|---|
ACCEPT |
允许数据包通过 |
DROP |
直接丢弃数据包,不给任何响应 |
REJECT |
拒绝数据包通过,并给数据发送端回复一条响应信息,客户端刚请求就会收到拒绝的信息 |
SNAT |
源地址转换,解决内网用户用同一个公网地址上网的问题 |
DNAT |
目标地址转换 |
MASQUERADE |
是SNAT的一种特殊形式,适用于动态的、临时会变的IP上 |
REDIRECT |
是DNAT的一种特殊形式,在本机做端口映射 |
LOG |
在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配 |
使用示例
实验1
查看已有的防火墙规则
1 | iptables -nvL |
实验2
清空已有的防火墙规则
1 | iptables -F |
实验3
把INPUT规则链的默认策略设置为拒绝
1 | iptables -P INPUT DROP |
说明
当规则链的默认策略为拒绝时,只能是DROP,不能是REJECT
实验4
向INPUT链中添加允许ICMP流量进入的策略规则
1 | iptables -I INPUT -p icmp -j ACCEPT |
实验5
删除INPUT规则链中刚刚加入的允许ICMP流量的策略(不要使用iptables -F清空所有策略),并把默认策略设置为允许
1 | # 方式一 |
实验6
将INPUT规则链设置为只允许指定网段的主机访问本机的22端口,拒绝来自其他所有主机的流量
1 | iptables -I INPUT -s 10.211.55.0/24 -p tcp --dport 22 -j ACCEPT |
实验7
向INPUT规则链中添加拒绝所有人访问本机8888端口的策略
1 | iptables -I INPUT -p tcp --dport 8888 -j REJECT |
实验8
向INPUT规则链中添加拒绝10.211.55.6主机访问本机80端口(WEB服务)的策略
1 | iptables -I INPUT -s 10.211.55.6/32 -p tcp --dport 80 -j REJECT |
实验9
向INPUT规则链中添加拒绝所有主机访问本机1000~1024端口的策略
1 | iptables -I INPUT -p tcp --dport 1000:1024 -j REJECT |
实验10
保存上述配置的所有策略,防止防火墙规则在系统下一次重启后失效
1 | service iptables save |
firewalld
firewalld是一个防火墙服务守护进程,其提供一个带有D-Bus接口的、动态可定制的、基于主机的防火墙。如果是动态的,它可在每次修改规则时启用、修改和删除规则,而不需要在每次修改规则时重启防火墙守护进程。
firewalld使用区和服务的概念来简化流量管理。zones是预定义的规则集,网络接口和源可以分配给区。允许的流量取决于您计算机连接到的网络,并分配了这个网络的安全级别。防火墙服务是预定义的规则,覆盖了允许特定服务进入流量的所有必要设置,并在区中应用。
服务使用一个或多个端口或地址进行网络通信。防火墙会根据端口过滤通讯。要允许服务的网络流量,必须打开其端口。firewalld会阻止未明确设置为打开的端口的所有流量。一些区(如可信区)默认允许所有流量。
说明
要防止不同的与防火墙相关的服务(firewalld、nftables或iptables)相互影响,请在主机上仅运行其中一个服务,并禁用其他服务。
区域和服务
firewalld区域包含了一组预定义的策略集合,用户可以根据生产场景的不同选择不同的策略集合,从而实现防火墙策略之间的快速切换。firewalld预定义了几个默认区域如下:
| 区域 | 默认规则策略 |
|---|---|
| trusted | 允许所有的数据包 |
| home | 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、mdns、ipp-client、smba-client、dhcpv6-client服务相关,则允许流量 |
| internal | 等同于home区域 |
| work | 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、dhcpv6-client服务相关,则允许流量 |
| public | 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、dhcpv6-client服务相关,则允许流量 |
| external | 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh服务相关,则允许流量 |
| dmz | 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh服务相关,则允许流量 |
| block | 拒绝流入的流量,除非与流出的流量相关 |
| drop | 拒绝流入的流量,除非与流出的流量相关 |
说明
/usr/lib/firewalld/zones/目录存储预定义的区域配置文件,文件采用以下格式命令:zone-name.xml,可以立即将它们应用到任何可用的网络接口。只有在修改后,这些文件才会被拷贝到/etc/firewalld/zones/目录中
firewalld服务是一组预定义的防火墙规则,其定义对特定应用程序或网络服务的访问。每个服务都代表了以下元素的组合:
- 本地端口
- 网络协议
- 关联的防火墙规则
- 源端口和目的地
- 启用服务时自动载入的防火墙帮助程序模块
firewalld服务可以简化数据包过滤,并节省时间,因为它会一次实现多个任务。例如firewalld一次可以执行以下任务:
- 打开端口
- 定义网络协议
- 启用数据包转发
服务配置选项和通用文件信息在firewalld.service (5)手册页中进行了描述。服务通过单独的XML配置文件来指定,这些文件采用以下格式命名:service-name.xml。
说明
/usr/lib/firewalld/services/目录存储预定义的服务配置文件,/etc/firewalld/services/目录存储自定义的服务配置文件
命令详解
命令格式
firewall-cmd [OPTIONS...]
firewall-cmd是firewalld防火墙配置管理工具的CLI版本(GUI版本为firewall-config)。它的参数一般都是以“长格式”来提供的。以下列举了常用的参数及其作用,更多参数说明可通过firewall-cmd --help获取
| 区域 | 默认规则策略 |
|---|---|
--get-default-zone |
查询默认的区域名称 |
--set-default-zone=<区域名称> |
设置默认的区域,使其永久生效 |
--get-zones |
显示可用的区域 |
--get-services |
显示预先定义的服务 |
--get-active-zones |
显示当前正在使用的区域与网卡名称 |
--add-source=<source>[/<mask>] |
将源自此IP或子网的流量导向指定的区域 |
--remove-source=<source>[/<mask>] |
不再将源自此IP或子网的流量导向某个指定区域 |
--add-interface=<网卡名称> |
将源自该网卡的所有流量都导向某个指定区域 |
--change-interface=<网卡名称> |
将某个网卡与区域进行关联 |
--list-all |
显示当前区域的网卡配置参数、资源、端口以及服务等信息 |
--list-all-zones |
显示所有区域的网卡配置参数、资源、端口以及服务等信息 |
--add-service=<服务名> |
设置默认区域允许该服务的流量 |
--add-port=<端口号/协议> |
设置默认区域允许该端口的流量 |
--remove-service=<服务名> |
设置默认区域不再允许该服务的流量 |
--remove-port=<端口号/协议> |
设置默认区域不再允许该端口的流量 |
--reload |
让“永久生效”的配置规则立即生效,并覆盖当前的配置规则 |
--panic-on |
开启应急状况模式 |
--panic-off |
关闭应急状况模式 |
与Linux系统中的其他防火墙策略配置工具一样,使用firewall-cmd配置的防火墙策略默认为运行时(Runtime)模式,又称为当前生效模式,会随着系统的重启而失效。如果想让配置策略一直存在,就需要使用永久(Permanent)模式了,方法就是在用firewall-cmd命令正常设置防火墙策略时添加--permanent参数,这样配置的防火墙策略就可以永久生效了。但是,永久模式有一个“不近人情”的特点,就是使用它设置的策略只有在系统重启之后才能自动生效。如果想让配置的策略立即生效,需要手动执行firewall-cmd --reload命令
说明
Runtime:当前立即生效,重启后失效。
Permanent:当前不生效,重启后生效。
使用示例
实验1
查看firewalld服务当前所使用的区域
1 | firewall-cmd --get-default-zone |
实验2
查看指定网卡在firewalld服务中绑定的区域
1 | firewall-cmd --get-zone-of-interface=eth0 |
实验3
把网卡默认区域修改为external,并在系统重启后生效
1 | firewall-cmd --zone=external --change-interface=eth0 --permanent |
实验4
把firewalld服务的默认区域设置为public
说明
默认区域也叫全局配置,指的是对所有网卡都生效的配置,优先级较低。如果当前默认区域为public,而eth0网卡的区域为external,此时便是以网卡的区域名称为准。
1 | firewall-cmd --set-default-zone=public |
实验5
启动和关闭firewalld防火墙服务的应急状况模式
说明
开启应急状况模式后会立即切断一切网络连接,因此在远程管理服务器时,在按下回车键前一定要三思
1 | firewall-cmd --panic-on |
实验6
查询SSH和HTTPS协议的流量是否允许放行
说明
firewall-cmd命令会自动依据默认区域进行查询,从而减少用户输入量。但是,如果默认区域与网卡所绑定的不一致时,就会发生冲突,因此规范写法的--zone参数是一定要加的。
1 | firewall-cmd --zone=public --query-service=ssh |
实验7
把HTTPS协议的流量设置为永久允许放行,并立即生效。
1 | firewall-cmd --zone=public --add-service=https --permanent |
实验8
把HTTP协议的流量设置为永久拒绝,并立即生效
1 | firewall-cmd --zone=public --remove-service=http --permanent |
实验9
把访问8080和8081端口的流量策略设置为允许,但仅限当前生效。
1 | firewall-cmd --zone=public --add-port=8080-8081/tcp |
实验10
把原本访问本机888端口的流量转发到22端口,并且要求当前和长期均有效
1 | # firewall-cmd --zone=<区域> --add-forward-port=port=<源端口号>:proto=<协议>:toport=<目标端口号>:toaddr=<目标IP地址> --permanent |
实验11
配置一条富规则,使其拒绝192.168.10.0/24网段的所有用户访问本机的ssh服务(22端口)
说明
富规则也叫复规则,表示更细致、更详细的防火墙策略配置,它可以针对系统服务、端口号、源地址和目标地址等诸多信息进行更有针对性的策略配置。它的优先级在所有的防火墙策略中也是最高的。
1 | firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.10.0/24" service name="ssh" reject' --permanent |