Red Hat Training

A Red Hat training course is available for Red Hat Linux

4.5. 使用防火墙

4.5.1. 防火墙简介

动态防火墙后台程序 firewalld 提供了一个 动态管理的防火墙,用以支持网络 zones ,以分配对一个网络及其相关链接和界面一定程度的信任。它具备对 IPv4IPv6 防火墙设置的支持。它支持以太网桥,并有分离运行时间和永久性配置选择。它还具备一个通向服务或者应用程序以直接增加防火墙规则的接口。

4.5.2. 了解防火墙

一个图像化的配置工具,firewall-config,用于配置 firewalld:它依次用 iptables工具 与执行数据包筛选的内核中的 Netfilter 通信,
使用图像化的 firewall-config 工具,按下 Super 键进入活动总览,点击 firewall,然后按下 Enterfirewall-config 工具就出现了。您将被提示输入管理员密码。
firewall-config 工具里有一个标记为 Configuration 的下拉菜单,可以在 运行时间永久 两种模式之间进行选择。要注意,如果您选择了 Permanent ,在左上角会出现一排附加的图标。因为不能在运行模式下改变一个服务参数,所以这些图标仅在永久配置模式中出现。
firewalld 提供的是动态的防火墙服务,而非静态的。因为配置的改变可以随时随地立刻执行,不再需要保存或者执行这些改变。现行网络连接的意外中断不会发生,正如防火墙的所有部分都不需要重新下载。
提供命令行客户端,firewall-cmd,用于进行永久性或非永久性运行时间的改变,正如在 man firewall-cmd(1)所解释的一样。永久性改变需要按照 firewalld(1) 手册页的解释来进行。注意, firewall-cmd 命令可以由 root 用户运行,也可以由管理员用户——换言之, wheel 群体的成员运行。在后一种情况里,命令将通过 polkit 进程来授权。
firewalld 的配置储存在 /usr/lib/firewalld//etc/firewalld/ 里的各种 XML 文件里,这样保持了这些文件被编辑、写入、备份的极大的灵活性,使之可作为其他安装的备份等等。
其他应用程序可以使用 D-bus 和 firewalld 通信。

4.5.3. 比较 system-config-firewall 以及 iptables 的 firewalld

firewalldiptables service 之间最本质的不同是:
  • iptables service/etc/sysconfig/iptables 中储存配置,而 firewalld 将配置储存在 /usr/lib/firewalld//etc/firewalld/ 中的各种 XML 文件里,。要注意,当 firewalld 在Red Hat Enterprise Linux上安装失败时, /etc/sysconfig/iptables 文件就不存在。
  • 使用 iptables service,每一个单独更改意味着清除所有旧有的规则和从 /etc/sysconfig/iptables里读取所有新的规则,然而使用 firewalld 却不会再创建任何新的规则;仅仅运行规则中的不同之处。因此,firewalld 可以在运行时间内,改变设置而不丢失现行连接。
使用 iptables tool 与内核包过滤对话也是如此。
防火墙堆栈

图 4.1. 防火墙堆栈

4.5.4. 对网络区的理解

基于用户对网络中设备和交通所给与的信任程度,防火墙可以用来将网络分割成不同的区域。 NetworkManager 通知 firewalld 一个接口归属某个区域。接口所分配的区域可以由 NetworkManager 改变,也可以通过能为您打开相关 NetworkManager 窗口的 firewall-config 工具进行。
/etc/firewalld/的区域设定是一系列可以被快速执行到网络接口的预设定。列表并简要说明如下:
drop(丢弃)
任何接收的网络数据包都被丢弃,没有任何回复。仅能有发送出去的网络连接。
block(限制)
任何接收的网络连接都被 IPv4icmp-host-prohibited 信息和 IPv6icmp6-adm-prohibited 信息所拒绝。
public(公共)
在公共区域内使用,不能相信网络内的其他计算机不会对您的计算机造成危害,只能接收经过选取的连接。
external(外部)
特别是为路由器启用了伪装功能的外部网。您不能信任来自网络的其他计算,不能相信它们不会对您的计算机造成危害,只能接收经过选择的连接。
dmz(非军事区)
用于您的非军事区内的电脑,此区域内可公开访问,可以有限地进入您的内部网络,仅仅接收经过选择的连接。
work(工作)
用于工作区。您可以基本相信网络内的其他电脑不会危害您的电脑。仅仅接收经过选择的连接。
home(家庭)
用于家庭网络。您可以基本信任网络内的其他计算机不会危害您的计算机。仅仅接收经过选择的连接。
internal(内部)
用于内部网络。您可以基本上信任网络内的其他计算机不会威胁您的计算机。仅仅接受经过选择的连接。
trusted(信任)
可接受所有的网络连接。
指定其中一个区域为默认区域是可行的。当接口连接加入了 NetworkManager,它们就被分配为默认区域。安装时,firewalld 里的默认区域被设定为公共区域。

4.5.5. 选择一个网络区域

网络区域名已经选定为不加说明,即可明了,并允许用户快速地做出合理决定。但是,应对默认配置的设定进行检查,而且根据您的需要和风险评估,不必要的服务将不能使用。

4.5.6. 对预先定义的服务的理解

