本文翻译自 How To Set Up a Firewall Using FirewallD on CentOS 7
引言
Firewalld是可用于许多Linux发行版的防火墙管理解决方案,它充当Linux内核提供的iptables数据包过滤系统的前端。 在本指南中,我们将介绍如何为服务器设置防火墙,并向您展示使用firewall-cmd管理工具管理防火墙的基本知识(如果您希望在CentOS中使用iptables,请遵循 这个指南。
Firewalld 的基本概念
在开始讨论如何实际使用firewall-cmd实用程序来管理防火墙配置之前,我们应该熟悉该工具引入的一些基本概念。
Zones(区域)
Firewalld守护程序使用称为“区域”的实体管理规则组。 区域基本上是一组规则,它们决定了允许哪些流量,具体取决于您对计算机所连接的网络的信任程度。 为网络接口分配一个Zone来指示防火墙应允许和拒绝哪些行为。
对于可能经常在网络之间移动的计算机(例如笔记本电脑),这种灵活性提供了一种根据环境更改规则的好方法。 在公共WiFi网络上运行时,您可能有严格的规则禁止大多数流量,而在连接到家庭网络时允许放宽限制。 对于服务器来说,这些区域并不是那么重要,因为网络环境很少更改。
无论您的网络环境动态性有多强,熟悉防火墙的每个预定义区域背后的概念仍然很有用。 按从最不信任到最受信任的顺序,firewalld中的预定义区域为:
drop:最低级别的信任度。 所有传入的连接都将被丢弃而不会回复,并且只能进行传出连接。
block:与上述类似,但不仅仅是丢弃连接,而是使用icmp-host-prohibited或icmp6-adm-prohibited消息拒绝传入的请求。
public:代表公共的,不受信任的网络。 您不信任其他计算机,但可能会视情况允许选择的传入连接。
external:external network用于这种情形:您将firewalld当成网关使用。 将其配置为伪NAT,以便您的内部网络保持私有但可访问。
internal:外部区域的另一侧,用于网关的内部。 这些计算机相当值得信赖,并且可以使用一些其他服务。
dmz:用于DMZ(无法访问网络其余部分的隔离计算机)。 仅允许某些传入连接。
work:用于工作机。 信任网络中的大多数计算机。 可能还允许其他一些服务。
home:家庭环境。 通常,这意味着您信任其他大多数计算机,并且将接受其他一些服务。
trusted:信任网络中的所有计算机。 可用选项中最开放的,应谨慎使用。
要使用防火墙,我们可以创建规则并更改区域的属性,然后将网络接口(network interface)分配给最合适的区域(zones)。
规则永久性
在firewalld中,可以将规则指定为永久规则或立即规则。 如果添加或修改规则,则默认情况下,将修改当前运行的防火墙规则。 下次启动时,旧规则将恢复。
大多数firewall-cmd
操作都可以使用--permanent
标志来指示应永久防火墙规则作为目标。 这将影响在引导时重新加载的规则。 这种分离意味着您可以在活动的防火墙实例中测试规则,然后在出现问题时重新加载。 您还可以使用--permanent
标志随着时间的推移建立一套完整的规则,这些规则将在发出reload
命令时立即应用。
安装并启动防火墙
firewalld默认安装在一些Linux发行版上,包括许多CentOS 7的映像。但是,您可能需要自己安装firewalld:
1 | sudo yum install firewalld |
安装firewalld之后,可以启用服务并重新启动服务器。请记住,启用firewalld将导致服务在引导时启动。最好的做法是先创建防火墙规则,并在配置此行为之前对其进行测试,以避免潜在的问题。
1 | sudo systemctl enable firewalld |
当服务器重新启动时,你的防火墙应该会打开,你的网络接口应该放入已配置的区域(或退回到已配置的默认区域),与区域相关的任何规则都将应用于相关的接口。
我们可以通过键入以下内容来验证该服务正在运行:
1 | sudo firewall-cmd --state |
这表明我们的防火墙已经启动并使用默认配置运行。
熟悉当前的防火墙规则
在开始进行修改之前,我们应该熟悉守护进程提供的默认环境和规则。
默认值
我们可以通过输入以下内容来查看当前选择的默认区域:
1 | firewall-cmd --get-active-zones |
1 | output |
在这里,我们可以看到示例服务器具有两个受防火墙控制的网络接口(eth0和eth1)。 目前,它们都根据为public zone定义的规则进行管理。
我们如何知道与public zone相关的规则? 我们可以通过输入以下内容来打印默认区域的配置:
1 | sudo firewall-cmd --list-all |
1 | output |
从输出中可以看出,该区域既是默认区域又是活动区域,并且eth0和eth1接口与此区域相关联(我们已经从之前的查询中了解了所有这些信息)。 但是,我们还可以看到,该区域允许与DHCP客户端(用于IP地址分配)和SSH(用于远程管理)相关的正常操作。
可替代区
现在,我们对缺省和活动区域的配置有了很好的了解。我们也可以找到其他区域的信息。要获得可用区域的列表,请输入:
1 | firewall-cmd --get-zones |
1 | output |
我们可以通过在—list-all
命令中包含—zone=
参数来查看与区域关联的特定配置
1 | sudo firewall-cmd --zone=home --list-all |
1 | output |
您可以使用–list-all-zones选项输出所有区域定义。 您可能希望将输出通过管道以便于查看:
1 | sudo firewall-cmd --list-all-zones | less |
为接口选择区域
除非您已经配置了您的网络接口,否则在防火墙启动时,每个接口都将放在默认区域。
改变接口的区域
您可以在会话期间使用—zone=
参数和—change-interface=
参数在区域之间转换接口。与修改防火墙的所有命令一样,您将需要使用sudo。
例如,我们可以通过输入以下内容将eth0接口转换到home区域:
1 | sudo firewall-cmd --zone=home --change-interface=eth0 |
每当将接口转换到新区域时,请注意,您可能正在修改将可操作的服务。例如,在这里,我们将移动到”home”区域,其中有 SSH 可用。这意味着我们的连接不应该断开。默认情况下,某些其他区域未启用 SSH,如果在使用这些区域之一时断开连接,您可能会发现自己无法重新登录。
我们可以通过再次请求活动区域来验证这是否成功:
1 | firewall-cmd --get-active-zones |
1 | output |
调整默认区域
如果所有接口都可以最好地由单个区域处理,那么只需选择最佳默认区域,然后将其用于配置可能更容易。
您可以使用 参数更改默认区域。这将立即将默认的接口更改回新区域:--set-default-zone=
1 | sudo firewall-cmd --set-default-zone=home |
1 | output |
为应用程序设置规则
为您希望提供的服务定义防火墙的基本方法非常简单。我们将在这里了解基本思想。
向区域添加服务
最简单的方法是将所需的服务或端口添加到正在使用的区域。同样,您可以使用以下选项获取可用服务的列表:--get-services
1 | firewall-cmd --get-services |
1 | output |
您可以使用命令行参数为区域启用服务。该操作将针对默认区域或参数指定的任何区域。默认情况下,这将仅调整当前防火墙会话。您可以通过包含permanent
标志来调整永久防火墙配置。--add-service=--zone=--permanent
例如,如果我们正在运行一个为传统HTTP流量提供服务的web服务器,我们可以通过输入以下命令来允许该会话的公共区域中的接口的流量:
1 | sudo firewall-cmd --zone=public --add-service=http |
我们可以用这个验证操作是否成功:--zone=--list-all--list-services
1 | sudo firewall-cmd --zone=public --list-services |
1 | output |
测试完所有功能后,可能需要修改永久防火墙规则,以便在重新启动后服务仍然可用。通过:
1 | sudo firewall-cmd --zone=public --permanent --add-service=http |
现在,您的“公共”区域将允许端口80上的HTTP Web通信。如果您的Web服务器配置为使用SSL / TLS,则还需要添加服务。 我们可以通过以下内容将其添加到当前session和永久规则集合中:
1 | sudo firewall-cmd --zone=public --add-service=https |
如果没有合适的服务可用呢?
firewalld安装中包含的防火墙服务代表了您可能希望允许访问的应用程序的许多最常见需求。但是,可能会出现这些服务不适合您的需求的情况。
在这种情况下,你有两种选择:
为你的区域开一个端口
支持你特定服务最简单的方法就是在合适的区域(zone)内开放一个端口, 这很容易指定端口或端口范围,以及需要打开的端口相关的协议。
比如,如果你的应用在5000端口中使用TCP,
你可以在public区域内使用这个参数进行增加,协议可以为tcp,udp:
1 | sudo firewall-cmd --zone=public --add-port=5000/tcp |
我们可以通过--list-ports
进行确认
1 | sudo firewall-cmd --zone=public --list-ports |
使用横杠进行连续端口的指定也是可能的,例如,下面的例子就开放了4990到4999的UDP端口,当然同样是在Public zone中:
1 | sudo firewall-cmd --zone=public ---add-port=4990-4999/udp |
在测试后,我们想把它们增加为永久的防火墙规则,你可以输入:
1 | sudo firewall-cmd --zone=public --permanent --add-port=5000/tcp |
定义一个服务
为您的区域打开端口很容易,但是很难跟踪每个端口的用途。如果您曾经在您的服务器上停止过一个服务,那么您可能很难记住哪些过去被打开了的端口仍然是必需的。为了避免这种情况,可以定义一个服务。
服务只是具有相关名称和描述的端口的集合。使用服务比端口更容易管理,但是需要一些前期工作。最简单的启动方式是将现有的脚本复制到防火墙查找非标准定义的目录中。/usr/lib/firewalld/services/etc/firewalld/services
例如,我们可以复制SSH服务定义来使用我们的’example’服务定义,如下所示。文件名减去后缀将指示防火墙服务列表中的服务名称:.xml
1 | sudo cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/example.xml |
首先,该文件将包含您复制的SSH定义
1 |
|
该定义的大部分实际上是元数据。 您将要在标签内更改服务的简称。 这是您的服务的易读名称。 您还应该添加描述,以便在需要审核服务时获得更多信息。 您需要进行的实际上会影响服务功能的唯一配置可能是端口定义,您可以在其中定义要打开的端口号和协议。 可以多次指定。
对于我们的示例服务,假设我们需要为TCP打开7777端口,为UDP打开8888端口。通过按下按钮进入插入模式,我们可以这样修改现有的定义
1 |
|
重新加载防火墙以访问新服务:
1 | firewall-cmd --get-services |
1 | output: |
我们可以看到example服务已经被成功定义。
创造属于你自己的区域(zones)
尽管预定义的区域对于大多数用户来说可能绰绰有余,但是定义自己的区域来描述其功能可能会有所帮助。
例如,您可能要为Web服务器创建一个名为“ publicweb”的zone。 但是,您可能希望为您在专用网络上提供的DNS服务而去配置另一个zone。 您可能需要一个名为“ privateDNS”的zone。
添加区域时,必须将其添加到永久防火墙配置中。 然后,您可以重新加载以将配置带入正在运行的会话。 例如,我们可以通过键入以下内容来创建我们上面讨论的两个区域:
1 | sudo firewall-cmd --permanent --new-zone=publicweb |
您可以通过键入来验证它们是否存在于您的永久配置中:
1 | sudo firewall-cmd --permanent --get-zones |
如前所述,这些在防火墙的当前实例中还不可用,重新加载防火墙,将这些新区域引入活动配置2
1 | sudo firewall-cmd --reload |
1 | block dmz drop external home internal privateDNS public publicweb trusted work |
现在,您可以开始为您的区域分配适当的服务和端口。先调整active instance,然后在测试之后将这些更改转移到永久配置,这通常是一个好主意。例如,对于publicweb专区,您可能希望添加SSH、HTTP和HTTPS服务
1 | sudo firewall-cmd --zone=publicweb --add-service=ssh |
1 | output |
同样,我们可以将DNS服务添加到我们的privateDNS zone
1 | sudo firewall-cmd --zone=privateDNS --add-service=dns |
1 | privateDNS |
然后,我们可以更改对应zone的网络接口以对其进行测试:
1 | sudo firewall-cmd --zone=publicweb --change-interface=eth0 |
1 | sudo firewall-cmd --zone=publicweb --change-interface=eth0 |
此时,您就有机会测试您的配置了。如果这些值对您有效,您将希望向永久配置添加相同的规则。您可以通过重新应用带有标志的规则来做到这一点:--permanent
1 | sudo firewall-cmd --zone=publicweb --permanent --add-service=ssh |
在永久地应用这些规则之后,您可以重新启动网络并重新加载防火墙服务
1 | sudo systemctl restart network |
确认已经成功分配了zones:
1 | firewall-cmd --get-active-zones |
1 | privateDNS |
确认合适的服务已经在每个zones里面可用:
1 | sudo firewall-cmd --zone=publicweb --list-services |
1 | output |
1 | sudo firewall-cmd --zone=privateDNS --list-services |
1 | dns |
现在您已经成功地建立了属于您的区域!如果您想要把其中一个区域设置为其他网络接口的默认区域,记得使用参数--set-defalut-zone=
1 | sudo firewall-cmd --set-default-zone=publicweb |
总结
您现在应该对如何在CentOS系统上日常使用的防火墙服务进行充分的了解。
Firewalld服务允许您配置依据网络环境的可维护规则和规则集。 它使您可以通过使用区域在不同的防火墙策略之间无缝过渡,并使管理员能够将端口管理抽象为更友好的服务定义。 掌握该系统的使用知识将使您能够利用此工具提供的灵活性和强大功能。
By Justin Ellingwood