安全指南

最近更新时间:2025-03-19 08:51:42

我的收藏

引言

TencentOS 安全指南对如何使用 TencentOS 系统内置的安全能力增强系统的安全性进行了详细说明,内容包括但不限于:
管理系统的认证与授权。
使用系统提供的密码学工具进行加密和签名。
配置强制访问控制来提高系统的安全性。
对常用系统服务(如 SSH)进行安全配置加固。
需要注意的是,安全并非没有代价,多数情况下用户都会面临安全性、性能、易用性的取舍,安全指南并不会提供例如必须开启某个安全特性,必须进行某种安全配置的建议(此类建议请参考安全配置基线),安全指南提供的是一份使用手册,客户应当根据自身环境对安全的需求来决定是否使用某项安全能力或进行某项安全配置。

系统安装

BIOS 安全

BIOS 安全是指在计算机硬件层面对计算机 BIOS 进行安全设置和保护的措施。BIOS(Basic Input/Output System)是计算机系统中的基础软件,它负责启动和初始化系统的硬件设备,如 CPU、内存、硬盘、显卡等。由于 BIOS 是系统启动的第一个软件,因此它对整个系统的安全性至关重要。在正式安装 TencentOS 前,对 BIOS 进行安全设置和保护,可以降低系统被黑客攻击或病毒感染的风险,提高系统的安全性和稳定性。
启用 BIOS 密码保护
启用 BIOS 密码保护是保护 BIOS 安全的重要措施之一。在计算机启动时,设置一个密码,可以限制未经授权的访问。这可以在 BIOS 设置中完成。请确保将密码保密,并定期更改密码。
禁用启动设备
通过禁用不必要的启动设备,如 USB、光驱等,可以降低系统的攻击面。这些选项通常在 BIOS 设置的 Boot 选项卡中。禁用不必要的启动设备可以防止黑客通过启动可启动介质进入系统,从而保护系统的安全性。
启用安全启动
安全启动是一种安全功能,它通过验证系统启动过程中使用的软件和固件来确保系统启动时不会遭受攻击。您可以在 BIOS 设置的 Security 选项卡中启用安全启动。安全启动通常需要与 UEFI(统一固件接口)一起使用,以实现更高级别的安全保护。
启用 TPM(Trusted Platform Module)
TPM 是一种硬件安全芯片,用于存储加密密钥和验证系统完整性。通过启用 TPM,您可以更加安全地存储敏感数据,并保护您的系统免受攻击。请确保系统支持 TPM,并在 BIOS 设置中启用此功能。启用 TPM 后,您可以使用 TPM 来加密磁盘、验证系统启动过程中的软件等,以提高系统的安全性。
禁用远程管理接口
如果不需要远程管理接口,则可以在 BIOS 设置中禁用它们。这样可以防止攻击者通过远程管理接口入侵系统。需要注意的是,BIOS 的远程管理接口可以提高计算机管理的效率和便利性,但同时也需要管理员谨慎配置和管理,以保护计算机的安全。管理员可以限制远程访问的 IP 地址或者仅允许通过安全的 VPN 隧道进行访问等来降低风险。
保持 BIOS 固件的最新版本,以获得更好的安全性和性能,定期审计 BIOS 设置,并确保它们符合最佳安全实践,以保证系统的安全性和稳定性。

磁盘分区安全

磁盘分区是将硬盘分成多个逻辑部分,每个分区可以单独使用,以达到分隔文件、数据、操作系统等目的。磁盘分区安全是指在分区的过程中采取一定的措施,以保障系统数据的安全性和稳定性。
磁盘分区的必要性在于:
提高数据安全性:通过将系统和数据分别存放在不同的分区中,可以有效地保障数据的安全性。当系统受到攻击或者出现故障时,数据也能够得到保护。
提高系统稳定性:将系统和数据分别存放在不同的分区中,可以有效地避免因数据的异常或者损坏对系统的影响。当出现系统故障时,能够快速定位问题,并采取相应的措施进行修复。
提高系统性能:通过对磁盘进行分区,可以提高系统的读写性能,从而提升系统的运行效率。
以下是磁盘分区安全的配置建议:
启用磁盘加密
磁盘加密是一种重要的磁盘安全功能,它可以对整个磁盘或某些分区进行加密,以保护系统数据不被未经授权的人访问。在 TencentOS 中,可以使用 LVM(Logical Volume Manager)来实现磁盘加密。在进行磁盘分区时,可以选择使用加密分区,以保护系统数据的安全性。
分离操作系统和数据
将操作系统和用户数据分别存放在不同的分区中,可以有效地保障数据的安全性和系统的稳定性。在进行磁盘分区时,可以将操作系统和用户数据分别存放在不同的分区中,并为每个分区设置相应的访问权限和安全策略,以避免数据泄露和系统异常。
配置分区权限
在 TencentOS 中,每个分区都有相应的权限设置。管理员可以根据实际需求,对分区进行相应的权限设置,以保护系统的安全性。例如,可以将系统分区设置为只读模式,防止系统文件被误删或修改。同时,可以将用户数据分区设置为只能读写,以防止未经授权的人访问或修改数据。
启用 SELinux
SELinux(Security-Enhanced Linux)是一种 Linux 内核安全模块,它可以通过强制访问控制来保护系统的安全性。在进行磁盘分区时,可以选择启用 SELinux,以提高系统的安全性。启用 SELinux 可以对文件、目录和进程等进行安全策略控制,可以限制系统访问、权限和操作。在进行磁盘分区时,可以根据实际需求,为每个分区设置相应的 SELinux 安全策略,以保护系统的安全性。需要注意的是, TencentOS 默认启动了 SELinux,用户可根据具体需要,来开启/关闭对应功能。
定期备份数据
无论在磁盘分区的过程中还是系统运行过程中,都可能会遇到数据丢失或者损坏的情况。因此,管理员应该定期备份数据,并将备份文件存储在不同的位置,以避免数据丢失和损坏。在进行磁盘分区时,可以选择将备份数据存放在不同的分区中,以提高备份数据的安全性。
以上是磁盘分区安全的配置建议。

必要软件安装

在 TencentOS 系统安装后,为了提高系统的安全性,需要安装并配置一些必要软件。以下是一些必要软件的安装和配置建议:

安装系统更新

在 TencentOS 系统安装完成后,需要及时更新系统软件包,以修复已知漏洞、提高系统的安全性。管理员可以使用以下命令更新系统:
dnf update
该命令将自动更新系统中所有的软件包和依赖项。

安装和配置防火墙

TencentOS 系统默认安装了 iptables 防火墙,但需要管理员配置规则来过滤网络流量。管理员可以使用以下命令安装iptables
dnf install iptables
安装完成后,可以使用以下命令启动 iptables 服务:
systemctl start iptables
管理员还需要根据实际需求,配置 iptables 规则,以过滤网络流量。例如,可以使用以下命令添加允许 SSH 流量的规则:
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

安装和配置 SELinux

SELinux 是一个强制访问控制框架,可以帮助管理员保护系统的安全性。在 TencentOS 系统中,SELinux 默认是开启的,但需要管理员根据实际需求,进行相应的配置。管理员可以使用以下命令安装和配置 SELinux:
dnf install selinux-policy selinux-policy-targeted
安装完成后,可以使用以下命令检查 SELinux 的状态:
sestatus
管理员还可以使用以下命令配置 SELinux 的访问策略:
setsebool -P httpd_can_network_connect on

配置 SSH 安全

SSH 是一个常用的远程登录协议,在 TencentOS 系统中,管理员需要配置 SSH 安全,以保护系统的安全性。管理员可以使用以下命令修改 SSH 的默认配置:
vi /etc/ssh/sshd_config
在该文件中,管理员可以修改以下参数来提高 SSH 的安全性:
禁用 root 登录:将PermitRootLogin参数设置为no
修改 SSH 端口:将Port参数设置为其他端口号,以避免被攻击者扫描到。
启用公钥认证:将PasswordAuthentication参数设置为no,只允许使用公钥进行认证。
修改完成后,需要重启 SSH 服务,以使配置生效:
systemctl restart sshd

配置 sudo 访问

sudo 是一个用于授权普通用户执行特权命令的工具,在 TencentOS 系统中,管理员可以使用以下命令安装 sudo:
dnf install sudo
安装完成后,管理员可以使用以下命令配置sudo的访问规则:
visudo
在打开的sudo配置文件中,管理员可以修改以下参数:
添加 sudo 用户:使用以下命令添加 sudo 用户,使其具有执行特权命令的权限:
usermod -aG wheel username
禁用用户通过 su 切换为 root 用户:使用visudo打开/etc/sudoers文件,添加以下行:
uesrname ALL=(ALL) ALL,!/bin/su
添加 sudo 规则:管理员可以根据实际需求,添加 sudo 规则,以允许特定用户执行特权命令。
以上是在 TencentOS 系统中进行必要软件安装和配置的建议。用户可参照手册定制化地配置系统,以提高系统软件的安全性。

必要服务运行

在 TencentOS 系统中,一些必要服务的运行对于系统的安全和稳定性至关重要。以下是一些必要服务的运行配置建议:

SSH 服务

SSH 服务是一种远程连接工具,可以帮助管理员在远程控制台上操作系统。在 TencentOS 系统中,管理员可以使用以下步骤配置 SSH 服务:
安装 OpenSSH 服务:
dnf install openssh-server
启动 OpenSSH 服务:
systemctl start sshd
设置 OpenSSH 服务自启动:
systemctl enable sshd
修改 SSH 服务配置文件(/etc/ssh/sshd_config),禁用 root 用户登录:
PermitRootLogin no

防火墙服务

防火墙服务是一种保护系统安全的技术,可以帮助管理员限制网络访问和流量。在 TencentOS 系统中,管理员可以使用以下步骤配置防火墙服务:
安装 firewalld 服务:
dnf install firewalld
启动 firewalld 服务:
systemctl start firewalld
设置 firewalld 服务自启动:
systemctl enable firewalld
配置 firewalld 服务规则,例如:
firewall-cmd --zone=public --add-port=80/tcp --permanent
以上命令将打开80端口的TCP连接,使外部主机可以访问系统的 Web 服务。

SELinux 服务

SELinux 服务是一种强制访问控制(MAC)技术,可以帮助管理员限制进程和用户对系统资源的访问和操作。在 TencentOS 系统中,管理员可以使用以下步骤配置 SELinux 服务:
启用 SELinux 服务:
setenforce 1
修改 SELinux 配置文件(/etc/selinux/config),使其在系统重启后自动启用:
SELINUX=enforcing
配置 SELinux 策略,例如:
semanage port -a -t http_port_t -p tcp 80
以上命令将打开 80 端口的 TCP 连接,允许外部主机访问系统的 Web 服务。

日志服务

日志服务是一种记录系统运行状态和事件的工具,可以帮助管理员诊断问题和分析攻击。在 TencentOS 系统中,管理员可以使用以下步骤配置日志服务:
安装 rsyslog 服务:
dnf install rsyslog
启动 rsyslog 服务:
systemctl start rsyslog
设置 rsyslog 服务自启动:
systemctl enable rsyslog
配置 rsyslog 服务规则,例如:
*.info;mail.none;authpriv.none;cron.none /var/log/messages
以上规则将记录系统的所有信息级别日志,但不包括邮件、身份验证和定时任务等日志。

时间同步服务

时间同步服务是一种帮助管理员同步系统时间和网络时间的工具,可以确保系统的时间和日期准确无误。在 TencentOS 系统中,管理员可以使用以下步骤配置时间同步服务:
安装 chrony 服务:
dnf install chrony
启动 chrony 服务:
systemctl start chronyd
设置 chrony 服务自启动:
systemctl enable chronyd
配置 chrony 服务服务器地址,例如:
echo 'server time1.cloud.tencent.com iburst' /etc/chrony.conf
server 'time1.tencentyun.com iburst' /etc/chrony.conf
以上命令将使用腾讯云的 NTP 服务器同步系统的时间和日期。
以上是在 TencentOS 系统中进行必要服务配置的建议。用户可参照手册定制化地配置系统服务,以提高系统软件的安全稳定性。

账户与口令

配置 su

在 TencentOS 系统中,正确配置 su 对于提高系统安全性同样重要。以下是关于如何配置 su 以提高系统安全性的详细说明:

禁止普通用户直接使用 su 命令

禁止普通用户直接使用 su 命令,只允许 wheel 组的用户切换到 root 用户。编辑/etc/pam.d/su文件,找到如下行:
#auth required pam_wheel.so use_uid
取消注释并保存:
auth required pam_wheel.so use_uid

添加用户到 wheel 组

将需要使用 su 命令的用户添加到 wheel 组中:
sudo usermod -aG wheel 用户名

设置强制密码策略

为了增强系统安全性,可以通过 PAM(Pluggable Authentication Modules)配置强制密码策略。编辑/etc/pam.d/system-auth文件,添加或修改以下行以设置所需的密码策略:
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok
这将要求密码至少包含 8 个字符,包括大写字母、小写字母、数字和特殊字符,并限制尝试次数为 3 次。

限制 root 用户的远程登录

编辑 sshd 配置文件以禁止 root 用户远程登录:
sudo vi /etc/ssh/sshd_config
找到以下行:
PermitRootLogin yes
将其更改为:
PermitRootLogin no
然后重启 sshd 服务:
sudo systemctl restart sshd

使用安全的 shell 作为默认 shell

确保系统中的默认 shell 是安全的。编辑/etc/passwd文件,将 root 用户的默认 shell 更改为/bin/bash
root:x:0:0:root:/root:/bin/bash

监控 su 命令的使用

通过查看系统日志,可以监控用户在系统上执行的 su 命令。默认情况下,su 命令的使用记录在/var/log/secure文件中。定期检查此日志以检测异常活动。

定期更新系统和软件包

确保系统和软件包始终保持最新状态。这有助于防止潜在的安全漏洞。定期运行以下命令以更新系统和软件包:
sudo dnf update
遵循以上配置步骤,您可以提高 TencentOS 系统的安全性。请确保根据实际需求调整配置,以适应特定环境和用户需求。

配置 sudo

在 TencentOS 系统中,正确配置 sudo 对于提高系统安全性至关重要。以下是一些关于如何配置 sudo 以提高系统安全性的详细说明:

安装 sudo

确保已经在系统上安装了 sudo。如果没有安装,可以使用以下命令安装:
sudo dnf install sudo

添加用户到 wheel 组

TencentOS 中默认的 wheel 组是用于授予特定用户 sudo 权限的。将用户添加到 wheel 组可以避免授予 root 权限。
sudo usermod -aG wheel username

编辑 sudoers 文件

使用visudo命令编辑/etc/sudoers文件:
sudo visudo

限制特定用户的 sudo 权限

不同用户可能需要不同的 sudo 权限。您可以为特定用户分配特定的权限,以确保他们只能访问所需的命令。
例如,将以下条目添加到 sudoers 文件中,以允许用户testuser仅使用/sbin/poweroff/sbin/reboot命令:
testuser ALL=(ALL) NOPASSWD: /sbin/poweroff, /sbin/reboot

设置密码超时

出于安全原因,您可以设置 sudo 密码超时,以便在一段时间后,用户需要重新输入密码。找到下面这一行:
Defaults env_reset
在其下方添加以下行:
Defaults timestamp_timeout=分钟数
其中分钟数是您希望设置的超时时间。

日志和审计

通过查看 sudo 日志,可以监控用户在系统上执行的命令。确保配置文件中启用了日志记录:
Defaults logfile=/var/log/sudo.log

配置别名

为提高安全性,可以为用户、主机和命令设置别名。例如,为用户组设置别名:
User_Alias ADMINS = 用户1, 用户2
然后为这些用户分配特定权限:
ADMINS ALL=(ALL) ALL
遵循以上配置步骤,可以提高 TencentOS 系统的安全性。请确保根据实际需求调整配置,以适应特定环境和用户需求。

认证与授权

配置 PAM

PAM 简介