一项服务可以是本地和目的地端口的列表,如果服务被允许的话,也可以是一系列自动加载的防火墙辅助模块。预先定义的服务的使用,让客户更容易被允许或者被禁止进入服务。与对开放端口或者值域,或者端口截然不同,使用预先定义服务,或者客户限定服务,或许能够让管理更容易。 firewalld.service(5) 中的手册页描述了服务配置的选择和通用文件信息。服务通过单个的 XML 配置文件来指定,这些配置文件则按以下格式命名:service-name.xml
用图形化 firewall-config 工具查看服务列表,按下 Super 键进入开始菜单,输入 firewall 然后按下 Enterfirewall-config 工具就出现了。您将被提示输入管理员密码。现在,在 Services 标签下,您可以查看服务列表了。
要使用命令行列出默认的预先定义服务,以 root 身份执行以下命令:
~]# ls /usr/lib/firewalld/services/
请勿编辑/usr/lib/firewalld/services/ ,只有 /etc/firewalld/services/ 的文件可以被编辑。
要列出系统或者用户创建的系统,以 root 身份执行以下命令:
~]# ls /etc/firewalld/services/
使用图形化 firewall-config 工具和通过编辑 /etc/firewalld/services/ 中的 XML 文件,服务可以被增加和删除。如果服务没有被用户增加或者改变,那么 /etc/firewalld/services/ 中不会发现相应的 XML 文件。如果您希望增加或者改变服务, /usr/lib/firewalld/services/ 文件可以作为模板使用。以 root 身份执行以下命令:
~]# cp /usr/lib/firewalld/services/[service].xml /etc/firewalld/services/[service].xml
然后您可以编辑最近创建的文件。firewalld 优先使用 /etc/firewalld/services/ 里的文件,如果一份文件被删除且服务被重新加载后,会切换到 /usr/lib/firewalld/services/

4.5.7. 理解直接接口

firewalld 有一个被称为 direct interface(直接接口),它可以直接通过 iptablesip6tablesebtables 的规则。它适用于应用程序,而不是用户。如果您不太熟悉 iptables,那么使用直接接口是很危险的,因为您可能无意中导致防火墙被入侵。firewalld 保持对所增加项目的追踪,所以它还能质询 firewalld 和发现由使用直接端口模式的程序造成的更改。直接端口由增加 --direct 选项到 firewall-cmd 命令来使用。
直接端口模式适用于服务或者程序,以便在运行时间内增加特定的防火墙规则。这些规则不是永久性的,它们需要在每次通过 D-BU S从 firewalld 接到启动、重新启动和重新加载信息后运用。

4.5.8. 检查是否已安装防火墙

在 Red Hat Enterprise Linux 7 中,默认安装 firewalld 和图形化用户接口配置工具 firewall-config。作为 root 用户运行下列命令可以检查:
~]# yum install firewalld firewall-config

4.5.9. 禁用防火墙

要禁用 firewalld,则作为 root 用户运行下列命令:
~]# systemctl disable firewalld
# systemctl stop firewalld

4.5.10. 使用 iptables 服务

要用 iptablesip6tables 服务代替 firewalld,则以 root 身份运行以下命令,先禁用 firewalld
~]# systemctl disable firewalld
# systemctl stop firewalld
然后安装 iptables-services 程序包,以 root 身份输入以下命令:
~]# yum install iptables-services
iptables-services 程序包包含了 iptables 服务和 ip6tables 服务。
然后,以 root 身份运行 iptablesip6tables 命令:
  # systemctl start iptables
  # systemctl start ip6tables
  # systemctl enable iptables
  # systemctl enable ip6tables

4.5.11. 启动防火墙

要启动 firewalld,则以 root 用户身份输入以下命令:
~]# systemctl start firewalld

4.5.12. 检查防火墙是否运行

如果 firewalld 在运行,输入以下命令检查:
~]$ systemctl status firewalld
firewalld.service - firewalld - dynamic firewall daemon
	  Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
	  Active: active (running) since Sat 2013-04-06 22:56:59 CEST; 2 days ago
	Main PID: 688 (firewalld)
	  CGroup: name=systemd:/system/firewalld.service
另外,检查 firewall-cmd 是否可以通过输入以下命令来连接后台程序:
~]$ firewall-cmd --state 
running

4.5.13. 安装防火墙

要安装firewalld,则以 root 用户身份运行以下命令:
~]# yum install firewalld
要安装图形化用户接口工具 firewall-config,则以 root 用户身份运行下列命令:
~]# yum install firewall-config

4.5.14. 配置防火墙

防火墙可以通过使用图形化用户接口工具 firewall-config、命令行接口工具 firewall-cmd 和编辑 XML 配置文件来配置。下面会以此详述这些方法:

4.5.14.1. 使用图形化用户接口配置防火墙

4.5.14.1.1. 启动图形化防火墙设置工具
要启动图形化 firewall-config 工具,按下 Super 键进入开始菜单,点击 firewall,然后按 Enter 键,firewall-config 工具就出现了。您会被提示输入一个管理员密码。
要用命令行启动图形化防火墙配置工具,则以 root 用户身份输入以下命令:
~]# firewall-config
Firewall Configuration 窗口就打开了。注意,这个命令可以由普通用户运行,但随后您会被反复提示输入管理员密码。
防火墙配置工具

图 4.2. 防火墙配置工具

在左下方角落寻找 Connected 字符,这标志着 firewall-config 工具已经连接到用户区后台程序 firewalld。注意,ICMP TypesDirect ConfigurationLockdown Whitlist 标签只在从 View 下拉菜单中选择之后才能看见。
4.5.14.1.2. 改变防火墙设置
要立刻改变现在的防火墙设置,须确定当前视图设定在 Runtime。或者,从下拉菜单中选择 Permanent,编辑下次启动系统或者防火墙重新加载时执行的设定。

注意

