Skip to content

firewalld

概述

  由于 iptables 相对来说配置起来比较复杂,因此新推出了 firewalld 防火墙[链接],用于减化防火墙的配置工作。

  firewalld 和 iptables 一样,本身不具备防火墙功能,他们的作用都是用于维护规则,而真正使用规则干活的是内核的 netfilter。

  本文档主要用于记录如何使用 firewalld 管理防火墙。

启动与关闭

安装与启动

bash
# CentOS 7 以后,默认已安装并使用 firewalld,因此不需要以下操作
$ yum update -y
$ yum install -y firewalld
$ systemctl start firewalld
$ systemctl enable firewalld
$ systemctl status firewalld

关闭与卸载

bash
$ systemctl stop firewalld
$ systemctl disable firewalld
$ yum remove -y firewalld

修改规则

  firewalld 使用 firewall-cmd 命令来修改防火墙规则。

基础命令

bash
# 显示 firewalld 状态
$ firewall-cm --state

# 不中断服务重新加载
$ firewall-cmd --reload

# 中断所有连接重新加载
$ firewall-cmd --complete-reload

# 将当前防火墙的规则永久保存
$ firewall-cmd --runtime-to-permanent

# 检查配置正确性
$ firewall-cmd --check-config

区域操作

  在 firewalld 中,区域(zones)是一个非常重要的概念。区域为网络提供了安全等级,不同的网络或接口可以分配到不同的区域,从而对它们应用不同的安全策略。区域定义了对进入的流量的处理方式,每个区域都定义了自己允许进入的流量和可提供的服务。

  在 firewalld 中,预定义了多个区域,其作用分别如下:

  • block: 限制区,任何接收的网络连接,都被 IPv4 的 icmp-host-prohibited 信息和 IPv6 的 icmp6-adm-prohibited 信息所拒绝
  • drop: 丢弃区,任何接收的网络数据包都被丢弃,没有任何回复。仅能有发送出去的网络连接。
  • public: 共公区(默认)。不可信任共公区域内其它计算机,只接收经过选取的连接。
  • external: 外部区,特别为了路由器启用了伪装功能的外部网络。不可信任来自该网络的其它计算机,只接收经过选取的连接。
  • dmz: 非军事区,通常在该网络下放置一些不含机密信息的公用服务器,,可以有限信任网络内其它的计算机。只接收经过选择的连接。
  • work: 工作区,可以基本相信网络内的其它计算机不会危害你的计算机。只接收经过选择的连接。
  • home: 家庭区,可以基本相信网络内的其它计算机不会危害你的计算机。只接收经过选择的连接。
  • internal: 内部区,可以基本相信网络内的其它计算机不会危害你的计算机。只接收经过选择的连接。
  • trusted: 信任区,可授受所有的网络连接。

  一般情况下,网络接口被绑定到 public 区,public 区的作用与限制基本也能满足我们对网络的安全要求,因此我们一般操作 public 区即可。

bash
# 获取所有区域
$ firewall-cmd --get-zones
block dmz drop external home internal public trusted work

# 查看指定区域信息
$ firewall-cmd --zone=<zone> --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules:

# 将网络接口(可以理解为网卡)分配到指定的区域
$ firewall-cmd --zone=<zone> --change-interface=<interface> --permanent

# 为区域添加服务(以服务的方式对外开放接口)
$ firewall-cmd --zone=<zone> --add-service=<service> --permanent

# 为区域开放端口
$ firewall-cmd --zone=<zone> --add-port=<port>/<protocol> --permanent

# 重新加载配置
$ firewall-cmd --reload

高级规则

  firewalld 支持使用 rich rule 来创建更复杂的规则,例如创建一条规则来阻止来自特定计算机的某种类型的流量、只允许特定网段的计算机流访问某个端口等。通过高级规则可以更好地保障服务器的安全。

  firewalld 常用的高级规则命令如下:

bash
# 查看指定区域下已创建的高级规则
$ firewall-cmd --zone=<zone> --list-rich-rules

# 删除指定区域下已创建的高级规则
$ firewall-cmd --zone=<zone> --remove-rich-rule='[RULE]'

# 在指定区域下创建高级规则
$ firewall-cmd --zone=<zone> --add-rich-rule="[RULE]"

  由于 rich rule 的规则非常复杂,本文档只例举了一些最常用的场景,更详细规则需要查看 firewalld 文档[链接]。

bash
# 只允许指定网段下的计算机访问指定端口
$ firewall-cmd --zone=public --add-rich-rule='rule family=ipv4 source address=192.168.0.1/24 port port=3000 protocol=tcp accept'

# 拒绝来自指定网段下过来的流量
$ firewall-cmd --zone=public --add-rich-rule='rule family=ipv4 source address=192.168.0.1/24 reject'

# 丢弃来自指定网段下过来的流量
$ firewall-cmd --zone=public --add-rich-rule='rule family=ipv4 source address=192.168.0.1/24 drop'

提示

  在上面的高级规则中,我们用到了 acceptrejectdrop 三个动作,其中 accept 动作很好理解,即接收流量。而 rejectdrop 两者具有以下不同效果:

  • reject:
    • 效果:当使用 reject 动作时,防火墙会返回一个明确的拒绝数据包给客户端,通常是 TCP FINUDP-ICMP-PORT-UNREACHABLE 等类型的错误信息包。
    • 用户体验:客户端会立即断开连接,并认为访问的主机不存在。由于得到了明确的拒绝信息,客户端知道其请求被拒绝了。
    • 安全性与调试:reject 提供了一种更符合规范地处理方式,特别是在可控的网络环境中,更易于诊断和调试网络或防火墙产生的问题。
  • drop
    • 效果:当使用 drop 动作时,防火墙会直接丢弃数据包,并不返回任何响应给客户端。
    • 用户体验:客户端不会得到任何响应,需要等待连接尝试超时后才会意识到其请求被丢弃。由于没有明确地反馈,客户端可能会不确定请求是否已经发送或是否被处理。
    • 安全性与调试:drop 提供了更高的防火墙安全性,因为攻击者无法从防火墙获得任何有用的反馈。然而,由于 drop 的处理方式很不规范,可能会对你的网络造成一些不可预期或难以诊断的问题。

  在选择使用 reject 还是 drop 时,需要根据具体使用场景和需求进行权衡。

  如果一个区域下有多个 rich rule 时,那么防火墙会根据规则的优先级执行这些规则。与我们想像中根据规则定义的先后依次执行所不同,firewalld 使用以下优先级规则:

  • 日志规则:无论日志规则被定义在哪里,优先执行日志规则;
  • drop/reject 规则:永远优先 accept 规则;
  • accept 规则:优先级最低。

  为了避免默认优先级给我们带来未知的影响,我们可以通过为 rich rule 添加优先级顺序参数,从而强制让 rich rule 根据我们期望的顺序执行:

bash
# priority 越小优先级越高
# priority 的取值范围为 -32768 ~ 32767 
$ firewall-cmd --zone=public --add-rich-rule='rule priority=-100 family=ipv4 source address=192.168.0.1/24 port port=3000 protocol=tcp accept'

Released under the MIT license.