使用和配置firewalld

TrumanWong
9/14/2023
TrumanWong

防火墙是保护机器不受来自外部的、不需要的网络数据的一种方式。它允许用户通过定义一组防火墙规则 来控制主机上的入站网络流量。这些规则用于对进入的流量进行排序,并可以阻断或允许流量。

firewalld 是一个防火墙服务守护进程,firewalld本身并不具备防火墙的功能,而是和iptables一样需要通过内核的netfilter来实现。也就是说,firewalldiptables一样,它们的作用都是用于维护规则,而真正使用规则干活的是内核的netfilter

firewalld 使用区域zones和服务的概念来简化流量管理。zones 是预定义的规则集。网络接口和源可以分配给区。允许的流量取决于您计算机连接到的网络,并分配了这个网络的安全级别。防火墙服务是预定义的规则,覆盖了允许特定服务进入流量的所有必要设置,并在区中应用。

服务使用一个或多个端口或地址进行网络通信。防火墙会根据端口过滤通讯。要允许服务的网络流量,必须打开其端口。firewalld 会阻止未明确设置为打开的端口的所有流量。一些区(如可信区)默认允许所有流量。

firewalld入门

启动firewalld

# 启动firewalld
$ sudo systemctl start firewalld
# 设置开机自启
$ sudo systemctl enable firewalld

停止firewalld

# 停止firewalld
$ sudo systemctl stop firewalld
# 防止firewalld在系统启动时自启动
$ sudo systemctl disable firewalld

验证firewalld配置

在某些情况下,例如在手动编辑 firewalld 配置文件后,想要验证更改是否正确,可以使用 firewall-cmd 工具来验证配置。

前提条件

# 验证firewalld服务的配置,如果配置有效,则该命令会返回succes,否则,会返回一个带有更多详情的报错
$ sudo firewall-cmd --check-config
success

查看firewalld当前状态

# 查看firewalld服务状态
$ sudo firewalld-cmd --state
# 查看更多服务状态信息
$ sudo systemctl status firewalld

控制端口

端口是可让操作系统接收和区分网络流量并将其转发到系统服务的逻辑设备。它们通常由侦听端口的守护进程来表示,它会等待到达这个端口的任何流量。

通常,系统服务侦听为它们保留的标准端口。例如,httpd 守护进程监听 80 端口。但默认情况下,系统管理员会将守护进程配置为在不同端口上侦听以便增强安全性或出于其他原因。

开放指定端口

通过开放端口,系统可从外部访问,这代表了安全风险。通常,让端口保持关闭,且只在某些服务需要时才打开。

# 列出所有允许的端口
$ sudo firewall-cmd --list-ports
# 开放指定端口
$ sudo firewall-cmd --add-port=port-number/port-type
# 使新设置具有持久性
$ sudo firewall-cmd --runtime-to-permanent
端口类型为 tcpudpsctpdccp

关闭指定端口

当打开的端口不再需要时,在 firewalld 中关闭此端口,因为端口处于打开状态会存在安全隐患。

# 关闭端口
$ sudo firewall-cmd --remove-port=port-number/port-type
# 使新设置具有持久性
$ sudo firewall-cmd --runtime-to-permanent

区域Zones

区域是firewalld中一个十分重要的概念,预定义的区存储在 /usr/lib/firewalld/zones/ 目录中,并可立即应用到任何可用的网络接口。只有在修改后,这些文件才会被拷贝到 /etc/firewalld/zones/ 目录中。预定义区的默认设置如下:

添加规则时,如果没有指定区域,它们会被分配到默认区。安装时,firewalld 中的默认区被设为 public 区。默认区可以被修改。

列出区域

# 查看系统中所有可用区,但不显示特定区的详情。
$ sudo firewall-cmd --get-zones
# 查看所有区的详细信息
$ sudo firewall-cmd --list-all-zones
# 查看指定区的详细信息
$ sudo firewall-cmd --zone=zone-name --list-all

更改指定区的firewalld设置

# 允许在public区中使用ssh服务
$ sudo firewall-cmd --add-service=ssh --zone=public
# 添加子网络接口刀public区域
$ sudo firewall-cmd --add-interface=ens37

更改默认区域

系统管理员在其配置文件中为网络接口分配区域。如果接口没有被分配给指定区,它将被分配给默认区。每次重启 firewalld 服务后,firewalld 会加载默认区的设置,并使其处于活动状态。

# 查看当前默认区
$ sudo firewall-cmd --get-default-zone
# 设置新的默认区,此操作是一个永久设置,即使没有 --permanent 选项
$ sudo firewall-cmd --set-default-zone <zone-name>

将网络接口分配给区域

