🛡️ firewalld(CentOS/RHEL 防火墙)
什么是 firewalld?
firewalld 引入了**"区域"(Zone)**的概念——想象你的服务器在不同场合有不同的"面孔":在家(trusted 区域)什么都允许,在咖啡厅(public 区域)只开必要端口,在公司(work 区域)开放办公需要的服务。
区域(Zones)
| 区域名 | 默认行为 | 适用场景 |
|---|---|---|
| drop | 丢弃所有入站 | 最高安全级别 |
| block | 拒绝所有入站(返回 ICMP 拒绝) | 类似 drop,但会通知对方 |
| public | 默认区域,只允许选中的服务 | 公网服务器 |
| external | 启用伪装(MASQUERADE) | 路由器/网关 |
| work | 允许常见办公服务 | 办公网络 |
| home | 信任大部分入站 | 家庭网络 |
| trusted | 允许所有入站 | 完全信任的网络 |
基本管理
bash
# 启动和开机自启
sudo systemctl start firewalld
sudo systemctl enable firewalld
# 查看状态
sudo firewall-cmd --state
running
# 查看默认区域
sudo firewall-cmd --get-default-zone
public
# 查看所有区域
sudo firewall-cmd --get-zones
block dmz drop external home internal public trusted work
# 查看当前区域的规则
sudo firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
rich rules:
# 查看所有区域的规则
sudo firewall-cmd --list-all-zones服务和端口管理
bash
# 查看可用服务列表
sudo firewall-cmd --get-services
RH-Satellite-6 amanda-client amanda-k5-client bacula
bacula-client bitcoin bitcoin-rpc ... ssh dhcpv6-client
http https mysql postgresql redis ...
# 添加服务(运行时生效)
sudo firewall-cmd --add-service=http
sudo firewall-cmd --add-service=https
# 添加端口
sudo firewall-cmd --add-port=8080/tcp
sudo firewall-cmd --add-port=3000-4000/tcp # 端口范围
# 永久添加(重启后仍然生效)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=8080/tcp
# 重新加载使永久规则生效
sudo firewall-cmd --reload
# 移除服务/端口
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --permanent --remove-port=8080/tcp
# 查看当前生效的规则(运行时)
sudo firewall-cmd --list-services
dhcpv6-client http https ssh
sudo firewall-cmd --list-ports
8080/tcp⚠️ 注意: ⚠️ 运行时 vs 永久:--add-service只在当前会话生效(重启后消失)。加上--permanent才会永久保存。加了--permanent后需要--reload才生效。
Rich Rules(富规则)
富规则是 firewalld 的高级语法,能做更精细的控制。
bash
# 只允许特定 IP 访问 SSH
sudo firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="192.168.1.100"
port protocol="tcp" port="22"
accept'
# 限制连接速率(每分钟最多 10 个新 SSH 连接)
sudo firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
port protocol="tcp" port="22"
accept
limit value="10/m"'
# 拒绝特定 IP
sudo firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="10.0.0.50"
drop'
# 允许特定网段访问 MySQL
sudo firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="192.168.1.0/24"
port protocol="tcp" port="3306"
accept'
# 查看所有富规则
sudo firewall-cmd --list-rich-rules
# 删除富规则
sudo firewall-cmd --permanent --remove-rich-rule='
rule family="ipv4"
source address="10.0.0.50"
drop'
sudo firewall-cmd --reloadDirect Rules(直接规则)
bash
# 直接插入 iptables 规则(firewalld 的后门)
sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 \
-p tcp --dport 9090 -j ACCEPT
# 查看直接规则
sudo firewall-cmd --direct --get-all-rules
# 永久化
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 \
-p tcp --dport 9090 -j ACCEPT
sudo firewall-cmd --reload📝 备注: 📝 什么时候用 Direct Rules?当 firewalld 的富规则无法满足你的需求时(比如复杂的 iptables 规则),可以用 direct 规则直接操作底层 iptables。
区域绑定
bash
# 把网卡绑定到区域
sudo firewall-cmd --permanent --zone=public --change-interface=eth0
# 把 IP 绑定到区域
sudo firewall-cmd --permanent --zone=trusted --add-source=192.168.1.100
# 查看接口对应的区域
sudo firewall-cmd --get-active-zones
public
interfaces: eth0 eth1