Runtime 模式下更改防火墙的设定时,一旦您启动或者清除连接服务器的复选框,选择立即生效。当您在一个也许还被其他用户使用的系统上工作时,应当谨记这一点。
Permanent 模式下更改防火墙的设定,您的选择将仅仅在您重新加载防火墙或者系统重启之后生效。您可以使用 文件 菜单下的重新加载图标,或者点击 选项 菜单,选择 重新加载防火墙
您可以选择左边列里的分区。您将注意到这些分区包含一些可用的服务,您可能需要调整或者滚动窗口才能看见整个列表。您可以通过选择和取消选择一个服务来自定义设定。
4.5.14.1.3. 增加一个接口到分区
要增加或者重新分配一个连接到分区的接口,则启动 firewall-config,从菜单栏选择 Options,由下拉菜单里选择 更改连接的分区 Connections 列表就出现了。选择被分配的连接,出现 Select Zone for Connection 窗口。从下拉菜单中选择新的防火墙分区并点击 OK
4.5.14.1.4. 设置默认分区
要设定一个将要被分配新接口的分区作为默认值,则启动 firewall-config,从菜单栏选择Options,由下拉菜单中选择 Change Default Zone,出现Default Zone 窗口。从给出的列表中选择您需要用的分区作为默认分区,点击 OK
4.5.14.1.5. 配置服务
要使用或者禁用一个预先设定或用户服务,则启动 firewall-config工具并选择将要配置服务的网络分区。选中Services标签并选择每个您需要信任的服务类型的复选框。清除复选框则限制服务。
要编辑一项服务,开始 firewall-config 工具,然后从标记为 Configuration 的下拉选项菜单选择 Permanent 模式。其余的图标和菜单案件会出现在 Services 窗口的底部。选择您想要配置的服务。
Ports and Protocols 标签可以为选择的服务执行增加、更改、移除端口和协议。模块标签用于配置 Netfilter 辅助模块。Destination模块使得受限的流量进入一个特定的目的地址和互联网协议 (IPv4 or IPv6)。
4.5.14.1.6. 打开防火墙里的端口
要允许流量通过防火墙到达某个端口,则启动 firewall-config 并选择您想更改设定的网络区域。选择 Ports 图标并点击右边的 Add 按钮,Port and Protocol 就打开了。
输入端口数量或者端口号范围,获得许可。从下拉菜单中选择 tcp 或者 udp
4.5.14.1.7. 使用伪装的 IP 地址
要将 IPv4 地址转换为一个单一的外部地址,则启动 firewall-config 工具并选择需要转换地址的网络区域。选择 Masquerading 标签和复选框以便把 IPv4 地址转换成一个单一的地址。
4.5.14.1.8. 配置端口转发
为一个特定端口转发入站网络流量或 packets 到一个内部地址或者替代端口,首先激活伪装IP地址,然后选择 Port Forwarding 标签。
在窗口靠上部分选择入站流量协议和端口或者端口范围。靠下部分是用于设置目的端口细节的。
要转发流量到一个本地端口即同一系统上的端口,需选择 Local forwarding 复选框,输入要转发的流量的本地端口或者端口值范围。
要转发流量到其他的 IPv4 地址,则选择 Forward to another port 复选框,输入目的地 IP 地址和端口或者端口范围。如果端口位置空缺则默认发送到同一个端口。点击 OK 执行更改。
4.5.14.1.9. 配置 ICMP 过滤
要使用或者禁用一个 ICMP 过滤,则启动 firewall-config 工具并选择要过滤其信息的网络区域。选择 ICMP Filter 图标并选择每种您需要过滤的 ICMP 信息类型的复选框。清除复选框以禁用过滤。这种设定是单向的,默认允许全部。
要编辑一个 ICMP 类型,则启动 firewall-config然后从标签为 Configuration 的下拉菜单里选择 Permanent 模式。在 Services 窗口底部会出现附加图标。

4.5.14.2. 用命令行工具 firewall-cmd 配置防火墙

命令行工具 firewall-cmd 是默认安装的应用程序 firewalld 的一部分。您可以查证到它是为检查版本或者展示帮助结果而安装的。输入如下命令来检查版本:
~]$ firewall-cmd --version
输入如下命令来查看帮助输出:
~]$ firewall-cmd --help
我们在下面选列出一些命令,完整列表请查看操作说明 man firewall-cmd(1)

注意

为了设置一个永久或者可执行命令,除了 --direct 命令(它们本质上是暂时的)之外,要向所有命令添加 --permanent 选择。注意,这不只是意味着永久更改,而且更改将仅仅在防火墙重新加载、服务器重启或者系统重启之后生效。用 firewall-cmd 设置的缺少 --permanent 选项的设定能立即生效,但是它仅仅在下次防火墙重新加载、系统启动或者 firewalld 服务重启之前可用。防火墙不会在断开连接时重新加载,而会提示您通过重新加载,放弃临时更改。

4.5.14.3. 用命令行接口(CLI)查看防火墙设置

输入以下命令,得到 firewalld 的状态的文本显示:
~]$ firewall-cmd --state
输入以下命令,查看活动分区的列别,并附带一个目前分配给它们的接口列表:
~]$ firewall-cmd --get-active-zones
public: em1 wlan0
输入以下命令,找出当前分配了接口(例如 em1)的区域:
~]$ firewall-cmd --get-zone-of-interface=em1
public
root 身份输入以下命令,找出分配给一个区域(例如公共区域)的所有接口:
~]# firewall-cmd --zone=public --list-interfaces
em1 wlan0
NetworkManager 可以得到这个信息,并且仅显示接口而非连接。
root 用户身份输入以下命令,找出像公共区域这样的一个区域的所有设置:
~]# firewall-cmd --zone=public --list-all
public
  interfaces: 
  services: mdns dhcpv6-client ssh
  ports: 
  forward-ports: 
  icmp-blocks: source-quench
root 身份输入以下命令,查看目前活动的网络区域:
~]# firewall-cmd --get-service
cluster-suite pop3s bacula-client smtp ipp radius bacula ftp mdns samba dhcpv6-client dns openvpn imaps samba-client http https ntp vnc-server telnet libvirt ssh ipsec ipp-client amanda-client tftp-client nfs tftp libvirt-tls
这样将列出 /usr/lib/firewalld/services/ 中的服务器名称。注意,配置文件是以服务本身命名的 service-name.xml
root 身份输入以下命令,查看所有在防火墙下次加载后将活跃的网络区域:
~]# firewall-cmd --get-service --permanent

4.5.14.4. 用命令行接口(CLI)更改防火墙设置