PAM(Pluggable Authentication Modules,可插拔认证模块)是一个模块化的认证机制。提供了一种统一的认证接口,使得应用程序可以更简便地处理各种认证技术,并返回验证结果(成功/失败)。允许系统管理员在不修改应用程序的情况下,灵活地配置和管理认证策略。
PAM 通过配置文件控制,配置文件定义了应用程序(服务)和实际执行身份验证任务的 PAM 之间的连接。每个应用程序或服务可能会有一个对应的 PAM 配置文件。例如,面向 SSH 的 PAM 配置文件名为/etc/pam.d/sshd

PAM 配置文件

/etc/pam.conf PAM的全局配置文件,/etc/pam.d PAM的配置目录,如果这个目录存在,/etc/pam.conf 文件会被忽略。
配置文件是一系列规则的集合,每个规则一行,包含以下四个字段:typecontrolmodule-pathmodule-arguments
控制字段 type:
账户管理(Account):提供账户验证类型的服务,例如检查用户密码是否过期,是否允许访问请求的服务等。
认证(Auth):对用户进行认证并设置用户证书。可以使用密码、一次性密码、硬件认证等多种方式进行认证。
密码管理(Password):更新认证机制,常用于管理用户密码的创建、更改和删除。例如设置密码的复杂度、过期时间等。
会话管理(Session):在用户每次登录和退出时执行一些操作。记录用户的登录时间、执行环境设置、设置资源限制、分配文件系统空间等。
如果上面列表中的字段值前面有一个 - 字符,表示如果由于系统中缺少该模块而无法加载该模块,则 PAM 库将不会记录到系统日志中。
四种控制标志 control:
required(必需):模块必须成功执行,否则认证失败。失败后会继续执行后续模块,返回失败信息。
requisite(关键):模块必须成功执行,否则认证立即失败,不再执行后续模块。
sufficient(充分):模块成功执行,认证立即成功,不再执行后续模块。如果模块失败,认证不会立即失败,而是继续执行后续模块。
optional(可选):模块执行结果不影响认证结果,除非它是唯一的模块。
include(包含):将另一个 PAM 配置文件的内容直接插入到当前配置文件中。
substack(子堆栈):将当前堆栈暂停,并开始执行被引用文件中的模块。当被引用文件中的所有模块执行完毕后,PAM 会恢复执行当前文件中的下一个模块。
对于更复杂的语法,有效的控制值具有以下形式: [value1=action1 value2=action2 ...]
模块路径 MODULE_PATH:
PAM 模块在文件系统中的存放位置。可以使用 PAM 提供的模块,位于 /lib64/security/ 目录下;也可以通过绝对路径使用自定义模块。
模块参数 MODULE_ARGS:
为 PAM 模块提供的参数,不同的 PAM 模块提供不同的参数,可以通过 man 手册查看每个模块具体的参数,例如 man pam_unix。

修改 PAM 配置

PAM 模块配置后立即生效,因此修改配置时请谨慎,建议先在测试环境中验证配置,并备份现有配置文件避免错误。
限制特定用户访问
使用 pam_listfile.so 模块允许或拒绝特定用户访问某个服务。例如可以进行如下配置阻止 root 用户通过 ssh 登录。
修改 /etc/pam.d/sshd文件
添加一条规则阻止 root 用户登录,对登录用户进行判断,必须不是 root 用户,因此该规则必须成功执行,选用 required 模块,可以添加在第一行。
>auth required pam_listfile.so item=user sense=deny file=/etc/ssh/deniedusers onerr=fail
item=user 是模块参数,指定检查对象为 usersense=deny 指定如果在 file 指定的文件中找到对应 user 要采取的动作,如果找不到则执行相反的动作;file=/etc/ssh/deniedusers 指定每行包含一个 user 的文件;onerr=fail 指定当错误发生时采取的动作
如果要查看关于 pam_listfile.so 模块更多参数:
man pam_listfile
创建文件 /etc/ssh/deniedusers ,添加阻止ssh登录的用户名:
>sudo vim /etc/ssh/deniedusers
设置文件权限,避免被其他用户误操作:
>sudo chmod 600 /etc/ssh/deniedusers
PAM 模块配置后立即生效,此时无法通过root用户访问 SSH 和登录服务。
限制用户登录会话数
使用 pam_limits.so 模块对系统资源设置限制。例如可以进行如下配置限制用户登录会话数。
修改 /etc/pam.d/login/etc/pam.d/sshd 文件
添加一条规则启用 pam_limits.so 模块
>session required pam_limits.so
编辑 /etc/security/limits.conf 文件
pam_limits.so 模块默认读取 /etc/security/limits.conf 配置文件和 /etc/security/limits.d/*.conf 文件,添加以下行限制用户 user1 和用户组 group1 的成员在同一时间最多只能有 3 个登录会话。
user1 - maxlogins 3
@group1 - maxlogins 3
PAM 模块配置后立即生效,用户 user1 登录多个会话会产生如下提示:
There were too many logins for 'user1'.

配置 Kerberos

基本概念

Kerberos是一种身份认证协议,可以通过密钥系统为服务器和客户端程序提供双向身份验证和授权服务,实现单点登录和统一身份认证,提高系统的安全性和管理效率。
Kerberos 认证过程分为以下几个步骤:
Client 向 AS 请求 TGT:
客户端向认证服务器(Authentication Service,AS)请求票据授权票据(Ticket Granting Ticket,TGT)。
AS 验证客户端身份后,生成 TGT 并将其传送给客户端。
客户端使用密钥解密 TGT,从中提取会话密钥。此时,客户端拥有一个有效的 TGT,用于请求访问服务的票据。
Client 向 TGS 请求 ST:当客户端需要访问受保护的服务时。
客户端向票据授权服务(Ticket Granting Service,TGS)发送请求,附带 TGT 和一个新的认证器(Authenticator)。
TGS 验证 TGT 和认证器,然后生成一个包含客户端和服务之间的会话密钥的服务票据(Service Ticket)。
客户端接收 Service Ticket,解密并提取会话密钥。
Client 与 Server 通信:
客户端使用会话密钥生成一个新的认证器,并将其与 Ticket 一起发送给服务。
服务验证服务票据和认证器,确认客户端的身份。
服务可以使用会话密钥与客户端安全地通信。
这个过程确保了客户端和服务之间的通信安全性,同时避免了在网络上传输明文密码。

使用与配置

环境配置
设置领域 realm 为: OPENCLOUDOS.COM。
使用两台机器,一台作为服务端,一台作为密钥分发中心(Key Distribution Center,KDC),一台作为客户端。
KDC 包含认证服务器(Authentication Server,AS)和票据授权服务器(Ticket Granting Server,TGS)。
主机名
内网IP
角色
KDC
192.168.160.161
Master KDC
Client
192.168.160.165
Kerberos Client
在两台主机的 /etc/hosts 文件中配置如下,确保主机名能够被解析。
192.168.160.161 KDC
192.168.160.165 Client
服务端配置
安装 Kerberos。
安装 Kerberos 服务器(KDC)和管理员工具:
>dnf install krb5-server krb5-client krb5-libs
配置 krb5.conf 文件。
文件默认路径为 /etc/krb5.conf ,对 Kerberos 认证服务进行配置,所有使用 kerberos 的主机上的文件都需要同步该文件。
>vi /etc/krb5.conf

[libdefaults] // 连接的默认配置
default_realm = OPENCLOUDOS.COM // 客户端的默认 Kerberos 域

[realms] // 指定kerberos域的配置信息
OPENCLOUDOS.COM = {
kdc = 192.168.160.161 // 指定该领域的KDC服务器的主机名或IP地址。
admin_server = 192.168.160.161 // 指定该领域的管理员服务器的主机名或IP地址
}
更多参数可以查看 man krb5.conf(5)。
配置 kdc.conf 文件。
文件默认路径为:/var/kerberos/krb5kdc/kdc.conf,修改KDC服务器上Kerberos域的配置信息。
>vi /var/kerberos/krb5kdc/kdc.conf

[realms]
OPENCLOUDOS.COM = { // KDC服务器上Kerberos域的配置信息
#master_key_type = aes256-cts
acl_file = /var/kerberos/krb5kdc/kadm5.acl
dict_file = /usr/share/dict/words
default_principal_flags = +preauth
admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
supported_enctypes = aes256-cts:normal aes128-cts:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal
}
配置 kadm5.acl 文件。
文件默认路径为:/var/kerberos/krb5kdc/kadm5.acl,该文件控制Kerberos数据库的管理权限,授予 admin 主体完全访问权限。
>vi /var/kerberos/krb5kdc/kadm5.acl

*/admin@OPENCLOUDOS.COM *
其中 */admin 是 Kerberos 中的账户形式,这个账户属于 OPENCLOUDOS.COM 这个域,最后的 * 表示符合 */admin 的账户拥有所有权限。
创建 Kerberos 数据库并设置主密钥。
>kdb5_util create -s -r OPENCLOUDOS.COM
Initializing database '/var/kerberos/krb5kdc/principal' for realm 'OPENCLOUDOS.COM',
master key name 'K/M@OPENCLOUDOS.COM'
You will be prompted for the database Master Password.
It is important that you NOT FORGET this password.
Enter KDC database master key:
Re-enter KDC database master key to verify:
-s :表示创建安全的 Kerberos 数据库。
-r :指定数据库的 Kerberos 领域。
数据库创建成功后,会在目录 /var/kerberos/krb5kdc/ 下生成新文件。
>ls /var/kerberos/krb5kdc
kadm5.acl kdc.conf principal principal.kadm5 principal.kadm5.lock principal.ok
添加 Kerberos 用户。
Kerberos 使用主体(principals)来表示用户、服务和其他实体。首先,创建一个名为 admin 的管理员主体并设置密码。
>kadmin.local -q "addprinc root/admin"
Authenticating as principal root/admin@OPENCLOUDOS.COM with password.
No policy specified for root/admin@OPENCLOUDOS.COM; defaulting to no policy
Enter password for principal "root/admin@OPENCLOUDOS.COM":
Re-enter password for principal "root/admin@OPENCLOUDOS.COM":
Principal "root/admin@OPENCLOUDOS.COM" created.
-q :表示在命令行中执行一个 kadmin 命令。在这种模式下,kadmin.local 将执行指定的命令,然后退出。
addprinckadmin 命令,用于添加一个新的主体(用户或服务),命名为 root/admin。
添加 Kerberos 测试用户。
>kadmin.local -q "addprinc krbtest/admin"
Authenticating as principal root/admin@OPENCLOUDOS.COM with password.
No policy specified for krbtest/admin@OPENCLOUDOS.COM; defaulting to no policy
Enter password for principal "krbtest/admin@OPENCLOUDOS.COM":
Re-enter password for principal "krbtest/admin@OPENCLOUDOS.COM":
Principal "krbtest/admin@OPENCLOUDOS.COM" created.
使用 listprincs 命令查看所有用户。
>kadmin.local
Authenticating as principal root/admin@OPENCLOUDOS.COM with password.
kadmin.local: listprincs
K/M@OPENCLOUDOS.COM
admin@OPENCLOUDOS.COM
kadmin/admin@OPENCLOUDOS.COM
kadmin/changepw@OPENCLOUDOS.COM
krbtest/admin@OPENCLOUDOS.COM
krbtgt/OPENCLOUDOS.COM@OPENCLOUDOS.COM
root/admin@OPENCLOUDOS.COM
kadmin.local:
启动 Kerberos 服务并设置开机自启动。
其中,krb5kdc 是 Kerberos 认证服务,kadmin 是 Kerberos 管理服务。
>sudo systemctl start krb5kdc
>sudo systemctl start kadmin
>sudo systemctl enable krb5kdc
>sudo systemctl enable kadmin
启动服务后,可以查看日志文件 /var/log/krb5kdc.log/var/log/kadmind.log。
配置防火墙。
如果启动了防火墙,需要允许相关服务,以 firewalld 防火墙为例,采用以下命令进行防火墙的相关设置:
>firewall-cmd --add-service=kerberos --permanent
success
>firewall-cmd --add-service=kadmin --permanent
success
>firewall-cmd --add-service=kpasswd --permanent
success
>firewall-cmd --reload
success
客户端配置
安装 Kerberos。
安装 Kerberos 客户端:
>dnf install krb5-client krb5-libs
配置 krb5.conf 文件,需要与 KDC 中 krb5.conf 文件保持一致。
使用 kinit 命令验证 KDC 颁发票据。
票据会存储在凭证缓存文件中,该命令也可用于测试 Kerberos 认证服务,将 krbtest/admin 修改为要测试的 Kerberos 用户名。
>kinit krbtest/admin
查看当前缓存中的票据及其信息:
>klist
销毁缓存及其包含的票据:
>kdestroy

配置 SSSD

SSSD 简介

系统安全服务后台程序 (System Security Services Daemon, SSSD) 是一种用于访问远程目录和身份验证机制的系统服务。 SSSD 维护一个守护进程,后者是一个介于本地用户和数据存储之间的进程,可以用来访问多种验证服务器,如 LDAP,Kerberos 等,并提供授权。本地客户端首先连接 SSSD,再由 SSSD 联系外部资源提供者,如:一台远程服务器。
SSSD 的特点:
避免了本地每个客户端程序对认证服务器大量连接,所有本地程序仅联系 SSSD,由 SSSD 连接认证服务器或 SSSD 缓存,有效的降低了负载。
允许离线授权。SSSD 可以缓存远程服务器的用户认证身份,这允许在远程认证服务器宕机是,继续成功授权用户访问必要的资源。

SSSD 常用命令

查询 SSSD 的状态信息。
idm.example.com 域生成报告,请输入如下命令:
# sssctl access-report idm.example.com
1 rule cached

Rule name: example.user
Member users: example.user
Member services: sshd
要显示特定用户的用户数据,请输入如下命令:
# sssctl user-checks -a acct -s sshd example.user
user: example.user
action: acct
service: sshd
查询域信息。
显示可用域列表:
# sssctl domain-list
implicit_files
idm.example.com
ad.example.com
sub1.ad.example.com
显示特定域的用户数据:
# sssctl domain-status idm.example.com
Online status: Online

Active servers:
IPA: server.idm.example.com

Discovered IPA servers:
- server.idm.example.com
配置拼写错误检查。
拼写检查:
# cat /etc/sssd/sssd.conf
[domain/example1]
ldap_search = dc=example,dc=com

# sssctl config-check

Issues identified by validators: 1
[rule/allowed_domain_options]: Attribute 'ldap_search' is not allowed in section 'domain/example1'. Check for typos.

Messages generated during configuration merging: 0

Used configuration snippet files: 0
将 ldap_search 替换为 ldap_search_base,保存后重启 SSSD:
# systemctl restart sssd
重新检查,拼写报错消失。
# sssctl config-check

Issues identified by validators: 0

Messages generated during configuration merging: 0

Used configuration snippet files: 0

=SSSD 常用配置

环境准备。
切换到 root,并确认 sssd-tools 包已安装:
# dnf -y install sssd-tools
启用离线验证。
/etc/sssd/sssd.conf 文件中添加如下选项:
[domain/your-domain-name]
cache_credentials = true
配置离线身份验证时间限制:
[pam]
offline_credentials_expiration = 3
注意:
offline_credentials_expiration 默认为 0,即不限制。
配置 DNS 服务发现(以 LDAP 为例)。
/etc/sssd/sssd.conf 文件中添加如下选项:
[domain/your-domain-name]
id_provider = ldap
ldap_uri = _srv_

