保护 Linux 机器通常是一项平衡的工作。 最终的目的是保护数据不受不必要的访问。 虽然有许多方法可以实现这一目标,但我们应该采用能够产生最大保护的方法,以及最有效的系统管理。 测量攻击和漏洞表面(包括内部和外部)总是一个好的开始。 剩下的工作是建造栅栏和穿上盔甲——不要太高也不要太重。 外部的栅栏是网络防火墙。 在内部,在系统级别,我们构建应用安全策略。 这一章将介绍这两种方法,尽管平衡的艺术留给你了。
在本章的第一部分,我们将了解访问控制机制和相关的安全模块——SELinux 和 AppArmor。 在第二部分中,我们将探索包过滤框架和防火墙解决方案。
完成本章后,您将熟悉用于设计和管理应用安全框架和防火墙的工具——这是确保 Linux 系统安全的坚实的第一步。
以下是本章将涉及的主题的简要概述:
- 理解 Linux 安全——概述 Linux 内核中可用的访问控制机制
- 介绍 SELinux——深入了解用于管理访问控制策略的 Linux 内核安全框架
- 引入 AppArmor——一个相对较新的安全模块,它基于安全配置文件控制应用功能
- 使用防火墙-全面概述防火墙模块,包括
netfilter
、iptables
、nftables
、firewalld
和ufw
本章涵盖了相当多的主题,其中一些主题将通过大量的命令行操作进行介绍。 我们建议您同时使用 CentOS 和 Ubuntu 平台,并使用终端或 SSH 访问。 直接通过控制台访问系统是非常可取的,因为修改防火墙规则的方式可能具有破坏性。
保护计算机系统或网络安全的一个重要考虑因素是系统管理员控制用户和进程如何跨系统访问各种资源(如文件、设备和接口)的方法。 Linux 内核提供了一些这样的机制,统称为访问控制机制(ACMs)。 下面我们将简要描述它们。
Discretionary Access Control(DAC)是与文件系统对象(包括文件、目录和设备)相关的典型 ACM。 在管理权限时,这种访问权由对象的所有者决定。 DAC 基于用户和组(主题)的身份控制对对象的访问。 根据主题的访问权限,它们还可以将权限传递给其他主题——例如,管理普通用户的管理员。
访问控制列表(acl)提供控制哪些主体(如用户和组)可以访问特定的文件系统对象(如文件和目录)。
强制访问控制(MAC)对主体所拥有的对象提供不同的访问控制级别。 与 DAC 不同,在 DAC 中,用户可以完全控制他们所拥有的文件系统对象,MAC 为所有文件系统对象添加了额外的标签或类别。 因此,受试者必须有适当的访问这些类别与被标记为这些类别的对象交互。 在 RHEL/CentOS 上的Security-Enhanced Linux(SELinux)和 Ubuntu/Debian 上的 AppArmor 强化了 MAC 的。
基于角色的访问控制(RBAC)是文件系统对象的基于权限的访问控制的替代方案。 系统管理员分配角色,这些角色对特定的文件系统对象具有访问权限,而不是权限。 角色可以基于某些业务或功能标准,并且可能具有对对象的不同访问级别。
DAC 或 MAC 中,主体可以严格根据所涉及的权限访问对象,与之相反,RBAC 模型代表了 MAC 或 DAC 上的逻辑抽象,因为主体在与对象交互之前必须是特定组或角色的成员。
多层次安全(美国职业足球大联盟)是一个具体 MAC 方案主题的过程和【显示】对象文件、套接字和其他类似的系统资源。
**### 多媒体安全
多类别安全(MCS)是 SELinux 的改进版本,允许用户给文件贴上类别的标签。 MCS 在 SELinux中重用了许多 MLS 框架。
结束我们的简短演讲 ACMs 系统,我们应该注意我们的一些内部覆盖 DAC 和 ACL第四章,管理用户和组,在部分管理权限。 接下来,我们将把注意力转向 SELinux——用于 MAC 实现的一等公民。*
*# SELinux 简介
security - enhanced Linux(SELinux)是 Linux 内核中用于管理系统资源访问控制策略的安全框架。 它支持前一节中描述的 MAC、RBAC 和 MLS 模型的组合。 SELinux 是一组内核空间安全模块和用户空间命令行实用程序,它为系统管理员提供了一种机制来控制谁可以访问系统上的哪些。 SELinux 还被设计用于保护系统不受可能的错误配置和潜在的破坏进程的影响。
SELinux 的介绍了国家安全局(国家安全局)的Linux 安全模块**(【显示】lsm)内核更新。 SELinux 最终于 2000 年发布给开源社区,并从 2003 年的 2.6 内核系列开始进入 Linux。**
那么,SELinux 是如何工作的呢? 我们接下来再看这个。
SELinux 使用安全策略为系统上的应用、进程和文件定义各种访问控制级别。 安全策略是一组规则,描述什么可以访问,什么不能访问。
SELinux 对受试者和受试者进行操作。 当特定的应用或进程(主题)请求访问一个文件(对象)时,SELinux 检查请求中涉及的所需权限,并强制执行相关的访问控制。 主题和对象的权限存储在一个名为Access Vector Cache(AVC)的查找表中。 AVC 是基于 SELinux策略数据库生成的。
典型的 SELinux 策略由以下资源(文件)组成,每个资源(文件)反映安全策略的一个特定方面:
- 类型强制:已授予或拒绝策略的操作(例如,读取或写入文件)。
- 接口:策略交互的应用接口(如日志记录)。
- 文件上下文:策略关联的系统资源(如日志文件)。
这些策略文件使用 SELinux 构建工具一起编译,以生成特定的安全策略。 该策略被加载到内核中,添加到 SELinux 策略数据库中,并在不重新启动系统的情况下激活。
在创建 SELinux 策略时,我们通常首先在许可模式下测试它们,在此模式下会记录违规,但仍然允许。 当出现违规时,SELinux 工具集中的audit2allow
实用程序可以来解决。 我们使用audit2allow
产生的日志跟踪来创建策略所需的附加规则,以说明合法的访问权限。 SELinux 违规记录在/var/log/messages
中,并以avc: denied
作为前缀。
下一节将描述创建 SELinux 安全策略的必要步骤。
让我们假设有一个名为packtd
的守护进程,我们需要保护它以访问/var/log/messages
。 为了便于说明,该守护进程有一个简单的实现:定期打开/var/log/messages
文件进行写入。 使用您喜欢的文本编辑器(例如nano
)将以下内容(C 代码)添加到文件中。 让我们将该文件命名为packtd.c
:
图 9.1 -一个简单的守护进程定期检查日志
让我们编译并构建packtd.c
来生成相关的二进制可执行文件(packtd
):
gcc -o packtd packtd.c
RHEL/CentOS 8 默认安装gcc
GNU 编译器。 否则,您可以使用以下命令安装它:
sudo yum install gcc
我们已经准备好继续执行创建packtd
守护进程的步骤和所需的 SELinux 安全策略:
- 安装守护程序。
- 生成策略文件。
- 构建安全策略。
- 验证和调整安全策略。
让我们从安装我们的packtd
守护进程开始。
首先,我们必须为packtd
守护进程创建systemd
单元文件。 您可以使用您喜欢的文本编辑器(如nano
)来创建相关文件。 我们将此文件命名为packtd.service
:
图 9.2 - packtd 守护文件
将我们创建的文件复制到它们各自的位置:
sudo cp packtd /usr/local/bin/
sudo cp packtd.service /usr/lib/systemd/system/
现在,我们准备启动我们的packtd
守护进程:
sudo systemctl start packtd
sudo systemctl status packtd
状态显示如下:
图 9.3 - packtd 守护进程的状态
让我们确保packtd
守护进程没有被 SELinux 限制:
ps -efZ | grep packtd | grep -v grep
ps
的-Z
选项参数检索进程的 SELinux 上下文。 命令回显信息如下:
图 9.4 - SELinux 不限制 packtd 守护进程
安全属性unconfined_service_t
表明packtd
不受 SELinux 的限制。 实际上,如果我们尾加/var/log/messages
,我们可以看到packtd
记录的消息:
sudo tail -F /var/log/messages
下面是输出的摘录:
图 9.5 - packtd 守护进程的日志记录不受限制
接下来,我们将为packtd
守护进程生成安全策略文件。
要为packtd
构建安全策略,我们需要生成相关的策略文件。 用于构建安全策略的 SELinux 工具是sepolicy
。 另外,打包最终的安全策略二进制文件需要使用rpm-build
实用程序。 这些命令行工具可能在你的系统上默认是不可用的,所以你可能需要安装相关的包:
sudo yum install -y policycoreutils-devel rpm-build
以下命令生成packtd
的策略文件(不需要超级用户权限):
sepolicy generate --init /usr/local/bin/packtd
相关输出如下:
图 9.6 -使用 sepolicy 生成策略文件
接下来,我们需要重新构建系统策略,以便它包含自定义的packtd
策略模块。
我们将使用在前面步骤中创建的packtd.sh
构建脚本。 这个命令需要超级用户权限,因为它将新创建的策略安装在系统上:
sudo ./packtd.sh
这个构建需要相对较短的时间来完成,并产生以下输出(摘录):
图 9.7 -为 packtd 构建安全策略
请注意,构建脚本使用restorecon
命令(在前面的输出中突出显示)为packtd
恢复默认的SELinux安全上下文。 既然已经构建了安全策略,现在就可以验证相关的权限了。
首先,我们需要重新启动packtd
守护进程来处理策略更改:
sudo systemctl restart packtd
packtd
进程现在应该反映新的 SELinux 安全上下文:
ps -efZ | grep packtd | grep -v grep
输出显示了安全上下文的新标签(packtd_t
):
图 9.8 - packtd 的新安全策略
由于 SELinux 现在控制我们的packtd
守护进程,我们应该在/var/log/messages
中看到相关的审计跟踪,SELinux 在其中记录了系统的活动。 让我们看看关于权限问题的审计日志。 下面的命令使用ausearch
实用程序获取 AVC 消息类型的最新事件:
sudo ausearch -m AVC -ts recent
我们将立即注意到packtd
对/var/log/messages
没有读写权限:
图 9.9 - packtd 没有读写权限
为了进一步查询packtd
所需的权限,我们将ausearch
的输出输入audit2allow
,这是一个生成所需安全策略存根的工具:
sudo ausearch -m AVC -ts recent | audit2allow -R
输出提供了我们正在寻找的代码宏:
图 9.10 -查询 packtd 缺少的权限
audit2allow
的-R``(--reference
)选项调用存根生成任务,这有时可能会产生不准确或不完整的结果。 在这种情况下,可能需要一些迭代来更新、重建和验证相关的安全策略。 让我们继续进行所需的更改,就像前面建议的那样。 我们将编辑前面生成的类型强制文件(packt.te
),并按照audit2allow
的输出准确地添加行(复制/粘贴)。 保存文件之后,我们需要重新构建安全策略,重启packtd
守护进程,并验证审计日志。 我们在重申整个流程中的最后三个步骤:
sudo ./packtd.sh
sudo systemctl restart packtd
sudo ausearch -m AVC -ts recent | audit2allow -R
这一次,SELinux 审计应该是干净的:
图 9.11 - packtd 不再有权限问题
有时,ausearch
可能需要一段时间来刷新其最近的缓冲区。 或者,我们可以指定一个开始分析的时间戳,比如在我们更新了安全策略之后,使用一个相对最近的时间戳:
sudo ausearch --start 12/14/2020 '22:30:00' | audit2allow -R
现在,我们对 SELinux 安全策略的内部机制有了基本的了解。 接下来,我们将转向在日常管理任务中管理和控制 SELinux 的一些更高级别的操作。
SELinux 在系统中被启用或禁用。 当启用时,它以以下模式之一运行:
Enforcing
:SELinux 有效地监控安全策略。 RHEL/CentOS 操作系统默认启用该模式。Permissive
:主动监控安全策略,不执行访问控制。 策略违规已登录/var/log/messages
。
禁用 SELinux 时,既不会监视也不会强制执行安全策略。
下面的命令获取系统上 SELinux 的当前状态:
sestatus
输出如下:
图 9.12 -获取 SELinux 当前状态
当 SELinux 启用时,下面的命令获取当前模式:
getenforce
在permissive mode
中,我们得到以下输出:
图 9.13 -获取 SELinux 当前模式
要将强制更改为permissive mode
,我们可以运行以下命令:
sudo setenforce 0
在这种情况下,getenforce
命令将显示Permissive
。 要切换回强制模式,我们可以运行以下命令:
sudo setenforce 1
SELinux 模式也可以通过编辑/etc/selinux/config
中的SELINUX
值来设置。 可能的值记录在配置文件中。
重要提示
手动编辑 SELinux 配置文件需要重新引导系统才能使更改生效。
启用 SELinux 后,系统管理员可以通过修改/etc/selinux/config
:targeted
、minimum
和mls
中的SELINUXTYPE
值来选择以下 SELinux 策略级别。 相应的值记录在配置文件中。
重要提示
默认的 SELinux 策略设置是targeted
,除了mls
之外,一般不建议更改此设置。
有了targeted
策略后,只有专门配置为使用 SELinux 安全策略的进程才在受限(或受限)域中运行。 这些进程通常包括系统守护进程(如dhcpd
和sshd
)和知名的服务器应用(如Apache和PostgreSQL)。 所有其他(非目标)进程都不受限制地运行,并且通常用unconfined_t
域类型标记。
为了完全禁用 SELinux,我们可以使用自己选择的文本编辑器(比如sudo nano /etc/selinux/config
)编辑/etc/selinux/config
文件,并进行以下更改:
SELINUX=disabled
或者,我们可以运行以下命令将 SELinux 模式从enforcing
更改为disabled
:
sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
我们可以使用以下命令检索当前配置:
cat /etc/selinux/config
使用 SELinuxdisabled
,我们得到以下输出:
图 9.14 -禁用 SELinux
我们需要重启系统以使更改生效:
sudo systemctl reboot
接下来,让我们通过引入 SELinux上下文来研究如何做出访问控制决策。
启用了 SELinux,流程和文件都贴有上下文包含额外的SELinux-specific的信息,比如用户,角色、【显示】类型和(可选)。 上下文数据用于 SELinux 访问控制决策。**
**SELinux 在ls
、ps
和其他命令中添加了-Z
选项,从而显示文件系统对象、进程等的安全上下文。
让我们创建一个任意文件,并检查相关的 SELinux 上下文:
touch afile
ls -Z afile
输出如下:
图 9.15 -显示一个文件的 SELinux 上下文
SELinux 上下文具有以下格式—由四个字段组成的序列,由冒号(:
)分隔:
USER:ROLE:TYPE:LEVEL
我们将解释 SELinux 上下文字段。
SELinux 用户是身份已知一组特定的政策授权角色和一个特定水平指定的 MLS / MCS【显示】范围(见SELinux 水平部分的更多细节)。 每个 Linux 用户帐户都使用 SELinux 策略映射到相应的 SELinux 用户身份。 这种机制允许普通 Linux 用户继承与 SELinux 用户关联的策略限制。
Linux 用户拥有的进程接收映射的 SELinux 用户的身份,以承担相应的 SELinux角色和级别。
下面的命令显示 Linux 帐户与其相应的 SELinux 用户身份之间的映射列表。 该命令需要超级用户权限。 此外,semanage
实用程序可与policycoreutils
包一起使用,您可能需要在系统上安装该包:
sudo semanage login -l
系统与系统之间的输出可能略有不同:
图 9.16 -显示 SELinux 用户映射
有关semanage
命令行实用程序的更多信息,您可以参考相关的系统参考(man semanage
,man semanage-login
)。
SELinux角色是 RBAC 安全模型的一部分,它们本质上是 RBAC 的属性。 在 SELinux 上下文层次结构中,授权用户使用角色,授权角色使用类型或域。 在 SELinux 上下文术语中,类型指的是文件系统对象类型,domains指的是进程类型(详见SELinux 类型一节)。
以 Linux 进程为例。 SELinux角色作为域和 SELinux用户之间的中间访问层。 一个可访问的角色决定哪些域(即进程)可以通过角色访问。 最终,该机制控制进程可以访问哪些对象类型,从而最大限度地减少了特权升级攻击的可能性。
SELinux类型是 SELinux类型实施的属性——一个MAC安全结构。 对于 SELinux 类型,我们将域称为进程类型,而类型称为文件系统对象类型。 SELinux 安全策略控制特定类型如何相互访问——通过域到类型访问或域到域交互。
SELinux级别是MLS/MCS模式的属性,也是 SELinux 上下文中的一个可选字段。 级别通常是指主体对对象的访问控制的安全许可。 清除水平包括unclassified
、confidential
、secret
和top-secret
,以范围表达。 一个MLS 范围表示一对水平,如果水平不同则定义为low-high
,如果水平相同则定义为low
。 例如,s0-s0
水平与s0
水平相同。 每个级别代表一个敏感性-类别对,类别是可选的。 当指定类别时,级别定义为sensitivity:category-set
; 否则,它只定义为sensitivity
。
现在我们已经熟悉了 SELinux 上下文。 接下来,我们将从用户的 SELinux 上下文开始,看到它们的实际应用。
下面的命令显示与当前用户关联的 SELinux 上下文:
id -Z
在我们的例子中,输出如下:
图 9.17 -显示当前用户的 SELinux 上下文
RHEL/CentOS 中,Linux 用户默认为unconfined
(不受限制),其上下文字段如下:
unconfined_u
:用户身份unconfined_r
:角色unconfined_t
:域关联s0-s0
:MLS范围(相当于s0
)c0.c1023
:类别集合,代表所有类别(从c0
到c1023
)
接下来,我们将研究进程的 SELinux 上下文。
显示当前 SSH 进程的 SELinux 上下文:
ps -eZ | grep sshd
该命令输出如下:
图 9.18 -显示 ssh 相关进程的 SELinux 上下文
从输出中,我们可以推断出上面的一行指的是sshd
服务器进程,它以system_u
用户身份、system_r
角色和sshd_t
域关联运行。 第二行是当前用户的 SSH 会话,即unconfined
上下文。 系统守护进程通常与system_u
用户和system_r
角色相关联。
在结束关于 SELinux 上下文的这一节之前,我们将研究 SELinux 域转换的一个相对常见的场景,即一个域中的进程访问另一个域中的对象(或进程)。
假设一个域中的 SELinux 安全进程请求访问另一个域中的对象(或另一个进程),那么 SELinux 域转换就发挥作用了。 除非有特定的安全策略允许相关的域转换,否则 SELinux 将拒绝访问。
由 selinux 保护的进程从一个域转换到另一个域时会调用新域的entrypoint
类型。 SELinux 评估相关的入口点权限,并决定请求流程是否可以进入新域。
为了演示一个域转换场景,我们将举一个简单的例子,当用户更改其密码时使用passwd
实用程序。 相关操作涉及到passwd
进程与/etc/shadow
(可能还有/etc/gshadow
)文件之间的交互。 当用户输入(并再次输入)密码时,passwd
将散列并将用户的密码存储在/etc/shadow
中。
让我们来看看 SELinux 域的亲缘关系:
ls -Z /usr/bin/passwd
ls -Z /etc/shadow
对应的输出如下:
图 9.19 -比较域关联上下文
passwd
实用程序标记为passwd_exec_t
类型,而/etc/shadow
标记为shadow_t
。 必须有一个特定的安全策略链,允许相关域从passwd_exec_t
过渡到shadow_t
; 否则,passwd
将无法正常工作。
让我们验证一下我们的假设。 我们将使用sesearch
工具来查询我们假定的安全策略:
sudo sesearch -s passwd_t -t shadow_t -p write --allow
下面是对前面命令的简要解释:
sesearch
:搜索 SELinux 策略数据库-s passwd_t
:查找以passwd_t
作为源的策略规则类型或角色-t shadow_t
:查找以shadow_t
为目标的策略规则类型或角色-p write
:查找权限为write
的策略规则--allow
:查找策略规则允许查询的权限(用-p
指定)
命令回显信息如下:
图 9.20 -查询 SELinux 策略
在这里,我们可以看到append create
权限,正如我们正确假设的那样。
我们如何选择passwd_t
源类型而不是passwd_exec_t
? 根据定义,与可执行文件类型passwd_exec_t
对应的域类型为passwd_t
。 如果我们不确定关于【病人】写shadow_t
文件权限类型,我们可以简单地排除源类型(-s passwd_t
)sesearch
解析查询和输出(例如,使用grep passwd
)。
在查询安全策略时,使用sesearch
工具非常方便。 有一些类似的工具用于故障诊断或管理 SELinux 配置和策略。 最著名的 SELinux 命令行实用程序之一是用于管理 SELinux 策略的semanage
。 我们接下来将研究它。
SELinux 提供了几个用于管理安全策略和模块的实用程序,下面的SELinux 问题故障排除一节将简要描述其中一些实用程序。 对这些工具的研究超出了本章的范围,但是我们将以semanage
为例,快速回顾一些涉及安全策略管理的用例。
semanage
命令的一般语法如下:
semanage TARGET [OPTIONS]
TARGET
通常表示策略定义的特定名称空间(例如,login
、user
、port
、fcontext
、boolean
、permissive
等等)。 让我们看几个例子来了解semanage
是如何工作的。
让我们假设我们想要为自定义 SSH 端口启用 SELinux,而不是默认的22
。 我们可以使用以下命令检索 SSH 端口上的当前安全记录(标签):
sudo semanage port -l | grep ssh
对于默认配置,我们将得到以下输出:
图 9.21 -查询 SSH 端口的 SELinux 安全标签
如果我们想在不同的端口(如2222
)上启用 SSH,首先,我们需要配置相关的服务(sshd
)来监听不同的端口。 我们不会在这里讨论这些细节。 这里,我们需要使用以下命令在新端口上启用安全绑定:
sudo semanage port -a -t ssh_port_t -p tcp 2222
下面是对前面命令的简要解释:
-a
(--add
):为给定类型添加一个新记录(标签)-t ssh_port_t
:对象的 SELinux 类型-p tcp
:与端口相关联的网络协议
作为前面命令的结果,针对ssh_port_t
类型的新安全策略如下所示:
图 9.22 -更改 SSH 端口的 SELinux 安全标签
我们可以删除旧的安全标签(针对端口22
),但如果禁用端口22
,这就无关紧要了。 如果我们想要删除一个端口安全记录,我们可以使用以下命令:
sudo semanage port -d -p tcp 22
我们使用-d
(--delete
)选项来删除相关的安全标签。 要查看semanage port
策略的本地定制,可以调用-C
(--locallist
)选项:
sudo semanage port -l -C
有关semanage port
的更多信息,请参考相关系统参考(man semanage port
)。 接下来,我们将研究如何修改特定服务器应用的安全权限。
semanage
使用boolean
命名空间来切换目标服务的特定特性。 目标服务是具有内置 SELinux 保护的守护进程。 在下面的示例中,我们希望启用 FTP over HTTP 连接。 默认情况下,Apache 的这个安全特性(httpd
)是关闭的。 下面查询相关的httpd
安全策略:
sudo semanage boolean -l | grep httpd | grep ftp
我们得到以下输出:
图 9.23 -查询与 FTP 相关的 httpd 策略
正如我们所看到的,相关的特性——httpd_enable_ftp_server
——默认为off
。 current
和persisted
状态目前为off: (off, off)
。 我们可以使用以下命令启用它:
sudo semanage boolean -m --on httpd_enable_ftp_server
要查看semanage boolean
策略的本地定制,可以调用-C
(--locallist
)选项:
sudo semanage boolean -l -C
新的配置现在看起来像这样:
图 9.24 -启用 FTP over HTTP 的安全策略
在前面的示例中,我们使用-m
(--modify
)选项和semanage boolean
命令来切换httpd_enable_ftp_server
特性。
有关semanage boolean
的更多信息,请参考相关系统参考(man semanage boolean
)。 现在,让我们学习如何修改特定服务器应用的安全上下文。
在本例中,我们希望安全 SSH 密钥存储在本地系统上的自定义位置。 因为我们的目标是一个与文件系统相关的安全策略,所以我们将在semanage
中使用fcontext
(文件上下文)命名空间。
查询sshd
的文件上下文安全设置。
sudo semanage fcontext -l | grep sshd
以下是输出的相关摘录:
图 9.25 - SSH 密钥的安全上下文
下面的命令还将/etc/ssh/keys/
路径添加到与sshd_key_t
上下文类型相关联的安全位置:
sudo semanage fcontext -a -t sshd_key_t '/etc/ssh/keys(/.*)?'
'/etc/ssh/keys(/.*)?'
正则表达式匹配/etc/ssh/keys/
目录中的任何文件,包括任何嵌套级别的子目录。 要查看semanage fcontext
策略的本地自定义,我们可以调用-C
(--locallist
)选项:
sudo semanage fcontext -l -C
我们应该看到新的安全背景:
图 9.26 -修改后的 SSH 密钥的安全上下文
我们还应该初始化/etc/ssh/keys
目录的文件系统安全上下文(如果我们已经创建了它):
sudo restorecon -r /etc/ssh/keys
restorecon
是一个 SELinux 实用程序,用于将默认的安全上下文恢复到文件系统对象。 选项-r
(或-R
)指定相关路径上的递归操作。
有关semanage fcontext
的更多信息,请参考相关系统参考(man semanage fcontext
)。 接下来,我们将研究为特定服务器应用启用permissive mode
。
在本章前面的中,我们创建了一个带有安全策略的自定义守护进程(packtd
)。 请参阅创建 SELinux 安全策略一节中的相关主题。 当我们处理packtd
守护进程并测试其功能时,最初我们必须处理它的 SELinux 策略违规。 最终,我们修复了所需的安全策略上下文,一切正常。 在整个过程中,我们能够使用packtd
运行和测试,而不需要 SELinux 因为不遵从而关闭守护进程。 然而,我们的 Linux 系统以enforcing
模式运行 SELinux(默认情况下),结果是not permissive
模式。 有关enforcing
和permissive modes
的更多信息,请参见理解 SELinux 模式部分。
那么,packtd
如何可能不受限制地运行,同时又违反安全策略?
默认情况下,SELinux 是permissive
到系统中任何非目标类型。 我们所说的非目标是指还没有被强制进入限制性(或受限)模式的域(类型)。
当我们为packtd
守护进程构建安全策略时,我们让相关的 SELinux 构建工具为我们的域生成默认的类型强制文件(packt.te
)和其他资源。 快速浏览一下packt.te
文件,我们的packtd_t
类型是permissive
:
cat packt.te
以下是该文件的相关摘录:
图 9.27 - packtd_t 域是允许的
因此,packtd_t
域本质上就是permissive
。 限制packtd
的惟一方法是从packtd.te
文件中删除permissive
行并重新构建相关的安全策略。 我们把这个留给你们做练习。 在这里,我们希望提出一个可能行为不端的域(在本例中是permissive
),我们可以通过semanage permissive
命令管理permissive
类型捕获。
要为单个目标管理permissive mode
,可以将命令与permissive namespace
一起使用semanage
命令。 下面的命令列出了当前permissive mode
中的所有域(类型):
sudo semanage permissive -l
在我们的例子中,我们有内置的*packtd_t
域,即permissive
:*
图 9.28 -显示允许类型
一般来说,默认 SELinux 配置不太可能有任何permissive types
。
在测试或故障排除特定功能时,可以使用semanage permissive
命令将一个受限制的域临时放置到permissive mode
中。 例如,下面的命令在permissive mode
中设置 Apache(httpd
)守护进程:
sudo semanage permissive -a httpd_t
当我们查询permissive
类型时,我们得到以下结果:
图 9.29 -自定义许可类型
使用semanage permissive
命令生成permissive
的域或类型将显示为Customized Permissive Types
。
要将httpd_t
域恢复为受限(受限)状态,可以使用-d
(--delete
)选项调用semanage permissive
命令:
sudo semanage permissive -d httpd_t
注意,我们不能用semanage
命令限制内置的permissive types
。 如前所述,packtd_t
域本质上是permissive
,不能加以限制。
即使在我们对 SELinux 相对短暂的探索过程中,我们也使用了一些工具和方法来检查安全策略的一些内部工作,以及主体(用户和进程)和对象(文件)之间的访问控制。 SELinux 的问题通常归结为行为被拒绝,或者是在特定的主体之间,或者是在一个主体和一些客体之间。 与 selinux 相关的问题并不总是很明显,也不容易进行故障排除,但是了解能够提供帮助的工具已经是解决这些问题的良好开端。
以下是其中一些工具,简要说明:
/var/log/messages
:包含 SELinux 访问控制跟踪和策略违规的日志文件audit2allow
:根据被拒绝操作对应的日志轨迹生成 SELinux 策略规则audit2why
:提供对 SELinux 策略违规审计消息的友好翻译ausearch
:查询/var/log/messages
策略违规- 列出文件系统对象及其相应的 SELinux 上下文
- 列出进程及其相应的 SELinux 上下文
restorecon
:恢复文件系统对象的默认 SELinux 上下文seinfo
:提供 SELinux 安全策略的一般信息semanage
:管理并提供 SELinux 策略的洞察力semodule
:管理 SELinux 策略模块sepolicy
:检查 SELinux 策略sesearch
:查询 SELinux 策略数据库
对于这些工具中的大多数,都有相应的系统参考(如man sesearch
),它提供了关于使用该工具的详细信息。 除了这些工具,您还可以探索 SELinux 提供的大量文档。 这是如何。
SELinux 有大量的文档,可以作为 RHEL/CentOS 可安装包获得,也可以通过https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/using_selinux/index在线获取(适用于 RHEL/CentOS 8)。
在 RHEL/CentOS 8 系统上安装 SELinux 文档:
sudo yum install -y selinux-policy-doc.noarch
可以使用(例如)以下命令浏览特定的 SELinux 主题:
man -k selinux | grep httpd
SELinux 是 Linux 内核中最成熟、可高度定制的安全框架之一。 然而,它相对广阔的领域和固有的复杂性可能会让许多人感到不知所措。 有时,即使是经验丰富的系统管理员,Linux 发行版的选择也可能取决于底层的安全模块。 SELinux 主要在 RHEL/CentOS 平台上可用。 Linux 内核的最新版本现在正在远离 SELinux,转而采用一种相对更轻、更有效的安全框架。 地平线上冉冉升起的新星是幻影显形。
AppArmor 是一个基于 MAC 模型的 LSM,它将应用限制在有限的一组资源中。 AppArmor 使用基于已加载到内核中的安全配置文件的 ACM。 每个概要文件包含一组用于访问各种系统资源的规则。 AppArmor 可以配置为enforce
访问控制,也可以配置为complain
访问控制违规。
通过防止已知和未知的漏洞被利用,AppArmor 主动保护应用和操作系统资源免受内部和外部威胁,包括零日攻击。
AppArmor 从 2.6.36 版本开始就内置在主流 Linux 内核中,目前随Ubuntu、Debian、OpenSUSE以及类似的发行版一起发布。
在下面几节中。 我们将使用 Ubuntu 20.04 环境来展示一些使用 AppArmor 的实际示例。 大多数相关的命令行实用程序在安装了 AppArmor 的任何平台上都可以相同地工作。
AppArmor 命令行实用程序通常需要超级用户特权。
使用如下命令检查 apapparmor 的当前状态:
sudo aa-status
下面是命令输出的摘录:
图 9.30 -获取 AppArmor 的状态
aa-status
(或apparmor_status
)命令提供当前加载的 AppArmor 配置文件的完整列表(没有在前面的摘录中显示)。 接下来我们来看看幻影显形。
使用 AppArmor 时,过程被剖面限制(或限制)。 在系统启动时加载 AppArmor 配置文件,并在enforce mode
或complain mode
中运行。 下面我们将解释这些模式。
AppArmor 阻止在enforce mode
中运行的应用执行受限制的操作。 在syslog
的日志条目中通知访问违规。 Ubuntu 默认在enforce mode
中加载应用概要文件。
在complain mode
中运行的应用可以采取受限制的操作,而 AppArmor 为相关违规创建一个日志条目。 complain mode
是测试 AppArmor 配置文件的理想选择。 在将配置文件切换到enforce mode
之前,潜在的错误或访问违规可以被捕获并修复。
记住这些介绍性说明后,让我们创建一个带有 AppArmor 配置文件的简单应用。
在本节中,我们将创建一个由 AppArmor 保护的简单应用。 我们希望这个练习能帮助你对幻影显形的内部工作方式有一个合理的了解。 让我们将此应用命名为appackt
。 我们将使它成为一个简单的脚本,创建一个文件,写入文件,然后删除文件。 我们的目标是让 AppArmor 阻止我们的应用访问本地系统中的任何其他路径。 为了理解这一点,可以把它想象成琐碎的日志回收。
下面是appackt
脚本,请原谅这个节俭的实现:
图 9.31 - appackt 脚本
我们假设log
目录已经存在于与脚本相同的位置:
mkdir ./log
让我们使脚本可执行并运行它:
chmod a+x appackt
./appackt
输出如下:
图 9.32 - appackt 脚本的输出
现在,让我们用 AppArmor 来保护和执行我们的脚本。 在我们开始之前,我们需要安装apparmor-utils
包——AppArmor 工具集:
sudo apt-get install -y apparmor-utils
我们将使用一些工具来帮助创建配置文件:
aa-genprof
:生成一个 AppArmor 安全配置文件aa-logprof
:更新一个 AppArmor 安全配置文件
我们使用aa-genprof
在运行时监视应用,并让 AppArmor了解。 在这个过程中,我们会被提示承认并选择在特定情况下需要的行为。
一旦创建了概要文件,我们将使用aa-logprof
实用程序在complain mode
中进行测试时进行进一步的调整,以防出现任何违反。
让我们从aa-genprof
开始。 我们需要两个终端:一个用于aa-genprof
监控会话(在终端 1中),另一个用于运行脚本(在终端 2中)。
我们将从终端 1开始,并运行以下命令:
sudo aa-genprof ./appackt
第一个提示符在等着我们。 接下来,当终端 1提示符等待时,我们将切换到终端 2并运行以下命令:
./appackt
现在我们必须回到终端 1,回答aa-genprof
发送的提示,如下:
此提示要求扫描系统日志以发现 AppArmor 事件,以便检测可能的投诉(违规)。
:S
(T1):
图 9.33 -提示 1 -等待用 aa-genprof 进行扫描
让我们看看下一个提示符。
这个提示请求运行应用的进程(/usr/bin/bash
)的执行权限。
:I
(T1):
图 9.34 - Prompt 2 -执行/usr/bin/bash 的权限
让我们看看下一个提示符。
提示请求应用控制终端的读写权限(/dev/tty
)。
:A
(T1):
Figure 9.35 – Prompt 3 – Read/write permissions to /dev/tty
现在,让我们看看最后一个提示符。
提示符要求保存或检查更改。
:S
(T1):
图 9.36 -提示 4 -保存更改
此时,我们已经用aa-genprof
完成扫描,可以用F (Finish)
回答最后一个提示。 我们的应用(appackt
)现在被complain mode
强制执行(默认)。 如果我们尝试运行我们的脚本,我们将得到以下输出:
图 9.37 -第一次使用禁闭的 appack
正如输出结果所表明的那样,事情还不完全正确。 这就是aa-logprof
工具发挥作用的地方。 对于其余步骤,我们只需要一个终端窗口。
让我们运行aa-logprof
命令来进一步优化appackt
安全配置文件:
sudo aa-logprof
我们将再次得到几个提示,类似于前面的提示,要求我们的脚本需要更多的权限,即touch
、cat
和rm
命令。 提示符根据需要在Inherit
和Allow
答案之间交替。 由于篇幅有限,我们在这里就不细讲了。 到目前为止,您应该对这些提示及其含义有了大致的了解。 但是,总是建议考虑所请求的权限并相应地采取行动。
我们可能需要运行aa-logprof
命令几次,因为在每次迭代时,将发现并处理新的权限,这取决于脚本生成的子进程,等等。 最终,appackt
脚本将成功运行。
在前面描述的迭代过程中,我们可能会在 AppArmor 数据库中得到几个未知的或孤立的条目,它们是我们之前尝试的产物,以确保应用的安全:
图 9.38 -迭代过程的残余
它们都将根据我们的应用(/home/packt/appackt
)的路径命名。 我们可以用下面的命令清理这些条目:
sudo aa-remove-unknown
现在,我们可以验证我们的应用确实受到了 AppArmor 的保护:
sudo aa-status
输出的相关摘录如下:
图 9.39 - appackt 在抱怨模式
正如所料,我们的应用(/home/packt/appackt
)以complain
模式显示。 另外两个是系统应用相关的,与我们无关。
接下来,我们需要验证我们的应用是否符合 AppArmor 执行的安全策略。 让我们编辑appackt
脚本,并将第 6 行中的LOG_FILE
路径更改为以下内容:
LOG_FILE="./logs/appackt"
我们已经将输出目录从log
更改为logs
。 让我们创建logs
目录并运行我们的应用:
mkdir logs
./appackt
前面的输出表明appackt
正试图访问 AppArmor 允许的边界之外的路径,因此验证了我们的配置文件:
图 9.40 - appackt 在安全边界之外
让我们恢复前面的更改,让appackt
脚本正常运行。 我们现在已经准备好enforce
我们的应用,通过以下命令改变它的配置文件模式:
sudo aa-enforce /home/packt/appackt
输出如下:
图 9.41 -改变 appackprofile 到强制模式
我们可以使用下面的命令来验证我们的应用确实是在enforce
模式下运行:
sudo aa-status
相关输出如下:
图 9.42 - appackt 在强制模式下运行
如果我们想要对我们的应用进行进一步的调整,然后用相关的更改对它进行测试,那么我们必须将概要文件模式更改为complain
,然后重申本节中前面描述的步骤。 将应用应用配置文件设置为complain mode
:
sudo aa-complain /home/packt/appackt
AppArmor 配置文件是存储在/etc/apparmor.d/
目录中的纯文本文件。 创建或修改 AppArmor 配置文件通常需要使用aa-genprof
和aa-logprof
工具手动编辑本节描述的相应文件或过程。
**接下来,让我们看看如何禁用或启用 AppArmor 应用配置文件。
有时,我们可能想要禁用有问题的应用概要文件,而正在开发更好的版本。 我们是这样做的。
首先,我们需要定位想要禁用的应用概要文件(例如,appackt
)。 相关文件在/etc/apparmor.d/
目录中,它是根据其完整路径命名的,用圆点(.
)而不是斜杠(/
)。 在我们的示例中,文件是/etc/apparmor.d/home.packt.appackt
。
要禁用配置文件,我们必须运行以下命令:
sudo ln -s /etc/apparmor.d/home.packt.appackt /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/home.packt.appackt
如果我们运行aa-status
命令,我们将不再看到appackt
概要文件。 相关的配置文件仍然存在于文件系统中/etc/apparmor.d/disable/home.packt.appackt
:
图 9.43 -被禁用的 appack 配置文件
在这种情况下,appackt
脚本不受任何限制强制执行。 要重新启用相关的安全配置文件,我们可以运行以下命令:
sudo rm /etc/apparmor.d/disable/home.packt.appackt
sudo apparmor_parser -r /etc/apparmor.d/home.packt.appackt
appackt
配置文件现在应该显示在aa-status
输出中,因为运行在complain mode
中。 我们可以通过以下方式将其带入enforce mode
:
sudo aa-enforce /home/packt/appackt
除了相关的文件系统操作外,我们还使用了apparmor_parser
命令来禁用或启用该概要文件。 此实用程序帮助在内核中加载(-r
,--replace
)或卸载(-R
,--remove
)安全配置文件。
删除 AppArmor 安全配置文件在功能上等同于禁用它们。 我们也可以选择从文件系统中完全删除相关文件。 如果我们删除一个配置文件而不首先从内核中删除它(使用apparmor_parser -R
),我们可以使用aa-remove-unknown
命令来清除孤立的条目。
让我们用一些最后的想法来总结我们对 AppArmor 内部结构的相对简短的研究。
与 SELinux 相比,使用 AppArmor 相对容易一些,特别是在生成安全策略或在permissive mode
和non-permissive mode
之间来回切换时。 SELinux 只能为整个系统切换许可上下文,而 AppArmor 可以在应用级别切换。 另一方面,在这两者之间可能没有选择,因为一些主要的 Linux 发行版要么支持其中一个,要么支持另一个。 AppArmor 是 Debian、Ubuntu 和最近的 OpenSUSE 的一个奇迹,而 SELinux 运行在 RHEL/CentOS 上。 理论上,你可以尝试在不同的发行版之间移植相关的内核模块,但这并不是一个简单的任务。
作为最后的说明,我们应该重申,在 Linux 安全的大背景下,SELinux 和 AppArmor 是acm,在应用级别上对系统进行本地操作。 当涉及到保护应用和计算机系统不受外部世界影响时,防火墙就起作用了。 下面我们来看看防火墙。
传统上,防火墙是一种位于两个网络之间的网络安全设备。 它监视网络流量并控制对这些网络的访问。 一般来说,防火墙保护本地网络不受外来入侵或攻击。 但防火墙也可以阻止针对公共互联网的不请自来的本地流量。 从技术上讲,防火墙根据特定的安全规则允许或阻止进出网络流量。
例如,除了一组选择的入站网络协议(如 SSH 和 HTTP/HTTPS)外,防火墙可以阻止所有的网络协议。 它也可能阻止所有在本地网络中除了批准的主机建立特定的出站连接,例如允许出站 SMTP 连接只起源于本地电子邮件服务器。
下图显示了一个简单的防火墙部署,调节本地网络和互联网之间的流量:
图 9.44 -一个简单的防火墙图
外向的安全规则防止坏的行为者,如被入侵的电脑和不值得信任的个人,直接攻击公共互联网。 由此产生的保护有利于外部网络,但它最终对组织也是必不可少的。 阻止来自本地网络的敌对行动,可以避免它们被**互联网服务提供商****(isp)**标记为不受约束的互联网流量。
配置防火墙通常需要一个作用于全局范围的默认安全策略,然后根据端口号(协议)、IP 地址和其他标准配置该通用规则的特定例外。
在下面的部分中,我们将探索各种防火墙实现和防火墙管理器。 首先,让我们通过介绍 Linux 防火墙链来简要地了解防火墙是如何监视和控制网络流量的。
在较高的层次上,Linux 内核中的 TCP/IP 栈通常执行以下工作流:
- 从应用(进程)接收数据,将数据序列化为网络数据包,并根据各自的 IP 地址和端口将数据包发送到网络目的地
- 从网络接收数据,将网络数据包反序列化为应用数据,并将应用数据发送给一个进程
理想情况下,在这些工作流中,Linux 内核不应该以任何特定的方式改变网络数据,除了根据 TCP/IP 协议对其进行整形。 然而,在分布式和可能不安全的网络环境中,数据可能需要进一步检查。 内核应该提供必要的钩子来根据各种条件进一步过滤和修改数据包。 这就是防火墙和其他网络安全和入侵检测工具发挥作用的地方。 它们适应内核的 TCP/IP 包过滤接口,并对网络包执行所需的监视和控制。 Linux 内核的网络包过滤过程的蓝图也被称为防火墙或防火墙链:
图 9.45 - Linux 防火墙链
当进入的数据进入防火墙包过滤链时,根据包的目的地做出路由决策。 基于该路由决定,包可以遵循INPUT链(对于本地主机)或FORWARD链(对于远程主机)。 这些链可以通过网络安全工具或防火墙实现的钩子以各种方式改变传入的数据。 默认情况下,内核不会改变遍历链的包。
INPUT链最终将数据包送入本地应用进程消耗数据。 这些本地应用通常是用户空间进程,例如网络客户机(例如 web 浏览器、SSH 和电子邮件客户机)或网络服务器(例如 web 和电子邮件服务器)。 它们也可能包括内核空间进程,例如内核的网络文件系统(NFS)。
FORWARD链和本地进程在将数据包放到网络上之前,都将数据包路由到OUTPUT链。
任何一条链都可以根据特定的条件过滤数据包,如下所示:
- 源或目的 IP 地址
- 源或目的端口
- 数据事务中涉及的网络接口
每个链都有一组与输入数据包匹配的安全规则。 如果匹配,则内核将数据包路由到该规则指定的目标。 一些预定义的目标包括:
- ACCEPT:接受数据包进行进一步处理
- REJECT:拒绝数据包
- DROP:忽略该数据包
- QUEUE:将数据包传递给用户空间进程
- RETURN:停止对数据包的处理,将数据返回到上一个链
要获得预定义目标的完整列表,请参考iptables-extensions
系统参考(man iptables-extensions
)。
在下面的部分中,我们将基于内核的网络堆栈和防火墙链探索一些最常见的网络安全框架和工具。 我们将从netfilter
开始——Linux 内核的包过滤系统。 接下来,我们来看看iptables
-用于配置 netfilter
的传统接口。 iptables
是一种高度可配置、灵活的防火墙解决方案。 然后,我们将简要介绍nftables
,这是一个实现iptables
大部分复杂功能的工具,它将iptables
包装到一个相对易于使用的命令行界面中。 最后,我们将离开内核与包过滤框架的直接关系,看看防火墙管理器-firewalld
(RHEL/CentOS)和ufw
(Debian/Ubuntu)——两个用户友好的前端,用于在主要 Linux 发行版上配置 Linux 防火墙。
让我们从netfilter
开始。
netfilter
是 Linux 内核中的一个包过滤框架,它提供了高度可定制的处理程序(或钩子)来控制与网络相关的操作。 这些操作包括以下内容:
- 接受或拒绝数据包
- 包路由和转发
- 网络地址和端口转换(NAT/NAPT)
实现netfilter
框架的应用使用一组围绕着钩子构建的回调函数,这些钩子注册在操纵网络堆栈的内核模块中。 这些回调函数进一步映射到安全规则和概要文件,这些规则和概要文件控制遍历网络链的每个包的行为。
防火墙应用是netfilter
框架实现的一等公民。 因此,对netfilter
钩子的良好理解将有助于 Linux 高级用户和管理员创建可靠的防火墙规则和策略。
下面我们将简要介绍这些netfilter
钩子。
当数据包穿越网络堆栈中的各种链时,netfilter
会触发内核模块的事件,这些内核模块被相应的钩子注册。 这些事件导致模块或包过滤应用(例如防火墙)中实现钩子的通知。 接下来,应用根据特定的规则控制数据包。
包过滤应用有 5 个 netfilter
钩子可用。 每一个都对应一个组网链,如图 9.44 所示:
NF_IP_PRE_ROUTING
:由进入网络堆栈的流量触发,并且在路由决定将数据包发送到哪里之前触发NF_IP_LOCAL_IN
:当包有一个本地主机目的地时,路由一个传入包后触发NF_IP_FORWARD
:当报文有远端主机目的地时,路由入报文后触发NF_IP_LOCAL_OUT
:由本地发起的出方向流量进入网络栈触发NF_IP_POST_ROUTING
:由发送或转发的流量触发,该流量在路由之后,在它退出网络堆栈之前
内核模块或用netfilter
钩子注册的应用必须提供一个优先级编号,以确定触发钩子时模块被调用的顺序。 这种机制允许我们确定性地对已注册到特定钩子中的多个模块(或同一模块的多个实例)排序。 当一个已注册的模块处理完一个信息包后,它会向 netfilter
框架提供一个关于该如何处理信息包的决策。
netfilter
框架的设计和实现是一个社区驱动的协作项目,作为自由开源软件(自由/开源软件)运动的一部分。 对于netfilter
项目的一个好的起点,你可以参考到http://www.netfilter.org/。
netfilter
最著名的实现之一是iptables
——一个广泛使用的防火墙管理工具,它与netfilter
包过滤框架共享一个直接接口。 对iptables
的实际检查将进一步揭示netfilter
的功能方面。 接下来让我们一起探索iptables
。
iptables
是一个相对低级的 Linux 防火墙解决方案和命令行实用程序,它使用netfilter
链来控制网络流量。 iptables
与规则结合链操作。 规则定义了匹配遍历特定链的信息包的标准。 iptables
使用表根据标准或决策类型组织规则。 iptables
定义了以下表:
filter
:默认表,当我们决定是否允许数据包通过特定的链(INPUT
,FORWARD,``OUTPUT
)时使用。nat
:用于需要源或目的地址/端口转换的报文。 该表对以下链进行操作:PREROUTING
、INPUT
、OUTPUT
和POSTROUTING
。mangle
:用于涉及 IP 报头的特殊报文改变(如MSS
=最大段大小或TTL
=生存时间)。 该表支持以下链:PREROUTING
、INPUT
、FORWARD
、OUTPUT
、POSTROUTING
。raw
:在禁用特定数据包的连接跟踪(NOTRACK
)时使用,主要用于无状态处理和性能优化目的。 该表与PREROUTING
和OUTPUT
链相关。security
:当报文受 SELinux 策略约束时,用于MAC。 该表与INPUT
、FORWARD
和OUTPUT
链相互作用。
下图总结了iptables
中支持的相应链表:
图 9.46 - iptables 中的表和链
数据包在内核网络栈中的链遍历顺序如下:
- 本地主机目的地的入包:
PREROUTING
|INPUT
- 远程主机目的地的入包:
PREROUTING
|FORWARD
|POSTROUTING
- 本地生成的报文(由应用进程):
OUTPUT
|POSTROUTING
既然我们已经熟悉了一些介绍性的概念,我们可以处理一些实际的例子来理解iptables
是如何工作的。
下面的示例使用 RHEL/CentOS 8 系统,但是它们应该适用于所有主流 Linux 发行版。 请注意,从 RHEL/CentOS 7 开始,默认的防火墙管理应用是firewalld
(在本章后面讨论)。 如果您想使用iptables
,首先需要禁用firewalld
:
sudo systemctl stop firewalld
sudo systemctl disable firewalld
sudo systemctl mask firewalld
接下来,安装iptables-services
包(CentOS):
sudo yum install iptables-services
(在 Ubuntu 上,你必须安装iptables
和sudo apt-get install iptables
)。
现在,我们开始配置iptables
。
iptables
命令需要超级用户权限。 首先,让我们检查当前的iptables
配置。 对于一个特定的表检索链中的规则的一般语法如下:
sudo iptables -L [CHAIN] [-t TABLE]
-L
(--list
)选项列出了链中的规则。 选项-t
(--table
)指定一个表。 CHAIN
和TABLE
参数是可选的。 如果省略了CHAIN
选项,那么所有的链及其相关规则将被考虑在一个表中。 当没有指定TABLE
选项时,假设使用filter
表。 因此,下面的命令列出了filter
表的所有链和规则:
sudo iptables -L
在默认配置防火墙的系统中,输出如下:
图 9.47 -在 iptables 中列出当前配置
我们可以更具体一些,例如,通过下面的命令列出nat
表的所有INPUT
规则:
sudo iptables -L INPUT -t nat
-t
(--table
)选项参数仅在iptables
操作的目标不是默认的filter
表时才需要。
重要提示
除非指定了-t
(--table
)选项参数,否则iptables
默认采用filter
表。
当你从头开始设计防火墙规则时,通常建议以下步骤:
- 刷新当前防火墙配置中的任何残留物。
- 设置默认防火墙策略。
- 创建防火墙规则,确保将更具体(或限制性)的规则放在首位。
- 保存配置。
让我们通过使用filter
表创建一个示例防火墙配置,来简要地了解前面的每个步骤。
下面的命令将刷新filter
表链(INPUT
、FORWARD
和OUTPUT
中的规则:
sudo iptables -F INPUT
sudo iptables -F FORWARD
sudo iptables -F OUTPUT
除非出现错误,或者使用-v
(--verbose
)选项调用iptables
命令,否则前面的命令不会产生输出; 例如:
sudo iptables -v -F INPUT
输出如下:
图 9.48 -刷新 iptables 中的 INPUT 链
接下来,我们将设置防火墙的默认策略。
默认情况下,iptables
允许所有包通过网络(防火墙)链。 安全防火墙配置应该使用DROP
作为相关链的默认目标:
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT DROP
选项参数-P
(--policy
)将特定链(如INPUT
)的策略设置为给定目标(例如DROP
)。 DROP
目标使系统正常忽略所有报文。
此时,如果我们要保存防火墙配置,系统将不会接受任何传入或传出的数据包。 因此,如果我们使用 SSH 或没有直接的控制台访问,我们应该小心不要不经意地放弃对系统的访问。
接下来,我们将设置防火墙规则。
让我们创建一些示例防火墙规则,例如接受 SSH、DNS 和 HTTPS 连接。
下面的命令使能从本地网络(192.168.0.0/24
)访问 SSH:
sudo iptables -A INPUT -p tcp --dport 22 -m state \
--state NEW,ESTABLISHED -s 192.168.0.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --sport 22 -m state \
--state ESTABLISHED -s 192.168.0.0/24 -j ACCEPT
让我们解释一下在前面的代码块中使用的参数:
-A INPUT
:指定要将规则添加到的链(例如INPUT
)-p tcp
:传输报文的网络协议,如tcp
或udp
--dport 22
:报文的目的端口--sport 22
:报文的源端口-m state
:我们想要匹配的数据包属性(例如state
)--state NEW,ESTABLISHED
:要匹配的报文状态-s 192.168.0.0/24
:报文的源 IP 地址/掩码-j ACCEPT
:目标或对数据包(如ACCEPT
、DROP
、REJECT
等)做什么
我们使用两个命令来启用 SSH 访问。 第一个允许传入的 SSH 流量(--dport 22
)用于新的和现有的连接(-m state --state NEW,ESTABLISHED
)。 第二条命令为现有连接(-m state –state ESTABLISHED
)开启 SSH 响应流量(--sport 22
)。
同样,下面的命令可以启用 HTTPS 流量:
sudo iptables -A INPUT -p tcp --dport 443 -m state \
--state NEW,ESTABLISHED -j ACCEPT
sudo iptables -A INPUT -p tcp --sport 443 -m state \
--state ESTABLISHED,RELATED -j ACCEPT
为了启用 DNS 流量,我们需要使用以下命令:
sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 53 -j ACCEPT
更多关于iptables
选项参数的信息,请参考以下系统参考手册:
- iptables(T0)
- iptables-extensions(
man iptables-extensions
)。
现在,我们已经准备好保存iptables
配置。
要保存当前iptables
配置,我们必须运行以下命令:
sudo service iptables save
输出如下:
图 9.49 -保存 iptables 配置
我们还可以将当前配置转储到一个文件(例如iptables.config
)中,以供以后使用,使用下面的命令:
sudo iptables-save -f iptables.config
-f
(--file
)选项参数指定要保存(备份)iptables
配置的文件。 稍后我们可以使用以下命令恢复保存的iptables
配置:
sudo iptables-restore ./iptables.config
在这里,我们可以指定到我们的iptables
备份配置文件的任意路径。
用iptables
探索更复杂的规则和主题超出了本章的范围。 我们到目前为止提供的示例,以及iptables
的理论介绍,应该是一个很好的开始,让大家探索更高级的配置。
另一方面,通常不鼓励使用iptables
,特别是在最新的 Linux 发行版(如nftables
、firewalld
和ufw
中附带的新兴防火墙管理工具和框架中。 人们也多少接受了iptables
存在性能和可伸缩性问题。
接下来,我们将看看nftables
,一个由Netfilter 项目设计和开发的相对较新的框架,构建它是为了取代iptables
。
nftables
是iptables
的继任人。 nftables
是一个防火墙管理框架,支持包过滤网络地址转换(NAT)和各种包整形操作。 nftables
与以前的包过滤工具相比,在功能、便捷性和性能方面都有显著的改进,例如:
- 查找表代替规则的线性处理。
- 规则是单独应用的,而不是处理一个完整的规则集。
- IPv4 和 IPv6 协议的统一框架。
- 没有特定于协议的扩展。
nftables
背后的功能原则通常遵循前面关于防火墙网络链的部分中介绍的设计模式; 即netfilter
和iptables
。 与iptables
一样,nftables
使用表来存储链。 每个链包含一组用于包过滤操作的规则。
nftables
是 Debian 和 RHEL/CentOS 8 Linux 发行版中的默认包过滤框架,取代了旧的iptables
(和相关)工具。 操作nftables
配置的命令行界面是nft
。 然而,有些用户更喜欢使用更友好的前端,比如firewalld
。 (firewalld
最近添加了nftables
的后端支持。) 以 RHEL/CentOS 8 为例,其默认防火墙管理方案为firewalld
。
在本节中,我们将展示一些示例,说明如何使用nftables
和相关的命令行实用程序来执行简单的防火墙配置任务。 为此,我们将使用 RHEL/CentOS 8 发行版,其中我们将禁用firewalld
。 让我们快速浏览一下运行本节中的示例所需的准备步骤。
如果是 RHEL/CentOS 7 系统,nftables
默认不安装。 你可以用以下命令安装它:
sudo yum install -y nftables
本节以 RHEL/CentOS 8 发行版为例进行说明。 要直接配置nftables
,我们需要禁用firewalld
,并可能禁用iptables
(如果您运行了相关部分中的示例)。 在配置 iptables一节的开始部分显示了禁用firewalld
的步骤。
另外,如果您启用了iptables
,则需要使用以下命令停止和禁用相关服务:
sudo systemctl stop iptables
sudo systemctl disable iptables
接下来,我们需要启用和启动nftables
:
sudo systemctl enable nftables
sudo systemctl start nftables
我们可以使用以下命令检查nftables
的状态:
sudo systemctl status nftables
nftables
的运行状态应该显示active
:
图 9.50 -检查 nftables 的状态
现在,我们准备配置nftables
了。 让我们来看几个例子。
ntftables
从/etc/sysconfig/nftables.conf
加载其配置。 我们可以使用以下命令显示配置文件的内容:
sudo cat /etc/sysconfig/nftables.conf
默认的nftables
配置在nftables.conf
中没有活动的条目,除了一些注释:
图 9.51 -默认的 nftables 配置文件
如注释所示,要更改nftables
配置,我们有几个选项:
- 直接编辑
nftables.conf
文件。 - 手动编辑配置文件
/etc/nftables/main.nft
,然后取消注释nftables.conf
中的相关行。 - 使用
nft
命令行实用工具编辑规则,然后将当前配置转储到nftables.conf
。
不管采用哪种方法,我们都需要通过重新启动nftables
服务来重新加载已更新的配置。 在本节中,我们将使用nft
命令行示例来更改nftables
配置。 高级用户通常编写nft
配置脚本,但最好先学习基本步骤。
显示当前配置中的所有规则:
sudo nft list ruleset
您的系统可能已经设置了一些默认规则。 在继续下一步之前,您可以选择对相关配置(例如,/etc/sysconfig/nftables.conf
和/etc/nftables/main.nft
)进行备份。
下面的命令将刷新所有已经存在的规则:
sudo nft flush ruleset
此时,我们有一个空配置。 让我们设计一个简单的防火墙,它接受 SSH、HTTP 和 HTTPS 通信,阻止其他任何东西。
首先,我们需要创建一个表和一个链。 下面的命令创建了一个名为packt_table
的表:
sudo nft add table inet packt_table
接下来,我们将在packt_table
中创建一个名为packt_chain
的链:
sudo nft add chain inet packt_table packt_chain { type filter hook input priority 0 \; }
现在,我们可以开始向packt_chain
添加规则了。 允许 SSH、HTTP 和 HTTPS 访问:
sudo nft add rule inet packt_table packt_chain tcp dport {ssh, http, https} accept
让我们同时启用 ICMP (ping):
sudo nft add rule inet packt_table packt_chain ip protocol icmp accept
最后,我们将reject
一切:
sudo nft add rule inet packt_table packt_chain reject with icmp type port-unreachable
现在,让我们来看看我们的新配置:
sudo nft list ruleset
输出如下:
图 9.52 -带有 nftables 的简单防火墙配置
输出建议为我们的输入链(packt_chain
)设置以下:
- 允许目的端口
22
、80
、443
(tcp dport { 22, 80, 443 } accept
)TCP 流量。 - 允许
ping
请求(ip protocol icmp accept
)。 - 拒绝一切 else(
meta nfproto ipv4 reject
)。
接下来,我们将当前配置保存为/etc/nftables/packt.nft
:
sudo nft list ruleset | sudo tee /etc/nftables/packt.nft
最后,通过添加以下行,我们将当前的nftables
配置指向/etc/sysconfig/nftables.conf
文件中的/etc/nftables/packt.nft
:
include "/etc/nftables/packt.nft"
我们将使用nano
(或您选择的编辑器)来进行更改:
sudo nano /etc/sysconfig/nftables.conf
新的nftables.conf
现在包含了对packt.nft
配置的引用:
图 9.53 -在 nftables 中包含新的配置
下面的命令重新加载新的nftables
配置:
sudo systemctl restart nftables
在这个练习之后,您可以使用nft list ruleset
命令的输出快速编写一个脚本来配置nftables
。 事实上,我们刚刚使用了/etc/nftables/packt.nft
配置文件。
至此,我们将结束对包过滤框架和相关命令行实用程序的研究。 它们使高级用户能够对底层网络链和规则的每个功能方面进行细粒度控制。 然而,一些 Linux 管理员可能会发现这些工具的使用令人难以应付,转而使用相对简单的防火墙管理工具。
接下来,我们将研究两个本地 Linux 防火墙管理工具,它们为配置和管理防火墙提供了更精简和用户友好的命令行界面。
防火墙管理器是具有防火墙安全规则的相对易于使用的配置界面的命令行实用程序。 通常,这些工具需要超级用户特权,它们是 Linux 系统管理员的重要资产。
在接下来的章节中,我们将介绍两个在当今 Linux 发行版中广泛使用的最常见的防火墙管理器:
firewalld
:RHEL/CentOS 平台ufw
:在 Ubuntu/Debian 上
防火墙管理器与其他网络安全工具(如iptables
、netfilter
和nftables
)相似,其主要区别在于它们为防火墙安全提供了更精简的用户体验。 使用防火墙管理器的一个重要好处是,当您操作各种安全配置更改时,不必重新启动网络守护进程。
让我们从 RHEL/CentOS 的默认防火墙管理器firewalld
开始。
firewalld
是用于各种 Linux 发行版的默认防火墙管理工具,包括以下内容:
- RHEL/CentOS 7(及更新版本)
- OpenSUSE 15(及更新版本)
- Fedora 18(及更新版本)
在 CentOS 上,如果没有firewalld
,我们可以用下面的命令安装它:
sudo yum install -y firewalld
我们可能还需要在启动时使用以下命令启用firewalld
守护进程:
sudo systemctl enable firewalld
在继续之前,让我们确保firewalld
已启用:
systemctl status firewalld
状态应该是active (running)
,如下截图所示:
图 9.54 -确保防火墙处于激活状态
firewalld
有一组命令行实用程序用于不同的任务:
firewall-cmd
:firewalld
的主要命令行工具firewall-offline-cmd
:用于在离线(未运行)时配置firewalld
firewall-config
:图形用户界面工具,用于配置firewalld
firewall-applet
:一个系统托盘应用,用于提供firewalld
的基本信息(如运行状态、连接等)
在本节中,我们将查看一些使用firewall-cmd
实用程序的实际示例。 对于任何其他实用程序,您可以参考相关的系统参考手册(如man firewall-config
)以获得更多信息。
firewalld
(与之相关的firewalld-cmd
)使用与监视和控制网络包相关的几个关键概念:区域、规则和目标。
区域是firewalld
配置的顶层组织单元。 firewalld
监控的网络报文如果匹配了该网络区域关联的网口或 IP 地址/掩码源,则该网络报文属于该网络区域。 下面的命令列出了预定义区域的名称:
sudo firewall-cmd --get-zones
该命令输出如下:
图 9.55 -防火墙中预定义的区域
关于当前已配置的所有区域的详细信息,我们可以运行以下命令:
sudo firewall-cmd --list-all-zones
以下是相关输出的摘录:
图 9.56 -详细列出防火墙区域
前面的输出说明了两个区域(trusted
和work
),每个区域都有自己的属性,下面将解释其中的一些属性。 与接口和源相关联的区域是,称为活动区域。 查询激活的 zone:
sudo firewall-cmd --get-active-zones
在我们的例子中,输出如下:
图 9.57 - firewaldactive 区域
接口表示连接到本地主机的网络适配器。 活动接口被分配到缺省区域或用户自定义区域。 一个接口不能加入多个安全区域。
源是入方向的 IP 地址或地址范围,也可以分配到区域中。 单个源或多个重叠 IP 地址范围不能分配给多个安全区域。 这样做将导致未定义的行为,因为它将不清楚哪个规则优先于相关区域。
缺省情况下,firewalld
将所有网络接口分配到public
区域,不关联任何源。 而且,在默认情况下,public
是唯一的活动区域,因此是默认区域。 显示默认的 zone:
sudo firewall-cmd --get-default-zone
默认输出如下:
图 9.58 -在防火墙中显示默认区域
可选参数。 因此,对于每个数据包,将有一个区域与匹配的网络接口。 但是,不一定有匹配的源的区域。 该范例将在匹配规则的评估顺序中发挥重要作用。 我们将在规则优先部分讨论相关主题。 但首先,让我们先熟悉一下firewalld
规则。
firewalld
配置中定义的规则或rich
规则表示控制与特定区域关联的数据包的配置设置。 通常,一个规则会根据一些标准来决定数据包是被接受还是被拒绝。
例如,要阻止public
区域使用 ping (ICMP 协议),我们可以添加以下rich
规则:
sudo firewall-cmd --zone=public --add-rich-rule='rule protocol value="icmp" reject'
相关输出如下:
图 9.59 -使用防火墙禁用 ICMP 访问
我们可以使用以下命令检索public
区域信息:
sudo firewall-cmd --info-zone=public
rich
rules 属性反映更新后的配置:
图 9.60 -使用防火墙获取公共区域配置
此时,我们的主机将不再响应 ping (ICMP)请求。 我们可以通过以下命令删除刚刚添加的规则:
sudo firewall-cmd --zone=public --remove-rich-rule='rule protocol value="icmp" reject'
或者,我们可以使用以下命令启用 ICMP 访问:
sudo firewall-cmd --zone=public --add-rich-rule='rule protocol value="icmp" accept'
请注意,没有firewall-cmd
实用程序的--permanent
选项所做的更改是暂时的,在系统或firewalld
重启后不会持续。
当区域没有定义或匹配rich
规则时,firewalld
使用区域目标控制报文的行为。 下面让我们来看看target。
当报文匹配特定的区域时,firewalld
根据相应区域的rich
规则控制报文的行为。 如果没有定义rich
规则,或者没有rich
规则与数据包匹配,则数据包的行为最终由区域关联的target
决定。 可能的目标值如下:
ACCEPT
:接收报文REJECT
:拒绝报文,返回拒绝应答DROP
:没有回复就丢弃数据包default
:遵循firewalld
的默认行为
区域、规则、目标是firewalld
分析和处理数据包时使用的关键配置元素。 数据包使用区域进行匹配,然后使用规则或目标进行操作。 由于区域-基于网络接口和 IP 地址/范围源的双重特性,firewalld
在计算匹配标准时遵循特定的顺序(或优先级)。 我们接下来再看这个。
让我们先定义术语。 我们将与接口相关联的区域称为接口区域。 与源相关联的区域称为源区域。 由于区域可以同时具有接口和源,因此一个区域可以作为接口区域、*源区域、*或两者兼有。
firewalld
处理数据包的顺序如下:
- 查看对应的源区域。 最多将有一个这样的区域(因为源只能与单个区域关联)。 如果匹配,则按照区域关联的规则或目标处理报文。 否则,下一步进行数据包分析。
- 查看对应的接口区域*。 恰好有一个这样的区域(总是)存在。 如果匹配,则根据区域的规则或目标处理数据包。 否则,下一步将进行报文验证。*
*让我们假设默认目标为firewalld
——它接受 ICMP 数据包,拒绝其他所有数据包。
从前面的验证工作流中可以得到的关键信息是,源区域优先于接口区域。 多区域firewalld
配置的典型设计模式定义了以下区域:
- 特权源区域:从选择的 IP 地址提升系统访问
- 限制接口区域:限制其他所有人的访问
让我们使用firewall-cmd
实用程序来探索一些潜在的有用示例。
显示防火墙中已开启的服务。
sudo firewall-cmd --list-services
使用默认配置,我们得到以下输出:
图 9.61 -显示防火墙中启用的服务
启用 HTTPS 访问(端口443
):
sudo firewall-cmd --zone=public --add-service=https
要添加用户定义的服务或端口(例如8443
),我们可以运行以下命令:
sudo firewall-cmd --zone=public --add-port=8443/tcp
下面的命令列出了防火墙中开放的端口:
sudo firewall-cmd --list-ports
在我们的例子中,输出如下:
图 9.62 -在防火墙中显示已启用的端口
在没有--permanent
选项的情况下调用firewall-cmd
命令会导致在系统(或firewalld
)重启后不会持续的瞬时更改。 要重新加载先前保存的firewalld
(永久)配置,我们可以运行以下命令:
sudo firewall-cmd --reload
有关firewalld
的更多信息,请参考相关系统参考(man firewalld
)或https://www.firewalld.org。
简单防火墙(ufw)是 Ubuntu 中的默认防火墙管理器。 ufw
为iptables
和netfilter
提供了一个相对简单的管理框架,并为操作防火墙提供了一个易于使用的命令行界面。
让我们看几个使用ufw
的例子。 请注意,ufw
命令行实用程序需要超级用户特权。 下面的命令报告了ufw
的状态:
sudo ufw status
缺省情况下,ufw
为inactive
(未启用):
图 9.63 -显示 ufw 的当前状态
我们可以使用以下命令启用ufw
:
sudo ufw enable
当您启用防火墙或执行任何可能影响您访问系统的更改时,始终要小心。 默认情况下,当启用ufw
时,将阻止除 ping (ICMP)请求外的所有传入访问。 如果你用 SSH 登录,当你试图启用ufw
时,你可能会得到以下提示:
图 9.64 -启用 ufw 可能会中断现有的连接
为了安全起见,您可能想要通过按n
(No
)并在防火墙中启用 SSH 访问来中止上述操作:
sudo ufw allow ssh
如果已经启用 SSH 访问,则不添加相关的安全规则:
图 9.65 -尝试添加一个现有的规则到 ufw
此时,您可以安全地启用ufw
,而不必担心当前或现有的 SSH 连接会被删除。 启用ufw
后,我们得到如下输出:
图 9.66 -启用 ufw
查看防火墙的详细状态,可以使用如下命令:
sudo ufw status verbose
显示如下信息,说明 SSH(22/tcp
)和 HTTP/HTTPS(80,443/tcp
)访问已开启。
图 9.67 - ufw 的详细状态
如我们所见,HTTP/HTTPS 访问是通过Nginx Full
应用概要文件启用的。 该规则被 Nginx 安装自动添加到ufw
中。 请注意,其他客户机或服务器应用也可能向ufw
添加此类规则。 总是建议检查您的防火墙设置,以确保无意访问系统是不允许的。
我们可以用下面的命令列出当前的应用安全配置文件:
sudo ufw app list
在我们的例子中,输出如下:
图 9.68 -在 ufw 中列出应用安全配置文件
要删除特定服务(如 HTTP)的访问,可以运行以下命令:
sudo ufw deny http
输出显示添加了一个新规则*:*
图 9.69 -在 ufw 中禁用 HTTP 访问
随后的详细状态检查将显示对端口80/tcp
的访问被拒绝。 然而,结果却有些复杂:
图 9.70 - ufw 中复杂的规则
我们只在中突出显示了涉及 HTTP 访问的 IPv4 对等规则。 在我们的例子中,我们有两个控制 HTTP 访问的规则:
80,443/tcp (Nginx Full) ALLOW IN Anywhere
80/tcp DENY IN Anywhere
通过只关注 HTTP,我们可以看到第一条规则允许从任何地方访问 HTTP。 第二个规则拒绝从任何地方访问 HTTP。 结果规则:HTTP允许从任何地方开始。 为什么? 因为符合标准的第一个规则获胜。 匹配相同标准(即从任何地方访问 80/tcp)的后续规则将被丢弃。
重要提示
总是把更具体的*(限制性)规则放在首位。 在添加或更改规则时,您可能需要删除旧条目或重新排列它们的顺序,以确保规则被适当地放置和评估。*
*在本例中,我们需要删除Nginx Full
规则。 请记住,该规则还支持 HTTPS 访问(443/tcp
),我们可能希望保留该规则。 为了以正确的顺序恢复规则,让我们先得到规则列表的numbered
输出:
sudo ufw status numbered
输出结果如下:
图 9.71 - ufw 规则编号列表
这些规则的顺序是由序列号提示的。 接下来,我们将使用相应的规则 ID(1
)删除Nginx Full
规则:
sudo ufw delete 1
我们会得到一个提示来批准这个操作:
图 9.72 -在 ufw 中删除一个规则
防火墙现在的状态如下:
图 9.73 -在 ufw 中删除 Nginx Full 应用配置文件后防火墙的状态
同样,我们删除相应的 IPv6 配置文件Nginx Full (v6)
,并删除相应的 ID(3
)。 请注意,规则列表已经在之前的ufw delete
操作中重新创建:
sudo ufw delete 3
现在,它是安全的重新添加Nginx HTTPS
配置文件到只有启用 HTTPS 访问(443/tcp
):
sudo ufw allow 'Nginx HTTPS'
最终状态现在产生以下输出:
图 9.74 -在 ufw 中应该先使用更具体的规则
如我们所见,更具体的(限制性的)规则(80/tcp DENY
)首先出现(仅针对 IPv4 突出显示)。 我们甚至可以允许Nginx Full
配置文件,它将启用 HTTP 访问。 然而,相应的规则(80/tcp ALLOW
)将被放在更具限制性的对应规则之后,因此被丢弃。
或者,我们可以使用insert
选项在给定位置添加特定规则。 例如,下面的命令将80/tcp DENY
规则放置在第二位置(如上图所示):
sudo ufw insert 2 deny http
让我们再看几个使用ufw
的例子。 从特定的源地址范围(192.168.0.0/24
)开启所有协议(any
)的 SSH 访问(端口22
):
sudo ufw allow from 192.168.0.0/24 to any port 22
启用ufw
日志:
sudo ufw logging on
相应的日志痕迹通常在/var/log/syslog
中:
grep -i ufw /var/log/syslog
下面的日志跟踪表明失败(UFW BLOCK
)从源地址(SRC=172.16.191.1
)到我们的目的地地址(DST=172.16.191.4
),针对 HTTP 服务端口80
(DPT=80
),使用 TCP 协议(PROTO=TCP
):
图 9.75 -分析 ufw 日志
禁用ufw
日志记录功能。
sudo ufw logging off
下面的命令将ufw
恢复为系统默认值:
sudo ufw reset
执行上述命令将导致删除所有规则并禁用ufw
。
有关ufw
的更多信息,您可能希望在https://help.ubuntu.com/community/UFW中查看UFW 社区帮助或相关的系统参考(man ufw
)。
与较低级别的包过滤实用程序(例如netfilter
、iptables
和nftables
)相比,防火墙管理工具(如ufw
和firewalld
)的使用可能对某些 Linux 管理员更有吸引力。 除了平台考虑之外,选择一种工具而不是另一种工具的一个理由是与脚本和自动化功能有关。 一些高级用户可能认为nft
命令行实用程序是设计防火墙规则的首选工具,因为nftables
提供了粒度控制。 其他用户可能倾向于使用iptables
,特别是在旧的遗留平台上。 最后,这是一个选择或偏好的问题,因为所有这些工具都能够在大致相同的程度上配置和管理防火墙。
让我们以一些最后的考虑来结束本章。
这一章的内容相当丰富,可能显得令人难以应付。 一个关键的要点应该是关注框架(模块)。 如果我们正在讨论防火墙,我们应该看看包过滤框架,如iptables
、netfilter
和nftables
。 对于访问控制,我们有 SELinux 和 AppArmor 等安全模块。 我们讨论了每种方法的优缺点。 关键的选择是在 AppArmor 和 SELinux 之间,这可能决定了 Linux 发行版。 其中一个可能比另一个更快,因为相关政府的努力悬而未决。 例如,选择 AppArmor 可以将主要的 Linux 发行版缩小到 Ubuntu、Debian 和 OpenSUSE。 反过来,发行版的选择将进一步决定可用的防火墙管理解决方案,等等。
掌握应用安全性框架和防火墙管理工具将帮助您以最小的努力保持系统的安全。 与任何典型的 Linux 系统管理任务一样,有许多方法可以保护您的系统。 我们希望您将在本章中介绍的探索性知识和工具的基础上,做出一个关于保持系统安全的平衡决策。
下一章将通过介绍灾难恢复、诊断和故障排除实践,进一步提高系统的安全性和保护。
这里有一个关于本章中涉及到的一些基本概念的小测验:
- 列举至少两个在 Linux 中使用的 acm。
- 枚举 SELinux 安全上下文的字段。
- SELinux 中的域是什么?
- 您能想到 SELinux 和 AppArmor 在执行安全策略方面的显著区别吗?
- 用于检索当前应用概要文件的 AppArmor 命令行实用程序是什么?
- 我们如何在
enforce
和complain
模式之间切换 AppArmor 应用配置文件? - 在 Linux 内核网络堆栈中,您能想到多少条链?
- RHEL/CentOS 8 的默认防火墙管理解决方案是什么? Ubuntu 怎么样?
- 您能想到设计防火墙规则的最佳实践吗?
- 如果你必须选择一个包过滤框架,你会选择哪个? 为什么?
有关本章所涵盖的主题,请参阅以下资料:
- 掌握 Linux 安全加固-第二版,Donald A. Tevault,packagpublishing
- Practical Linux Security Cookbook - Second Edition,Tajinder Kalsi,packpublishing
- Practical Linux Security (video),Tajinder Kalsi,Packt Publishing
- Linux 防火墙:通过 nftables 和 Beyond 增强安全性-第 4 版,Steve Suehring,addion - wesley Professional*************