4.5.14.4.1. 终止所有数据包(Panic模式)
root 身份输入以下命令,开始终止所有输入和输出的数据包:
~]# firewall-cmd --panic-on
所有输入和输出的数据包都将被终止。在一段休止状态之后,活动的连接将被终止;花费的时间由单个会话的超时值决定。
root 身份输入以下命令,开始再次传输输入和输出的数据包:
~]# firewall-cmd --panic-off
禁用 panic 模式之后,如果 panic 模式被运行一小段时间,建立的连接可以再次工作。
输入命令,确定 panic 模式被使用或者禁用:
~]$ firewall-cmd --query-panic
如果在运行模式,屏幕会显示 yes,退出状态为 0,如果被启用,屏幕会显示 no,退出状态为 0
4.5.14.4.2. 用命令行接口(CLI)重新加载防火墙
root 身份输入以下命令,重新加载防火墙,并不中断用户连接,即不丢失状态信息:
~]# firewall-cmd --reload
root 身份输入以下信息,重新加载防火墙并中断用户连接,即丢弃状态信息:
~]# firewall-cmd --complete-reload
通常在防火墙出现严重问题时,这个命令才会被使用。比如,防火墙规则是正确的,但却出现状态信息问题和无法建立连接。
4.5.14.4.3. 用命令行接口(CLI)为分区增加接口
要为一个分区增加接口,比如,把 em1 增加到公共分区,则以 root 身份输入以下命令:
~]# firewall-cmd --zone=public --add-interface=em1
增加 --permanent 选项并重新加载防火墙,使之成为永久性设置。
4.5.14.4.4. 通过编辑接口配置文件为分区增加接口
要通过编辑 ifcfg-em1 配置文件来为一个分区增加接口,比如,把 em1 增加到工作分区,需以 root 身份用一个编辑器增加以下行到 ifcfg-em1
ZONE=work
注意,如果您遗漏 ZONE 选项,或者使用 use ZONE=ZONE='',那么默认区将被使用。
NetworkManager 程序将自动连接,相应地,分区将被设定。
4.5.14.4.5. 通过编辑防火墙配置文件来配置默认分区
root 用户身份,打开 /etc/firewalld/firewalld.conf 并按如下方式编辑文件:
 # default zone
 # The default zone used if an empty zone string is used.
 # Default: public
 DefaultZone=home
root 身份输入以下命令,以重新加载防火墙:
~]# firewall-cmd --reload
这样可以在不丢失状态信息的同时重新加载防火墙(TCP对话不会被中断)。
4.5.14.4.6. 使用命令行接口(CLI)设置默认分区
root 用户身份输入以下命令来设置默认分区,比如设置为公共区域:
~]# firewall-cmd --set-default-zone=public
这个更改将立刻生效,而且在此情况下不需要重新加载防火墙。
4.5.14.4.7. 用命令行接口打开防火墙的端口
通过以 root 身份输入以下命令,列出一个区域,例如 dmz 的所有开放端口:
~]# firewall-cmd --zone=dmz --list-ports
要将一个端口加入一个分区,例如,允许 TCP 的流量通过端口 8080 的 进入dmz分区,则以 root 身份输入以下命令:
~]# firewall-cmd --zone=dmz --add-port=8080/tcp
增加 --permanent 选项并重新加载防火墙,使之成为永久性设置。
要将一系列端口加入一个分区,比如允许从 5060 到 5061 的端口都接入公共分区,则以 root 身份输入以下命令:
~]# firewall-cmd --zone=public --add-port=5060-5061/udp
增加 --permanent 选项并重新加载防火墙,使之成为永久性设置。
4.5.14.4.8. 使用命令行接口(CLI)将一个服务加入到分区
要把一个服务加入到分区,例如允许 SMTP 接入工作区,则以 root 身份运行以下命令:
~]# firewall-cmd --zone=work --add-service=smtp
增加 --permanent 选项并重新加载防火墙,使之成为永久性设置。
4.5.14.4.9. 使用命令行接口(CLI)从一个分区移除服务
要从分区移除服务,比如从工作区移除 SMTP,则以 root 身份输入以下命令:
~]# firewall-cmd --zone=work --remove-service=smtp
增加 --permanent 可使这个更改在系统启动后被允许。如果用这个选项,并且希望立刻产生更改,以 root 身份输入以下命令,重新加载防火墙:
~]# firewall-cmd --reload
注意,这并不会中断已经建立的连接。如果您打算中断,您可以使用 --complete-reload 选项,但这不仅仅中断您已经移除的服务,还会中断所有已经建立的连接。
4.5.14.4.10. 通过编辑 XML 文件为一个分区增加服务
root 身份输入以下命令,查看默认分区文件:
~]# ls /usr/lib/firewalld/zones/
block.xml  drop.xml      home.xml      public.xml   work.xml
dmz.xml    external.xml  internal.xml  trusted.xml
这些文件不能编辑。如果 /etc/firewalld/zones/ 目录里没有等效文件存在,它们被默认为可使用。
root 身份输入以下命令,查看从默认区被更改的分区文件:
~]# ls /etc/firewalld/zones/
external.xml  public.xml  public.xml.old
在上述示例中,工作区域文件不存在。以 root 身份输入以下命令,加入工作区文件:
~]# cp /usr/lib/firewalld/zones/work.xml /etc/firewalld/zones/
现在您可以在 /etc/firewalld/zones/ 目录中编辑该文件。如果您删除该文件,firewalld 将切换到使用 /usr/lib/firewalld/zones/ 里的默认文件。
要将一个服务加入分区,比如允许 SMTP 进入工作区,则以 root 权限编辑程序,编辑 /etc/firewalld/zones/work.xml 文件,使之包括如下行:
<service name="smtp"/>
4.5.14.4.11. 通过编辑 XML 文件从一个分区中移除服务
编辑 XML 区域文件,必须以 root 权限运行编辑程序。以 root 身份输入以下命令,查看过去配置的分区的文件:
~]# ls /etc/firewalld/zones/
external.xml  public.xml  work.xml
root 权限来编辑程序,编辑 /etc/firewalld/zones/work.xml 文件来移除如下行:
<service name="smtp"/>
就能从一个分区移除服务,比如从工作区移除 SMTP。如果 work.xml 文件没有进行其他更改,它可以被移除,并且 firewalld 会在下一次重新加载或者系统启动之后使用默认的 /usr/lib/firewalld/zones/work.xml 配置。
4.5.14.4.12. 配置伪装 IP 地址
如果伪装 IP 不能为一个外部区域启用,则以 root 身份输入以下命令来检查:
~]# firewall-cmd --zone=external --query-masquerade
如果可用,屏幕会显示 yes,退出状态为 0; 否则,屏幕显示 no,退出状态为 1。如果省略zone ,默认区域将被使用。
root 身份输入以下命令,允许伪装IP:
~]# firewall-cmd --zone=external --add-masquerade
增加 --permanent 选项并重新加载防火墙,使之成为永久性设置。
root 身份输入以下命令,禁用伪装IP:
~]# firewall-cmd --zone=external --remove-masquerade
增加 --permanent 选项并重新加载防火墙,使之成为永久性设置。
4.5.14.4.13. 使用命令行接口(CLI)配置端口转发
要将进入网络的程序包从一个端口转发到一个替代端口或者地址,首先需以 root 身份输入以下命令来为一个区域(比如外部区域),运行伪装 IP 地址:
~]# firewall-cmd --zone=external --add-masquerade
root 身份输入以下命令,把程序包转发到一个本地端口,即相同系统上的一个端口:
~]# firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toport=3753
在这个例子里,本来要送到 22 端口的程序包现在被转发到 3753 端口。源目的端口用 port 选项指定。这个选项可以是一个端口,或者一组端口范围并加上协议。如果指定协议的话,这个协议必须是 tcpudp。这个新的本地端口,即流量被转发过去的端口或者端口范围,需用 toport 选项指定。增加 --permanent 选项并重新加载防火墙,可以使设置永久保存。
root 身份输入以下命令,不改变目的端口将程序包转发到另一个通常是内部地址的 IPv4 地址:
~]# firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toaddr=192.0.2.55
在这个示例中,原本发往22端口的程序包现在被转发到相同的端口,地址则由 toaddr 提供。源目的地端口用 port 指定。这个选项可能是一个端口,或者一组端口范围并加上协议。如果被指定,协议必须是 tcpudp 中的一个。这个新端口,即流量被转发过去的端口或者端口范围,用 toport 指定。增加 --permanent 选项并重新加载防火墙,使这个设定永久保存。
root 身份输入以下命令,把程序包转发到通常是内部地址的另一个 IPv4 地址:
~]# firewall-cmd --zone=external /
      --add-forward-port=port=22:proto=tcp:toport=2055:toaddr=192.0.2.55
