防火墙作为公网与内网之间的保护屏障,在保障数据的安全性方面起着至关重要的作用。本章将学习使用 iptables、firewall-cmd、firewall-config 和 TCP Wrapper 等防火墙策略配置服务,学习防火墙不仅能够过滤请求的流量进行允许和拒绝操作,还可以使用 Cockpit 轻松监控系统的运行状态。
8.1 防火墙管理工具
相较于企业内网,外部的公网环境更加恶劣;在公网与企业内网之间充当保护屏障的防火墙有软件或硬件之分,主要功能都是依据策略对穿越防火墙的流量进行过滤。防火墙策略可以基于流量的源目地址、端口号、协议、应用等信息来定制,然后使用预先定制的策略规则监控出入的流量,若流量与某一条策略规则相匹配,则执行相应的处理,反之则丢弃。这样就能够保证仅有合法的流量在企业内网和外部公网之间流动了。
从 RHEL 7 系统开始,firewalld 防火墙正式取代了 iptables 防火墙。其实 iptables 与 firewalld 都不是真正的防火墙,它们都只是用来定义防火墙策略的防火墙管理工具而已;或者说它们只是一种服务。iptables 服务会把配置好的防火墙策略交由内核层面的 netfilter 网络过滤器来处理,而 firewalld 服务则是把配置好的防火墙策略交由内核层面的 nftables 包过滤框架来处理。当前 Linux 系统中其实存在多个防火墙管理工具,我们只需要配置妥当其中的一个就足够了。
8.2 iptables
在早期的 Linux 系统中默认使用的是 iptables 防火墙管理服务来配置防火墙。尽管新型的 firewalld 防火墙管理服务已经被投入使用多年,但是大量的企业在生产环境中依然出于各种原因而继续使用 iptables。各个防火墙管理工具的配置思路是一致的,掌握了 iptables 后再学习其他防火墙管理工具时也有借鉴意义。
8.2.1 策略与规则链
防火墙会按照从上到下的顺序来读取配置的策略规则,在找到匹配项后就立即结束匹配工作并去执行匹配项中定义的行为(即放行或阻止)。如果在读取完所有的策略规则之后没有匹配项,就去执行默认的策略。当防火墙的默认策略为拒绝时(堵),就要设置允许规则(通),否则谁都进不来;如果防火墙的默认策略为允许,就要设置拒绝规则,否则谁都能进来,防火墙也就失去了防范的作用。
iptables 服务把用于处理或过滤流量的策略条目称之为规则,多条规则可以组成一个规则链,而规则链则依据数据包处理位置的不同进行分类,具体如下:
➢ 在进行路由选择前处理数据包(PREROUTING);
➢ 处理流入的数据包(INPUT);
➢ 处理流出的数据包(OUTPUT);
➢ 处理转发的数据包(FORWARD);
➢ 在进行路由选择后处理数据包(POSTROUTING)。
从内网向外网发送的流量一般都是可控且良性的,因此使用最多的就是 INPUT 规则链,该规则链可以增大黑客从外网入侵内网的难度。
仅有策略规则不够精细,还应该知道采用什么样的动作来处理这些匹配的流量,比如“允许”“拒绝”“登记”“不理它”。这些动作对应到 iptables 服务的术语中分别是 ACCEPT(允许流量通过)、REJECT(拒绝流量通过)、LOG(记录日志信息)、DROP(拒绝流量通过)。“允许流量通过”和“记录日志信息”都比较好理解,这里需要着重讲解的是 REJECT 和 DROP 的不同点。就 DROP 来说,它是直接将流量丢弃而且不响应;REJECT 则会在拒绝流量后再回复一条“信息已经收到,但是被扔掉了”信息,从而让流量发送方清晰地看到数据被拒绝的响应信息。
8.2.2 基本的命令参数
根据 OSI 七层模型的定义,iptables 属于数据链路层的服务,所以可以根据流量的源地址、目的地址、传输协议、服务类型等信息进行匹配;一旦匹配成功,iptables 就会根据策略规则所预设的动作来处理这些流量。介于防火墙策略规则的匹配顺序是从上到下的,因此要把较为严格、优先级较高的策略规则放到前面,以免发生问题。建议无须死记硬背如“四表五链”的概论,多做实验理解就好;常用的 iptables 命令参数如图。
下面来用 iptables 命令后添加 -L 参数查看已有的防火墙规则链。
在 iptables 命令后添加 -F 参数清空已有的防火墙规则链。
把 INPUT 规则链的默认策略设置为拒绝。
当把 INPUT 链设置为默认拒绝后,就要往里面写入允许策略了,否则所有流入的数据包都会被默认拒绝掉。需要注意的是默认策略拒绝动作只能是 DROP,而不能是 REJECT。
在日常运维工作中,经常会使用ping命令来检查对方主机是否在线,而向防火墙的 INPUT 规则链中添加一条允许 ICMP 流量进入的策略规则就等于允许了 ping 命令检测行为。
试试删除 INPUT 规则链中刚刚加入的那条策略(允许ICMP流量),并把默认策略设置为允许。上面使用 -F 参数会清空已有的所有防火墙策略;但用 -D 参数可以删除某一条指定的策略,因此更加安全和准确。
将 INPUT 规则链设置为只允许指定网段的主机访问本机的 22 端口,拒绝来自其他所有主机的流量;要对某台主机进行匹配,可直接写出它的IP地址;如需对网段进行匹配要写为子网段的形式(比如192.168.187.0/24)。
介于防火墙策略规则是按照从上到下的顺序匹配的,因此一定要把允许动作放到拒绝动作前面,否则当先匹配到 REJECT 拒绝动作就不会继续下面的 ACCEPT 允许动作了,从而导致任何主机都无法访问。 这里提到的 22 号端口是 ssh 服务使用的(下一章会讲到);接着使用另一台主机 IP 地址在 192.168.187.0/24 网段内访问本机 22 端口。
再使用 IP 地址在 192.168.188.0/24 网段内的主机访问服务器的 22 端口(虽网段不同,但已路由可以相互通信),提示连接请求被拒绝了(Connection failed)。
[root@RHEL7.6 ~]# ssh 192.168.187.128
Connecting to 192.168.187.128:22...
Could not connect to '192.168.187.128' (port 22): Connection failed.
向 INPUT 规则链中添加拒绝所有人访问本机12555端口的策略规则。
向 INPUT 规则链中添加拒绝192.168.187.5主机访问本机 80 端口(Web服务)的策略规则。
向 INPUT 规则链中 -A 添加拒绝所有主机访问本机1000~1024端口的策略规则。前面用的-I 参数添加的策略默认会在首位,-A参数则相反。
使用iptables命令配置的防火墙规则默认会在系统下一次重启时失效,如果想让配置的防火墙策略永久生效,还要执行保存命令:iptables-save,如果是RHEL 5/6/7 得用 service iptables save 命令。
8.3 firewalld
RHEL 8 系统中集成了多款防火墙管理工具,其中 firewalld(Dynamic Firewall Manager of Linux systems,Linux 系统的动态防火墙管理器)服务是默认的防火墙配置管理工具,它拥有基于 CLI(命令行界面)和基于 GUI(图形用户界面)的两种管理方式。
相较于传统的防火墙管理配置工具,firewalld 支持动态更新技术并加入了区域(zone)的概念。区域相当于 firewalld 预先准备了几套防火墙策略集合(策略模板),用户可以根据生产场景的不同而选择合适的策略集合,从而实现防火墙策略之间的快速切换,极大地提升了防火墙策略的应用效率。firewalld 中常见的区域名称(默认为 public)以及相应的策略规则如图。
8.3.1 终端管理工具
firewall-cmd 是 firewalld 防火墙配置管理工具的 CLI(命令行界面)版本,参数一般都是以“长格式”提供的;好在现在系统除了能用 Tab 键自动补齐命令或文件名等内容之外,还可以用 Tab 键来补齐下图中所示的长格式参数。
与 Linux 系统中其他的防火墙策略配置工具一样,使用 firewalld 配置的防火墙策略默认为运行时(Runtime)模式,又称为当前生效模式,而且会随着系统的重启而失效。如果想让配置策略一直存在,就需要使用永久(Permanent)模式了,方法就是在用 firewall-cmd 命令正常设置防火墙策略时添加--permanent 参数,但是只有在系统重启之后才能自动生效。如果想让配置的策略立即生效,需要手动执行 firewall-cmd --reload 命令。
首先查看firewalld服务当前默认所使用的区域;
这是一步非常重要的操作,在配置防火墙策略前,必须查看当前生效的是哪个区域,否则配置的防火墙策略可能会无效。
查询指定网卡在firewalld服务中绑定的区域;
大多数服务器不止有一块网卡。一般充当网关的服务器有两块网卡,一块对公网,另外一块对内网,那么这两块网卡在审查流量时所用的策略肯定也是不一致的。因此可以根据网卡针对的流量来源,为网卡绑定不同的区域策略实现灵活管控。
再把网卡默认区域修改为external,并在系统重启后生效;
默认区域也叫全局配置,指的是对所有网卡都生效的配置,优先级最低。当前默认区域为public,而ens160网卡的区域改为external。此时便是以网卡的区域名称为准。
启动和关闭firewalld防火墙服务的应急状况模式。
如果想在 1s 的时间内阻断一切网络连接,有什么好办法?可以“拔掉网线!”这是一个物理级别的切断;如果人在异地没法拔网线呢?panic紧急模式在这个时候就派上用场了。使用--panic-on参数会立即切断一切网络连接,而使用--panic-off则会恢复网络连接。因此在远程连接管理服务器时,在按下回车键前一定要三思。
把HTTPS协议的流量设置为永久允许放行,并立即生效。
默认情况下进行的修改都属于Runtime模式,即当前生效而重启后失效,而在使用--permanent参数时,则是当前不会立即看到效果,而在重启或重新加载后方可生效。因此在添加了允许放行 https 流量的策略后,查询当前模式策略,发现依然是不允许放行 https 协议的流量;不方便重启服务器,可用--reload 参数立即生效。
把HTTP协议的流量设置为永久拒绝,并立即生效。
提示 “Warning: NOT_ENABLED: http”的信息,是因为默认就没有允许 http 服务;提示对实际操作没有影响。
把访问8080和8081端口的流量策略设置为允许,但仅限当前生效。
把访问本机888端口的流量转发到22端口,要求当前和长期均有效。
SSH远程控制协议是基于TCP/22端口传输控制指令的,如果想让用户通过其他端口号也能访问ssh服务,就可以试试端口转发技术了。通过这项技术,新的端口号在收到用户请求后会自动转发到原本服务的端口上,使得用户能够通过新的端口访问到原本的服务。
firewall-cmd --permanent --znotallow=<区域> --add-forward-port=port=<源端口号>:proto=<协议>:toport=<目标端口号>:toaddr=<目标IP地址>
上图查询到目前网卡绑定的 zone 是 external,所以转发端口的配置也要保持一致zone;可以看到用客户端用 888 端口访问 ssh 成功。
firewall 富规则的设置。
富规则也叫复规则,表示更细致的防火墙策略配置,它可以针对系统服务、端口号、源地址和目标地址等诸多信息进行更有针对性的策略配置。它的优先级在所有的防火墙策略中也是最高的。比如,我们可以在 firewalld 服务中配置一条富规则,使其拒绝 192.168.10.0/24 网段的所有用户访问本机的 ssh 服务(22 端口)。再次使用 ssh 命令尝试访问 192.168.187.128 主机显示连接超时。
8.3.2 图形管理工具
firewall-config 是 firewalld 防火墙配置管理工具的 GUI(图形用户界面)版本,几乎可以实现所有以命令行来执行的操作。毫不夸张地说,即使读者没有扎实的 Linux 命令基础,也完全可以通过它来妥善配置 RHEL 8 中的防火墙策略。但在默认情况下系统并没有提供 firewall-config 命令,需要自行安装,所以需要先配置软件仓库。在第 4 章的时候配置过这里就不在赘述。
可以用 yum 或 dnf 命令安装软件。这两个命令在实际操作中除了名字不同外,执行方法完全一致。下面用 dnf install firewall-config 安装 firewalld 图形用户界面工具。
安装成功后输入 firewall-config 按回车键即可运行;工具的界面如图,其功能具体如下。
1:选择运行时(Runtime)或永久(Permanent)模式的配置。
2:可选的策略集合区域列表。
3:常用的系统服务列表。
4:主机地址的黑白名单。
5:当前正在使用的区域。
6:管理当前被选中区域中的服务。
7:管理当前被选中区域中的端口。
8:设置允许被访问的协议。
9:设置允许被访问的端口。
10:开启或关闭SNAT(源网络地址转换)技术。
11:设置端口转发策略。
12:控制请求icmp服务的流量。
13:管理防火墙的富规则。
14:被选中区域的服务,若勾选了相应服务前面的复选框,则表示允许与之相关的流量。
15:firewall-config工具的运行状态。
除了图中列出的功能,还有用于将网卡与区域绑定的 Interfaces 选项,以及用于将IP地址与区域绑定的Sources选项。并且使用 firewall-config 工具配置完防火墙策略之后,无须进行二次确认,因为只要有修改内容,它就自动进行保存。
下面试着将当前区域中请求 http 服务的流量设置为允许放行,但仅限当前生效。具体配置如图。
再添加一条防火墙策略规则,使其放行访问 8080~8088 端口(TCP 协议)的流量,并将其设置为永久生效,为达到系统重启后防火墙策略依然生效的目的。在按照下图所示的界面配置完毕之后,还需要在 Options 菜单中单击 Reload Firewalld 命令,让配置的防火墙策略立即生效。这与在命令行中使用--reload 参数的效果一样。
前面标注 firewall-config 功能的第 10 项 SNAT(Source Network Address Translation,源网络地址转换)技术。SNAT 是一种为了解决 IP 地址匮乏而设计的技术,它可以使得多个内网中的用户通过同一个外网 IP 接入 Internet。该技术的应用非常广泛,甚至可以说我们每天都在使用。
下图在网络中不使用 SNAT 技术和使用 SNAT 技术区别。图一所示的局域网网关路由没有应用 SNAT 技术,则互联网中的网站服务器在收到 PC 的请求数据包,并回送响应数据包时,将无法在网络中找到这个私有网络的 IP 地址,所以 PC 也就收不到响应数据包了。图二所示的局域网中由于网关服务器应用了 SNAT 技术,所以互联网中的网站服务器会将响应数据包发给网关服务器,再由后者转发给局域网中的 PC。
使用 iptables 命令实现 SNAT 技术是一件很麻烦的事情,但是在 firewall-config 中却很容易实现。用户只需在 Masquerading 配置项选中其下 Masquerade zone 复选框,就自动开启了 SNAT 技术。
了解一下不同工具在实现相同功能时的区别,针对前面使用 firewall-cmd 配置的防火墙策略规则,这里使用 firewall-config 工具进行了重新演示:将本机 888 端口的流量转发到 22 端口,要求当前和长期均有效,最后在左上角点Options 其下第一项Reload Firewalld 加载。
下面用图形用户界面工具添加富规则;让 192.168.187.130 主机访问本机的 1233 端口号,其中 Element 选项能够根据服务名称、端口号、协议等信息进行匹配;Source 与 Destination 选项后的 inverted 复选框代表反选功能,勾选即表示所填信息以外的主机地址;Log 复选框在选中后,日志不仅会被记录到日志文件中,而且还可以在设置日志的级别(Level)后,再将日志记录到日志文件中,以方便后续的筛查。
服务器有多块网卡在同时提供服务(这种情况很常见),则对内网和对外网提供服务的网卡要选择的防火墙策略区域也会不一样。这样就可以绑定不同的防火墙区域策略,对源自不同网卡的流量进行有针对性的监控,效果会更好。
8.4 服务的访问控制列表
TCP Wrapper 是 RHEL 6/7 系统中默认启用的一款流量监控程序,它能够根据来访主机的地址与本机的目标服务程序做出允许或拒绝的操作。在 RHEL 8 版本中,它已经被 firewalld 正式替代。换句话说,Linux 系统中其实有两个层面的防火墙,第一种是前面讲到的基于 TCP/IP 协议的流量过滤工具,而 TCP Wrapper 则是能允许或禁止 Linux 系统服务的防火墙,从而在更高层面保护了 Linux 系统的安全运行。
TCP Wrapper 服务的防火墙策略由两个控制列表文件所控制,用户可以编辑允许控制列表文件来放行对服务的请求流量,也可以编辑拒绝控制列表文件来阻止对服务的请求流量。控制列表文件修改后会立即生效,系统将会先检查允许控制列表文件(/etc/hosts.allow),如果匹配到相应的允许策略则放行流量;如果没有匹配,则会进一步匹配拒绝控制列表文件(/etc/hosts.deny),若找到匹配项则拒绝该流量。如果这两个文件都没有匹配到,则默认放行流量;常用的参数如图。
在配置 TCP Wrapper 服务时需要遵循两个原则:
➢ 编写拒绝策略规则时,填写的是服务名称,而非协议名称;
➢ 建议先编写拒绝策略规则,再编写允许策略规则,以便直观地看到相应的效果。
下面 vim 编写拒绝策略规则文件 /etc/hosts.deny ,禁止访问本机 sshd 服务的所有流量(# 号开头行为注释信息);由于 RHEL 8 版本已经不再支持 TCP Wrapper 服务程序,因此在 RHEL 7版本上进行实验。
客户端访问可以ping通,但在 ssh 连接时却不行。
再 vim 编辑允许策略规则文件 /etc/hosts.allow;添加条目 sshd:192.168.187.0/24 ,即表示允许此网段的所有主机访问本机 sshd 服务。可以看到访问 sshd 服务成功。
8.5 Cockpit 驾驶舱管理工具
Cockpit 英文单词翻译为驾驶舱、驾驶座,基于 Web 的图形化服务管理工具对用户相当友好。而且它天然具备很好的跨平台性,因此被广泛应用于服务器、容器、虚拟机等多种管理场景。红帽公司对 Cockpit 也十分看重,直接将它默认安装到了 RHEL 8 系统中,由此衍生的 CentOS 和 Fedora 也都标配有 Cockpit。
Cockpit 服务默认没有启用,命令行输入 systemctl start cockpit 开启;打开系统自带的浏览器,在地址栏中输入“本机地址:9090”即可访问。由于访问 Cockpit 的流量会使用 HTTPS 进行加密,而证书又是在本地签发的,因此还需要进行添加并信任本地证书的操作,进入 Cockpit 的登录界面后,输入 root 管理员的账号与系统密码,单击 Log In 按钮后即可进入。
进入 Cockpit 的 Web 界面,总共分为 13 个功能模块:系统状态(System)、日志信息(Logs)、硬盘存储(Storage)、网卡网络(Networking)、账户安全(Accounts)、服务程序(Services)、软件仓库(Applications)、报告分析(Diagnostic Reports)、内核排错(Kernel Dump)、SElinux、更新软件(Software Updates)、订阅服务(Subscriptions)、终端界面(Terminal)。下面逐一进行简单介绍。
1.System
进入Cockpit界面后默认显示的便是System(系统)界面,在该界面中能够看到系统架构、版本、主机名与时间等信息,还能够动态地展现出CPU、硬盘、内存和网络的复杂情况,这有点类似于Web版的“Winodws系统任务管理器”。
2.Logs
这个模块能够提供系统的全部日志,两个选项中:时间和日志严重级别。通过这两个选项可以筛选不同日期和日志类别,而不是像 /var/log/message文件那样一股脑儿地都抛给用户。
3.Storage
这个功能模块有 Windows 的感觉,原因不是这个模块显示了硬盘的 I/O读写负载情况,而是可以让用户通过该界面,用鼠标创建出 RAID、LVM、VDO和 iSCSI 等存储设备,是的 RAID 和 LVM 都可以用鼠标进行创建了。
4.Networking
既然名为 Networking 模块,那么动态看网卡的输出和接收值肯定是这个模块的标配功能了。不仅可以在这里进行网卡的绑定(Bonding)和聚合(Team),还可以创建桥接网卡及添加 VLAN。最下方会单独列出与网卡相关的日志信息。
5.Accounts
虽然它的功能界面有些简陋,只有一个用于创建账户的按钮,但只要点击进入某个用户的管理界面中,就可以对用户进行重命名,设置用户的权限,还可以锁定、修改密码以及创建 SSH 密钥信息。
6.Services
Services 功能模块可以查看系统中已有的服务列表和运行状态。单击某一服务进入管理界面后,可以对具体的服务进行开启、关闭操作。在 Services 功能模块中设置了服务并将其加入到开机启动项后,在系统重启后也依然会为用户提供服务。
7.Applications
后期采用 Cockpit 或红帽订阅服务安装的软件都会显示在这个功能模块中,目前没有买也就为空。
8.Diagnostic Report
Diagnostic Report 模块的功能是帮助用户收集及分析系统的信息,找到系统出现问题的原因,单击 Create Report 按钮后大约两分钟左右,开始创建相关报表。这个功能其实很鸡肋就是将 sosreport 命令做成了一个网页按钮。
9.Kernel Dump
Kernel Dump(Kdump)是一个在系统崩溃、死锁或死机时用来收集内核参数的一个服务。举例来说,如果有一天系统崩溃了,这时Kdump服务就会开始工作,将系统的运行状态和内核数据收集到一个名为dump core的文件中,以便后续让运维人员分析并找出问题所在。
10.SElinux
SELinux服务的控制按钮和警告信息界面,第10章将详细介绍 SELinux 安全子系统,很多公司没在使用该服务,可以理解为内核级防火墙。
11.Software Updates
Software Updates 功能模块是用来对红帽客户订阅的服务进行更新的界面;用户只有在购买了红帽第三方服务后才能使用这里面的功能,下载到相应服务程序的最新版本和稳定版本。
12.Subscriptions
Subscriptions 功能模块是红帽公司的“小广告”—如果想成为尊贵的红帽服务用户,只要付费购买订阅服务。有需求的大公司才会购买成为贵宾用户。
13.Terminal
Terminal功能模块是 Cockpit 服务提供的Shell终端的在线控制平台,可方便用户通过网页上的终端功能管理服务器。