chpass_provider = ldap
ldap_chpass_dns_service_name = ldap
对于要使用服务发现的每个服务,在 DNS 服务器中添加 DNS 记录:
_service._protocol._domain TTL priority weight port host_name
可选项: 默认情况下,服务发现使用系统主机名的域部分作为域名,要使用不同的 DNS 域,请使用 dns_discovery_domain 选项指定域名。 默认情况下,针对 LDAP 服务类型的服务发现扫描。要使用不同的服务类型,请使用 ldap_dns_service_name 选项指定类型。 默认情况下,SSSD 尝试查找 IPv4 地址。如果尝试失败,SSSD 会尝试查找 IPv6 地址。要自定义此行为,请使用 lookup_family_order 选项。
配置访问规则。
将 access_provider 设置为 simple 模式,可以基于用户名或组允许或拒绝访问,从而限制对特定机器的访问。
/etc/sssd/sssd.conf 文件中添加如下选项:
[domain/your-domain-name]
access_provider = simple
为用户定义访问控制规则:
simple_allow_users允许访问用户名单。
simple_deny_users 拒绝访问用户名单。
定义组的访问控制规则:
simple_allow_groups允许访问组名单。
simple_deny_groups拒绝访问组名单。
例如,以下示例允许访问 user1、user2 和 group1 的成员,同时拒绝对所有其他用户的访问:
[domain/your-domain-name]
access_provider = simple
simple_allow_users = user1, user2
simple_allow_groups = group1
注意:
如果拒绝对特定用户/组的访问,则会自动允许对所有其他用户/组的访问。因此,允许访问特定用户通常被认为比拒绝对特定用户的访问更安全。

SSSD 使用场景举例

在本节中,我们将当前的 OS 环境配置为 OpenLDAP 客户端,实现如下功能:
验证存储在 OpenLDAP 用户账户数据库中的用户。
使用 SSSD 服务检索用户数据。
通过 TLS 加密的连接与 OpenLDAP 服务器通信。
环境准备:
1. 切换到root,并安装如下软件包。
# dnf -y install openldap-clients sssd sssd-ldap oddjob-mkhomedir
2. OpenLDAP 服务器安装并配置了用户信息。
3. 已持有 OpenLDAP 服务器证书颁发机构的 root CA 签名证书链的 PEM 格式副本,存储在名为 core-dirsrv.ca.pem 的本地文件中。
具体步骤:
1. 将身份验证提供者切换到 sssd:
# authselect select sssd with-mkhomedir
2. 将证书副本 core-dirsrv.ca.pem 复制到/etc/openldap/certs目录。
# cp core-dirsrv.ca.pem /etc/openldap/certs
3. 将 LDAP 服务器的 URL 和后缀添加到/etc/openldap/ldap.conf文件中:
URI ldap://ldap-server.example.com/
BASE dc=example,dc=com
4. /etc/openldap/ldap.conf 文件的 TLS_CACERT 选项指定证书路径。
# When no CA certificates are specified the Shared System Certificates
# are in use. In order to have these available along with the ones specified
# by TLS_CACERTDIR one has to include them explicitly:
TLS_CACERT /etc/openldap/certs/core-dirsrv.ca.pem
5. /etc/sssd/sssd.conf 文件中,将环境信息添加到 ldap_uri 和 ldap_search_base 参数中:
[domain/default]
...
ldap_uri = ldap://ldap-server.example.com/
ldap_search_base = dc=example,dc=com
...
6. /etc/sssd/sssd.conf 文件中指定 TLS 身份验证要求:
...
cache_credentials = True
ldap_tls_cacert = /etc/openldap/certs/core-dirsrv.ca.pem
ldap_tls_reqcert = hard
...
7. 调整 /etc/sssd/sssd.conf 文件的权限:
# chmod 600 /etc/sssd/sssd.conf
8. 重启并启用 SSSD 服务和 oddjobd 守护进程:
# systemctl restart sssd oddjobd
# systemctl enable sssd oddjobd
9. 验证。 通过 id 命令指定 LDAP 用户从 LDAP 服务器检索用户数据:
# id ldap_user
uid=17388(ldap_user) gid=45367(sysadmins) groups=45367(sysadmins),25395(engineers),10(wheel),1202200000(admins)

系统服务安全加固

SSH 安全加固

SSH 协议简介

SSH(Secure Shell)是一种使用客户机-服务器架构在两个系统之间提供安全通信的协议,允许用户远程登录到服务器主机系统。SSH 协议为两个不受信任的主机在不安全的网络上提供安全的加密通信。
TencentOS Server 提供 SSH 开源版本的实现,它包括通用的 openssh 包、客户端软件包 openssh-client 和服务端软件包 openssh-server。它们提供以下了一系列用户态工具:
ssh SSH 客户端,用于远程登录服务器。
sshd 存在于服务端的 SSH 守护进程。
scp 基于 SSH 的安全远程文件复制程序。
sftp 基于 SSH 的安全文件传输程序。
ssh-agent 用于缓存私钥的身份验证代理。
ssh-addssh-agent 添加私钥身份。
ssh-keygen 生成、管理并转换 ssh 验证密钥。

配置文件

系统范围的 SSH 配置信息保存在 /etc/ssh/ 目录中。用户特定的 SSH 配置信息保存在用户主目录中的 ~/.ssh/ 中。有关 OpenSSH 配置文件的详细列表,请查看 sshd(8) man page 中的 FILES 部分。
/root/.ssh/authorized_keys 用于保存已认证用户的公钥。
/etc/ssh/ssh_config SSH 客户端的全局配置文件。此文件中的设置将应用于系统上的所有用户。通常,该文件包含默认的连接设置。用户级别的配置文件(如~/.ssh/config)可以覆盖全局配置文件中的参数。
/etc/ssh/sshd_config SSH 服务器的主要配置文件。此文件定义了 SSH 服务器的行为和设置,如:端口号、root 登录选项、登录超时、密钥验证等。要更改 SSH 服务器设置,请编辑该文件并重启 SSH 服务。
/etc/ssh/ssh_host_*key/etc/ssh/ssh_host_*key.pub :这是 SSH 服务器的私钥和公钥文件,用于其身份验证和连接加密。文件名中的星号( * )可以是 rsaecdsaed25519 等不同类型的密钥。这些文件在服务器端生成,并在建立 SSH 连接时与远程客户端共享。SSH 连接的安全性基于这些密钥。

安全加固案例

以下是一些安全加固建议。在系统中进行如下配置将增加您 SSH 服务的安全性,请根据您实际的情况和需求调整以下设置。
修改 SSH 默认端口
更改默认的 SSH 端口(22)以阻止基于端口的自动扫描。
修改默认监听端口号
编辑 /etc/ssh/sshd_config 文件,并找到/修改以下行:
Port <custom_port_number>
<custom_port_number> 替换为您想要的自定义端口号。
防火墙设置。
确保防火墙允许新端口上的 SSH 流量。
> sudo firewall-cmd --add-port=<custom_port_number>/tcp --permanent
> sudo firewall-cmd --reload
SELinux 设置。
如果您的系统上运行了 SELinux,并设置为了 enforcing ( TencentOS Server 默认配置),可能需要调整 SELinux 的策略以允许新的 SSH 端口。运行以下命令:
> sudo semanage port -a -t ssh_port_t -p tcp <custom_port_number>
重启 sshd 服务。
> sudo systemctl restart sshd
禁用 root 用户登录
禁止使用 root 用户远程登录。防止攻击者针对这个用户进行暴力破解攻击,而且限制了远程登录的权限。
修改 /etc/ssh/sshd_config 文件设置:
PermitRootLogin no
这个配置可以降低被攻击的风险,同时可以帮助您更好地跟踪和审查在您的系统上执行的操作。
重启 sshd 服务
> sudo systemctl restart sshd
免密登录配置
以下操作均在客户端机器上进行。
生成 SSH 公钥和私钥:
> ssh-keygen -t rsa
这样会在当前用户的 /home/<username>/.ssh 目录生成名为 id_rsa 的私钥文件和名为 id_rsa.pub 的公钥文件,-t 表示密钥类型是 rsa。
上传公钥:
> ssh-copy-id username@remote-server
这个命令将把本地计算机中的 id_rsa.pub 文件(即公钥)追加到远程服务器的 /home/<username>/.ssh/authorized_keys 文件中。如果该文件不存在,将自动创建。
验证:
在客户机上 ssh username@server-ip 验证是否可以免密登录。

FTP 安全加固

FTP & vsftpd

FTP(File Transfer Protocol )是一种传统的、广泛使用的文件传输工具。在不需要身份验证的情况下(允许匿名用户连接到服务器)通过网络在服务器和客户端之间传输文件。FTP 在默认情况下是不安全的,因为它传输用户凭证和数据时没有对数据进行加密。
vsftpd ( Very Secure File Transfer Protocol Daemon ) 是一个流行的、安全的、快速的、免费的 FTP 服务器软件,用于 Unix 和 Linux 类操作系统。它采用了许多安全和性能优化措施,因此广泛用于多种环境中,包括个人和企业服务器。

安装和启用 vsftpd

> sudo dnf install vsftpd
> sudo systemctl enable vsftpd
> sudo systemctl start vsftpd

配置 vsftpd

编辑配置文件 /etc/vsftpd/vsftpd.conf ,原始配置文件中可能包含以下参数,按照需求修改或添加以下配置:
# 禁止匿名登录:只允许已验证的用户访问。
anonymous_enable=NO

# 启用本地用户的 FTP 访问。
local_enable=YES

# 开启写权限,用以创建/更新文件或目录。视需求决定是否开启。
write_enable=YES

# 允许基于 chroot 的安全性:将用户限制在其主目录。
chroot_local_user=YES

# 确保带有写权限的用户始终处于 chroot 环境。
allow_writeable_chroot=YES

# 启用用户登录信息的记录。
xferlog_enable=YES

# 监听:启用 pasv_min_port 和 pasv_max_port 之间的被动模式端口范围。
pasv_enable=YES
pasv_min_port=40000
pasv_max_port=50000

# 禁用 SSL/TLS 的隐式和显式 FTPS: 如果需要的话,
# 还需要将 ssl_enable 关闭
force_local_data_ssl=NO
force_local_logins_ssl=NO
ssl_enable=NO

FTP 服务相关防火墙设置

为 FTP 服务允许端口 21(默认情况下为 FTP 端口)以及被动模式端口范围。
> sudo firewall-cmd --add-port=21/tcp --permanent
> sudo firewall-cmd --add-port=40000-50000/tcp --permanent
> sudo systemctl restart firewalld

配置 FTP 专用用户

创建新的用户和组,仅用于 FTP 访问,并限制其权限:
> sudo groupadd ftp-users
> sudo useradd -m -g ftp-users -s /sbin/nologin <ftp_user>
> sudo passwd <ftp_user>
/sbin/nologin 是一个非法的 shell,以此禁止该用户通过 SSH 执行 Shell 登录。让这样的用户只能使用 FTP 登录。

使用 SFTP 替代 FTP

如要提高安全性,可以考虑使用 SFTP(Secure File Transfer Protocol)替代 FTP。SFTP是一种基于 SSH 协议的安全文件传输方法。通过单个加密通道传输文件和命令,比基于明文的 FTP 更加安全。

BIND 安全加固

BIND 服务简介

BIND(Berkeley Internet Name Domain)服务是一个开源的 DNS(域名系统)服务器软件,用于将域名解析为 IP 地址,反之亦然。BIND 服务主要负责在互联网上处理域名解析请求和管理 DNS 记录。它在世界范围内广泛使用,并被认为是最受欢迎和广泛部署的 DNS 服务器解决方案之一。
BIND 服务包括两种主要功能:递归解析器和权威 DNS 服务器。作为递归解析器,BIND 负责将客户端请求的域名解析为与之关联的 IP 地址。当用户在互联网上请求域名解析(如查找与域名关联的 IP 地址)时,BIND 会查询其他 DNS 服务器,从而找到请求的域名与之关联的 IP 地址,并将结果返回给用户。作为权威 DNS 服务器,BIND 负责存储和提供与特定域相关的 DNS 记录,例如:域名服务器(NS)记录、地址(A)记录、邮件交换(MX)记录等。权威 DNS 服务器负责回答其他 DNS 服务器关于它所管辖的具体域名解析的查询请求。除此之外,BIND 服务还支持 DNS 缓存以提高解析速度、DNS 安全扩展(DNSSEC)、负载均衡和其他功能。

限制对管理区域的查询

对于查询和操作 BIND 服务器的管理区域,应该限制访问权限。对 BIND 服务的管理区域进行访问限制主要是为了确保仅允许授权客户端对特定区域进行查询。这样可以防止未经授权的用户访问潜在敏感的 DNS 信息,以及减少 DDoS 攻击的威胁。例如,允许仅允许内部网络的客户端进行查询。编辑 /etc/named.conf ,将以下内容添加到 options 块:
options {
...
allow-query {
localhost;
192.168.0.0/24;
};
...
};
在此示例中,仅允许本地计算机和 CIDR 范围为 192.168.0.0/24 的客户端查询。

限制区域传递

对 BIND 服务进行区域传递限制是指仅允许特定的、经授权的辅助(secondary)DNS 服务器从主(primary)DNS 服务器获取和复制管理区域数据。管理区域数据包括各种 DNS 记录,例如 A 记录、CNAME 记录、MX 记录等。通过限制区域传递(zone transfer),您可以确保敏感的 DNS 记录仅在可信任的服务器之间共享,从而增强网络安全。区域传递限制还可以抵御 DNS 遍历攻击。在 DNS 遍历攻击中,攻击者通过伪造区域传送请求来获取有关您其他 DNS 记录的信息。这些信息可能被用于针对您的网络资源发起更多攻击,如 DDoS 攻击。限制区域传递到指定的合法辅助 DNS 服务器,有助于降低潜在安全风险。
为了实施这种限制,您需要在 BIND 的配置文件 /etc/named.conf 内修改相关区域(zone)的设置。具体操作是添加一个 allow-transfer 配置参数,仅指定允许接收区域传递的辅助 DNS 服务器的 IP 地址或地址范围。以下是一个区域传递限制的示例:
zone "example.com" {
type master;
file "/etc/named/zones/db.example.com";
allow-transfer {
192.168.1.2;
};
};
在这个示例中,将区域传递限制为只允许 IP 地址为 192.168.1.2 的辅助 DNS 服务器接收 example.com 区域信息传递。

禁用递归查询

递归解析是 DNS 服务器在响应查询时获取域名和 IP 地址映射的过程。当递归查询被禁用时,BIND 服务器将不再处理来自外部客户端的递归查询请求,不会追踪外部域名解析。如果服务器不负责递归查询,那么它将只为其管理的区域提供权威解析服务。禁用递归查询可以防止外部用户利用服务器进行攻击,诸如 DNS 放大攻击、DNS 缓存污染等。关闭递归查询还可以减轻服务器负担,从而提高其性能。
编辑 /etc/named.conf ,将以下内容添加到 options 块即可禁止递归查询:
options {
...
recursion no;
...
};

启用 DNSSEC

DNSSEC(Domain Name System Security Extensions,域名系统安全扩展)旨在为 DNS 查询提供额外的安全性。通过为 DNS 记录和查询添加数字签名(加密验证),DNSSEC 可以确保查询数据的完整性和源可靠性,使客户端能确认所接收到的 DNS 解析结果的真实性。
启用 DNSSEC 以提供额外的安全性。编辑 /etc/named.conf ,将以下内容添加到 options 块:
options {
...
dnssec-enable yes;
dnssec-validation yes;
...
};

使用黑名单阻止恶意域名

通过创建一个黑名单文件,可以阻止特定的恶意域名。首先,在 /etc/named/ 目录下创建一个名为 named.blacklist 的文件。然后,在 /etc/named.conf 文件中,将以下内容添加到 options 部分:
options {
...
response-policy { zone "blacklist"; };
...
};
接下来,在 /etc/named.blacklist 文件中添加以下内容:
zone "blacklist" {
type master;
file "named.blacklist";
allow-query { none; };
};
对于要阻止的每个恶意域名,向 named.blacklist 文件中添加一行:
bad-domain.example CNAME .

邮件服务安全加固

在 Linux 系统中,邮件服务涉及多个组件(邮件传输代理、邮件传递代理、IMAP/POP3 服务器和 Webmail)共同完成电子邮件的发送、接收、存储和检索。在 TencentOS Server 上,有许多不同的软件包可以为用户提供邮件服务。例如,postfixsendmaildovecot。在选择您的邮件服务软件包时,根据您的需求、偏好和环境综合考虑。postfix + dovecot 是目前最流行的邮件服务软件,因为它提供了良好的安全性和性能。以下将基于这两个软件包列举一些实用的安全加固案例。