在这个示例中,原本发往 22 端口的程序包现在被转发到和 toaddr 选项一起给出地址的2055端口。源目的端口用 port 选项指定。这个选项可以是一个端口,或者打包了协议的端口范围。如果被指定,这个协议一定是 tcpudp 中的一个。这个新的目的端口,即流量被转发过去的端口或者端口范围,用 toport 指定。增加 --permanent 选项并重新加载防火墙,使这个设置永久保留。

4.5.14.5. 用 XML 文件配置防火墙

firewalld 的配置设定存储在/etc/firewalld/ 目录下的 XML 文件里。切勿编辑 /usr/lib/firewalld/ 目录下的文件,因为它们是为默认设定准备的。查看和编辑这些 XML 文件,您需要 root 的用户许可。三个操作手册对 XML 文件进行了解说:
  • firewalld.icmptype(5) 操作手册 — 描述了 ICMP 过滤的 XML 配置文件。
  • firewalld.service(5) 操作手册 — 描述了 firewalld service 的 XML 配置文件。
  • firewalld.zone(5) 操作手册 — 描述了配置 firewalld 区域的 XML 配置文件。
用图形化工具和命令行工具可以对 XML 文件进行直接创建、编辑或者间接创建。组织可以把它们分配到 RPM 文件里,使管理和版本控制更容易。例如 Puppet 的工具可以分配这种配置文件。

4.5.14.6. 使用直接接口

通过 firewall-cmd 工具,可以使用 --direct 选项在运行时间里增加或者移除链。现提供一些例子,请查阅 firewall-cmd(1) 操作说明获取更多信息。
如果不熟悉 iptables ,使用直接接口非常危险,因为您可能无意间导致防火墙被入侵。
直接端口模式适用于服务或者程序,以便在运行时间内增加特定的防火墙规则。这些规则不是永久性的,它们需要在每次通过 D-BU S从 firewalld 接到启动、重新启动和重新加载信息后运用。
4.5.14.6.1. 使用直接接口增加一个自定义规则
root 身份按照以下格式发布一个命令,增加一个自定义规则到 IN_public_allow 链里:
~]# firewall-cmd --direct --add-rule ipv4 filter IN_public_allow \
      0 -m tcp -p tcp --dport 666 -j ACCEPT
4.5.14.6.2. 用直接接口移除一个自定义规则
root 用户身份按照以下格式发布一个命令,从 IN_public_allow 链移除一个自定义规则:
~]# firewall-cmd --direct --remove-rule ipv4 filter IN_public_allow \
      0 -m tcp -p tcp --dport 666 -j ACCEPT
4.5.14.6.3. 用直接接口列出自定义规则
root 用户身份按照以下格式发布一个命令,列出 IN_public_allow 链中的规则:
~]# firewall-cmd --direct --get-rules ipv4 filter IN_public_allow