# 列出活跃区域及分配给他们的接口
$ sudo firewall-cmd --get-active-zones
# 为不同的区分配接口
$ sudo firewall-cmd --zone=zone_name --change-interface=interface_name --permanent

创建区域

要使用自定义区,创建一个新的区并使用它像预定义区一样。新区需要 --permanent 选项,否则命令无法工作。

# 创建一个新区
$ sudo firewall-cmd --permanent --new-zone=zone-name
$ sudo firewall-cmd --reload
# 检查是否在永久设置中添加了新的区
$ sudo firewall-cmd --get-zones
# 使新设置具有持久性
$ sudo firewall-cmd --runtime-to-permanent

区配置文件

区也可以通过区配置文件创建。如果你需要创建新区,但想从不同区重复使用设置,这种方法就很有用了。

firewalld 区配置文件包含区的信息。这些区描述、服务、端口、协议、icmp-blocksmasqueradeforward-ports 和丰富的语言规则采用 XML 文件格式。文件名必须是 *zone-name*.xml,其中 zone-name 的长度限制最多为 17 个字符。区域配置文件位于 /usr/lib/firewalld/zones//etc/firewalld/zones/ 目录中。

以下示例是一个允许端口范围为1025~65535的TCPUDP协议及ssh服务的配置:

<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>My Zone</short>
  <description>Here you can describe the characteristic features of the zone.</description>
  <service name="ssh"/>
  <port protocol="udp" port="1025-65535"/>
  <port protocol="tcp" port="1025-65535"/>
</zone>

设定传入流量的默认行为

对于每个区,可以设置处理尚未进一步指定的传入流量的默认行为。有以下四个选项:

# 列出指定区的信息,查看默认目标
$ sudo firewall-cmd --zone=zone-name --list-all
# 修改默认行为
$ sudo firewall-cmd --permanent --zone=zone-name --set-target=<default|ACCEPT|REJECT|DROP>
# 重载配置
$sudo firewall-cmd --reload

服务

服务是firewalld中一个重要概念,此处的服务是指某种具体的网络服务,如HTTPFTPDNS等。与区域一样,每个服务都有一个相应的配置文件。默认情况下,firewalld已经为很多网络服务提供了默认的配置文件,位于/usr/lib/firewalld/services/目录中。用户也可以自定义自己的服务,用户自定义服务的配置文件位于/etc/firewalld/services/ 目录中。当服务定义好之后,用户可以在区域文件中直接引用相应的服务。

下面是默认的ssh服务的配置文件内容:

$ cat /usr/lib/firewalld/services/ssh.xml 
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>SSH</short>
  <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
  <port protocol="tcp" port="22"/>
</service>

服务的配置文件由一堆service标签包裹起来,其中定义了服务的名称及服务端口。

添加新服务

$ sudo firewall-cmd --new-service=<service_name> --permanent
# 如果使用本地文件添加新服务,可以使用以下命令
$ sudo firewall-cmd --new-service-from-file=<service_xml_file> --permanent
# 更改服务设置后,服务的更新副本放在 /etc/firewalld/services/ 中。
# 可以输入以下命令来手动复制服务
$ sudo cp /usr/lib/firewalld/services/service-name.xml /etc/firewalld/services/service-name.xml

Sources

Sources是入站IP地址的范围,它也可以被分配到区域,以允许或禁止该流量可访问的服务。

***如果给区域添加一个source或interface,这个区域就会成为活跃的区域,来自该源的所有进入流量都会被定向到它。***可以为每个区指定不同的设置,这些设置相应地应用于来自给定源的网络流量。

源可以是一个CIDR格式的 IP 地址或 IP 掩码。

添加来源

# 在当前区域中设置源
$ sudo firewall-cmd --add-source=<source>
# 为指定区域设置源IP地址
$ sudo firewall-cmd --zone=zone-name --add-source=<source>
# 将ip加入到internal区域中
$ sudo firewall-cmd --zone=internal --add-source=192.168.118.128
# 使新设置具有持久性
$ sudi firewall-cmd --runtime-to-permanent
# 检查internal区域是否活跃
$ sudo firewall-cmd --zone=internal --list-all
internal (active)
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 192.168.118.128
  services: cockpit dhcpv6-client mdns samba-client ssh
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules:
当配置此场景时,请使用具有 default 目标的区。使用目标设为 ACCEPT 的区存在安全风险,因为对于来自 192.168.118.128 的流量,所有网络连接都将被接受。

删除来源

# 列出指定区域的允许源
$ sudo firewall-cmd --zone=zone-name --list-sources
# 从区域中永久删除源
$ sudo firewall-cmd --zone=zone-name --remove-source=<source>