强制使用 SSL/TLS 加密

SSL/TLS 加密是一种安全技术,用于在客户端(如邮件客户端)与邮件服务器(如邮件传输代理 Postfix 和 IMAP/POP3 服务器 Dovecot)之间加密通信。它通过使用数字证书和密钥来实现安全连接,确保在传输过程中邮件内容以及用户的登录凭据不被窃听或篡改。
生成 SSL/TLS 证书:
以下示例使用 OpenSSL 生成自签名证书。您也可以使用可信 SSL 证书颁发机构提供的证书,例如 Let's Encrypt。使用 OpenSSL 生成自签名证书:
> sudo openssl req -new -x509 -days 365 -nodes -out /etc/pki/tls/certs/mailserver.pem -keyout /etc/pki/tls/private/mailserver.key
> sudo chmod 0600 /etc/pki/tls/private/mailserver.key
生成证书期间,将被提示提供一些信息,如国家、组织等。
配置 Postfix 使用 SSL/TLS:
编辑 Postfix 配置文件 /etc/postfix/main.cf ,添加或修改以下配置项:
smtp_use_tls = yes
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/pki/tls/certs/mailserver.pem
smtpd_tls_key_file = /etc/pki/tls/private/mailserver.key
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_timeout = 3600s
配置 Dovecot 使用 SSL/TLS:
编辑 Dovecot SSL 配置文件 /etc/dovecot/conf.d/10-ssl.conf ,添加或修改以下内容:
ssl = required
ssl_cert = </etc/pki/tls/certs/mailserver.pem
ssl_key = </etc/pki/tls/private/mailserver.key
重启 Postfix 和 Dovecot 服务:
> sudo systemctl restart postfix
> sudo systemctl restart dovecot

配置邮箱认证

邮箱认证是用于验证用户身份的一种安全机制,通常由邮件传输代理(MTA,例如 Postfix)和 IMAP/POP3 服务器(例如 Dovecot)配合协同实现。邮箱认证旨在确保只有经过身份验证的用户能够发送和接收电子邮件,防止未经授权的用户利用邮件服务进行垃圾邮件发送等恶意活动。为实现邮箱认证,您需要配置邮件传输代理(例如 Postfix)以使用诸如简单认证安全层(SASL)之类的认证机制。SASL 是一个通用的身份验证框架,支持各种身份验证协议(例如 PLAIN、LOGIN 等)。
Dovecot 配置:
编辑 /etc/dovecot/dovecot.conf 文件,修改或添加以下行:
auth_mechanisms = plain login
编辑 /etc/dovecot/conf.d/10-auth.conf 文件,找到以下行并取消注释,以禁用不安全的纯文本身份验证:
disable_plaintext_auth = yes
Postfix 配置:
编辑 Postfix 配置文件 /etc/postfix/main.cf ,添加下列配置项:
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = <myhostname>
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
修改 Postfix 配置文件 /etc/postfix/master.cf ,以将 Dovecot 用作邮件传输代理(MTA)的身份验证代理。找到以下部分:
smtp inet n - n - - smtpd
在其后添加以下行,启用 SASL 认证:
-o smtpd_sasl_auth_enable=yes
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
重启 Postfix 和 Dovecot 服务:
> sudo systemctl restart postfix
> sudo systemctl restart dovecot

文件权限

合理配置文件权限

在 Linux 中可以将普通文件和目录都统一当作文件来处理,而文件的安全性主要通过权限和属主来控制。
Linux 文件系统中,一般通过常见的 rwx 权限控制文件的访问。但在部分场景下,单一的 rwx 权限可能过为严格,还会用到 s 权限。例如, /etc/shadow 文件存储了系统中所有用户的加密密码,因此不能直接授予所有用户对该文件的访问。但是普通用户确实会有变更密码的需求,此时便可引入 s 权限,以允许用户更改自己的密码。

SUID 权限

1. SUID 权限查看。
当普通用户修改密码时,并不会直接授予其操作 /etc/shadow 文件的权限,而是通过 /usr/bin/passwd 进行操作,因此需要先赋予 /usr/bin/passwd SetUID (简称 SUID) 权限,ls 查看可知:
>ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 31984 Mar 31 23:51 /usr/bin/passwd
可以看到 owner 权限为 rws,而不是rwx ,当 s 出现在 s 的位置上时,即可称之为 SetUID Bits 或 SUID。其特点如下:
SUID 权限仅作用于可执行二进制文件。
当执行者对该二进制文件有执行权限,则执行者会短暂获得该文件的 owner 权限。
所以对于本次密码修改过程,当普通用户执行 /usr/bin/passwd 时,会短暂获得 root 权限进而执行该指令,完成密码的修改访问。
2. SUID 权限设置。
SUID 权限可以通过符号方式设置,也可以通过数字方式设置。SUID 权限对应数字4,因此设置方式参照如下:
> chmod u+s filename # 符号方式,+ 表增加该权限
> chmod 4755 filename # 数字方式,对应数字4
3. SUID 权限取消。
反之,SUID 权限可以通过符号和数字两种方式取消:
> chmod u-s filename # 符号方式,- 表增加该权限
> chmod 755 filename # 数字方式

SGID 权限

1. SGID 权限查看。
SGID 适用于用户,用户组也有一个等效的属性:SGID。其特点如下:
SGID 权限作用于目录。
用户在此目录下所创建的新文件,其用户组与该目录的用户组相同。
2. SGID 权限设置。
同理,SGID 权限可以通过符号和数字方式设置。SGID 权限对应数字2,设置方式参照如下:
> chmod g+s dirname # 符号方式,+ 表增加该权限
> chmod 2755 dirname # 数字方式,对应数字2
3. SGID 权限取消。
反之,SGID 权限可以通过符号和数字两种方式取消:
> chmod g-s dirname # 符号方式,- 表增加该权限
> chmod 755 dirname # 数字方式

Sticky BIT 权限

1. SBIT 权限查看。
Sticky BIT (全称为 the restricted deletion flag or sticky bit,简称 SBIT ),可意为黏滞位、黏着位、防删除位。
SBIT 目前只对目录有效,用来阻止非文件的 owner 删除文件,比较常见的例子为 /tmp 目录:
> ls -ld /tmp/
drwxrwxrwt. 7 root root 140 May 6 15:03 /tmp/
可以看到权限信息中最后一位被设置为 t,表明该目录被设置了 SBIT 权限。此时,当用户在该目录下创建新文件或目录时,仅有自己和 root 才有权限删除,防止他人的删除操作。
2. SBIT 权限设置。
SBIT 也可以通过符号和数字方式设置,对应数字1,设置方式参照如下:
> chmod o+t dirname # 符号方式,+ 表增加该权限
> chmod 2755 dirname # 数字方式,对应数字1
3. SBIT 权限取消。
SBIT 权限可以通过符号和数字两种方式取消:
> chmod o-t dirname # 符号方式,- 表增加该权限
> chmod 755 dirname # 数字方式

umask 值设置

user file-creation mode mask(umask)值用于为新创建的文件和目录设置默认权限。如果没有设定 umask 值,则生成的文件对任意系统用户而言都有可写权限,存在一定的风险。您可以通过执行 umask 查看当前系统的默认 umask 值:
> sudo umask
0022
注意:
root 用户默认 umask 值为 0022,普通用户默认 umask 值为 0002。新生成目录/文件的默认权限为 777/666 减去 umask 值。
当然您也可以根据安全需要,自行指定更严格的 umask 值:
临时更改。
> sudo umask 0037 #临时生效
永久更改。
要在系统中持久更改 umask 值,可以编辑 /etc/bashrc/etc/profile 中 umask 值所在的行,将其更改为新的值。
注意:
/etc/profile 修改只在用户第一次登录时被执行,而 /etc/bashrc 修改则在用户每次登录加载 shell 时执行。

配置 ACL

在 Linux 系统中,访问控制列表(Access Control Lists,ACL)是一个重要的安全机制。传统文件权限对每个文件和目录,通过划分 owner/group/others 并赋予不同的 rwx 权限。ACL 在此基础上,为每个文件和目录添加了一组更细粒度的访问控制规则,允许您为不同的用户和组设置不同的访问权限。

安装 ACL

ACL 目前已内置支持,因此在大多数情况下无需手动安装。若出现特殊情况未预安装,则可自行安装 ACL:
> sudo dnf install acl

查看 ACL

要查看文件或目录的 ACL,可以使用 getfacl 命令。例如,要查看 file1 的 ACL 设置,可以运行以下命令:
> getfacl file1
该命令将显示对应文件的访问控制列表,包括默认权限、属主和所属组的访问权限,以及任何特定用户或组的访问权限。例如:
# file: file1
# owner: root
# group: root
user::rw-
group::r--
other::r--

设置 ACL

要设置文件或目录的 ACL,可以使用 setfacl 命令。例如,要给用户 opencloudos 添加对 file1 的写和执行权限,可以使用以下命令:
> sudo setfacl -m u:opencloudos:rwx file1
然后我们再次查看 file1 的 ACL:
> getfacl file1
# file: file1
# owner: root
# group: root
user::rw-
user:opencloudos:rwx #新增
group::r--
mask::rwx #新增
other::r--
可以发现其实已新增了 opencloudos 用户对该文件的写、执行权限,该用户可以往 file1 中写入内容。反之,也可通过 ACL 减少某用户、用户组的文件权限。
此外,细心的用户可能已经发现设置 ACL 后,同时新增了 mask 权限信息。此处 mask 权限,指的是用户或群组能拥有的最大 ACL 权限,也就意味着 ACL 分配的权限如果超出 mask 权限的部分则是无效的。
简言之,ACL 分配权限与 mask 权限取交集后,才是用户真实的权限。倘若此处 mask权限 为 r-x,那么 opencloudos 用户实际上还是无法获取对 file1 的写权限。

删除 ACL

如果 ACL 权限设置冗余后,您也可以使用 -x 选项来删除一个 ACL 条目,例如:
> sudo setfacl -x u:opencloudos file1
这将从 file1 中删除名为 opencloudos 的用户的 ACL 条目,示例如下:
> getfacl file1
# file: file1
# owner: root
# group: root
user::rw-
group::r--
mask::r--
other::r--

默认 ACL

如果您想让某个目录下的所有文件和子目录默认使用相同的 ACL 规则,可以设置默认 ACL。例如,要让 dir1 目录中创建的所有新文件和目录默认继承 dir1 的 ACL,可以使用以下命令:
setfacl -d -m u::rwx,g::r-x,o::r-x dir1
该命令将给 dir1 目录添加一个默认 ACL 条目,其中 u::rwxg::r-xo::r-x 分别表示对 owner/group/others 的权限设置。

加密与签名

加密磁盘分区

基本概念

磁盘加密是一种保护数据安全的技术,通过对磁盘上的数据进行加密,确保未经授权的用户无法访问,有助于防止数据泄露。磁盘加密可以应用于整个磁盘(全盘加密)或特定的分区(分区加密)。
LUKS(Linux Unified Key Setup):块设备加密的规范,为数据建立磁盘格式,以及密码/密钥管理策略。LUKS 通过 dm-crypt 模块使用内核设备映射器子系统,提供了一个处理设备数据加密和解密的低级映射。cryptsetup 是一个分区加密工具,通过调用内核中的 dm-crypt 来实现磁盘加密的功能。

创建加密磁盘

由于创建加密磁盘需要对磁盘分区进行格式化操作,会清空整个磁盘分区的内容,请做好数据备份。
安装分区工具:
>dnf install cryptsetup
创建虚拟磁盘
创建虚拟磁盘对 LVM 逻辑卷进行加密;如果使用 LUKS 对物理分区进行加密,可以直接跳过当前步骤。
使用 dd 命令创建一个文件,该文件位于 /tmp/my_virtual_disk.img ,大小为 1GB(1024MB)。
>dd if=/dev/zero of=/tmp/my_virtual_disk.img bs=1M count=1024
对磁盘进行 LUKS 加密:
>cryptsetup luksFormat /tmp/my_virtual_disk.img
打开加密分区并创建映射到 /dev/mapper/my_encrypted_volume:
>cryptsetup luksOpen /tmp/my_virtual_disk.img my_encrypted_volume
格式化映射分区:
>mkfs.ext4 /dev/mapper/my_encrypted_volume
创建挂载点并挂载分区:
>mkdir /mnt/my_encrypted_volume
>mount /dev/mapper/my_encrypted_volume /mnt/my_encrypted_volume
查看加密盘状态:
>sudo cryptsetup status my_encrypted_volume
/dev/mapper/my_encrypted_volume is active and is in use.
type: LUKS2
cipher: aes-xts-plain64
keysize: 512 bits
key location: keyring
device: /dev/loop0
loop: /tmp/my_virtual_disk.img
sector size: 4096
offset: 32768 sectors
size: 2064384 sectors
mode: read/write
卸载并关闭分区:
>umount /mnt/my_encrypted_volume
>cryptsetup luksClose /dev/mapper/my_encrypted_volume

加密文件

文件加密是一种将文件内容转换为无法读取的形式的技术,以保护文件的机密性和安全性。通过使用加密算法,可以将原始文件转换为密文,使得除了授权的用户外,其他人无法读取文件内容。 文件加密通常使用对称加密或公钥加密算法。对称加密算法使用相同的密钥来加密和解密数据,因此需要确保密钥的安全性。公钥加密算法使用一对密钥(公钥和私钥),其中公钥用于加密数据。 而私钥用于解密数据。由于公钥可以公开,因此公钥加密算法更安全。 文件加密可以用于保护各种类型的文件,包括文本文件、图像文件、音频文件和视频文件等。加密文件可以防止未经授权的访问和窃取,从而保护个人隐私和商业机密。 国际开源界已经为我们提供了密码学相关的函数库:OpenSSL。OpenSSL不但提供了编程用的API函数,还提供了强大的命令行工具,可以通过命令来进行常用的加解密、签名验签、证书操作等功能。本节以 openssl 命令行的形式,介绍一下如何加解密文件。

OpenSSL 介绍

OpenSSL 采用 C 语言作为开发语言,使得 OpenSSL 具有优秀的跨平台性能,可以在不同的平台使用。OpenSSL 支持 Linux、Windows、BSD、Mac 等平台,具有广泛的适用性。OpenSSL 实现8种对称加密算法。 (AES、DES、Blowfish、CAST、IDEA、RC2、RC4、RC5),4种非对称加密算法(DH 算法、RSA 算法、DSA 算法、椭圆曲线算法(ECC))、5种信息摘要算法(MD2、MD5、MDC2、SHA1 和 RIPEMD)、密钥及证书管理。OpenSSL的license(许可证)是 Ssleay license和OpenSSL license 的结合,这两种 license 实际上都是 BSD 类型的 license,依照 license 里面的说明,OpenSSL 可以被用作各种商业、非商业的用途,但是需要相应遵守一些协定。其实这都是为了保护自由软件作者及其作品的权利。
OpenSSL 整个软件包大概可以分成三个主要的功能部分:密码算法库、SSL 协议库以及应用程序。

利用 OpenSSL 加密文件