4.5.15. 给复杂防火墙规则配置“Rich Language" 语法

通过 rich language 语法,可以用比直接接口方式更易理解的方法建立复杂防火墙规则。此外,还能永久保留设置。这种语言使用关键词值,是 iptables 工具的抽象表示。这种语言可以用来配置分区,也仍然支持现行的配置方式。

4.5.15.1. 多语言命令的格式

在这个部分,所有命令都必须以 root 用户身份运行。增加一项规则的命令格式如下:
firewall-cmd [--zone=zone] --add-rich-rule='rule' [--timeout 9=seconds]
这样将为 zone 分区增加一项多语言规则 rule 。这个选项可以多次指定。如果分区被省略,将使用默认分区。如果出现超时,规则将在指定的秒数内被激活,并在之后被自动移除。
移除一项规则:
firewall-cmd [--zone=zone] --remove-rich-rule='rule'
这将为 zone 分区移除一项多语言规则 (rule) 。这个选项可以多次指定。如果分区被省略,将使用默认分区。
检查一项规则是否存在:
firewall-cmd [--zone=zone] --query-rich-rule='rule'
这将复查是否已经为区域(zone) 增加一个多语言规则 (rule) 。如果可用,屏幕会显示 yes,退出状态为 0; 否则,屏幕显示 no,退出状态为 1。如果省略 zone,默认区域将被使用。
使用在分区配置文件里的多语言表述的相关信息,可查阅 firewalld.zone(5) 说明。

4.5.15.2. 理解多规则结构

多规则命令的格式或结构如下所示:
rule [family="<rule family>"]
    [ source address="<address>" [invert="True"] ]
    [ destination address="<address>" [invert="True"] ]
    [ <element> ]
    [ log [prefix="<prefix text>"] [level="<log level>"] [limit value="rate/duration"] ]
    [ audit ]
    [ accept|reject|drop ]
一个规则是关联某个特定分区的,一个分区可以有几个规则。如果几个规则互相影响或者冲突,则执行和数据包相匹配的第一个规则。如果提供了规则系列,它可以是 ipv4 或者 ipv6 。规则系列把规则限定在 IPv4IPv6 。如果没有提供规则系列, 将为 IPv4IPv6 增加规则。如果源地址或者目标地址在一个规则中被使用,那么必须提供规则系列。端口转发也存在这种情况。

4.5.15.3. 理解多规则命令

source
通过制定源地址,一个尝试连接的源头可以被限制在源地址中。一个源地址或者地址范围是一个为 IPv4 或者 IPv6 做掩护的 IP 地址或者一个网络 IP 地址。网络系列( IPv4IPv6 )将被自动覆盖。针对 IPv4 的伪装可以是一个网络伪装或者一个普通数字。针对 IPv4 的伪装是一个简单数字。不支持使用主机名。可以通过增加 invert="true" 或 invert="yes" 来颠倒源地址命令的意思。所有提供的地址都匹配。
destination
通过制定目的地址,目标可以被限制在目的地址中。目标地址使用跟源地址相同的语法。原地址和目标地址的使用是有选择的,不可能目标地址的所有要素都使用。这取决于目标地址的使用,例如在服务项中,这个要素只可以是以下要素类型之一: serviceportprotocolmasqueradeicmp-blockforward-port
service
服务名称是 firewalld 提供的其中一种服务。要获得被支持的服务的列表,输入以下命令: firewall-cmd --get-services 。如果一个服务提供了一个目标地址,它将和规则中的目标地址冲突,并且导致一个错误。使用内部目的地址的服务大多是使用了多路传送的服务。命令为以下形式:
service name=service_name
port
端口既可以是一个独立端口数字,又或者端口范围,例如,5060-5062。协议可以指定为 tcpudp 。命令为以下形式:
port port=number_or_range protocol=protocol
protocol
协议值可以是一个协议 ID 数字,或者一个协议名。预知可用协议,请查阅 /etc/protocols。命令为以下形式:
protocol value=protocol_name_or_ID
icmp-block
用这个命令阻绝一个或多个 ICMP 类型。 ICMP 类型是 firewalld 支持的 ICMP 类型之一。要获得被支持的 ICMP 类型列表,输入以下命令:
~]$ firewall-cmd --get-icmptypes
在此,指定一个动作是不被允许的。icmp-block 在内部使用 reject 动作。命令为以下形式:
icmp-block name=icmptype_name
masquerade
打开规则里的 IP 伪装。用源地址而不是目的地址来把伪装限制在这个区域内。在此,指定一个动作是不被允许的。
forward-port
从一个带有指定为 tcpudp 协议的本地端口转发数据包到另一个本地端口,或另一台机器,或另一台机器上的另一个端口。 portto-port 可以是一个单独的端口数字,或一个端口范围。而目的地址是一个简单的 IP 地址。在此,指定一个动作是不被允许的。 forward-port 命令使用内部动作 accept 。这个命令为以下形式:
forward-port port=number_or_range protocol=protocol /
            to-port=number_or_range to-addr=address
log
注册含有内核记录的新的连接请求到规则中,比如系统记录。您可以定义一个前缀文本——可以把记录信息作为前缀加入。记录等级可以是 emergalertcriterrorwarningnoticeinfo 或者 debug 中的一个。可以选择记录的用法,可以按以下方式限制注册:
log [prefix=prefix text] [level=log level] limit value=rate/duration
等级用正的自然数 [1, ..] 表达,持续时间的单位为 smhds 表示秒, m 表示分钟, h 表示小时, d 表示天。最大限定值是 1/d ,意为每天最多有一条日志进入。
audit
审核为发送到 auditd 服务的审核记录来注册提供了另一种方法。审核类型可以是 ACCEPTREJECTDROP 中的一种,但不能在 audit 命令后指定,因为审核类型将会从规则动作中自动收集。审核不包含自身参数,但可以选择性地增加限制。审核的使用是可选择的。
accept|reject|drop
可以是 acceptrejectdrop 中的一个行为。规则中仅仅包含一个要素或者来源。如果规则中包含一个要素,那么行为可以处理符合要素的新连接。如果规则中包含一个来源,那么指定的行为可以处理来自源地址的一切内容。
accept | reject [type=reject type] | drop
选择 accept 所有新的连接请求都会被允许。选择 reject ,连接将被拒绝,连接来源将接到一个拒绝信息。拒绝的类型可以被设定为使用另一种值。选择 drop , 所有数据包会被丢弃,并且不会向来源地发送任何信息。

