集群架构 - Firewalld防火墙

1. 防火墙基本概述

1.1 Firewalld简介

RHEL/CentOS 7系统中集成了多款防火墙管理工具,其中firewalld(Dynamic Firewall Manager of Linux systems,Linux系统的动态防火墙管理器)服务是默认的防火墙配置管理工具,它拥有基于CLI(命令行界面)和基于GUI(图形用户界面)的两种管理方式。

1.2 Firewalld特点

相较于传统的Iptables防火墙管理工具,firewalld具有以下特点:

  1. 支持动态更新: 可以动态修改防火墙规则,无需重启服务
  2. 区域概念: 加入了区域(zone)的概念
  3. 策略模板: 预先准备了几套防火墙策略集合(策略模板)
  4. 快速切换: 用户可以根据生产场景的不同而选择合适的策略集合,实现防火墙策略之间的快速切换

1.3 区域(Zone)概念

简单来说,区域就是firewalld预先准备了几套防火墙策略集合(策略模板),用户可以根据生产场景的不同而选择合适的策略集合,从而实现防火墙策略之间的快速切换。

重要说明:

  • 一个zone区域仅能绑定一个网卡,设定不同的匹配规则
  • 一个zone区域又可以针对不同的源地址设定不同的规则

1.4 Firewalld相关配置文件

配置文件路径 说明
/usr/lib/firewalld 默认定义的模板配置文件
/etc/firewalld/ 存储规则配置文件

2. 防火墙区域概述

2.1 预定义区域

Firewalld提供了多个预定义区域,每个区域都有不同的安全级别和默认规则。

区域名称 说明 默认规则
trusted 信任区域 允许所有流量
home 家庭区域 允许SSH、mdns、ipp-client、samba-client、dhcpv6-client
internal 内部区域 与home区域相同
work 工作区域 允许SSH、ipp-client、dhcpv6-client
public 公共区域(默认) 允许SSH、dhcpv6-client
external 外部区域 允许SSH,默认启用IP伪装
dmz 非军事化区域 允许SSH
block 阻塞区域 拒绝所有传入流量
drop 丢弃区域 丢弃所有传入流量(无响应)

2.2 区域选择建议

场景 推荐区域
公共网络(如咖啡厅) public
家庭网络 home
公司内部网络 work
服务器区域 dmz
完全信任的网络 trusted

3. 防火墙基本指令参数

3.1 服务管理

为了能够使用firewalld服务和相关工具去管理防火墙,必须启动firewalld服务,并且需要禁用以前旧防火墙相关服务。

管理工具:

  • firewall-config: 图形界面管理工具
  • firewall-cmd: 命令行管理工具

3.2 规则状态

firewalld的规则分两种状态:

状态 说明 特点
runtime(运行时) 修改规则马上生效 临时生效,重启后失效(不建议)
permanent(持久配置) 修改后需要reload重载才会生效 永久生效(强烈推荐)

3.3 firewall-cmd命令分类

命令类型 说明 示例
查询类 查询防火墙状态和规则 --get-zones, --list-all
修改类 添加、删除、修改规则 --add-service, --remove-port
区域类 管理区域配置 --set-default-zone, --change-interface
服务类 管理服务规则 --add-service, --remove-service
端口类 管理端口规则 --add-port, --remove-port
富规则类 管理复杂规则 --add-rich-rule, --list-rich-rules

4. 防火墙区域配置策略

4.1 启动Firewalld服务

为了能正常使用firewalld服务和相关工具去管理防火墙,必须启动firewalld服务,同时关闭以前旧防火墙相关服务。

1
2
3
4
5
6
7
8
9
10
# 禁用旧版防火墙服务
[root@liyanzhao ~]# systemctl mask iptables
[root@liyanzhao ~]# systemctl mask ip6tables

# 启动firewalld防火墙,并加入开机自启动服务
[root@liyanzhao ~]# systemctl start firewalld
[root@liyanzhao ~]# systemctl enable firewalld

# 检查服务状态
[root@liyanzhao ~]# systemctl status firewalld

4.2 备份配置文件

1
2
# 备份firewalld相关配置文件(重要)
[root@Firewalld ~]# cp -r /etc/firewalld/ /etc/firewalld_backup