对称加密算法
对称加密算法通常在需要加密大量数据时使用,双方使用同样的密钥进行加密和解密。对称算法的优点是算法公开、计算量小、加密速度快、加密效率高。对称算法的缺点是产生的密钥过多和密钥分发困难。 常用的对称算法有 DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK、AES 以及国家密码局颁布的 SM1 和 SM4 算法。
显示当前 openssl 的版本:
> openssl version
OpenSSL 1.1.1k FIPS 25 Mar 2021
显示系统支持的对称加密算法:
> openssl enc -list
-aes-128-cbc -aes-128-cfb -aes-128-cfb1
-aes-128-cfb8 -aes-128-ctr -aes-128-ecb
-aes-128-ofb -aes-192-cbc -aes-192-cfb
-aes-192-cfb1 -aes-192-cfb8 -aes-192-ctr
..........
-sm4 -sm4-cbc -sm4-cfb
-sm4-ctr -sm4-ecb -sm4-ofb
我们以-aes-128-cbc为例,来说明该参数的具体含义:
aes:表示使用AES对称加密算法,是一种加密算法名称。openssl-1.1.1k 一共提供了9种对称加密算法,其中8种是分组加密算法,仅有一种流加密算法是 RC4。8种分组加密算法分别是 AES、DES、Blowfish、CAST、IDEA、RC2/5、SEED、Camellia。
128:表示128 位密钥长度。
cbc:表示模式,涉及到的模式有:电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)这4种常用的分组密码加密模式。
使用 AES-256-CBC 算法进行文件的对称加解密,使用用户输入密码的形式进行加密。
# 该命令需要用户输入密码
# 其中`-pbkdf2`:表示使用 PBKDF2(Password-Based Key Derivation Function 2)算法进行密钥派生。PBKDF2 是一种密码学算法,用于从密码中派生出加密密钥。使用 PBKDF2 可以增加密钥的复杂度,提高安全性。
# `-in file.txt`:表示要加密的明文文件
# `-out file.enc`:表示加密后的密文文件
> openssl enc -aes-256-cbc -pbkdf2 -in file.txt -out file.enc
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:
使用相同的用户密码,进行解密:
> openssl enc -aes-256-cbc -pbkdf2 -d -in file.enc -out file.txt -pass pass:<password>
直接使用密钥进行文件的对称加密:
#生成256位的AES密钥:
> openssl rand -base64 32 > mykey.txt

#使用密钥进行对称加密:
> openssl enc -aes-256-cbc -pbkdf2 -in file.txt -out file.enc -pass file:mykey.txt

#使用相同的密钥进行解密:
> openssl enc -aes-256-cbc -d -pbkdf2 -in file.enc -out plaintext.txt -pass file:mykey.txt
使用国密算法 sm4 进行对称加解密。
加密,其中-K 选项指定加密使用的密钥,-iv 选项指定加密使用的初始向量:
> openssl enc -sm4 -in file.txt -K ******************************** -iv ******************************** -out file.enc
解密,需要使用相同的密钥和初始向量:
> openssl enc -d -sm4 -in file.enc -K ******************************** -iv ******************************** -out file.raw
非对称加密算法 OpenSSL 一共实现了4种非对称加密算法,包括 DH 算法、RSA 算法、DSA 算法和椭圆曲线算法(ECC)。DH 算法一般用于密钥交换。RSA 算法既可以用于密钥交换,也可以用于数字签名,如果您能够忍受其缓慢的速度,那么也可以用于数据加解密。DSA算法一般只用于数字签名。 这里我们使用RSA算法和椭圆曲线算法(ECC)尝试进行文件的加解密。
RSA 进行文件的加解密。
1.1 使用genrsa子命令生成密钥对,密钥对是一个文件:
# 生成的密钥长度是 2048 比特
> openssl genrsa -out mykey.pem 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
..................+++++
.+++++
e is 65537 (0x010001)
1.2 从密钥对中分离出公钥:
# 生成的密钥长度是 2048 比特
> openssl rsa -in mykey.pem -pubout -out mypubkey.pem
writing RSA key
1.3 显示公钥信息:
> openssl rsa -pubin -in mypubkey.pem -text
1.4 加密命令:
> openssl pkeyutl -encrypt -in plaintext.txt -inkey mypubkey.pem -pubin -out ciphertext.txt
其中, plaintext.txt 是待加密的明文文件, mypubkey.pem 是公钥文件, ciphertext.txt 是加密后的密文文件。
1.5 解密命令:
> openssl pkeyutl -decrypt -in ciphertext.txt -inkey mykey.pem -out plaintext.txt
其中, ciphertext.txt 是加密后的密文文件, mykey.pem 是私钥文件, plaintext.txt 是解密后的明文文件。
国密 sm2(ECDSA 密钥的一种)进行文件的加解密。
1.1 生成 SM2 密钥对:
> openssl ecparam -genkey -name SM2 -out sm2.pem
1.2 提取 SM2 公钥:
> openssl ec -in sm2.pem -pubout -out sm2.pub.pem
read EC key
writing EC key
1.3 SM2 加密:
> openssl pkeyutl -encrypt -in plaintext.txt -inkey sm2.pub.pem -pubin -out ciphertext.txt
其中,plaintext.txt 是明文文件,ciphertext.txt 是加密后的密文文件。
1.4 SM2 解密:
> openssl pkeyutl -decrypt -in ciphertext.txt -inkey sm2.pem -out plaintext.txt
其中,ciphertext.txt 是密文文件,plaintext2.txt 是解密后的明文文件。

签名与验签

数字签名是公钥密码学发展过程中衍生出的一种安全认证技术,主要用于提供实体认证、认证密钥传输和认证密钥协商等服务。简单来说,发送消息的一方可以通过添加一个起签名作用的编码来代表消息文件的特征,如果文件发生了改变,那么对应的数字签名也要发生改变,即不同的文件经过编码所得到的数字签名是不同的。使用基于 RSA 公钥算法的数字签名技术,如果密码攻击者试图对原始消息进行篡改和冒充等非法操作,由于无法获取消息发送方的私钥,因此也就无法得到正确的数字签名,若消息的接收方试图否认和伪造数字签名,则公证方可以用正确的数字签名对消息进行验证,判断消息是否来源于发送方,这样的方式很好地保证了消息文件的完整性、鉴定发送者身份的真实性与不可否认性。
数字签名技术可以分为以下几种:
RSA 数字签名:RSA 是最早的数字签名算法之一,它使用 RSA 密钥对进行数字签名和验证。RSA 数字签名算法具有较高的安全性和可靠性,但是计算复杂度较高,不适合用于大规模数据的签名和验证。
DSA 数字签名:DSA 是一种基于离散对数问题的数字签名算法,它使用 DSA 密钥对进行数字签名和验证。DSA 数字签名算法具有较高的安全性和较快的计算速度,适合用于大规模数据的签名和验证。
ECDSA 数字签名:ECDSA 是一种基于椭圆曲线的数字签名算法,它使用 ECC 密钥对进行数字签名和验证。ECDSA 数字签名算法具有较高的安全性和较快的计算速度,适合用于大规模数据的签名和验证。

数字签名的流程

签名生成流程:

签名验证流程:

本节依旧以 openssl 为例完成数字签名和验签。

RSA 数字签名

# 1. 生成一个RSA密钥对,密钥长度 1024 比特
> openssl genrsa -out rsaprivatekey.pem 1024
# 2. 从密钥对中分离出公钥
> openssl rsa -in rsaprivatekey.pem -pubout -out rsapublickey.pem
# 3. 对plain.txt文件使用sha256 Hash算法和签名算法生成签名文件signature.txt
> echo "hello" >>plain.txt
> openssl dgst -sha256 -sign rsaprivatekey.pem -out signature.txt plain.txt
# 4. 用相同的摘要算法和签名算法校验签名文件,需要对比签名文件和原始文件
> openssl dgst -sha256 -verify rsapublickey.pem -signature signature.txt plain.txt
Verified OK

DSA 数字签名

1. 生成参数文件和密钥对文件。
# 1. 生成参数文件,类似于DH参数文件(DH参数文件是包含 Diffie-Hellman 密钥交换算法所需参数的文件)
> openssl dsaparam -out dsaparam.pem 1024
# 2. 通过参数文件生成密钥对dsaprivatekey.pem
> openssl gendsa -out dsaprivatekey.pem dsaparam.pem
# 3. 对私钥对文件使用des3 算法进行加密
> openssl gendsa -out dsaprivatekey2.pem -des3 dsaparam.pem
Generating DSA key, 1024 bits
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
# 4. 通过密钥对文件拆分出公钥
> openssl dsa -in dsaprivatekey.pem -pubout -out dsapublickey.pem
2. 生成和验证签名。
> echo "hello" >plain.txt
# 进行签名,查看signature.txt可以发现有原始信息hello
> openssl dgst -sha256 -sign dsaprivatekey.pem -out signature.txt plain.txt
# 验证签名
> openssl dgst -sha256 -verify dsapublickey.pem -signature signature.txt plain.txt
Verified OK

基于国密的 ECDSA 数字签名

1. 直接生成 ECDSA 私钥,不用预先生成 ECC 参数文件,这里使用国密算法。
> openssl ecparam -genkey -name SM2 -out priv.key
2. 拆分密钥获取公钥。
# 生成私钥对应的公钥
> openssl ec -in priv.key -pubout -out pub.key
read EC key
writing EC key
# 显示公钥信息
> openssl ec -in pub.key -pubin -text -noout
read EC key
Public-Key: (256 bit)
pub:
04:4f:2b:3c:93:0f:ed:49:cb:e9:18:78:7f:1b:a6:
f9:67:61:0e:32:5c:34:28:27:c0:05:48:58:40:0a:
79:25:dc:2d:5f:51:49:1a:c5:f5:4d:83:df:44:81:
d1:97:b7:69:a1:c1:86:4f:41:26:fa:9f:c1:eb:c3:
ad:e9:07:35:75
ASN1 OID: SM2
3. 生成签名值和验证。
> echo "hello" >>plain.txt
# 使用SM2算法对文件进行签名,摘要算法指定为SM3:
> openssl dgst -sm3 -sign priv.key -out signature.txt plain.txt
# 使用公钥进行验签:
> openssl dgst -sm3 -verify pub.key -signature signature.txt plain.txt
Verified OK

防火墙

在 Linux 中,可以使用防火墙来保护网络安全。防火墙可以过滤网络流量,阻止未经授权的访问,并保护系统免受网络攻击。
以下是系统提供的三种防火墙服务:
firewalld:高级防火墙管理工具,底层使用 iptablesnftables,提供基本防火墙功能,适合初学者。
iptables:底层防火墙管理工具,提供灵活的包处理和转发,适合熟悉网络协议的用户。
nftables:新一代底层防火墙管理工具,iptables 的继任者,提供更简洁和易于管理的语法,适合熟悉网络协议的用户,对于新的防火墙配置,相比iptables,更推荐使用nftables。
为了避免导致不兼容和规则冲突的情况发生,系统中只应该使用一种防火墙服务。使用前请确认系统是否启用或配置了防火墙规则,如有,建议备份这些规则,并确保在使用防火墙服务时不会产生冲突或重复。如果不再需要使用相关防火墙规则,建议停止或禁用相关服务。

firewalld

firewalld 基础

firewalld 将网络接口划分为不同的区域(zone),不同的区域提供不同级别的安全性,每个区域都预定义了一系列规则进行防火墙管理。
firewalld 服务没有启动时,可以使用 firewall-offline-cmd 命令修改防火墙配置,添加的配置是永久性的,重启后也会保留。
firewalld 墙服务正在运行时,需要使用 firewall-cmd 命令修改防火墙配置,添加的配置是临时性的,使用 --permanent 将规则永久保存到防火墙配置文件中,并执行 firewall-cmd --reload 生效。
区域(zone)
以下是 firewalld 中预定义的区域:
drop:该区域的策略是拒绝所有传入的数据包,不发送任何响应。这是最严格的安全策略。
block:该区域也拒绝所有传入的数据包,但会向发送方发送一个错误响应。
public:该区域适用于公共网络。它允许某些传入连接,但仍然具有较高的安全策略。
external:该区域适用于外部网络,如连接到因特网的路由器。它通常启用源地址伪装(masquerading)以支持网络地址转换。
internal:该区域适用于内部网络,如公司局域网。它允许更多的传入连接,但仍然具有一定的安全策略。
dmz:该区域适用于隔离区,即在内部网络和外部网络之间设置的缓冲区。它允许某些传入连接,但限制了对内部网络的访问。
work:该区域适用于工作环境。它允许更多的传入连接,但仍然具有一定的安全策略。
home:该区域适用于家庭网络。它允许更多的传入连接,但仍然具有一定的安全策略。
trusted:该区域的策略是允许所有传入和传出的数据包。这是最宽松的安全策略。

firewalld 安装

通过 dnf 安装 firewalld。
> sudo dnf install firewalld

firewalld 配置

使用 firewalld 首先需要启动对应的 firewalld 服务,启动 firewalld 服务之前,需要确认不会影响当前系统的正常使用,通过 --list-all 可以查看活跃的区域及其配置:
> sudo firewall-offline-cmd --list-all
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: dhcpv6-client mdns ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
默认活跃区域为 public,允许的服务有 dhcpv6-client mdns ssh。需要注意,此处允许的服务相当于启用该服务的默认端口,例如允许 ssh 服务,则启用 22 端口,如果当前机器使用的不是默认端口,需要单独配置端口规则。
如果使用 ssh 登录机器,并且 ssh 服务监听的不是默认 22 端口,请先确保已经启用对应端口再开启防火墙服务:
> sudo firewall-offline-cmd --zone=public --add-port=<port>/tcp
启动 firewalld 服务:
# 启动服务
> sudo systemctl start firewalld.service

# 设置开机默认启动服务
> sudo systemctl enable firewalld.service
查看 firewalld 状态,是否运行:
> sudo firewall-cmd --state
running
当不需要使用 firewalld 时:
# 开机禁用服务
> sudo systemctl disable firewalld.service

# 关闭服务
> sudo systemctl stop firewalld.service
上文提到,firewalld 提供了多个区域,查看预配置区域列表:
> sudo firewall-cmd --get-zones
block dmz drop external home internal nm-shared public trusted work
可以为内部网络使用 homework 区域,为外部网络使用 publicexternal 区域。firewalld 默认启用的是 public 区域,在启动服务前我们已经在 public 区域进行了简单的配置。
查看默认区域,默认区域为 public,在进行配置时可以使用 --zone= 指定区域,不指定则指向默认区域:
> sudo firewall-cmd --get-default-zone
public
如果需要在 public 区域允许 http/https 服务,首先查看 firewalld 预定义服务列表,是否包含所需服务:
> sudo firewall-cmd --get-services | grep http
... http http3 https ...
添加 http、http3、https 服务到默认 public 区域,由于 public 是默认区域,因此也可以不指定 --zone 参数;使用 --permanent 参数设置为永久规则,避免防火墙配置更新后服务被刷新掉:
> sudo firewall-cmd --zone=public --add-service=http --permanent
> sudo firewall-cmd --zone=public --add-service=http3 --permanent
> sudo firewall-cmd --zone=public --add-service=https --permanent
查看 public 区域所有打开的端口,此时并没有输出,因为在 firewalld 中,通过服务打开的都是默认端口,不会通过 --list-ports 显示:
> sudo firewall-cmd --zone=public --list-ports
如果希望为 http 服务打开一个新的端口 8080/tcp:
> sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
不中断服务,并重新加载 firewall 配置:
> sudo firewall-cmd --reload
检验该端口是否已经打开:
> sudo firewall-cmd --query-port=8080/tcp
yes
如果需要移除端口:
> sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanent
保存、恢复配置:
保存:firewalld 会自动保存您所做的更改,因此无需执行额外操作。
恢复:要恢复 firewalld 的配置,只需将备份的 /etc/firewalld/ 目录复制回原始位置,然后重启 firewalld 服务即可。
> sudo systemctl restart firewalld
如果需要查看更多参数以及信息:firewall-cmd --helpfirewall-cmd(1)firewall-offline-cmd(1)。

iptables

iptables 基础

iptables 通过表(table)、链(chain)和规则(rule)提供提供灵活高效的包处理和转发服务。
规则可以基于源 IP、目标 IP、源端口、目标端口、传输协议(如 TCP、UDP、ICMP)和服务类型(如 HTTP、FTP、SMTP)等条件进行匹配。可以实现阻止来自特定 IP 的流量或允许某个特定服务的功能。
表(Tables)
iptables 一共提供五张表,每张表都包含内置链,也可以包含用户定义的链。iptables 提供的表如下:
filter:iptables 的默认表,用于过滤数据包。
nat:用于网络地址转换,通常与 IP 地址重写规则一起使用。
mangle:用于修改数据包的特定属性,例如数据包的TTL(生存时间)和 TOS(服务类型)。
raw:用于设置不被跟踪的数据包
security:用于处理与 SELinux 相关的规则。
链(Chains)
iptables 一共提供五条链,同事用户可以自定义链。每个链都是可以匹配一组数据包的规则列表,每个规则指定如何处理匹配的数据包。当报文经过系统时,会经过不同的链,并与链上的规则逐条匹配。iptables 提供的链如下:
INPUT:处理进入本地系统的数据包。
OUTPUT:处理从本地系统发出的数据包。
FORWARD:处理在本地系统中进行路由的数据包。
PREROUTING:处理在路由决策之前到达的数据包。
POSTROUTING:处理在路由决策之后离开本地系统的数据包。
以下为各个表包含的链:

