firewall-cmd命令

firewall-cmd 命令 #

firewall-cmd是 firewalld 防火墙的命令行管理工具,用于配置和管理 Linux 系统上的防火墙规则。firewalld 是一个动态防火墙管理器,它使用"区域"概念来管理网络流量,并支持运行时配置更改,无需重启防火墙服务。

语法 #

firewall-cmd [选项]

常用选项 #

选项 描述
--state 显示防火墙状态
--reload 重新加载防火墙配置
--complete-reload 完全重新加载防火墙(会断开连接)
--list-all 列出所有配置
--list-all-zones 列出所有区域的配置
--get-default-zone 显示默认区域
--set-default-zone=区域 设置默认区域
--get-active-zones 显示当前活动的区域
--get-zones 列出所有可用区域
--zone=区域 指定操作的区域
--permanent 使更改永久生效(需要重新加载)
--timeout=秒数 指定规则的超时时间
--add-service=服务 添加服务
--remove-service=服务 移除服务
--list-services 列出允许的服务
--add-port=端口/协议 添加端口
--remove-port=端口/协议 移除端口
--list-ports 列出允许的端口
--add-protocol=协议 添加协议
--remove-protocol=协议 移除协议
--list-protocols 列出允许的协议
--add-source=源地址 添加源地址
--remove-source=源地址 移除源地址
--list-sources 列出源地址
--add-rich-rule=规则 添加富规则
--remove-rich-rule=规则 移除富规则
--list-rich-rules 列出富规则
--add-icmp-block=类型 添加 ICMP 阻止
--remove-icmp-block=类型 移除 ICMP 阻止
--list-icmp-blocks 列出 ICMP 阻止
--add-forward-port=端口规则 添加端口转发
--remove-forward-port=端口规则 移除端口转发
--list-forward-ports 列出端口转发
--add-masquerade 启用 IP 伪装
--remove-masquerade 禁用 IP 伪装
--query-masquerade 查询 IP 伪装状态

常见用法 #

基本操作 #

1. 检查防火墙状态 #

firewall-cmd --state

2. 重新加载防火墙配置 #

firewall-cmd --reload

3. 查看默认区域 #

firewall-cmd --get-default-zone

4. 设置默认区域 #

firewall-cmd --set-default-zone=public

5. 查看活动区域 #

firewall-cmd --get-active-zones

6. 查看特定区域的所有配置 #

firewall-cmd --zone=public --list-all

7. 查看所有区域的配置 #

firewall-cmd --list-all-zones

服务管理 #

1. 查看可用服务 #

firewall-cmd --get-services

2. 查看区域中允许的服务 #

firewall-cmd --zone=public --list-services

3. 临时添加服务 #

firewall-cmd --zone=public --add-service=http

4. 永久添加服务 #

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --reload

5. 移除服务 #

firewall-cmd --zone=public --remove-service=http

6. 检查服务是否允许 #

firewall-cmd --zone=public --query-service=http

端口管理 #

1. 查看开放的端口 #

firewall-cmd --zone=public --list-ports

2. 添加端口 #

firewall-cmd --zone=public --add-port=8080/tcp

3. 永久添加端口 #

firewall-cmd --permanent --zone=public --add-port=8080/tcp
firewall-cmd --reload

4. 移除端口 #

firewall-cmd --zone=public --remove-port=8080/tcp

5. 检查端口是否开放 #

firewall-cmd --zone=public --query-port=8080/tcp

协议管理 #

1. 列出允许的协议 #

firewall-cmd --zone=public --list-protocols

2. 添加协议 #

firewall-cmd --zone=public --add-protocol=icmp

3. 移除协议 #

firewall-cmd --zone=public --remove-protocol=icmp

源地址管理 #

1. 列出允许的源地址 #

firewall-cmd --zone=public --list-sources

2. 添加源地址 #

firewall-cmd --zone=trusted --add-source=192.168.1.0/24

3. 移除源地址 #

firewall-cmd --zone=trusted --remove-source=192.168.1.0/24

端口转发 #

1. 列出端口转发规则 #

firewall-cmd --zone=public --list-forward-ports

2. 添加端口转发 #

firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080

3. 添加到不同主机的端口转发 #

firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.1.100

4. 移除端口转发 #

firewall-cmd --zone=public --remove-forward-port=port=80:proto=tcp:toport=8080

IP 伪装(NAT) #

1. 启用 IP 伪装 #

firewall-cmd --zone=public --add-masquerade

2. 禁用 IP 伪装 #

firewall-cmd --zone=public --remove-masquerade

3. 查询 IP 伪装状态 #

firewall-cmd --zone=public --query-masquerade

ICMP 管理 #

1. 列出阻止的 ICMP 类型 #

firewall-cmd --zone=public --list-icmp-blocks

2. 添加 ICMP 阻止 #

