如何在 Rocky Linux 9 上使用 firewalld 设置防火墙
介绍
iptables 包过滤系统。
在本指南中,您将回顾如何为您的 Rocky Linux 9 服务器设置 firewalld
防火墙,并涵盖使用 firewall-cmd
管理工具管理防火墙的基础知识.
先决条件
要完成本教程,您需要一台运行 Rocky Linux 9 的服务器。您应该以非 root 用户身份登录该服务器,启用 sudo
。要进行设置,请参阅我们的 Rocky Linux 9 初始服务器设置指南。
第 1 步 — 回顾 firewalld 中的核心概念
在查看如何实际使用 firewall-cmd
实用程序来管理防火墙配置之前,您应该熟悉该工具引入的一些概念。
区域
firewalld
守护程序使用名为 zones 的实体管理规则组。区域是一组规则,根据您在网络中的信任级别规定应允许哪些流量。网络接口被分配到一个区域来指示防火墙应该允许的行为。
对于可能经常在网络之间移动的计算机(如笔记本电脑),这种灵活性提供了一种根据环境更改规则的好方法。您可能制定了严格的规则,禁止在公共 WiFi 网络上运行时的大部分流量,同时在连接到您的家庭网络时允许更宽松的限制。对于服务器,这些区域通常不那么重要,因为网络环境很少(如果有的话)发生变化。
无论您的网络环境多么动态,熟悉 firewalld
的每个预定义区域背后的一般概念仍然很有用。 firewalld
中的预定义区域按从最不信任到最受信任的顺序排列:
- drop:最低级别的信任。所有传入连接都被丢弃,没有回复,只有传出连接是可能的。
- 块:与上面类似,但不是丢弃连接,传入的请求被拒绝,并带有
icmp-host-prohibited
或icmp6-adm-prohibited
消息。< /li> - public:代表公共的、不受信任的网络。您不信任其他计算机,但可以根据具体情况允许选定的传入连接。
- 外部:如果您使用防火墙作为网关,则为外部网络。它针对 NAT 伪装进行配置,以便您的内部网络保持私密但可访问。
- 内部:外部区域的另一侧,用于网关的内部部分。这些计算机相当值得信赖,并且提供一些额外的服务。
- dmz:用于位于 DMZ 中的计算机(无法访问网络其余部分的隔离计算机)。仅允许某些传入连接。
- work:用于工作机器。信任网络中的大多数计算机。可能会允许更多的服务。
- 家:家庭环境。这通常意味着您信任大多数其他计算机,并且会接受更多的服务。
- 可信:信任网络中的所有机器。最开放的可用选项,应谨慎使用。
要使用防火墙,您可以创建规则并更改区域的属性,然后将您的网络接口分配给最合适的区域。
规则永久性
在 firewalld 中,规则可以应用于当前的运行时 规则集,或者永久。添加或修改规则时,默认情况下,只会修改当前运行的防火墙。下次重新启动后——或重新加载 firewalld
服务——只有永久规则会保留。
大多数 firewall-cmd
操作都可以使用 --permanent
标志来指示更改应应用于永久配置。此外,可以使用 firewall-cmd --runtime-to-permanent
命令将当前运行的防火墙保存到永久配置中。
这种运行时配置与永久配置的分离意味着您可以安全地测试活动防火墙中的规则,然后在出现问题时重新加载以重新开始。
第 2 步 — 安装和启用 firewalld
firewalld
默认安装在某些 Linux 发行版上,包括 Rocky Linux 的许多部署。但是,您可能需要自己安装 firewalld。你可以使用 Rocky 的 dnf
包管理器来做到这一点:
- sudo dnf install firewalld -y
安装 firewalld
后,您需要使用 systemctl
启用该服务。请记住,启用 firewalld 将导致服务在启动时启动。最好创建您的防火墙规则并趁机测试它们,同时仍然通过 SSH 登录以避免潜在的问题。
- sudo systemctl enable firewalld
- sudo systemctl start firewalld
您可以通过键入以下内容来验证该服务是否正在运行并且可以访问:
- sudo firewall-cmd --state
Outputrunning
这表明您的防火墙已启动并使用默认配置运行。在进行进一步修改之前,您应该熟悉 firewalld 提供的默认环境和规则。
探索默认值
您可以通过运行 firewall-cmd --get-default-zone
查看当前选择哪个区域作为默认区域:
- firewall-cmd --get-default-zone
Outputpublic
由于您没有给 firewalld 任何命令来偏离默认区域,并且您的接口都没有配置为绑定到另一个区域,因此该区域也将是唯一的活动区域(控制我们接口流量的区域) .您可以通过运行 firewall-cmd --get-active-zones
来验证:
- firewall-cmd --get-active-zones
Outputpublic
interfaces: eth0 eth1
在这里,您可以看到您的示例服务器有两个由防火墙控制的网络接口(eth0
和 eth1
)。它们目前都根据为公共区域定义的规则进行管理。
您可以使用 firewall-cmd --list-all
打印出与默认区域配置相关的规则:
- sudo firewall-cmd --list-all
Outputpublic (active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
您可以从输出中看出该区域既是默认区域又是活动区域,并且 eth0
和 eth1
接口与该区域相关联。从 services:
行,您还可以看到该区域允许 DHCP 客户端(用于 IP 地址分配)、SSH(用于远程管理)和 Cockpit(基于 Web 的控制台)的流量。
探索替代区域
您也可以找到有关其他区域的信息。
要获取可用区域的列表,请运行 firewall-cmd --get-zones
:
- firewall-cmd --get-zones
Outputblock dmz drop external home internal nm-shared public trusted work
您可以通过在 --list-all
命令中包含 --zone=
参数来查看与区域关联的特定配置:
- sudo firewall-cmd --zone=home --list-all
Outputhome
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client mdns samba-client ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
您可以使用 --list-all-zones
选项输出所有区域定义。接下来,您将了解如何将区域分配给网络接口。
第 3 步 — 为您的接口选择区域
除非您以其他方式配置了网络接口,否则每个接口都会在防火墙启动时放入默认区域。
更改接口的区域
通过结合使用 --zone=
参数和 --change-interface=
参数,您可以在会话期间在区域之间移动接口。与所有修改防火墙的命令一样,您需要使用 sudo
。
例如,您可以将 eth0
接口移至主区域:
- sudo firewall-cmd --zone=home --change-interface=eth0
Outputsuccess
注意:无论何时将接口移动到新区域,请注意您正在修改哪些服务将运行。在这种情况下,您将移动到具有 SSH 可用的家庭区域。这意味着您的连接不应断开。默认情况下,其他一些区域没有启用 SSH,切换到这些区域之一可能会导致您的连接断开,从而阻止您重新登录到您的服务器。
您可以通过再次检查活动区域来验证这是否成功:
- firewall-cmd --get-active-zones
Outputhome
interfaces: eth0
public
interfaces: eth1
调整默认区域
如果您的所有接口都可以由一个预定义区域很好地处理,您应该将该区域指定为默认区域。您可以使用 --set-default-zone=
参数更改默认区域。这将立即更改使用默认区域的任何接口:
- sudo firewall-cmd --set-default-zone=home
Outputsuccess
第 4 步 — 为您的应用程序设置规则
让我们来看看定义防火墙例外的方法。
向您的区域添加服务
最直接的方法是将您需要的服务或端口添加到您正在使用的区域。您可以使用 firewall-cmd
的 --get-services
选项获取可用服务定义的列表:
- firewall-cmd --get-services
OutputRH-Satellite-6 RH-Satellite-6-capsule amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-mon cfengine cockpit collectd condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns dns-over-tls docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger foreman foreman-proxy freeipa-4 freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp galera ganglia-client ganglia-master git grafana gre high-availability http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kdeconnect kerberos kibana klogin kpasswd kprop kshell kube-api kube-apiserver kube-control-plane kube-controller-manager kube-scheduler kubelet-worker ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns memcache minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nbd netbios-ns nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy prometheus proxy-dhcp ptp pulseaudio puppetmaster quassel radius rdp redis redis-sentinel rpc-bind rquotad rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync spotify-sync squid ssdp ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tentacle tftp tile38 tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wireguard wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server
注意:您可以通过查看 /usr/lib/firewalld/services
目录中的相关 .xml
文件来找到有关这些服务的更多详细信息。例如,SSH 服务定义如下:
<?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>
您可以使用 --add-service=
参数为区域启用服务。该操作将以默认区域或 --zone=
参数指定的区域为目标。默认情况下,这只会调整当前的防火墙会话,并且不会在服务重新启动或重新启动后持续存在。您可以通过包含 --permanent
标志来调整永久防火墙配置。
例如,如果您正在运行一个服务于传统 HTTP 流量的 Web 服务器,您可以暂时允许此流量用于您的公共区域中的接口:
- sudo firewall-cmd --zone=public --add-service=http
您可以省略 --zone=
标志来修改默认区域。您可以使用 --list-all
或 --list-services
操作来验证操作是否成功:
- sudo firewall-cmd --zone=public --list-services
Outputcockpit dhcpv6-client http ssh
测试一切正常后,您可以修改永久防火墙规则,以便您的服务在重启后仍然可用。您可以通过添加 --permanent
标志使之前的命令永久化:
- sudo firewall-cmd --zone=public --add-service=http --permanent
Outputsuccess
或者,您可以使用 --runtime-to-permanent
标志将当前运行的防火墙配置保存到永久配置:
- sudo firewall-cmd --runtime-to-permanent
请谨慎使用此选项,因为对正在运行的防火墙所做的所有更改都将永久提交。
无论您选择哪种方法,您都可以通过将 --permanent
标志添加到 --list-services
操作来验证它是否成功。您需要使用 sudo
进行任何 --permanent
操作:
- sudo firewall-cmd --zone=public --list-services --permanent
Outputcockpit dhcpv6-client http ssh
您的公共区域现在将允许端口 80 上的 HTTP 网络流量。如果您的网络服务器配置为使用 SSL/TLS,您还需要添加 https
服务。您可以通过键入以下内容将其添加到当前会话和永久规则集中:
- sudo firewall-cmd --zone=public --add-service=https
- sudo firewall-cmd --zone=public --add-service=https --permanent
firewalld 安装中包含的服务代表了您可能需要允许访问的许多最常见的应用程序。但是,在某些情况下,这些服务可能不符合您的要求。
在这种情况下,您有两种选择。
为你的区域打开一个端口
为您的特定应用程序添加支持的最直接方法是打开它在适当区域中使用的端口。这是通过指定端口或端口范围以及端口的关联协议(TCP 或 UDP)来完成的。
例如,如果您的应用程序在端口 5000 上运行并使用 TCP,您可以使用 --add-port=
参数将其临时添加到 public
区域。协议可以指定为 tcp
或 udp
:
- sudo firewall-cmd --zone=public --add-port=5000/tcp
Outputsuccess
您可以使用 --list-ports
操作验证这是否成功:
- sudo firewall-cmd --zone=public --list-ports
Output5000/tcp
也可以通过用破折号分隔范围内的开始和结束端口来指定连续的端口范围。例如,如果您的应用程序使用 UDP 端口 4990 到 4999,您可以通过键入以下内容公开打开这些端口:
- sudo firewall-cmd --zone=public --add-port=4990-4999/udp
测试后,您可以将这些添加到永久防火墙中。使用 sudo firewall-cmd --runtime-to-permanent
,或使用 --permanent
标志重新运行命令:
- sudo firewall-cmd --zone=public --permanent --add-port=5000/tcp
- sudo firewall-cmd --zone=public --permanent --add-port=4990-4999/udp
- sudo firewall-cmd --zone=public --permanent --list-ports
Outputsuccess
success
5000/tcp 4990-4999/udp
定义服务
为您的区域打开端口是一个简单的解决方案,但可能很难跟踪每个端口的用途。如果您曾停用服务器上的一项服务,您可能很难对哪些已打开的端口仍然需要进行分类。为避免这种情况,您可以定义一个新服务。
服务是具有关联名称和描述的端口集合。使用服务管理防火墙通常比映射端口更易于维护,但需要一些初始配置。您可以首先将 /usr/lib/firewalld/services
中的现有脚本复制到防火墙查找非标准定义的 /etc/firewalld/services
目录。
例如,您可以复制 SSH 服务定义以用于您的示例服务定义,如下所示。防火墙服务列表中的服务名称将是该文件的名称,减去 .xml
后缀:
- sudo cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/example.xml
使用 vi
或您最喜欢的文本编辑器打开文件:
- sudo vi /etc/firewalld/services/example.xml
首先,该文件将包含您复制的 SSH 定义:
<?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>
这个定义的大部分实际上是元数据。您应该在 <short>
标记中更改服务的简称。这是您的服务的人类可读名称。您还应该添加描述,以便在需要审核服务时获得更多信息。您需要进行的唯一实际影响服务功能的配置可能是端口定义,您可以在其中标识要打开的端口号和协议。可以指定多个
标签。
对于您的示例
服务,假设您需要为 TCP 打开端口 7777,为 UDP 打开端口 8888。您可以使用以下内容修改现有定义:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>Example Service</short>
<description>This is just an example service. It probably shouldn't be used on a real system.</description>
<port protocol="tcp" port="7777"/>
<port protocol="udp" port="8888"/>
</service>
保存并关闭文件。
重新加载防火墙以访问新服务:
- sudo firewall-cmd --reload
您可以看到它现在位于可用服务列表中:
- firewall-cmd --get-services
OutputRH-Satellite-6 RH-Satellite-6-capsule amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-mon cfengine cockpit collectd condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns dns-over-tls docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server example finger foreman foreman-proxy freeipa-4 freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp galera ganglia-client ganglia-master git grafana gre high-availability http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kdeconnect kerberos kibana klogin kpasswd kprop kshell kube-api kube-apiserver kube-control-plane kube-controller-manager kube-scheduler kubelet-worker ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns memcache minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nbd netbios-ns nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy prometheus proxy-dhcp ptp pulseaudio puppetmaster quassel radius rdp redis redis-sentinel rpc-bind rquotad rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync spotify-sync squid ssdp ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tentacle tftp tile38 tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wireguard wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server
您现在可以像往常一样在您的区域中使用此服务。
第 5 步 — 创建您自己的区域
虽然预定义区域应该适用于大多数用户,但定义更能描述其功能的自己的区域可能会有所帮助。
例如,您可能需要为您的 Web 服务器创建一个名为 publicweb
的区域。但是,您可能需要为您在专用网络上提供的 DNS 服务配置另一个区域。您可以为此创建另一个名为 privateDNS
的区域。
添加区域时,您必须将其添加到永久防火墙配置中。然后您可以重新加载以将配置带入正在运行的会话中。例如,您可以使用 firewall-cmd –new-zone
创建这两个区域:
- sudo firewall-cmd --permanent --new-zone=publicweb
- sudo firewall-cmd --permanent --new-zone=privateDNS
您可以通过键入以下内容来验证这些是否存在于您的永久配置中:
- sudo firewall-cmd --permanent --get-zones
Outputblock dmz drop external home internal nm-shared privateDNS public publicweb trusted work
重新加载防火墙以将这些新区域带入活动的运行时配置:
- sudo firewall-cmd --reload
- firewall-cmd --get-zones
Outputblock dmz drop external home internal nm-shared privateDNS public publicweb trusted work
现在,您可以开始为您的区域分配适当的服务和端口。调整运行时防火墙通常是个好主意,然后在测试后将这些更改保存到永久配置中。例如,对于 publicweb
区域,您可以添加 SSH、HTTP 和 HTTPS 服务:
- sudo firewall-cmd --zone=publicweb --add-service=ssh
- sudo firewall-cmd --zone=publicweb --add-service=http
- sudo firewall-cmd --zone=publicweb --add-service=https
- sudo firewall-cmd --zone=publicweb --list-all
Outputpublicweb
target: default
icmp-block-inversion: no
interfaces:
sources:
services: http https ssh
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
然后您可以将 DNS 服务添加到您的 privateDNS
区域:
- sudo firewall-cmd --zone=privateDNS --add-service=dns
- sudo firewall-cmd --zone=privateDNS --list-all
OutputprivateDNS
target: default
icmp-block-inversion: no
interfaces:
sources:
services: dns
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
然后,您可以将我们的界面更改为这些新区域以对其进行测试:
- sudo firewall-cmd --zone=publicweb --change-interface=eth0
- sudo firewall-cmd --zone=privateDNS --change-interface=eth1
此时,您有机会测试您的配置。如果这些值适合您,您应该将这些规则添加到永久配置中。您可以通过附加 --permanent
标志再次运行所有命令来做到这一点,但在这种情况下,您将使用 --runtime-to-permanent
标志来永久保存整个运行时配置:
- sudo firewall-cmd --runtime-to-permanent
永久应用这些规则后,重新加载防火墙以测试更改是否仍然存在:
- sudo firewall-cmd --reload
验证是否分配了正确的区域:
- firewall-cmd --get-active-zones
OutputprivateDNS
interfaces: eth1
publicweb
interfaces: eth0
并验证适当的服务可用于两个区域:
- sudo firewall-cmd --zone=publicweb --list-services
Outputhttp https ssh
- sudo firewall-cmd --zone=privateDNS --list-services
Outputdns
您已成功设置自己的区域!要使这些区域之一成为其他接口的默认区域,请记住使用 --set-default-zone=
参数配置该行为:
- sudo firewall-cmd --set-default-zone=publicweb
结论
您现在应该对如何在日常使用的 Rocky Linux 系统上管理 firewalld 服务有一个相当透彻的了解。
firewalld 服务允许您配置可维护的规则和规则集,将您的网络环境考虑在内。它允许您通过使用区域在不同的防火墙策略之间无缝转换。获得该系统的应用知识将使您能够利用该工具提供的灵活性和强大功能。
有关 firewalld 的更多信息,请参阅 firewalld 官方文档。