filter
nat
mangle
raw
security
PREROUTING
-
&check;
&check;
&check;
-
INPUT
&check;
&check;
&check;
-
&check;
FORWARD
&check;
-
&check;
-
&check;
OUTPUT
&check;
&check;
&check;
&check;
&check;
POSTROUTING
-
&check;
&check;
-
-
规则(Rules)
链上包含一系列规则。每个规则包含匹配条件(match)和动作(target)。匹配条件用于匹配网络流量,而动作用于控制网络流量的处理方式。
配置防火墙的主要工作就是选取合适的表和链,添加、修改和删除这些规则。常用 target 如下:
ACCEPT:允许数据包通过。满足匹配条件的数据包将被允许进入下一个链或被处理。
DROP:丢弃数据包。满足匹配条件的数据包将被丢弃,防火墙不会向发送方发送任何提示或通知。
REJECT:拒绝数据包。与 DROP 类似,满足匹配条件的数据包会被阻止。但不同之处在于 REJECT 会向数据包的发送方发送一条 ICMP 错误消息,通知对方请求被拒绝。
LOG:记录数据包。满足匹配条件的数据包会被记录在系统日志中。通常用于调试和监控防火墙规则。
RETURN:返回上一链。将处理返回到前一个链,接着处理该链中的下一个规则。此目标通常用于自定义链。用户规则和规定常集中在专门的链中,并在名为“用户定义链”的默认链中使用 RETURN 目标结尾。
REDIRECT:将数据包重定向到另一个端口。类似于 DNAT 操作,但限制在一台系统的 IP 和本地数据包上。用于透明代理等应用场景。
DNAT:目标地址转换(Destination NAT)。允许在数据包通过系统时更改目标 IP 地址。这通常用于将外部请求转发到内部网络的私有服务器。
SNAT:源地址转换(Source NAT)。允许在数据包通过系统时更改源 IP 地址。该操作可隐藏内部网络结构,也可将内部 IP 地址映射到外部 IP 地址。
此外,iptables 还提供了许多其他的动作用于实现更复杂的网络流量控制,详见 iptables-extensions(8)

iptables 安装

通过 dnf 安装 iptables:
> sudo dnf install iptables

iptables 使用

以下是一个简单的例子,用于启用 iptables 并配置规则。注意 iptables 配置后立即生效,因此在进行防火墙规则配置时,需要格外注意。
首先查看 iptables 默认配置的规则,使用 --line-numbers 参数显示行号。iptables 默认表为 filter,包含 INPUT、FORWARD 和 OUTPUT 三个链。
> sudo iptables --list --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination

Chain FORWARD (policy ACCEPT)
num target prot opt source destination

Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
可以看到,默认表 filter 包含三条链,分别是 INPUT、FORWARD 和 OUTPUT,并且它们默认的规则都是 accept,因此当我们启动 iptables 服务时,经过系统的流量默认都会被接受。
启动 iptables 服务:
# 启动服务
> sudo systemctl start iptables.service

# 开机自启服务
> sudo systemctl enable iptables.service
当不需要使用 iptables 时:
# 开机禁用服务
> sudo systemctl disable iptables.service

# 关闭服务
> sudo systemctl stop iptables.service
创建新规则:
因为 iptables 规则是从上到下读取的,因此需要合理设置规则的顺序,当创建新规则时,可以使用 -A, --append 在规则最后追加,或者使用 -I, --insert 指定插入规则的顺序(number),如果不指定默认添加到规则列表的首行。
添加一条规则允许通过 SSH 连接到系统:
> sudo iptables -I INPUT -p tcp --dport 22 -j ACCEPT
-p --protocal 表示数据包使用 tcp 协议,--dport 表示目的端口为本机的 22 端口,-j --jump 表示执行动作为 accept 。
添加规则,允许本地回环接口的所有流量通过防火墙:
> sudo iptables -A INPUT -i lo -j ACCEPT
-i lo:匹配条件,表示仅处理通过本地回环接口(loopback interface)lo 的数据包。回环接口通常用于本地系统内的通信。
添加规则,允许已建立连接的流量通过防火墙:
> sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-m --match 指明使用 state 匹配模块。这个模块根据数据包的连接状态来匹配数据包。--state ESTABLISHED,RELATED:匹配条件,表示仅处理已建立(ESTABLISHED)或与已建立连接相关(RELATED)的数据包。已建立的连接表示双方已经进行了数据交换。相关连接通常是指与已建立连接有关的新连接,例如 FTP 数据连接或 ICMP 错误报告。
接下来可以根据需要添加其他规则来限制或允许特定类型的流量。
设置最后一条策略(policy)为拒绝所有流量,如果进入系统的流量不匹配我们已有的任何规则,则拒绝以保护系统安全。
注意:
前面我们已经提到,iptables配置后立即生效,因此配置 DENY ALL 规则需要格外谨慎。
> sudo iptables -A INPUT -j DROP
也可以通过 -P --policy 直接设置每条链的策略,策略值必须为 ACCEPT 或者 DROP,例如刚刚通过 -A 设置的策略也可以通过 -P 设置:
> sudo iptables -P INPUT DROP
删除规则:
需要指定列表(INPUT、OUTPUT 或 FORWARD)以及该列表中规则的行号(line-numbers),删除命令没有输出。
> sudo iptables --list --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
2 ACCEPT all -- anywhere anywhere
3 ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
4 DROP all -- anywhere anywhere

Chain FORWARD (policy ACCEPT)
num target prot opt source destination

Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
删除 INPUT 列表的第四条规则,即 DENY ALL 规则。
> sudo iptables -D INPUT 4
保存、恢复配置:
要保存当前的 iptables 规则,可以使用 iptables-save 命令将规则输出到文件:
> sudo iptables-save > /etc/sysconfig/iptables
要恢复 iptables 规则,可以使用 iptables-restore 命令从文件中加载规则:
> sudo iptables-restore < /etc/sysconfig/iptables
如果需要查看更多参数以及信息:iptables --helpiptables(8)。

nftables

nftables 基础

nftables 引入了新的、更简洁的语法,能够更加灵活地处理数据包。相比于 iptables,更推荐使用 nftables 进行防火墙管理。
nftables 通过表(table)、链(chain)和规则(rule)进行规则管理,与 iptables 类似。
nftables 默认不创建任何表。
地址族(Address families)
nftables 的每张表都有一个对应的地址族(Address families),决定处理的数据包类型。新建一张 nftables 表需要指定地址族,如果不指定,默认值为 ip。
ip:IPv4 地址族。
ip6:IPv6 地址族。
inet:IPv4/IPv6 地址族。
arp:ARP地址族,处理 IPv4 ARP 包。
bridge:网桥地址族,处理通过网桥设备的数据包。
netdev:Netdev 地址族,处理入口和出口的数据包。

nftables 安装

通过 dnf 安装 nftables:
> sudo dnf install nftables

nftables 配置

使用 nftables 服务的前提是启动对应的 nftables 服务,由于nftables 默认不创建任何表,也没有任何规则,因此启动 nftables 服务不会对系统有影响:
启动 nftables 服务:
# 启动服务
> sudo systemctl start nftables.service

# 设置开机默认启动服务
> sudo systemctl enable nftables.service
当不需要使用 nftables 时:
# 开机禁用服务
> sudo systemctl disable nftables.service

# 关闭服务
> sudo systemctl stop nftables.service
查看当前规则并列出所有表信息:
nftables 默认不创建任何表,因此输出应该为空:
> sudo nft list ruleset
创建一张名为 filter 的新表 ,作用是过滤数据包,指定地址族为 inet,处理 IPv4/IPv6 相关的数据包:
> sudo nft add table inet filter
add 后面可以接 tablechainrule,分别表示添加表,添加链,添加规则。
为 filter 表创建名为 input 的基本链,基本链是来自网络栈数据包的入口点:
> sudo nft add chain inet filter input { type filter hook input priority 0 \\; policy accept \\; }
反斜杠 \\ 用来转义,避免 Shell 将分号解释为命令结束。
列出链信息,筛选地址族为 inet,表名为 filter 的表中,名为 input 的链:
> sudo nft list chain inet filter input
table inet filter {
chain input {
type filter hook input priority filter; policy accept;
}
}
添加允许 ssh 登录的规则:
dport 可以接常见服务,也可以接具体的端口号:
> sudo nft add rule inet filter input tcp dport ssh accept
可以看到添加了 ssh 默认的 22 端口:
> sudo nft list ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy accept;
tcp dport 22 accept
}
}
修改默认策略为 drop:
> sudo nft chain inet filter input { policy drop \\; }
可以看到默认策略变成了 drop:
> sudo nft list ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
tcp dport 22 accept
}
}
保存、恢复配置:
保存:nftables 的配置文件会自动保存您所做的更改,因此无需执行额外操作。
恢复:要恢复 nftables 配置,只需将备份的 /etc/nftables.conf 文件复制回原始位置,然后运行以下命令以应用更改。
> sudo nft -f /etc/nftables.conf
如果需要查看更多参数以及信息:nft --helpnft(8)。

强制访问控制

SELinux

SELinux(Security Enhanced Linux) 是由美国国家安全局(NSA)联合其他安全机构共同开发的,旨在增强传统 Linux 操作系统的安全性,解决传统 Linux 系统中自主访问控制系统中的各种权限问题 (如 root 权限过高等)。
值得注意的是,SELinux 的 MAC 并非用于完全取代 DAC。恰恰相反,对于 Linux 系统安全来说,它是一个额外的安全层。换句话说,当使用 SELinux 时,DAC 仍然被使用,且会首先被使用。如果DAC允许访问,再使用 SELinux 策略;反之,如果 DAC 规则拒绝访问,则根本无需使用 SELinux 策略。

SELinux 介绍

传统的 Linux 系统中,默认权限是对文件或目录的所有者、所属组和其他人的读、写和执行权限进行控制,这种控制方式称为自主访问控制(DAC) 方式,而在 SELinux 中,采用的是强制访问控制(MAC)方式,也就是控制一个进程对具体文件系统上面的文件或目录是否拥有访问权限,而判断进程是否可以访问文件或目录的依据,取决于 SELinux 中设定的很多策略规则。
为实现此目的,SELinux 会捕获到达内核的所有系统调用,并默认拒绝这些调用。这意味着,在启用了 SELinux 但未配置任何其他设置的系统上,一切都无法正常运行。要使系统能够执行任何操作,管理员都需要编写规则并将其放入策略中,以策略决定是否允许访问。同时由于 SELinux 策略包含大量规则,较为庞杂。为了使其更易于管理,我们通常将策略分成模块。以便于管理员为系统的不同部分打开或关闭 SELinux 策略。
在启用了 SELinux 的系统上,进程和文件都有自己的安全上下文,以作为控制进行访问文件资源的工具。SELinux 会为进程和文件添加安全信息标签,例如 SELinux 用户、角色、类型、类别等,您可以通过 ls -Z 来查看目录中文件的安全上下文、 ps -Zaux 查看进程的上下文。
#查看/根目录本身的安全上下文
> ls -Zd /
system_u:object_r:root_t:s0 /

#查看/根目录中文件的安全上下文
> ls -Z /
system_u:object_r:bin_t:s0 bin
system_u:object_r:boot_t:s0 boot
system_u:object_r:default_t:s0 data
...

#查看进程上下文
> ps -Zaux | grep systemd-udevd
system_u:system_r:udev_t:s0-s0:c0.c1023 root 565 0.0 0.1 36964 15172 ? Ss Mar17 0:01 /usr/lib/systemd/systemd-udevd
···

其中,安全上下文以 : 进行字段分隔,各字段含义如下:
字段
含义
system_u
SELinux用户
object_r
角色
root_t
类型
s0
灵敏度等级
SELinux用户(user) : 每个 Linux 用户都通过 SELinux 策略映射到一个 SELinux 用户。这允许 Linux 用户继承对 SELinux 用户的限制。映射的 SELinux 用户身份在该会话中的进程的 SELinux 上下文中使用,以便定义他们可以进入的角色和级别。
角色(role) : SELinux 基于角色的进行访问控制(Role-Based Access Control,RBAC)安全模型。主要用来表示此数据是进程还是文件或目录。常见的角色有两种: object_r(代表文件或目录) ,system_r(代表进程)。
类型(type) : 类型字段是安全上下文中最重要的字段,进程是否可以访问文件,主要就是看进程的安全上下文类型字段是否和文件的安全上下文类型字段相匹配,如果匹配则可以访问。
注意:
类型字段在文件或目录的安全上下文中被称作类型(type) ,但是在进程的安全上下文中被称作域 (domain)
灵敏度等级(level) : level 为 MLS 和 MCS 的一个属性。MLS 范围是一对级别,如果级别不同,则写为 lowlevel-highlevel ,如果级别相同,则写为 s0-s0(同 s0) 。每个级别都是一个灵敏度类别对,类别是可选的。如果有类别,则级别写为 sensitivity:category-set。如果没有类别,则写为 sensitivity。

安装 SELinux 工具包

在 TencentOS Server 中,SELinux 默认设置为 enforcing 模式,并使用 targeted 策略。此外,在完整安装中会默认安装 SELinux 相关包,除非您在安装过程中手动排除。安装包名单及其作用介绍如下:
policycoreutils:提供用于操作和管理 SELinux 的实用程序,例如 restorecon、setfiles、semodule、load_policy和 setsebool。
selinux-policy:为 SELinux 引用策略提供配置。SELinux Policy 是一个完整的 SELinux 策略,并作为 targeted 等其他策略的基础。此软件包包含 selinux-policy.conf 文件和 RPM 宏。
selinux-policy-targeted:提供 SELinux targeted策略。
libselinux:为 SELinux 应用程序提供 API。
libselinux-utils:提供 avcstat、getenforce、getsebool、matchpathcon、selinuxconlist、selinuxdefcon、selinuxenabled 和 setenforce 实用程序。
除了以上默认安装软件包,在 SELinux 使用过程中,您可能会用到默认安装范围以外的 SELinux 包,包括但不限于:
selinux-policy-devel:提供用于创建自定义 SELinux 策略和策略模块的实用程序。
selinux-policy-doc:提供了描述配置 SELinux 及其服务的手册页。
selinux-policy-mls:提供 MLS(多级安全)SELinux 策略。
setroubleshoot-server:将 SELinux 拒绝访问时产生的拒绝消息转换为可以使用该 sealert 实用程序查看的详细描述,该实用程序也在该包中提供。
setools-console:提供用于分析和查询策略、审计日志监控和报告以及文件上下文管理的实用程序和库。
对于上述软件包,您可以按照自己的需求,通过以下命令自行安装:
> sudo dnf install <package> #安装该<package>包
> rpm -q <package> #查看已安装的<package>包

安装 SELinux 策略