4.5.15.4. 使用多规则登录命令

使用 Netfilter 登录目标可以完成登录,也可以使用审核目标。用 zone_log 格式命名的新链可以加入到所有分区,其中 zone 为该分区名。在 deny 链之前进行该项处理,以便获得适当的排序。根据规则的行为,整个规则或者部分规则会按照规则被分别放置在独立链中,如下所示:
zone_log
zone_deny
zone_allow
所有登录规则将放在 zone_log 链中,这会最先被解析。所有 rejectdrop 规则都被放置在 zone_deny 链,在登录链之后被解析。所有 accept 规则被放在 zone_allow 链里,它将在 deny 链之后被解析。如果规则中既包含了 log ,又有 deny 或者 allow ,各部分将被放在相应的链中。
4.5.15.4.1. 多规则登录命令使用示例 1
为认证报头协议 AH 使用新的IPv4IPv6 连接:
rule protocol value="ah" accept
4.5.15.4.2. 多规则登录命令使用示例 2
同意新的 IPv4IPv6 连接 FTP,并使用审核每分钟登录一次:
rule service name="ftp" log limit value="1/m" audit accept
4.5.15.4.3. 多规则登录命令使用示例 3
TFTP 协议同意来自 192.168.0.0/24 地址的新的 IPv4 连接,并且使用系统日志每分钟登录一次:
rule family="ipv4" source address="192.168.0.0/24" service name="tftp" log prefix="tftp" level="info" limit value="1/m" accept
4.5.15.4.4. 多规则登录命令使用示例 4
RADIUS 协议拒绝所有来自 1:2:3:4:6:: 的新 IPv6 连接,并每分钟在级别3登录。接受来自其他来源的新的 IPv6 连接:
rule family="ipv6" source address="1:2:3:4:6::" service name="radius" log prefix="dns" level="info" limit value="3/m" reject
rule family="ipv6" service name="radius" accept
4.5.15.4.5. 多规则登录命令使用示例 5
转发带有 TCP 协议的端口 4011 上的来自 1:2:3:4:6::IPv6 包,到端口 4012 上的 1::2:3:4:7
rule family="ipv6" source address="1:2:3:4:6::" forward-port to-addr="1::2:3:4:7" to-port="4012" protocol="tcp" port="4011"
4.5.15.4.6. 多规则登录命令使用示例 6
把一个源地址加入白名单,以便允许来自这个源地址的所有连接
rule family="ipv4" source address="192.168.2.2" accept
更多示例请查阅 firewalld.richlanguage(5) 说明页。

4.5.16. 锁定防火墙

如果以 root 身份运行本地应用或者服务(比如 libvirt ),就能更改防火墙设置。因为这个功能,管理员可以锁定防火墙设置,这样无论是不向锁定的白名单添加应用,还是仅允许添加应用,都可以要求防火墙更改。锁定设置默认不启动,如果启动,用户可以确保本地应用或者服务不需要对防火墙做任何设置更改。

4.5.16.1. 设置防火墙锁定

root 身份运行一个编辑器,把以下行增加到 /etc/firewalld/firewalld.conf 文件:
Lockdown=yes
root 身份使用以下命令重启防火墙:
~]# firewall-cmd --reload
欲在默认区内使用 imaps 服务,则以管理员账户,也就是 wheel 组中的用户(通常是系统的第一位用户),使用以下命令:
~]$ firewall-cmd --add-service=imaps
Error: ACCESS_DENIED: lockdown is enabled
欲使用 firewall-cmd ,以 root 身份输入以下命令:
~]# firewall-cmd --add-lockdown-whitelist-command='/usr/bin/python -Es /usr/bin/firewall-cmd*'
如果需要重启后会继续使用此设定,增加 --permanent 选项。
root 身份重启防火墙:
~]# firewall-cmd --reload
以管理员账户输入以下命令,尝试在默认区里再次启动 imaps 服务。您将被提示输入用户密码:
~]$ firewall-cmd --add-service=imaps
这样,命令成功运行。

4.5.16.2. 用命令行客户端配置锁定

查询锁定是否执行,以 root 身份输入以下命令:
~]# firewall-cmd --query-lockdown
如果是锁定状态,打印退出状态为 0yes。否则,打印退出状态为 1no
启动锁定,以 root 身份输入以下命令:
~]# firewall-cmd --lockdown-on
关闭锁定,以 root 身份输入以下命令:
~]# firewall-cmd --lockdown-off

4.5.16.3. 用命令行配置锁定白名单选项