4.3 Zone区域相关指令

查看当前默认区域

1
2
3
# 查看当前默认区域
[root@liyanzhao ~]# firewall-cmd --get-default-zone
public

修改默认区域

1
2
3
# 将当前默认区域修改为work
[root@liyanzhao ~]# firewall-cmd --set-default-zone=work
success

配置区域服务

1
2
3
4
5
6
7
# work区域允许所有人访问http服务
[root@liyanzhao ~]# firewall-cmd --permanent --add-service=http --zone=work
success

# 重载配置
[root@liyanzhao ~]# firewall-cmd --reload
success

切换网络接口区域

1
2
3
# 将网络接口切换至work区域
[root@liyanzhao ~]# firewall-cmd --change-interface=eth0 --zone=work
success

4.4 将某网段IP路由至指定区域

1
2
3
4
5
6
7
8
9
# 将某网段IP路由至home区域,由该区域规则进行匹配决定是否放行
[root@Firewalld ~]# firewall-cmd --permanent --add-source=192.168.56.0/24 --zone=home
success

[root@Firewalld ~]# firewall-cmd --permanent --add-port=9000/tcp --zone=home
success

[root@Firewalld ~]# firewall-cmd --reload
success

4.5 查询Firewalld相关规则

查看当前处于活动的区域

1
2
3
4
5
6
# 查看当前处于活动的区域
[root@Firewalld ~]# firewall-cmd --get-active-zones
home //数据包的源IP是192.168.56网段走home区域
sources: 192.168.56.0/24
work //默认区域,eth0接口流量都由work区域过滤
interfaces: eth0 br0 vnet0