SELinux 提供 3 种策略,分别是 targeted(默认)、minimum 和 mls。不同的策略类型制定了不同的访问规则、甚至是 SELinux 上下文,直接影响了对应的主体(进程)是否可以访问的目标(文件或目录资源)。
targeted 策略:
targeted 策略主要对系统中的服务进程进行访问控制,同时,它还可以限制其他进程和用户。服务进程都被放入沙盒,在此环境中,服务进程会被严格限制,以便使通过此类进程所引发的恶意攻击不会影响到其他服务或 Linux 系统。
沙盒(sandbox)是一种环境,在此环境中的进程可以运行,但对其他进程或资源的访问会被严格控制。换句话说,位于沙盒中的各个进程,都只是运行在自己的域(进程所运行的区域被称为)内,它们无法访问其他进程或资源(除非被授予特殊的权限)。
通过使用此策略,可以更加安全地共享打印服务器、文件服务器、Web 服务器或其他服务,同时降低因访问这些服务而对系统中其他资源造成不利影响的风险。
minimum 策略:
minimum 策略最初是针对低内存计算机或者设备(例如智能手机)而创建的。从本质上来说,minimum 和 target 类似,不同之处在于,它仅使用基本的策略规则包。
对于低内存设备来说,minimum 策略允许 SELinux 在不消耗过多资源的情况下运行。
MLS 策略:
MLS(全称 Multi-Level Security),该策略会对系统中的所有进程进行控制。启用 MLS 之后,用户即便执行最简单的指令(如 ls),都会报错。
在使用过程中,我们可以通过 sestaus 指令查看 SELinux 策略类型,示例如下:
> sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted #当前策略类型
Current mode: enforcing #当前运行模式是enforcing模式

SELinux 配置与启用

SELinux 配置通过 /etc/selinux/config 文件进行修改 ,它控制 SELinux 工作模式和策略类型。SELinux 实现了3种工作模式,不同的 SELinux 模式具有不同特性:
enforcing 模式:启用 SELinux,并强制执行所有的安全策略规则。不符合策略规则的访问动作会被拒绝,并记录于日志。
permissive 模式:启用 SELinux,但并不强制执行安全策略规则。不符合策略规则的访问动作不会被拒绝,只是单纯的记录于日志。
disabled 模式:系统启动时不加载策略,因此不会访问策略规则,但并非完全关闭 SELinux。如果想要完全禁用 SELinux,需要通过内核命令行设置selinux=0
工作模式查看:
SELinux 的工作模式可以通过 getenforce 指令进行简明查看,如果想要获取更多信息,可以使用 sestaus 指令查看。
> getenforce
Enforcing
工作模式设置:
setenforce 指令可以便捷的实现 permissive、enforcing 模式间的切换,但不能实现 disabled 模式的切换。
# setenforce 0 #切换成宽容模式
# setenforce 1 #切换成强制模式
通过编辑 /etc/selinux/config 配置文件,可以实现disabled、permissive、enforcing三种模式自由切换。
注:
因为 SElinux 工作在 disabled 模式下不打标签、在 permissive 模式下可能出现不会正确打标的情况。而切换到 enforcing 模式下后,MAC 依赖正确的文件标签。
所以当切换回 enforcing 模式时,如果出现了文件标签异常的情况,可在 permissive 模式下执行以下指令进行 relabel 修复:
# fixfiles -F onboot
# reboot

SELinux 查看与管理

SELinux 安装后,默认会开启 enforcing 模式。enforcing 模式下众多的策略规则、用户映射、文件标签等,我们都可以进行查看和按需设置。部分常见查看、管理指令介绍如下:
seinfo: SELinux 默认工作在 targeted 模式下,包含众多策略规则,通过 seinfo 指令可以查询具体包含哪些规则。
# seinfo -b
Conditional Booleans:247
allow_domain_fd_use
allow_ftpd_full_access
getsebool/setsebool:查询到规则名称后,可以进一步通过 getsebool/setsebool 指令分别 查看、设置该规则的开启状态。
sesearch : 通过 seinfo 命令,可以相关策略规则的名称,但如果想要知道规则的具体内容,就需要使用 sesearch 命令了。
# sesearch --allow #查看所有允许的规则
allow NetworkManager_dispatcher_ddclient_t init_t:service status;
allow NetworkManager_dispatcher_ddclient_t init_t:system status;
allow NetworkManager_dispatcher_ddclient_t init_t:unix_stream_socket sendto;
semanage : semanage 是一个功能强大的指令,包括但不限于 SELinux 用户查询、用户管理、映射关系查询、规则查询、上下文查询等等。
# 查看登录账户 和 selinux用户 映射关系
> sudo semanage login -l
# 查看 SElinux用户 和 SElinux角色 映射关系
> sudo semanage user -l
# 查询规则
> sudo semanage boolean -l
# 安全上下文查询
> sudo semanage fcontext -l

完整性保护

配置 AIDE

AIDE(Advanced Intrusion Detection Environment)是一款轻量级的入侵检测工具,可在系统上创建文件数据库,存储的信息包括文件哈希输出、文件大小、所有权、修改时间、创建时间等关键文件属性。创建初始数据库后,AIDE 会重新扫描系统并将新扫描结果与先前存储的值进行比较,以确保文件完整性并及时发现针对系统的恶意入侵行为。AIDE 数据库能够使用 MD5、sha512 等算法,用密文形式建立每个文件的校验码或散列号。

初始化工作

1. 软件包安装。
默认不安装 aide 软件包,使用前需手动安装,流程如下:
#检查是否安装 rpm -q aide
#若 not installed,则 dnf 安装
> sudo dnf install aide
2. 初始化数据库。
建立初始数据库:
> sudo aide --init
输出示例如下;
Start timestamp: 2023-05-05 20:39:47 +0800 (AIDE 0.16)
AIDE initialized database at /var/lib/aide/aide.db.new.gz

Number of entries: 116821

---------------------------------------------------
The attributes of the (uncompressed) database(s):
---------------------------------------------------

/var/lib/aide/aide.db.new.gz
MD5 : dyb8CmPj//vR6+KZ0f5d0w==
SHA1 : pnNDT6WO2Eq524EGOwnnAa8K51M=
RMD160 : 2dS2vZkXpG8TWuZsc/beOVXYhn8=
TIGER : N+264sICZ/8iWu4+XJ6wFbL79DfY0PeG
SHA256 : e/zJGAZIRTSAowEXMnasStg7quOHoiQB
OsJeO0BtuF4=
SHA512 : zBE8vNVG2aRVK+p9yESYk9kotj8sGWnf
xUFvDBNw0h3QCw9OIx9CkfW+Vu3o7AjY
bt7JJL4EapSh1fYc88190A==

End timestamp: 2023-05-05 20:40:26 +0800 (run time: 0m 39s)
3. 使用数据库。
若想保存数据库将其作为对照基准,删除初始文件名中的 .new 字符:
> mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

进行完整性检查

建立初始数据库后,手动检测被保护文件变化:
> sudo aide --check
若无变化,则提示 AIDE found NO differences between database and filesystem. Looks okay!!。
若有变化,则提示 AIDE found differences between database and filesystem!!输出示例如下:
Start timestamp: 2023-05-06 10:35:53 +0800 (AIDE 0.16)
AIDE found differences between database and filesystem!!

Summary:
Total number of entries: 116821
Added entries: 0
Removed entries: 0
Changed entries: 4

---------------------------------------------------
Changed entries:
---------------------------------------------------

d = ... mc.. ... : /root
f ... i . . : /root/.viminfo
f = ... mc...... : /usr/lib/sysimage/rpm/rpmdb.sqlite-shm
f = ... .c...... : /usr/lib/sysimage/rpm/rpmdb.sqlite-wal

---------------------------------------------------
Detailed information about changes:
---------------------------------------------------

Directory: /root
Mtime : 2023-05-05 17:35:34 +0800 | 2023-05-06 10:22:45 +0800
Ctime : 2023-05-05 17:35:34 +0800 | 2023-05-06 10:22:45 +0800

...(omit partial output)...
通常 AIDE 需要定期执行检查,因此也可通过 cron 进行周期性检查。例如可在 /etc/crontab 文件添加以下配置,使得每天 6:30 执行 AIDE 检查:
30 6 * * * root /usr/sbin/aide --check

更新 AIDE 数据库

在您的系统发生主动变更后需要更新数据库,您可以通过如下操作刷新 AIDE 数据库信息:
aide --update
更新后数据库文件为 /var/lib/aide/aide.db.new.gz,同样需要删除初始文件名中的 .new 字符,方可将更新的数据库用于完整性检查。

配置 IMA 完整性度量

IMA 介绍

IMA 全称 Integrity Measurement Architecture(完整性度量架构),它是 Linux 内核完整性子系统的一部分,通过在 execve()mmap()open() 等系统调用中加入钩子,IMA 对被访问的文件进行完整性度量,度量结果可进一步用于远程证明,或者和文件扩展属性中的参考值比较以控制对文件的访问。
IMA 的功能主要分为以下三类:
度量(measure):度量文件并将度量结果记录在运行时度量列表中。
评估(appraise):度量文件并与一个存储在扩展属性中的参考值作比较,根据完整性校验结果进行访问控制。
审计(audit):将度量结果记入系统审计日志。
需要注意的是,IMA 并不能防止文件被篡改,无论是攻击者还是系统管理员,只要有足够的权限,就可能通过合法的方式修改文件内容。只是在修改后,下次访问该文件时,IMA 可通过校验文件内容的完整性,发现文件被篡改,如果开启了评估功能,还可进一步阻止文件被继续访问。
此外,建议在使用 IMA 之前开启 Secure Boot 保护机制,保护内核和内核启动参数不被篡改。

IMA 初始化

在安装完 TencentOS Server 后,IMA 已默认处于使能状态,只需要加载 IMA 策略,即可开始使用 IMA 完整性度量,加载策略的方式有两种:
1. 通过启动参数 ima_policy 指定预置策略。
2. 通过 /sys/kernel/security/ima/policy 接口导入手写策略。
如果使用第一种方式,请在内核启动参数中增加 ima_policy 策略参数,添加方式如下:
$ grubby --args="ima_policy=tcb" --update-kernel=/boot/vmlinuz-`uname -r`
除指定 IMA 策略外,内核启动参数还提供了更细粒度控制 IMA 行为的能力,常见的 IMA 启动参数包括:
启动参数
取值
含义
ima_hash
sha1/sha256/sm3/md5/...
设置 IMA 使用的度量算法,默认情况下为 SHA256
ima_template
ima/ima-ng/ima-sig
设置 IMA 使用的度量模板
ima_appraise
off
关闭 IMA 评估功能
-
fix
设置 IMA 评估 fix 模式,该模式可标记文件 security.ima 扩展属性,初始化环境时使用
-
log
设置 IMA 评估日志模式,该模式只校验文件完整性,但不做访问控制,只记录审计日志
-
enforce
设置 IMA 评估强制模式,该模式校验文件完整性,并根据校验结果进行访问控制
ima_policy
tcb
使用 IMA 预置度量策略,详见下一节
-
appraise_tcb
使用 IMA 预置评估策略,评估所有 root 属主的文件
-
secure_boot
使用 IMA 预置评估策略,评估内核、内核模块、固件、IMA 策略等的完整性
integrity_audit
0
提供基本审计信息(默认)
-
1
提供详细审计信息
添加启动参数后需要重启才生效,但运行时用户还可通过 SecurityFS 接口(位于 /sys/kernel/security/ima/ 路径下)与 IMA 进行交互:
SecurityFS 接口
权限
作用
ascii_runtime_measurement
440
提供 ASCII 字符形式的运行时度量列表
binary_runtime_measurement
440
提供二进制形式的运行时度量列表
runtime_measurement_count
440
提供系统 IMA 度量日志总数
violations
440
提供系统 IMA 度量冲突数
policy
600
自定义 IMA 策略读写接口
以上 5 个接口都具有读权限,可通过 cat 命令查看,其中第 5 个接口还有写权限,可用于更新自定义策略至内核中:
# 注意:此处/etc/ima/ima-policy可替换为任意其他绝对路径
$ echo /etc/ima/ima-policy > /sys/kernel/security/ima/policy

配置 IMA 度量策略

IMA 度量策略定义了 IMA 的具体行为,度量策略文件中包含了多条策略规则,每条策略规则又由一个或多个 token 组成,token 主要分为两类:
1. 行为 token:用于指定 IMA 的行为模式(度量/评估/审计),每条规则必须有且仅有一条行为 token。
2. 条件匹配 token:用于检查是否与待度量的请求相匹配,条件匹配 token 可以有多条,但是在一条规则内同类型的条件匹配 token 只能指定一次。
IMA 支持的常用的行为 token 如下:
行为 token
含义
measure
表示对文件客体进行度量,在度量过程中,会对文件内容计算摘要值,并将摘要值以及相关信息写到度量日志项中,最后将度量日志项加入 IMA 运行时度量列表。如果系统安装了 TPM 芯片,度量值还会扩展到 TPM 的 PCR 10 中。IMA 不会重复度量已被度量过的客体,这意味着运行时度量列表中不会出现重复的文件项(除非该文件内容被修改),而且已被度量过的客体的摘要值也不会被扩展到 TPM 的 PCR 中。
dont_measure
表示不对文件客体进行度量。
appraise
表示对文件客体进行评估,即使用文件扩展属性 security.ima 来验证文件内容的完整性,如果完整性遭到破坏,且当前的 IMA appraise 模式是 enforce,则返回错误表示评估失败。
dont_appraise
表示不对文件客体进行评估。
audit
表示对文件客体进行审计,在审计日志中会记录被度量文件的绝对路径以及摘要算法和摘要值。
IMA 支持的常用的条件匹配 token 如下:
条件匹配 token
取值
含义
func
FILE_CHECK
表示在打开常规文件前(包括打开一个已有的常规文件或创建一个全新的常规文件)使用该规则对目标文件的内容进行度量,如果指定了行为 token 但是没有指定任何条件匹配 token,则 func 的默认取值是 FILE_CHECK。
-
BPRM_CHECK
表示在运行一个可执行文件、共享库或通过 shebang 解释器调用的脚本前,对目标文件内容进行度量。
-
MMAP_CHECK
表示在以可执行权限对一个常规文件进行内存映射前(包括映射一个已有的常规文件或映射一个全新的常规文件),使用该规则对目标文件的内容进行度量。
-
MODULE_CHECK
表示在加载内核模块文件前对目标模块文件的内容进行度量。
-
FIRMWARE_CHECK
表示在加载固件前对目标固件文件的内容进行度量。
mask
MAY_EXEC
访问点应当正在加载可执行文件/内核模块/固件,或以只 EXEC 的模式对一个常规文件进行内存映射。
-
MAY_WRITE
访问点应当以只写的访问模式打开常规文件。
-
MAY_READ
访问点应当以只读的访问模式打开常规文件。
-
MAY_APPEND
访问点应当以只 append 的访问模式打开常规文件。
-
^MAY_EXEC
访问点应当正在执行可执行文件,或以 READ|WRITE|EXEC 的模式对一个常规文件进行内存映射。
-
^MAY_WRITE
访问点应当以写入的访问模式打开常规文件。
-
^MAY_READ
访问点应当以读取的访问模式打开常规文件。
-
^MAY_APPEND
访问点应当以 append 的访问模式打开常规文件。
fsmagic
16 进制串
文件系统 fsmagic 值。
fsuuid
16 进制串
块设备文件系统 uuid。
uid
10 进制数字
进程 UID。
euid
10 进制数字
进程 EUID。
fowner
10 进制数字
文件 UID。
obj_user
LSM 主体用户
LSM 主体用户。
obj_role
LSM 主体角色
LSM 主体角色。
obj_type
LSM 主体类型
LSM 主体类型。
subj_user
LSM 客体用户
LSM 客体用户。
subj_role
LSM 客体角色
LSM 客体角色。
subj_type
LSM 客体类型
LSM 客体类型。
下面以内核启动参数 ima_policy=tcb 对应的默认度量策略为例,解释在该策略下 IMA 如何度量系统文件:
dont_measure fsmagic=0x9fa0
dont_measure fsmagic=0x62656572
dont_measure fsmagic=0x64626720
dont_measure fsmagic=0x1021994
dont_measure fsmagic=0x1cd1
dont_measure fsmagic=0x42494e4d
dont_measure fsmagic=0x73636673
dont_measure fsmagic=0xf97cff8c
dont_measure fsmagic=0x27e0eb
dont_measure fsmagic=0x6e736673
measure func=MMAP_CHECK mask=MAY_EXEC
measure func=BPRM_CHECK mask=MAY_EXEC
measure func=FILE_CHECK euid=0
measure func=FILE_CHECK uid=0
measure func=MODULE_CHECK
measure func=FIRMWARE_CHECK
measure func=POLICY_CHECK
dont_measure fsmagic=xxx 表示不对特定文件系统类型(通过文件系统超级快标识符区分)中的文件进行度量,这些文件系统分别是:
magic 值
文件系统名称
0x9fa0
procfs 伪文件系统
0x62656572
sysfs 伪文件系统
0x64626720
debugfs 伪文件系统
0x1021994
tmpfs 伪文件系统
0x1cd1
devpts 伪文件系统
0x42494e4d
binfmt_misc 伪文件系统
0x73636673
securityfs 伪文件系统
0x27e0eb
cgroup 伪文件系统
0x6e736673
namespace 伪文件系统
这些不需要进行度量的文件系统都是基于内存而非磁盘的伪文件系统,因此对它们的内容进行度量是没有意义的。
measure func=MMAP_CHECK mask=MAY_EXEC 表示对带有 PROT_EXEC flag的 mmap() 文件映射的内容进行度量,通常共享库就是采用这种方式加载到进程的地址空间中的。因此这条规则可以近似理解为是对共享库内容的度量。
measure func=BPRM_CHECK mask=MAY_EXEC 表示对通过 execve() 系统调用执行的可执行文件(包括脚本)进行度量。
measure func=FILE_CHECK euid=0 表示对以 EUID 为 0 的身份(root 用户和 sudo 为 root 的用户)打开的文件的内容进行度量。
measure func=FILE_CHECK uid=0 表示对以 UID 为 0 的身份(root 用户)打开的文件的内容进行度量。
measure func=MODULE_CHECK 表示对加载的内核模块进行度量。
measure func=FIRMWARE_CHECK 表示对加载的固件文件进行度量。
measure func=POLICY_CHECK 表示对额外写入到 /sys/kernel/security/ima/policy 的 IMA 策略的内容进行度量。

