如何在CentOS 7上使用FirewallD设置防火墙

介绍

Firewalld是一种防火墙管理解决方案,可用于许多Linux发行版,它们充当Linux内核提供的iptables包过滤系统的前端。在本教程中,我们将介绍如何为您的服务器设置防火墙,并向您展示使用firewall-cmd管理工具管理防火墙的基础知识。

注意:您可能正在使用比撰写本文时更新版本的firewalld,或者您的服务器设置与本教程中使用的示例服务器略有不同。因此,本教程中介绍的某些命令的行为可能会因您的具体配置而异。

要完成本教程,你需要具备以下内容:

  • 一台已经设置好可以使用sudo命令的非root账号的CentOS服务器,并且已开启防火墙。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器

Firewalld的基本概念

在我们开始讨论如何实际使用该firewall-cmd实用程序来管理防火墙配置之前,我们应该熟悉该工具引入的一些基本概念。

firewalld守护程序管理使用实体被称为“区”的规则组。区域基本上是一组规则,规定应允许哪些流量,具体取决于您在计算机所连接的网络中的信任级别。为网络接口分配一个区域,以指示防火墙应允许的行为。

对于可能经常在网络之间移动的计算机(如笔记本电脑),这种灵活性提供了一种根据您的环境更改规则的好方法。在公共WiFi网络上运行时,您可能有严格的规则禁止大多数流量,同时在连接到家庭网络时允许更宽松的限制。对于服务器,这些区域不是那么重要,因为网络环境很少(如果有的话)发生变化。

无论您的网络环境有多动态,熟悉firewalld每个预定义区域背后的一般概念仍然很有用。从最不信任最信任的顺序,其中的firewalld预定义区域是:

  • drop:最低级别的信任。删除所有传入连接而不进行回复,只能进行传出连接。
  • block:与上面类似,但不是简单地删除连接,而是使用icmp-host-prohibitedicmp6-adm-prohibited消息拒绝传入的请求。
  • public:代表公共的,不受信任的网络。您不信任其他计算机,但可能会根据具体情况允许选定的传入连接。
  • external:如果您使用防火墙作为网关,则为外部网络。它配置为NAT伪装,以便您的内部网络保持私有但可访问。
  • internal:外部区域的另一侧,用于网关的内部部分。计算机相当值得信赖,并提供一些额外的服务。
  • dmz:用于位于DMZ中的计算机(无法访问网络其余部分的独立计算机)。仅允许某些传入连接。
  • 工作:用于工作机器。信任网络中的大多数计算机。可能会允许更多服务。
  • :一个家庭环境。它通常意味着您信任大多数其他计算机,并且将接受更多服务。
  • 信任:信任网络中的所有计算机。最开放的可用选项,应谨慎使用。

要使用防火墙,我们可以创建规则并更改区域的属性,然后将网络接口分配给最合适的区域。

规则持久性

在firewalld中,规则可以指定为永久或当下。如果添加或修改了规则,则默认情况下会修改当前运行的防火墙的行为。在下次启动时,将恢复旧规则。

大多数firewall-cmd操作都可以使用该--permanent标志来指示应该将非短暂防火墙作为目标。这将影响引导时重新加载的规则集。这种分离意味着您可以在活动防火墙实例中测试规则,然后在出现问题时重新加载。您还可以使用该--permanent标志随着时间的推移构建一整套规则,这些规则将在发出重新加载命令时立即应用。

安装并启用防火墙以在启动时启动

firewalld 默认安装在某些Linux发行版上,包括许多CentOS 7的图像。但是,您可能需要自己安装firewalld:

sudo yum install firewalld

安装firewalld后,您可以启用该服务并重新启动服务器。请记住,启用firewalld将导致服务在启动时启动。最佳做法是在配置此行为之前创建防火墙规则并利用机会对其进行测试,以避免潜在问题。

sudo systemctl enable firewalld
sudo reboot

当服务器重新启动时,应启动防火墙,将网络接口放入您配置的区域(或回退到配置的默认区域),并且与区域关联的任何规则将应用于关联的接口。

我们可以通过输入以下内容来验证服务是否正在运行且可访问:

sudo firewall-cmd --state

