认证目标4.03 基本的防火墙控制
过去,防火墙只配置在局域网与Internet这样的外部网络之间。但随着安全风险日益增大,越来越需要在每个系统上都安装防火墙。在RHEL 7的每个默认安装模式中都包含了防火墙。
Linux内核包含一个强大的框架Netfilter,使其他内核模块能够提供数据包过滤、网络地址转换(NAT)和负载平衡等功能。iptables命令是与Netfilter系统进行交互的主要工具,用于提供数据包过滤和NAT。
在我们把消息通过IP网络发送出去之前,消息需要拆分为更小的单元,即数据包(packet)。在每个数据包中都添加了管理信息(administrative information),如数据类型、源地址和目标地址等。到达目标计算机后,数据包需要重组。iptables规则会检查每个数据包中的管理字段,以此决定是否允许数据包通过。
iptables工具是基础,其他服务使用iptables来管理系统的防火墙规则。RHEL 7提供了两种服务:新增的防火墙守护进程和iptables服务,后者也包含在以前版本的Red Hat企业版Linux中。可使用图形实用工具firewall-config或命令行客户端firewall-cmd与firewalld进行交互。
iptables和firewalld服务都依赖于Linux内核中的Netfilter系统来过滤数据包。但iptables基于“过滤规则链”的概念来阻止或转发流量,而firewalld则基于区域,接下来将介绍这个概念。
RHCSA和RHCE考试对防火墙的配置和管理有相应的要求。对于RHCSA考试,考生需要掌握如何使用iptables、firewall-config或firewall-cmd来配置防火墙,以阻止或允许通过一个或多个端口进行网络通信。对于RHCE考试,考生需要深入掌握firewalld及其功能,如“丰富的规则、区域和自定义规则,以实现数据包过滤和配置网络地址转换(NAT)”。
考试提示
RHEL 7也包含一个可用于IPv6网络的防火墙命令,即ip6tables。相关的命令基本相同。不同于iptables, ip6tables命令并没有出现在Red Hat认证目标中。
4.3.1 标准端口
Linux主要用TCP/IP协议组实现网络之间的通信。默认情况下,根据/etc/services文件中的定义不同的协议使用不同的端口和协议。记住表4-7中一些常用端口号可能会大有帮助。注意,其中一些端口号可以用一个或多个以下协议进行通信:传输控制协议(Transmission Control Protocol, TCP)、用户数据报协议(User Datagram Protocol, UDP),甚至流控制传输协议(Stream Control Transmission Protocol, SCTP)。例如,以下是来自/etc/service文件的一段内容,其中向FTP服务分配了TCP和UDP端口:
表4-7 常用的TCP/IP端口
ftp-data 20/tcp ftp-data 20/udp ftp 21/tcp ftp 21/udp
稍后将看到,Red Hat防火墙配置工具只能打开FTP服务的TCP通信,此时第1章配置的默认vsFTP服务器可以正常运行。这是因为,互联网数字分配机构(Internet Assigned Number Authority, IANA)的默认策略是为TCP和UDP注册端口号,即使服务只支持TCP协议。
4.3.2 重点介绍iptables命令
iptables命令的核心思想是以“链“(chains)为基础。对于每个网络数据包都有一组规则应用其上以将它们串联起来。每个规则都做两件事:规定数据包满足规则的条件和当数据包满足条件时可以执行的操作。
iptables命令的基本格式如下:
iptables -t tabletype <action_direction> <packet_pattern> -j <what_to_do>
现在逐一分析这个命令的各个选项。首先是-t tabletype开关选项。iptables命令定义了两个基本的表格类型(tabletype)选项:
● filter 为过滤数据包定义一个规则。
● nat 配置网络地址转换,也称为伪装(Masquerading),这将在第10章介绍。
默认值为filter。如果在iptables命令中没有使用-t tabletype选项,则认为此命令作为数据包过滤器的规则。
接着是<action_direction>。与iptables规则有关的共有4个操作:
● -A(--append) 在规则链末尾添加一个规则。
● -D(--delete) 从规则链删除一个规则。根据规则号或数据包模式定义规则。
● -L(--list) 显示规则链上当前配置的规则。
● -F(--flush) 删除当前iptables链上的全部规则。
假设我们给规则链添加(-A)或删除(-D)一个规则时,我们想把它按以下三个方向之一作用于网络数据流上:
● INPUT 所有传入的数据包都要按此链上的规则进行检查。
● OUTPUT 所有传出的数据包都要按此链上的规则进行检查。
● FORWARD 所有转发给其他计算机的数据包都要按此链上的这些规则进行检查。换句话说,这些数据包通过本地服务器路由出去。
通常情况下,这些方向的每一个就是一个链的名字。
接着我们需要设置 <packet_pattern>参数。所有iptables防火墙都要对每个数据包进行检查,检查其是否与此模式一致。最简单的模式是IP地址:
● -s ip_address 检查所有数据包,确定它的源IP地址;
● -d ip_address 检查所有数据,确定它的目标IP地址;
数据包模式会比较复杂。在TCP/IP协议中,数据包用TCP、UDP或ICMP协议传输。用-p开关选项并且加上目标端口(--dport)可以指定协议。例如,-p tcp --dport 80模式会影响试图用HTTP连接访问我们网络的外部用户。
当iptables命令找到一个相匹配的数据包后,它需要知道如何对该数据包进行操作,这就是iptables命令的最后部分即-j <what_to_do>开关,它有三个基本选项:
● DROP 丢弃数据包,且不向请求计算机发送消息。
● REJECT 丢弃数据包,且向请求计算机发送一个错误消息。
● ACCEPT 允许数据包按-A开关选项规定的动作进行处理,即INPUT、OUTPUT和FORWARD。
通过一些例子来说明如何用iptables命令配置防火墙。第一步总是用下面命令先看看当前的配置情况:
# iptables -L
如果iptables防火墙已正确配置,则这个命令按三个不同的类别来返回链上的规则。这三个类别就是INPUT、FORWARD和OUTPUT。
4.3.3 确保防火墙在运行中
Linux防火墙(如firewalld和iptables服务)是建立在iptables命令之上。为检查当前规则,执行iptables -L命令。假设我们看到如下空白的规则列表:
Chain INPUT(policy ACCEPT) target prot opt source destination Chain FORWARD(policy ACCEPT) target prot opt source destination Chain OUTPUT(policy ACCEPT) target prot opt source destination
这说明firewalld服务可能还没有启用。在RHEL 7中,firewalld是默认的防火墙服务。确保该服务运行:
# systemctl status firewalld
如果该服务没有处于活动状态,则检查iptables服务是否已被禁用,然后启动firewalld,并确保在引导时启用firewalld服务:
# systemctl stop iptables # systemctl disable iptables # systemctl start firewalld # systemctl enable firewalld
在配置firewalld之前,我们将简要回顾iptables服务。除了RHCSA考试对此有要求之外,对iptables服务有基本的了解有助于理解firewalld中提供的更高级功能。
4.3.4 iptables服务
在RHEL 6中,iptables服务是默认防火墙,而在RHEL 7中,firewalld成为了默认防火墙。如果愿意,在RHEL 7中可以禁用firewalld并切换到原来的iptables服务。为此,只需执行下面的命令:
# systemctl stop firewalld # systemctl disable firewalld # systemctl start iptables # systemctl enable iptables
类似地,要切换回firewalld,可执行前一节中给出的命令。启动iptables服务后,使用iptables-L可列出现有的防火墙规则。在默认的server1.example.com系统上执行此命令的结果如图4-4所示。
图4-4 iptables服务的防火墙规则
图4-4中共有6列信息,它们对应iptables命令的各个选项。图中显示的防火墙是按以下规则配置的,这些规则出现在/etc/sysconfig/iptables文件中。第一行规定了所要遵循的规则为过滤规则。其他还有网络地址转换(或者mangling)。
*filter
默认情况下,ACCEPT选项允许网络流量发送到本地系统、准备转发或者是发送出去。[0:0]部分显示了字节和数据包计数。
:INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0]
接下来的几行都应用于iptables命令。此文件中的每个开关和选项都可用于相应的man帮助文档中。
接下来的一行保证当前的网络通信继续下去。ESTABLISHED选项继续接收当前网络连接上的数据包。RELATED选项接收之后网络连接上的数据包,如用于FTP数据传输:
-A INPUT -m state --state RELATED, ESTABLISHED -j ACCEPT
下一个连接接收与ICMP有关的数据包,通常是与ping命令有关的数据包。当一个数据包被拒绝后,相应的消息也使用ICMP协议。
-A INPUT -p icmp -j ACCEPT
下一行给INPUT规则链添加(-A)一个规则,这与回环适配器(lo)这类的网络接口(-i)有关。任何通过此设备处理的数据都转换为(-j)接受状态。
-A INPUT -i lo -j ACCEPT
下一行是直接接受新的普通网络数据的唯一一行,这些数据使用TCP协议传输,可通过所有接口。它为新(NEW)的连接状态(--state NEW)寻找一个匹配规则(-m),对于匹配的TCP数据包,用TCP协议(-p tcp)把它发送到22目标端口(--dport),对应于SSH服务。只有满足全部上述规则的网络数据包才可以接收(-j ACCEPT)。当一个新连接建立后,本章介绍的第一个普通规则继续在已经确立的连接上接收数据包。
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22-j ACCEPT
最后两个规则拒绝所有其他数据包,并给源系统发送了一个icmp-host-prohibited消息。
-A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited
规则列表的结尾是COMMIT关键字:
COMMIT
由于本节只介绍与RHCSA考试有关的内容,更多的内容将在第10章中介绍。在这一级,读者只需要知道如何用标准配置工具管理这些防火墙。
4.3.5 firewalld服务
可自动完成配置防火墙的过程。为此目的,在RHEL 7中,firewalld提供了一个控制台配置工具和一个GUI配置工具。虽然两个应用程序的外观和使用方法不同,但是都可以用来配置对受信服务的访问。在启动firewalld配置工具之前,回顾“确保防火墙在运行中”一节的步骤,确保firewalld正在运行,且在引导过程中自动启动。
除了具备iptables的所有功能,firewalld还提供了其他功能。其具有的新功能之一是基于区域的防火墙。在基于区域的防火墙中,网络和接口被分组为区域,每个区域配置为不同的信任级别。表4-8列出了firewalld中定义的区域,以及它们对于出站和入站连接的默认行为。
表4-8 firewalld中的区域
实际经验
区域由一组源网络地址和接口组成,还包含一些规则,用于处理与这些源地址和网络接口匹配的数据包。
1. GUI firewall-config工具
可在基于GUI的命令行使用firewall-config命令启动图形化的firewalld配置工具。或者,在GNOME桌面环境中,可单击Applications | Sundry | Firewall。结果如图4-5所示。
图4-5 图形化的firewall-config工具
如图所示,主窗口包含不同的菜单和选项卡。在左上部区域中,有一个Configuration下拉菜单,在这里可以将防火墙设为Runtime或Permanent模式。如果设为Runtime,则firewall-config应用的修改将立即生效,但是服务器重启后将丢失。选择Permanent模式后,所做的修改在服务器重启后仍然有效。任何时候都可以单击Options | Reload Firewalld,使新的firewalld配置立即生效。
实际经验
在Permanent模式中,只能修改区域和服务的定义。
Zone选项卡包含表4-8中列出的全部区域。当防火墙收到入站数据包时,会检查其源地址是否匹配现有区域中的网络地址。如果找不到匹配,则检查数据包的入站接口,看其是否属于一个区域。如果找到,就根据其匹配的区域的规则来处理该数据包。
在主firewall-config窗口中,以粗体显示公共区域,表明这是默认区域。默认区域有一个特殊的含义:添加到系统的任何新的网络接口将自动分配给默认区域。另外,对于不匹配其他任何区域的入站数据包,将应用默认区域的规则进行处理。通过单击Options | Change Default Zone,可将另一个区域设为默认区域。
为允许或拒绝通过防火墙的入站流量,可选择一个区域,然后在该区域的Services选项卡中,为想要允许或者阻止的服务添加或移除复选标记。另外,也可以在Ports选项卡中指定协议和端口。
在firewalld中,服务被定义为一组协议和端口。服务还可以包含一个Netfilter帮助模块,用来支持对动态打开多个连接的应用程序进行过滤。
Services窗口中已经定义了多种网络服务。表4-9中对最常用的网络服务进行了说明。
表4-9 常用的TCP/IP端口
如果将firewall-config工具切换到Permanent模式,就可以添加新服务或编辑现有服务。为完成此任务,滚动到Services窗口的底部,然后单击对应的图标来删除、添加或编辑服务。如果愿意,还可以单击Add或Edit图标,为现有服务配置自定义端口,如图4-6所示。
图4-6 在firewall-config工具中向服务添加自定义端口
2.控制台firewall-cmd配置工具
firewall-cmd配置工具的功能和服务与对应的GUI工具相同。事实上,图形化的firewall-config工具和命令接口firewall-cmd只是与底层的firewalld守护进程进行通信的客户端前端。
与GUI工具一样,firewall-cmd可以显示所有可用的区域,以及切换到不同的默认区域。在下面的例子中,默认区域从公共区域改为了内部区域:
# firewall-cmd --get-default-zone public # firewall-cmd --set-default-zone=internal success # firewall-cmd --get-default-zone internal #
选项--list-all特别有用。它列出了允许通过某区域的所有已配置接口和服务,如下所示:
# firewall-cmd --list-all internal(default, active) interfaces: eth0 sources: services: dhcpv6-client ipp-client mdns samba-client ssh ports: masquerade: no forward-ports: icmp-blocks: rich rules: #
考试提示
我们希望对防火墙所做的修改在重启后仍然有效。要在firewall-cmd命令中实现此目的,需要使用--permanent开关选项。
与firewall-cmd命令的许多选项一样,如果没有使用--zone命令开关指定区域,就假定使用默认区域。通过使用--add-port、--add-service、--remove-port、--remove-service开关,可分别在区域中添加和删除端口和服务。下面的例子对于进入dmz区域的流量启用了http服务:
# firewall-cmd --zone=dmz --add-service=http success #
默认情况下,使用firewall-cmd对配置做出的修改在重启后将会丢失。为了使修改在重启后依然有效,可在firewall-cmd命令中添加--permanent开关。然后,运行firewall-cmd --reload来立即实现修改。
4.3.6 练习4-2:调整防火墙配置
本练习要从命令行接口调整防火墙配置,然后用nmap和telnet命令检查结果。虽然在Red Hat考试中考生如何解决一个问题不重要,但在这个练习中将会看到使用firewall-cmd工具添加新服务时系统将会发生什么现象。当然,用图形化的firewall-config工具也能完成同样的任务。这里假设系统已安装了一个本章介绍的默认防火墙。
(1)首先,用nmap localhost命令检查本地系统上当前活动的服务。用ip addr命令显示本地系统的IP地址。假如本地系统是server1.example.com,则IP地址应该是192.168.122.50。
(2)使用systemctl status firewalld命令,确保firewalld正常运行。
(3)转到另一个系统。可在另一个虚拟机上进行操作,或者通过ssh命令远程访问本系统。如果tester1.example.com系统正在运行,则用ssh 192.168.122.150命令登录到该系统。
(4)用nmap命令查看哪些服务可以通过防火墙。对于前面提到的server1.example.com系统,正确的命令是nmap 192.168.122.50。如果在步骤(1)中设置了另一个IP地址,则做相应的替换。
(5)回到原来的系统。执行下面的命令来安装并启动telnet服务:
# yum install telnet-server # systemctl start telnet.socket
(6)执行下面的命令,显示默认区域的当前设置:
# firewall-cmd --list-all
(7)允许流量通过默认区域。不要忘记使用--permanent开关,这样才能使修改永久生效:
# firewall-cmd --permanent --add-service=telnet
(8)将前面的修改应用到防火墙的运行时配置:
# firewall-cmd --reload
(9)像步骤(3)那样,回到tester1.example.com系统。
(10)重复步骤(4)。你看到了什么?