firewall-cmd --zone=public --add-icmp-block=echo-request

3. 移除 ICMP 阻止 #

firewall-cmd --zone=public --remove-icmp-block=echo-request

富规则 #

1. 列出富规则 #

firewall-cmd --zone=public --list-rich-rules

2. 添加富规则(允许特定源地址访问特定服务) #

firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="http" accept'

3. 添加富规则(限制连接速率) #

firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="http" accept limit value="10/m"'

4. 添加富规则(记录连接) #

firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="http" log prefix="HTTP_CONNECTION" level="notice" limit value="3/m" accept'

5. 移除富规则 #

firewall-cmd --zone=public --remove-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="http" accept'

高级用法 #

1. 创建新区域 #

firewall-cmd --permanent --new-zone=myzone
firewall-cmd --reload

2. 删除区域 #

firewall-cmd --permanent --delete-zone=myzone
firewall-cmd --reload

3. 将网络接口分配给区域 #

firewall-cmd --zone=internal --change-interface=eth1

4. 永久将网络接口分配给区域 #

firewall-cmd --permanent --zone=internal --change-interface=eth1
firewall-cmd --reload

5. 设置区域目标 #

firewall-cmd --permanent --zone=public --set-target=DROP
firewall-cmd --reload

6. 添加服务定义 #

/etc/firewalld/services/目录中创建 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>MyService</short>
  <description>My custom service description</description>
  <port protocol="tcp" port="12345"/>
  <port protocol="udp" port="12345"/>
</service>

然后重新加载:

firewall-cmd --reload

7. 直接规则(直接访问 iptables) #

firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 22 -j ACCEPT

8. 锁定防火墙配置 #

firewall-cmd --lockdown-on

9. 解锁防火墙配置 #

firewall-cmd --lockdown-off

10. 查询锁定状态 #

firewall-cmd --query-lockdown

防火墙区域 #

firewalld 预定义了以下区域,每个区域具有不同的默认安全级别:

区域 描述
drop 丢弃所有传入连接,仅允许传出连接
block 拒绝所有传入连接,并发送 icmp-host-prohibited 响应
public 公共区域,不信任其他计算机,仅接受选定的连接
external 外部网络,用于启用伪装的网络接口
dmz 非军事区,允许有限的外部访问
work 工作区域,信任网络中的大多数计算机
home 家庭区域,信任网络中的其他计算机
internal 内部网络,信任网络中的其他计算机
trusted 信任所有网络连接

配置文件 #

firewalld 的主要配置文件和目录:

  • /etc/firewalld/:主配置目录
  • /etc/firewalld/firewalld.conf:主配置文件
  • /etc/firewalld/zones/:区域配置文件
  • /etc/firewalld/services/:服务定义
  • /etc/firewalld/icmptypes/:ICMP 类型定义
  • /usr/lib/firewalld/:默认配置(不应直接修改)

与 iptables 的关系 #

firewalld 是 iptables 的前端,它使用 iptables 作为后端实现。主要区别:

  • firewalld 使用区域概念组织规则
  • firewalld 支持动态规则更改,无需重启防火墙
  • firewalld 提供了更高级别的抽象(服务、区域等)
  • firewalld 配置存储在 XML 文件中,而不是脚本中

常见问题排查 #

1. 规则不生效 #

可能的原因:

  • 忘记添加--permanent标志和重新加载
  • 规则被其他规则覆盖
  • 网络接口分配到了错误的区域

解决方法:

firewall-cmd --get-active-zones  # 检查接口分配
firewall-cmd --zone=public --list-all  # 检查规则

2. 服务无法访问 #

可能的原因:

  • 服务端口未开放
  • 服务在不同的区域
  • SELinux 阻止了访问

解决方法:

firewall-cmd --add-service=<service>  # 或添加特定端口
setenforce 0  # 临时禁用SELinux以测试是否为SELinux问题

3. 防火墙状态问题 #

systemctl status firewalld  # 检查服务状态
firewall-cmd --state  # 检查防火墙状态

提示 #

  • 始终使用--permanent标志使更改永久生效,然后使用--reload应用更改
  • 使用--timeout选项可以临时添加规则,适用于测试或临时访问
  • 为不同的网络环境(如家庭、办公室、公共 Wi-Fi)使用不同的区域
  • 使用富规则可以创建更复杂的防火墙规则
  • 定期备份防火墙配置(/etc/firewalld/目录)
  • 在进行远程服务器的防火墙配置时,确保不会意外锁定自己
  • 使用firewall-cmd --panic-on可以在紧急情况下阻止所有流量
  • 使用firewall-config图形界面可以更直观地管理防火墙
  • 在生产环境中更改防火墙规则前,先在测试环境中验证
  • 使用firewall-cmd --get-log-denied--set-log-denied可以控制被拒绝连接的日志记录