安全审计

audit 介绍

Linux 审计(Linux Audit) 提供了一种跟踪系统与安全相关信息的方式,通过预配置的规则,Audit 会生成日志条目,记录系统所发生事件的相关信息。Audit 本身不提供额外的安全性 —— 它不能防范系统漏洞或系统被恶意利用。Audit 只用于跟踪相关安全事件,并帮助用户采取额外的安全措施(例如 SELinux)来防止这些问题。 Audit 包括多个组件,每个组件都为总体框架提供关键功能。Audit 内核模块会截获系统调用并记录相关事件。auditd守护程序会将审计报告写入磁盘。各种命令行实用程序会处理审计追踪的显示、查询和存档。 Audit 主要由以下程序组成:
auditd:Audit 守护进程负责将通过 audit 内核接口生成的审计信息写入文件audit.log,并保存至磁盘。auditd启动由systemd控制。auditd 功能由/etc/audit/auditd.conf控制。
auditctl:auditctl控制内核审计接口的日志生成参数和内核设置,以及跟踪事件的审计规则集。
audit.rules:/etc/audit/audit.rules包含一系列auditctl命令,由auditd加载这些命令集。
aureport:aureport可以基于审计事件日志创建自定义报告。
ausearch:ausearch用于在审计日志文件audit.log中搜索特定事件。
audispd:audispd将审计事件通知中继到其他程序,而不是写入磁盘的审计日志中。
autrace:autrace以类似strace的方式跟踪单个进程,并将输出记录到审计日志。

audit 基础配置

配置 auditd 规则

在进行 Linux 系统审计之前,需要对 Audit 进行配置。Audit 的配置文件位于/etc/audit/auditd.conf。使用任意文本编辑器打开即可。
log_file:定义审计日志文件的位置和名称。通常默认位置为/var/log/audit/audit.log
log_format:定义审计日志的格式。支持 raw/user/json/enriched/verbose 五个参数。
max_log_file_action:定义审计日志文件达到最大小时的操作。一般设置为 keep_logs,以防止审计日志文件被覆盖。
space_left:定义审计日志文件系统中必须保留的可用空间。
space_left_action:定义审计日志文件系统中可用空间不足时的操作。建议将参数设置为 email 或配置了适当通知方法的 exec。
admin_space_left:定义管理员空间中必须保留的可用空间。
admin_space_left_action:定义管理员空间中可用空间不足时的操作。一般应该设置为 single 来使系统进入单用户模式。

audit 守护进程

首先内核需要打开CONFIG_AUDITCONFIG_AUDITSYSCALL配置,TencentOS Server内核默认开启了 Audit 相关配置。 确认内核支持审计功能后,启动 Auditd 服务,以收集相关审计信息,并保存在日志文件中。以 root 用户身份运行以下命令来启动 auditd(TencentOS Server 4 默认打开 auditd.service):
# service start auditd
并将 auditd 配置为开机启动(TencentOS Server 4 默认开机启动 auditd.service):
# systemctl enable auditd
如果需要临时禁用 auditd,可以运行auditctl -e 0,重新运行则可以使用auditctl -e 1。 可以通过service auditd <command>控制auditd执行其他操作,command 可以是以下指令:
命令
作用
stop
停止 auditd
restart
重新启动 auditd
reload/force-reload
重新加载 /etc/audit/auditd.conf 文件中的 auditd 配置
rotate
备份旧 log 文件,日志写入新的空白 log 文件
resmue
在 auditd 被暂停后,重新恢复
condrestart/try-restart
只有 auditd 运行时才重新启动它
status
显示 auditd 的运行状态
注意:
service命令是唯一与 auditd 进程正确交互方式,systemctl命令只能用于两个操作:enable 和 status,其他指令均只能使用service

audit 日志介绍

使用 Audit 必须了解审计守护程序所生成的日志的构造方式,以及审计针对事件具体会记录哪些内容。只有在获知这些信息后,才能确定哪些报告类型最适合需求。 Audit 默认将日志条目记录在/var/log/audit/audit.log文件中。我们通过一个例子来描述 Audit 日志的各项记录参数。添加以下审计规则,来记录对/boot/grub2/grub.cfg文件的读写操作。
# auditctl -D
# auditctl -w /boot/grub2/grub.cfg -p warx -k grub.cfg
audit.log 对这个事件的记录如下:
type=SYSCALL msg=audit(1677250085.590:313): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=7fff8b0d2d09 a2=0 a3=0 items=1 ppid=1098 pid=1649 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=ttyS0 ses=1 comm="cat" exe="/usr/bin/cat" subj=root:sysadm_r:sysadm_t:s0-s15:c0.c1023 key="grub.cfg"ARCH=x86_64 SYSCALL=openat AUID="root" UID="root" GID="root" EUID="root" SUID="root" FSUID="root" EGID="root" SGID="root" FSGID="root"
type=CWD msg=audit(1677250085.590:313): cwd="/var/log/audit"
type=PATH msg=audit(1677250085.590:313): item=0 name="/boot/grub2/grub.cfg" inode=524302 dev=fc:01 mode=0100600 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:boot_t:s0 nametype=NORMAL cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0OUID="root" OGID="root"
type=PROCTITLE msg=audit(1677250085.590:313): proctitle=636174002F626F6F742F67727562322F677275622E636667
以上事件由四个记录组成,它们共享相同的时间戳和序列号。记录始终以type=关键字开头。每个记录由多个name=value对组成,它们之间由空格或逗号分开。对上述事件的详细分析如下:
第一条记录:
type=SYSCALL:type 字段包含记录的类型。在本例中,SYSCALL 值指定此记录是由对内核的系统调用触发的。
msg=audit(1677250085.590:313):msg 字段记录:记录的时间戳和唯一 ID,格式为audit(time_stamp:ID)。如果多个记录是作为同一审计事件的一部分而产生的,则它们共享相同的时间戳和 ID。时间戳使用 Unix 时间格式 - 自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数。
arch=c000003e:arch 字段包含系统的 CPU 架构信息。该值c000003e以十六进制表示法编码。当使用ausearch命令搜索审计记录时,请使用-i--interpret选项来自动将十六进制值转换成人类可读的等效值。c000003e值被解释为x86_64
syscall=257:syscall 字段记录了发送到内核的系统调用的类型。值 257 可以与/usr/include/asm/unistd_64.h文件中人类可读的等效值匹配。在本例中,257 是openat系统调用。ausyscall工具可以将系统调用号转换为人类可读的等效值。使用ausyscall --dump命令显示所有系统调用及其编号的列表。
success=yes:success 字段记录了该特定事件中记录的系统调用是成功还是失败。在这种情况下,调用成功。
exit=3:exit 字段包含一个值,指定系统调用返回的退出码。此值因不同的系统调用而不同。
a0=ffffff9c, a1=7fff8b0d2d09, a2=0, a3=0:a0 至 a3 字段记录了该事件中系统调用的前四个参数,用十六进制符号编码。这些参数取决于使用的系统调用,可以通过ausearch工具来解释它们。
items=1:items 字段包含系统调用记录后面的 PATH 辅助记录的数量。
ppid=1098:ppid 字段记录了父进程 ID(PPID)。在这种情况下,1098 是父进程(如bash)的 PPID 。
pid=1649:pid 字段记录了进程 ID(PID)。在本例中,1649 是cat进程的 PID。
auid=0:auid 字段记录了审计用户 ID,即 loginuid。此 ID 在登录时分配给用户,并被每个进程继承,即使用户的身份改变了,例如使用su - user命令切换用户账户。
uid=0:uid 字段记录了启动分析过程的用户的用户 ID。使用以下命令可以将用户 ID 解释成用户名:ausearch -i --uid UID
gid=0:gid 字段记录了启动分析过程的用户的组 ID。
euid=0:euid 字段记录了启动分析过程的用户的有效用户 ID。
suid=0:suid 字段记录了启动分析过程的用户的设置用户 ID。
fsuid=0:fsuid 字段记录了启动分析进程的用户的文件系统用户 ID。
egid=0:egid 字段记录了启动分析过程的用户的有效组 ID。
sgid=0:sgid 字段记录了启动分析过程的用户的组 ID。
fsgid=0:fsgid 字段记录了启动分析进程的用户的文件系统组 ID。
tty=ttyS0:tty 字段记录了分析过程被调用的终端。
ses=1:ses 字段记录了分析过程被调用的会话的会话 ID。
comm="cat":comm 字段记录了用于调用分析过程的命令行名称。在本例中,cat 命令用于触发此审计事件。
exe="/bin/cat":exe 字段记录了用于调用分析过程的可执行文件的路径。
subj=root:sysadm_r:sysadm_t:s0-s15:c0.c1023:subj 字段记录了被分析的进程在执行时被标记的 SELinux 上下文。
key="grub.cfg":key 记录了与在审计日志中生成该事件的规则相关联的管理员定义的字符串。后续跟着一连串重复的 key,则将前述 key=value 进行了人类可读的翻译性解释。
第二条记录:
type=CWD:在第二条记录中,type 字段值为 CWD - 当前工作目录。此类型用于记录从中调用第一条记录中指定的系统调用的进程的工作目录。此记录的目的是记录当前进程的位置,以防在相关 PATH 记录中捕获到相对路径。这样,就可以重建绝对路径。
msg=audit(1677250085.590:313):msg 字段持有与第一条记录中的值相同的时间戳和 ID 值。时间戳使用 Unix 时间格式。
cwd="/var/log/audit":cwd 字段包含系统调用所在目录的路径。
第三条记录:
type=PATH:在第三条记录中,type 字段值为 PATH。审计事件包含作为参数传递给系统调用的每个路径的 PATH 类型记录。在这个审计事件中,只有一个路径(/boot/grub2/grub.cfg) 被用作参数。
msg=audit(1677250085.590:313):msg 字段拥有与第一和第二条记录中的值相同的时间戳和 ID 值。
item=0:item 字段表示在 SYSCALL 类型记录所引用的项目总数中,当前记录是哪个项目。这个数是以零为基础的,值为 0 表示它是第一项。
name="/etc/ssh/sshd_config":name 字段记录了作为参数传递给系统调用的文件或目录的路径。在本例中,它是/boot/grub2/grub.cfg文件。
inode=524302:inode 字段包含与该事件中记录的文件或目录相关联的 inode 号。
dev=fc:01:dev 字段指定了包含该事件中记录的文件或目录的设备的次要和主要 ID。在本例中,值表示/dev/fc/1设备。
mode=0100600:mode 字段记录文件或目录权限,由数字标记。它是 st_mode 字段中的 stat 命令返回。如需更多信息,请参阅 stat(2) 手册页。在这种情况下,0100600 可以解释为 -rw-------,这意味着只有 root 用户对/boot/grub2/grub.cfg文件具有读和写的权限。
ouid=0:ouid 字段记录了对象所有者的用户 ID。
ogid=0:ogid 字段记录了对象所有者的组 ID。
rdev=00:00:rdev 字段包含一个记录的设备标识符,仅用于特殊文件。在这种情况下,不会使用它,因为记录的文件是一个常规文件。
obj=system_u:object_r:etc_t:s0:obj 字段记录了 SELinux 上下文,在执行时,记录的文件或目录被贴上了标签。
nametype=NORMAL:nametype 字段记录了每个路径记录在给定系统调用的上下文中的操作意图。
cap_fp=none:cap_fp 字段记录了与设置文件或目录对象的基于文件系统的允许能力有关的数据。
cap_fi=none:cap_fi 字段记录了与文件或目录对象的基于继承文件系统的能力设置有关的数据。
cap_fe=0:cap_fe 字段记录了文件或目录对象基于文件系统能力的有效位的设置。
cap_fver=0:cap_fver 字段记录了文件或目录对象基于文件系统能力的版本。与第一条记录类似,后续跟着两个重复的 key,则将前述 key=value 进行了人类可读的翻译性解释。
第四条记录:
type=PROCTITLE:type 字段包含记录的类型。在本例中,PROCTITLE 值指定此记录提供触发此审计事件的完整命令行,该事件是由对内核的系统调用触发的。
proctitle=636174002F626F6F742F67727562322F677275622E636667:proctitle 字段记录了用于调用分析过程的命令的完整命令行。该字段采用十六进制表示法编码,不允许用户影响审计日志解析器。对触发此审计事件的命令进行文本解码。当使用ausearch命令搜索审计记录时,请使用-i--interpret选项来自动将十六进制值转换成人类可读的等效值。636174002F626F6F742F67727562322F677275622E636667 值解释为cat /boot/grub2/grub.cfg

定义审计规则

审计系统根据一组规则进行操作,这些规则定义日志文件中所捕获的内容。使用auditctl工具,可以在命令行或/etc/audit/rules.d/目录中设置审计规则。 通过auditctl命令控制审计系统的基本功能,并定义决定记录哪些审计事件的规则。 这里给出一些示例可供参考: 定义一条规则,记录对/etc/passwd文件的所有写访问和属性修改:
# auditctl -w /etc/passwd -p wa -k passwd_changes
定义一条规则,记录对/etc/selinux/目录中所有文件的写访问和属性修改:
# auditctl -w /etc/selinux/ -p wa -k selinux_changes
定义一条规则,当程序每次使用adjtimexsettimeofday系统调用时就创建一条日志,系统使用 64 位构架:
# auditctl -a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time_change
定义一条规则,在 ID 为 1000 或以上的系统用户每次删除或重命名文件时创建一条日志:
# auditctl -a always,exit -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete
-F auid!=4294967295用于排除未设置登录 UID 的用户。
定义一条规则,记录所有/bin/id程序的执行,执行以下命令:
# auditctl -a always,exit -F exe=/bin/id -F arch=b64 -S execve -k execution_bin_id
要定义在重启过程中保持不变的审计规则,必须直接将其包含在/etc/audit/rules.d/audit.rules文件中,或者使用augenrules程序读取位于/etc/audit/rules.d/目录中的规则。请注意,每次auditd服务启动时都会生成/etc/audit/audit.rules文件。/etc/audit/rules.d/中的文件使用相同的auditctl命令行语法来指定规则即可。以上示例在audit.rules文件中可记录为:
-w /etc/passwd -p wa -k passwd_changes
-w /etc/selinux/ -p wa -k selinux_changes
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time_change
-a always,exit -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete
-a always,exit -F exe=/bin/id -F arch=b64 -S execve -k execution_bin_id