锁定白名单可以包含命令,安全环境,用户和用户ID。如果白名单上输入的一个命令以一个星号 * 结束,那么所有以这个命令开始的命令行都匹配。如果没有 * ,那么包括参数的绝对命令必须匹配。
环境,是指一个正在运行的应用或者服务的安全 (SELinux) 环境。用以下命令获取一个正在运行的应用的环境:
~]$ ps -e --context
这个命令检查所有运行中的应用。通过 grep 工具将输出转移,得到需要的应用。比如:
~]$ ps -e --context | grep example_program
列出白名单上的所有命令行,以 root 身份输入以下命令:
~]# firewall-cmd --list-lockdown-whitelist-commands
增加一个command 命令到白名单,以 root 身份输入以下命令:
~]# firewall-cmd --add-lockdown-whitelist-command='/usr/bin/python -Es /usr/bin/command'
从白名单移除一个 command 命令,以 root 身份输入以下命令:
~]# firewall-cmd --remove-lockdown-whitelist-command='/usr/bin/python -Es /usr/bin/command'
查询 command 命令是否在白名单上,以 root 身份输入以下命令:
~]# firewall-cmd --query-lockdown-whitelist-command='/usr/bin/python -Es /usr/bin/command'
如果存在,显示退出状态为 0yes ,否则,显示退出状态为 1no
列出白名单上的所有安全环境,以 root 身份输入以下命令:
~]# firewall-cmd --list-lockdown-whitelist-contexts
增加一个环境 context 到白名单,以 root 身份输入以下命令:
~]# firewall-cmd --add-lockdown-whitelist-context=context
要使这个命令持续,增加 --permanent 选项。
从白名单移除一个环境 context ,以 root 身份输入以下命令:
~]# firewall-cmd --remove-lockdown-whitelist-context=context
要使这个命令持续,增加 --permanent 选项。
查询白名单上是否有环境 context ,以 root 身份输入以下命令:
~]# firewall-cmd --query-lockdown-whitelist-context=context
如果存在,显示退出状态为 0yes ,否则,显示退出状态为 1no
列出白名单上所有用户 ID ,以 root 身份输入以下命令:
~]# firewall-cmd --list-lockdown-whitelist-uids
增加一个用户 ID uid 到白名单,以 root 身份输入以下命令:
~]# firewall-cmd --add-lockdown-whitelist-uid=uid
要使这个命令持续,增加 --permanent 选项。
从白名单上移除一个用户 ID uid ,以root 身份输入以下命令:
~]# firewall-cmd --remove-lockdown-whitelist-uid=uid
要使这个命令持续,增加 --permanent 选项。
查询用户 ID uid 是否在白名单上,输入以下命令:
~]$ firewall-cmd --query-lockdown-whitelist-uid=uid
如果存在,显示退出状态为 0yes ,否则,显示退出状态为 1no
列出白名单上所有用户名,以 root 身份输入以下命令:
~]# firewall-cmd --list-lockdown-whitelist-users
增加一个用户名 user 到白名单,以 root 身份输入以下命令:
~]# firewall-cmd --add-lockdown-whitelist-user=user
要使这个命令持续,增加 --permanent 选项。
从白名单移除一个用户名 user ,以 root 身份输入以下命令:
~]# firewall-cmd --remove-lockdown-whitelist-user=user
要使这个命令持续,增加 --permanent 选项。
查询用户名 user 是否在白名单上,输入以下命令:
~]$ firewall-cmd --query-lockdown-whitelist-user=user
如果存在,显示退出状态为 0yes ,否则,显示退出状态为 1no

4.5.16.4. 用配置文件来配置锁定白名单选项

默认的白名单配置文件包括 NetworkManager 环境和 libvirt 的默认环境。列表里也有用户 ID 0。
<?xml version="1.0" encoding="utf-8"?>
<whitelist>
  <selinux context="system_u:system_r:NetworkManager_t:s0"/>
  <selinux context="system_u:system_r:virtd_t:s0-s0:c0.c1023"/>
  <user id="0"/>
</whitelist>
这里跟随了一个示例白名单配置文件,它启动用于 firewall-cmd 功能的所有命令,为名为 user、用户 ID 为 815 的用户:
<?xml version="1.0" encoding="utf-8"?>
<whitelist>
  <command name="/usr/bin/python -Es /bin/firewall-cmd*"/>
  <selinux context="system_u:system_r:NetworkManager_t:s0"/>
  <user id="815"/>
  <user name="user"/>
</whitelist>
在这个范例里,我们出示了 user iduser name 两样,但只需要一个即可。Python 是一个解释器,所以写在命令行的最前面。您也可以使用一个非常特别的命令,比如:
/usr/bin/python /bin/firewall-cmd --lockdown-on
在这例子里,只有 --lockdown-on 命令会被允许。

注意

在 Red Hat Enterprise Linux 7 中,所有功能现在都放在 /usr/bin/ 中,而且 /bin/ 目录被系统链接到 /usr/bin/ 目录。换言之,尽管以 root 身份运行的 firewall-cmd 路径可能解析到 /bin/firewall-cmd,但是现在会使用 /usr/bin/firewall-cmd 。所有新的脚本可以使用新的地址,但要意识到,如果以 root 身份运行的脚本被写入使用 /bin/firewall-cmd 路径,那么,命令路径除了是传统意义上仅用于非 root 用户的 /usr/bin/firewall-cmd 路径以外,还必须被加入白名单。
在一个命令的名字属性结尾的 * 意味着所有以此行开头的命令都匹配。如果没有 * ,那么包括参数的绝对命令必须匹配。

4.5.17. 附加资源

下列信息的来源提供了关于 firewalld 的附加资源。

4.5.17.1. 已安装的文档

  • firewalld(1) 说明页——描述 firewalld 的命令选项。
  • firewalld.conf(5) 说明页——包括配置 firewalld 的信息。
  • firewall-cmd(1) 说明页——描述 firewalld 命令行客户端的命令选项。
  • firewalld.icmptype(5) 操作手册 — 描述了 ICMP 过滤的 XML 配置文件。
  • firewalld.service(5) 操作手册 — 描述了 firewalld service 的 XML 配置文件。
  • firewalld.zone(5) 操作手册 — 描述了配置 firewalld 区域的 XML 配置文件。
  • firewalld.direct(5) 说明页——描述 firewalld 直接接口配置文件。
  • firewalld.lockdown-whitelist(5) 说明页——描述 firewalld 白名单锁定配置文件。
  • firewall.richlanguage(5) 说明页——描述 firewalld 多语言规则语法。
  • firewalld.zones(5) 说明页——概述分区情况以及如何配置它们。