输出如下:

running

这表示我们的防火墙已启动并使用默认配置运行。

熟悉当前的防火墙规则

在我们开始进行修改之前,我们应该熟悉守护程序提供的默认环境和规则。

探索默认值

我们可以通过输入以下内容来查看当前选择的区域是否为默

firewall-cmd --get-default-zone

输出如下:

public

由于我们没有给出firewalld任何偏离默认区域的命令,并且我们的接口都没有配置为绑定到另一个区域,因此该区域也将是唯一的“活动”区域(控制接口流量的区域) )。我们可以通过输入来验证:

firewall-cmd --get-active-zones

输出如下:

public
  interfaces: eth0 eth1

在这里,我们可以看到我们的示例服务器有两个网络接口由防火墙(eth0eth1)控制。它们目前都是根据为公共区域定义的规则进行管理的。

我们怎么知道哪些规则与公共区域有关?我们可以输入以下内容打印出默认区域的配置:

sudo firewall-cmd --list-all

输出如下:

  public (default, active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources: 
  services: ssh dhcpv6-client
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

我们可以从输出中看出这个区域既是默认区域又是活动区域,eth0eth1接口与该区域相关联(我们之前的查询已经知道了这些)。但是,我们还可以看到此区域允许与DHCP客户端(用于IP地址分配)和SSH(用于远程管理)相关的正常操作。

探索替代区域

现在我们对默认和活动区域的配置有了一个很好的了解。我们也可以找到有关其他区域的信息。

要获取可用区域的列表,请输入:

firewall-cmd --get-zones

输出如下:

block dmz drop external home internal public trusted work

我们可以通过在--list-all命令中的--zone=参数来查看与区域关联的特定配置:

sudo firewall-cmd --zone=home --list-all

输出如下:

  home
  interfaces: 
  sources: 
  services: dhcpv6-client ipp-client mdns samba-client ssh
  ports: 
  masquerade: no
  forward-ports: 
  icmp-blocks: 
  rich rules:

您可以使用该--list-all-zones选项输出所有区域定义。您可能希望将输出通过管道传输到寻呼机以便于查看:

sudo firewall-cmd --list-all-zones | less

选择接口的区域

除非您已经配置了网络接口,否则在引导防火墙时,每个接口都将被置于默认区域中。

更改接口区域

通过将--zone=参数与--change-interface=参数结合使用,可以在会话期间转换区域之间的接口。与修改防火墙的所有命令一样,您将需要使用sudo

例如,我们可以通过输入以下内容将我们的eth0界面转换到“home”区域:

sudo firewall-cmd --zone=home --change-interface=eth0

输出如下:

success

注意

无论何时将接口转换到新区域,请注意您可能正在修改可运行的服务。例如,在这里我们将转移到具有SSH可用的“主页”区域。这意味着我们的连接不应该丢失。某些其他区域默认情况下未启用SSH,如果在使用其中一个区域时断开连接,则可能会发现自己无法重新登录。

我们可以通过再次询问活动区域来验证这是否成功:

firewall-cmd --get-active-zones

输出如下:

home
  interfaces: eth0
public
  interfaces: eth1

调整默认区域

如果您的所有接口最好由单个区域处理,则可能更容易选择最佳默认区域,然后将其用于您的配置。

您可以使用--set-default-zone=参数更改默认区域。这将立即将已恢复默认的任何界面更改为新区域:

sudo firewall-cmd --set-default-zone=home

输出如下:

success

为您的应用程序设置规则

为您希望提供的服务定义防火墙例外的基本方法很简单。我们将在这里介绍基本想法。

向您的区域添加服务

最简单的方法是将所需的服务或端口添加到您正在使用的区域。同样,您可以使用以下--get-services选项获取可用服务的列表:

firewall-cmd --get-services

输出如下:

RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry dropbox-lansync elasticsearch freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master high-availability http https imap imaps ipp ipp-client ipsec iscsi-target kadmin kerberos kibana klogin kpasswd kshell ldap ldaps libvirt libvirt-tls managesieve mdns mosh mountd ms-wbt mssql mysql nfs nrpe ntp openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius rpc-bind rsh rsyncd samba samba-client sane sip sips smtp smtp-submission smtps snmp snmptrap spideroak-lansync squid ssh synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local xmpp-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

输出如下:

dhcpv6-client http ssh

一旦您测试了一切正常,您可能需要修改永久防火墙规则,以便在重新启动后仍然可以使用您的服务。我们可以通过输入以下命令使我们的“公共”区域更改永久:

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

输出如下:

success

您可以通过向--list-services操作添加--permanent标志来验证这是否成功。您需要用sudo用于任何--permanent操作:

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

输出如下:

dhcpv6-client http ssh

您的“公共”区域现在将允许端口80上的HTTP Web流量。如果您的Web服务器配置为使用SSL / TLS,您还需要添加该https服务。我们可以通过输入以下内容将其添加到当前会话和永久规则集:

sudo firewall-cmd --zone=public --add-service=https
sudo firewall-cmd --zone=public --permanent --add-service=https

如果没有适当的服务怎么办?

firewalld安装中包含的防火墙服务代表了您可能希望允许访问的应用程序的许多最常见要求。但是,可能会出现这些服务不符合您要求的情况。

在这种情况下,您有两种选择。

为您的区域打开一个端口

为特定应用程序添加支持的最简单方法是打开它在相应区域中使用的端口。这与指定端口或端口范围以及您需要打开的端口的关联协议一样简单。

例如,如果我们的应用程序在端口5000上运行并使用TCP,我们可以使用该--add-port=参数将此添加到此会话的“公共”区域。协议可以是tcpudp

sudo firewall-cmd --zone=public --add-port=5000/tcp

输出如下:

success

我们可以使用该--list-ports操作验证这是否成功:

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

输出如下:

5000/tcp

也可以通过用短划线分隔范围内的开始和结束端口来指定连续的端口范围。例如,如果我们的应用程序使用UDP端口4990到4999,我们可以通过输入以下内容在“public”上打开它们:

sudo firewall-cmd --zone=public --add-port=4990-4999/udp

经过测试,我们可能希望将这些添加到永久防火墙。您可以通过输入以下内容来执行:

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

输出如下:

success
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

现在,您可以调整复制文件中的定义:

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。通过按下进入INSERT模式i,我们可以使用以下内容修改现有定义:

<?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>

ESC,然后输入:x以保存并关闭文件。

重新加载防火墙以访问您的新服务:

sudo firewall-cmd --reload

您可以看到它现在属于可用服务列表:

firewall-cmd --get-services

输出如下:

RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry dropbox-lansync elasticsearch example freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master high-availability http https imap imaps ipp ipp-client ipsec iscsi-target kadmin kerberos kibana klogin kpasswd kshell ldap ldaps libvirt libvirt-tls managesieve mdns mosh mountd ms-wbt mssql mysql nfs nrpe ntp openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius rpc-bind rsh rsyncd samba samba-client sane sip sips smtp smtp-submission smtps snmp snmptrap spideroak-lansync squid ssh synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local xmpp-server

您现在可以像平常一样在区域中使用此服务。

创建自己的区域

虽然预定义区域可能对大多数用户来说已经足够了,但定义您自己的区域可能会有所帮助,这些区域更能描述其功能。

例如,您可能希望为Web服务器创建一个名为“publicweb”的区域。但是,您可能希望为您在专用网络上提供的DNS服务配置另一个区域。您可能需要一个名为“privateDNS”的区域。

添加区域时,必须将其添加到永久防火墙配置中。然后,您可以重新加载以将配置带入正在运行的会话中。例如,我们可以通过输入以下内容来创建上面讨论的两个区域:

sudo firewall-cmd --permanent --new-zone=publicweb
sudo firewall-cmd --permanent --new-zone=privateDNS

您可以通过输入以下内容来验证永久配置中是否存在这些内容:

sudo firewall-cmd --permanent --get-zones

输出如下:

block dmz drop external home internal privateDNS public publicweb trusted work

如前所述,这些在防火墙的当前实例中尚不可用:

firewall-cmd --get-zones

输出如下:

block dmz drop external home internal public trusted work

重新加载防火墙以将这些新区域置于活动配置中:

sudo firewall-cmd --reload
firewall-cmd --get-zones

输出如下:

block dmz drop external home internal 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

输出如下:

  publicweb
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: ssh http https
  ports: 
  protocols: 
  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

输出如下:

  privateDNS
  interfaces: 
  sources: 
  services: dns
  ports: 
  masquerade: no
  forward-ports: 
  icmp-blocks: 
  rich rules:

然后我们可以将接口更改为这些新区域以测试它们:

sudo firewall-cmd --zone=publicweb --change-interface=eth0
sudo firewall-cmd --zone=privateDNS --change-interface=eth1

此时,您有机会测试您的配置。如果这些值适合您,则需要将相同的规则添加到永久配置中。您可以通过使用--permanent标志重新应用规则来实现:

sudo firewall-cmd --zone=publicweb --permanent --add-service=ssh
sudo firewall-cmd --zone=publicweb --permanent --add-service=http
sudo firewall-cmd --zone=publicweb --permanent --add-service=https
sudo firewall-cmd --zone=privateDNS --permanent --add-service=dns

永久应用这些规则后,您可以重新启动网络并重新加载防火墙服务:

sudo systemctl restart network
sudo systemctl reload firewalld

验证是否分配了正确的区域:

firewall-cmd --get-active-zones

输出如下:

privateDNS
  interfaces: eth1
publicweb
  interfaces: eth0

并验证适用于两个区域的服务:

sudo firewall-cmd --zone=publicweb --list-services

输出如下:

http https ssh
sudo firewall-cmd --zone=privateDNS --list-services

输出如下:

dns

您已成功设置自己的区域!如果要将其中一个区域设置为其他接口的默认区域,请记住使用--set-default-zone=参数配置该行为:

sudo firewall-cmd --set-default-zone=publicweb

结论

您现在应该非常了解如何在CentOS系统上管理firewalld服务以供日常使用。

firewalld服务允许您配置考虑到网络环境的可维护规则和规则集。它允许您通过区域的使用在不同的防火墙策略之间无缝转换,并使管理员能够将端口管理抽象为更友好的服务定义。获得该系统的工作知识将使您能够利用此工具提供的灵活性和强大功能。

想要了解更多关于CentOS的开源信息教程,请前往腾讯云+社区学习更多知识。

参考文献:《How To Set Up a Firewall Using FirewallD on CentOS 7》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏拂晓风起

Firefox 扩展开发 扩展学习 工具

1188
来自专栏编程微刊

十分钟上手-搭建vue开发环境(新手教程)

2124
来自专栏学海无涯

Java Web之Cookie和Session的理解

Cookie和Session.jpg 日常现象 登录了某个网站,过一会儿再登录,诶,不用输入密码了,直接是登录状态了,好神奇~~~ 在某网站看了一部手机,接下来...

2903
来自专栏编码小白

Ofbiz模块加载机制即创建独立模块(脱离热部署)

一般我们在ofbiz下的hot-deploy下直接创建模块组件就可以进行访问,但是我觉得文件过多话,就不方便管理,所以我们可以分离出来单独建立一个文件模块...

3035
来自专栏我是攻城师

spark on yarn 如何集成elasticsearch

3956
来自专栏风中追风

分布式基础__session 和 cookie的差异

HTTP协议是一种无状态的 通信协议 。那么这就以为着 客户端按道理是需要每次请求之前都要和服务器做连接的。 但是每次都进行这种连接,会非常耗时,并且这些重复...

39010
来自专栏性能与架构

Pinterest 的 ZooKeeper 经验

Pinterest 在官方博客上发布了自己对于 ZooKeeper 的运用经验,下面一起看下 Pinterest 是如何应用 ZooKeeper 及遇到的问题和...

4258
来自专栏Rainbond开源「容器云平台」

好雨云帮每周更新日志(2017.02.13~2017.02.19)

1135
来自专栏从流域到海域

数据库连接池

数据库连接池相关资料: 关于数据库连接池的使用,首先我们要明白我们为什么要用它,对应普通的数据库连接操作,通常会涉及到以下一些操作是比较耗时的: 网络通讯...

2267
来自专栏L宝宝聊IT

puppet部署与应用

1504

扫码关注云+社区