概述

在安装完系统之后有好几个东西会让我们体验到不爽,除了前面说过的 SELinux 之外,至少还有一个 Firewalld,所以为了让生活更美好,有必要好好来了解一下 Firewalld 这个组件。在以前,我只知道 CentOS 的防火墙是由 iptables 来控制的,而大概两年多前我也简单写过一篇总结的文章:iptables 深度详解,但是当到了 CentOS 7 之后,竟然被推荐关闭 iptables,转而打开 Firewalld,着实让我有点慌。

不过从介绍来看,Firewalld 其实就是 iptables 的一个上层封装和加强,正如 iptables 是内核 netfilter 的封装一般,Firewalld 可以让防火墙管理更加的自然和舒服。下面我就以我的理解来介绍一下 Firewalld 的部分特性,希望能够帮助到你。

Firewalld Concepts

在 Firewalld 中一个核心的概念就是 Zone 的概念,不同的 Zone 包含着一组不同的过滤规则,在某一个时刻,我们只会使用到一个 Zone,虽然 Firewalld 提供了 9 个 Zone,分别是:

默认情况下,应该使用的是 pubilc Zone,这个可以通过 firewall-cmd --get-default-zone 来查看:

public Zone 特点就是除了预设规则之内的端口或者 service 等,其他一律都是会被拒绝掉的,而且,这种拒绝不会以 icmp 的形式提醒,而是等待你的连接超时,所以当你遇到连接超时等情况的时候,不妨先看看 Firewalld 的状态。

除了 Zone 之外,Firewalld 与 SELinux 一样也存在 service 的概念,一个 service 就是我们常说的各种系统服务,例如 sshhttp,这里这是 Firewalld 预设好了这些 service 对应的端口(80)和协议(tcp),所以当我们需要主动打开一个端口的时候就不用指定 80/tcp 这样的组合了,直接指定 http 就 OK 了。

Firewalld 可以通过 firewall-cmd --list-all 来查看当前 Zone 的规则,通过可以通过 firewall-cmd --add-servicefirewall-cmd --remove-service 来添加和删除 service,这里就以 http 为例子演示一下:

从这里可以看到在 Line 9 中原本只有 sshdhcpv6-client 这两个 service,当添加 http 之后,在 Line 28 中就多了一个 http。如果你本地安装了 HTTP Server 的话,你就可以发现添加之前是访问不了 HTTP Server 的,直到添加之后才可以访问成功。OK,这就是所谓的 service 了。

Firewalld 的常见操作

了解这些基本概念之后,操作起来应该也就心中有底了,所以当我们玩的飞起得时候就会想是否有一些更好的命令来支撑设置。Firewalld 除了内置的 service 之外,还有各种功能可以发掘,下面我就以几个场景为例子,介绍一些可能会使用到的操作。

添加新的 service

因为 Firewalld 的 service 都是内置的,所以如果你需要自定义端口的时候,除了直接指定端口和协议外,自定义 service 也不失为一个好方式。Firewalld 自定义 service 有两种方式,一种是通过配置文件的形式添加,另外一种是通过命令行的形式添加。

在 Firewalld 中,定义配置文件有两个位置,分别是:

其中 /usr/lib/firewalld 是 Firewalld 内置的配置目录,所以作为使用者我们最好不去动他,这样的话,很明显,自定义 service 的配置就放在: /etc/firewalld 中了。Firewalld 定义 service 的配置是 XML 格式,内容也比较简单,这里就找一个简单的内置的 mysql 为例,简单看一下配置的格式:

可以看到整体上描述是比较清晰得,你可以按照这个格式设置好,然后放在:/etc/firewalld/services/ 目录下,记得设置外之后别忘了执行 firewall-cmd --reload 让 Firewalld 加载一下你的配置。

除了使用文件配置之外,Firewalld 还支持命令增加 service,不过不怎么方便的一点就是增加 service 的属性只能一个个增加,同时,使用命令行增加 service 如果使用的是 permanent 模式的话,也一样需要 reload 一下 Firewalld,下面就示例一下如何用命令行定义一个 service

这里可以看到定义 myservice 已经成功了,我们后续就可以在规则中应用了。

添加端口过滤

如果我们嫌添加一个 service 太麻烦,其实直接打开端口也是支持的,而且也很简单,并且支持多样化的操作。通过 firewall-cmd --add-port 我们可以一次添加一个端口,也可以添加范围端口,还可以添加多个端口,下面就演示一下怎么使用:

从这里可以看到前面说的几个示例:

Firewalld 的状态控制

如果你觉得你将 Firewalld 的配置弄乱了,不妨删除掉 /etc/firewalld 目录下的自定义配置,然后使用 firewall-cmd --reload 来恢复默认配置,这也是我为什么不推荐你动默认配置的原因,至少很多时候你有后悔的机会。

如果你觉得实在 hold 不住 Firewalld 了,想要关闭,没问题,可以通过 systemctl 进行 Firewalld 的运行关闭:

端口代理

在 iptables 中我们知道有个功能可以做端口转发代理,既然 Firewalld 比 iptables 要强大,那么这个简单的功能应该也不在话下,事实上就是这样的,而且使用起来及其简单,通过:firewall-cmd --add-forward-port 可以很方便得添加转发端口代理,下面就以本地 8080 端口代理 80 端口为例进行个示例:

可以看到,一条非常简单的命令就完成了这件事情,这个时候不妨访问一下你的 8080 端口看看效果,别忘了没提醒你,请记得打开 8080 端口的限制哦。

Reference