查看指定区域的明细

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查看指定区的明细
[root@liyanzhao ~]# firewall-cmd --list-all --zone=work
work (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: ssh dhcpv6-client http
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

查询区域服务

1
2
3
4
5
6
7
# 查询public区域是否允许请求SSH协议的流量
[root@Firewalld ~]# firewall-cmd --zone=public --query-service=ssh
yes

# 查询public区域是否允许请求HTTPS协议的流量
[root@Firewalld ~]# firewall-cmd --zone=public --query-service=https
no

5. 防火墙服务访问策略

5.1 配置HTTP和HTTPS服务

配置防火墙,允许请求http和https协议的流量设置为永久允许,并立即生效。

1
2
3
4
5
6
7
8
9
10
11
# 添加HTTP和HTTPS服务
[root@Firewalld ~]# firewall-cmd --permanent --add-service=http --add-service=https
success

# 重启加载生效
[root@Firewalld ~]# firewall-cmd --reload
success

# 检查相关配置
[root@Firewalld ~]# firewall-cmd --list-services
ssh dhcpv6-client http https

5.2 配置自定义服务(PHP-FPM)

配置防火墙,允许请求php-fpm服务的流量设置为永久允许,并立即生效。

创建PHP-FPM服务定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 进入服务定义目录
[root@Firewalld ~]# cd /usr/lib/firewalld/services/

# 拷贝相应的xml文件
[root@Firewalld services]# cp http.xml php-fpm.xml

# 修改端口为9000
[root@Firewalld services]# cat php-fpm.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>PHP-FPM</short>
<description>php-fpm</description>
<port protocol="tcp" port="9000"/>
</service>

添加PHP-FPM服务

1
2
3
4
5
6
7
8
9
10
11
# 增加PHP-FPM服务
[root@Firewalld ~]# firewall-cmd --permanent --add-service=php-fpm
success

# 重载配置
[root@Firewalld ~]# firewall-cmd --reload
success

# 查看服务列表
[root@Firewalld ~]# firewall-cmd --list-services
ssh dhcpv6-client http https php-fpm

安装并启动PHP-FPM

1
2
3
4
5
6
7
8
9
10
# 安装php-fpm,并监听9000端口
[root@Firewalld ~]# yum install php-fpm -y

# 修改php-fpm端口监听在本网段
[root@Firewalld ~]# vim /etc/php-fpm.d/www.conf
listen = 0.0.0.0:9000

# 启动php-fpm服务
[root@Firewalld ~]# systemctl start php-fpm
[root@Firewalld ~]# systemctl enable php-fpm

测试端口访问

1
2
3
4
5
# 外网telnet端口检测
telnet 192.168.56.11 9000
Trying 192.168.56.11...
Connected to 192.168.56.11.
Escape character is '^]'.

5.3 移除服务

配置防火墙,请求https协议的流量设置为永久拒绝,并立即生效。

1
2
3
4
5
6
7
8
9
10
# 移除HTTPS和PHP-FPM服务
[root@Firewalld ~]# firewall-cmd --permanent --remove-service=https --remove-service=php-fpm --zone=public
success

[root@Firewalld ~]# firewall-cmd --reload
success

# 检查当前活动服务
[root@Firewalld ~]# firewall-cmd --list-services
ssh dhcpv6-client http

6. 防火墙端口访问策略

6.1 添加端口规则

配置防火墙,访问8080/tcp和8080/udp端口的流量策略设置为永久允许,并立即生效。

1
2
3
4
5
6
7
8
9
10
11
# 添加firewalld规则
[root@Firewalld ~]# firewall-cmd --permanent --add-port=8080/udp --add-port=8080/tcp
success

# 动态加载
[root@Firewalld ~]# firewall-cmd --reload
success

# 检查端口规则
[root@Firewalld ~]# firewall-cmd --list-ports
8080/tcp 8080/udp

6.2 移除端口规则

配置防火墙,访问8080/udp的端口流量设置为永久拒绝,并立即生效。

1
2
3
4
5
6
7
8
# 移除UDP端口规则
[root@Firewalld ~]# firewall-cmd --permanent --remove-port=8080/udp
success

# 重载并检查端口规则
[root@Firewalld ~]# firewall-cmd --reload && firewall-cmd --list-ports
success
8080/tcp

6.3 端口范围规则

1
2
3
4
5
# 添加端口范围
firewall-cmd --permanent --add-port=8080-8090/tcp

# 重载配置
firewall-cmd --reload

7. 防火墙端口转发策略

端口转发是指传统的目标地址映射,实现外网访问内网资源。

7.1 端口转发命令格式

1
firewall-cmd --permanent --zone=<区域> --add-forward-port=port=<源端口号>:proto=<协议>:toport=<目标端口号>:toaddr=<目标IP地址>

7.2 配置端口转发

案例1: 将555端口转发到22端口

把访问本机555/tcp端口的流量转发到22/tcp端口,要求当前和长期有效。

1
2
3
4
5
6
# 添加端口转发规则
[root@Firewalld ~]# firewall-cmd --permanent --zone=public --add-forward-port=port=555:proto=tcp:toport=22:toaddr=192.168.56.11
success

[root@Firewalld ~]# firewall-cmd --reload
success

案例2: 将6666端口转发到80端口

把访问本机6666/tcp端口的流量转发到80/tcp端口,要求当前和长期有效。

1
2
3
4
5
6
7
8
9
10
# 首先需要开放80端口
[root@Firewalld ~]# firewall-cmd --permanent --add-port=80/tcp
success

# 添加端口转发规则
[root@Firewalld ~]# firewall-cmd --permanent --zone=public --add-forward-port=port=6666:proto=tcp:toport=80:toaddr=192.168.56.11
success

[root@Firewalld ~]# firewall-cmd --reload
success

7.3 移除端口转发

移除本地555/tcp端口转发策略,要求当前和长期有效。

1
2
3
4
5
6
# 移除端口转发规则
[root@Firewalld ~]# firewall-cmd --permanent --remove-forward-port=port=555:proto=tcp:toport=22:toaddr=192.168.56.11
success

[root@Firewalld ~]# firewall-cmd --reload
success

7.4 查看端口转发规则

1
2
3
4
5
# 查看所有端口转发规则
firewall-cmd --list-forward-ports

# 查看指定区域的端口转发
firewall-cmd --list-forward-ports --zone=public

8. 防火墙富规则策略

firewalld中的富规则表示更细致、更详细的防火墙策略配置,它可以针对系统服务、端口号、源地址和目标地址等诸多信息进行更有针对性的策略配置,优先级在所有的防火墙策略中也是最高的。

8.1 富规则语法

富规则帮助手册:

1
2
man firewall-cmd
man firewalld.richlanguage

基本语法结构:

1
2
3
4
5
6
7
rule
[source]
[destination]
service|port|protocol|icmp-block|masquerade|forward-port
[log]
[audit]
[accept|reject|drop]

详细语法:

1
2
3
4
5
6
7
8
9
rule [family="ipv4|ipv6"]
source address="address[/mask]" [invert="True"]
destination address="address[/mask]" invert="True"
service name="service name"
port port="port value" protocol="tcp|udp"
protocol value="protocol value"
forward-port port="port value" protocol="tcp|udp" to-port="port value" to-addr="address"
log [prefix="prefix text"] [level="log level"] [limit value="rate/duration"]
accept | reject [type="reject type"] | drop

重要说明: 区里的富规则按先后顺序匹配,按先匹配到的规则生效。

8.2 富规则管理命令

命令 说明
--add-rich-rule='<RULE>' 在指定的区添加一条富规则
--remove-rich-rule='<RULE>' 在指定的区删除一条富规则
--query-rich-rule='<RULE>' 找到规则返回0,找不到返回1
--list-rich-rules 列出指定区里的所有富规则
--list-all--list-all-zones 也能列出存在的富规则

8.3 富规则实战案例

案例1: 允许特定IP访问特定端口范围

允许来自于192.168.69.113/32主机请求8081-8083端口,当前和永久生效。

1
2
3
4
5
6
[root@Firewalld ~]# firewall-cmd --zone=public --permanent \
--add-rich-rule='rule family=ipv4 source address=192.168.69.113/32 port port=8081-8083 protocol=tcp accept'
success

[root@Firewalld ~]# firewall-cmd --reload
success

案例2: 拒绝特定IP的所有请求

拒绝来自192.168.69.113/32主机所有的请求,当前和永久生效。

1
2
3
4
5
6
[root@Firewalld ~]# firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family=ipv4 source address=192.168.69.113/32 reject'
success

[root@Firewalld ~]# firewall-cmd --reload
success

案例3: 拒绝特定网段访问SSH服务

拒绝来自于192.168.69.0/24网段请求ssh服务,当前和永久生效。

1
2
3
4
5
6
[root@Firewalld ~]# firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family=ipv4 source address=192.168.69.0/24 service name=ssh reject'
success

[root@Firewalld ~]# firewall-cmd --reload
success

案例4: 限制FTP服务并发连接数

限制所有请求ftp服务流量,每分钟1个并发,当前和永久生效。

1
2
3
4
5
6
[root@Firewalld ~]# firewall-cmd --permanent --zone=public \
--add-rich-rule='rule service name=ftp log prefix="ftp " level=notice limit value=1/m accept'
success

[root@Firewalld ~]# firewall-cmd --reload
success

查看日志:

1
2
3
4
5
6
# 开启多个ftp连接,查看日志
[root@Firewalld ~]# tail -f /var/log/messages

Apr 21 11:16:04 kvm-node1 kernel: ftp IN=br0 OUT= MAC=00:0c:29:72:6a96:00:50:56:c0:00:02:08:00
SRC=192.168.56.1 DST=192.168.56.11 LEN=64 TOS=0x00 PREC=0x00 TTL=64 ID=21160 DF PROTO=TCP
SPT=57050 DPT=21 WINDOW=65535 RES=0x00 SYN URGP=0

案例5: 临时规则(带超时)

防止规则设定错误导致网络连接断开,用于调试,规则在300秒后失效。

1
2
3
[root@Firewalld ~]# firewall-cmd \
--add-rich-rule='rule family=ipv4 source address=192.168.69.113/32 service name=ssh reject' --timeout=300
success

案例6: 富规则端口转发

将192.168.69.113/32主机访问443/tcp的数据包转发到本机的22/tcp端口,当前和永久生效。

1
2
3
4
5
6
7
# 端口转发规则
[root@Firewalld ~]# firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family=ipv4 source address=192.168.56.1/32 forward-port port=443 protocol=tcp to-port=22'
success

[root@Firewalld ~]# firewall-cmd --reload
success

案例7: 允许访问并记录日志

允许192.168.69.113/32访问httpd,并且记录日志,日志级别为notice,日志前缀为NEW HTTP,限制每秒最多3个并发,当前和永久生效。

1
2
3
4
5
6
7
8
9
10
11
12
# 安装并启动httpd
yum install httpd
systemctl start httpd
systemctl enable httpd

# 添加富规则
[root@Firewalld soft]# firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family=ipv4 source address=192.168.69.113/32 service name=http,https log level=notice prefix="New Http " limit value="3/s" accept'
success

[root@Firewalld soft]# firewall-cmd --reload
success

8.4 富规则日志级别

日志级别 说明
emerg 紧急
alert 警报
crit 严重
err 错误
warning 警告
notice 通知
info 信息
debug 调试

8.5 富规则限制值格式

格式 说明 示例
value/s 每秒 3/s
value/m 每分钟 1/m
value/h 每小时 10/h
value/d 每天 100/d

9. Firewalld服务管理

9.1 服务管理命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 启动服务
systemctl start firewalld

# 停止服务
systemctl stop firewalld

# 重启服务
systemctl restart firewalld

# 重载配置(不中断连接)
firewall-cmd --reload

# 查看状态
systemctl status firewalld

# 开机自启
systemctl enable firewalld

9.2 常用查询命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看所有区域
firewall-cmd --get-zones

# 查看默认区域
firewall-cmd --get-default-zone

# 查看活动区域
firewall-cmd --get-active-zones

# 查看所有配置
firewall-cmd --list-all

# 查看所有区域的配置
firewall-cmd --list-all-zones

# 查看指定区域配置
firewall-cmd --list-all --zone=public

9.3 接口管理

1
2
3
4
5
6
7
8
# 查看接口所属区域
firewall-cmd --get-zone-of-interface=eth0

# 将接口绑定到区域
firewall-cmd --change-interface=eth0 --zone=work

# 永久绑定接口
firewall-cmd --permanent --change-interface=eth0 --zone=work

10. Firewalld故障排查

10.1 常见问题

问题1: 规则不生效

排查步骤:

1
2
3
4
5
6
7
8
9
10
11
# 检查服务状态
systemctl status firewalld

# 检查配置语法
firewall-cmd --check-config

# 查看活动规则
firewall-cmd --list-all

# 查看iptables规则(firewalld底层使用iptables)
iptables -L -n

问题2: 无法连接服务

排查步骤:

1
2
3
4
5
6
7
8
# 检查服务是否允许
firewall-cmd --query-service=ssh

# 检查端口是否开放
firewall-cmd --query-port=22/tcp

# 检查富规则
firewall-cmd --list-rich-rules

问题3: 端口转发不工作

排查步骤:

1
2
3
4
5
6
7
8
9
# 检查IP转发是否启用
sysctl net.ipv4.ip_forward

# 启用IP转发
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p

# 检查端口转发规则
firewall-cmd --list-forward-ports

10.2 调试技巧

1
2
3
4
5
6
7
8
9
# 使用临时规则测试
firewall-cmd --add-rich-rule='...' --timeout=60

# 查看详细日志
journalctl -u firewalld -f

# 查看iptables规则
iptables -L -n -v
iptables -t nat -L -n -v

11. Firewalld最佳实践

11.1 安全建议

  1. 使用永久配置: 始终使用--permanent参数
  2. 及时重载: 修改后使用--reload重载配置
  3. 备份配置: 定期备份/etc/firewalld/目录
  4. 最小权限: 只开放必要的服务和端口
  5. 使用区域: 根据网络环境选择合适的区域

11.2 性能优化

1
2
3
4
5
6
7
# 禁用不需要的区域
firewall-cmd --get-zones

# 清理未使用的规则
firewall-cmd --list-all-zones

# 使用富规则替代多个简单规则

11.3 配置备份与恢复

1
2
3
4
5
6
# 备份配置
cp -r /etc/firewalld/ /backup/firewalld_$(date +%Y%m%d)

# 恢复配置
cp -r /backup/firewalld_20240225/* /etc/firewalld/
firewall-cmd --reload

实战优化