2290 字
11 分钟
Linux 服务器安全防护手册(二):系统层加固 —— 用户、内核、更新与文件系统

上一篇回顾#

第一道防线 封住了来自外部的攻击入口——SSH 加固、UFW 防火墙、Fail2ban 防爆破。但如果攻击者已经获得了服务器上的一个普通账户呢?

这就是系统层加固要解决的问题:假设边界已被突破,在系统内部限制攻击者能做什么、能看到什么。

本章涵盖 CIS Level 1 和 Level 2 的系统层核心配置。


用户与权限管理#

1. 创建非 root 管理员用户#

在服务器初始化时(云厂商提供的初始镜像通常已是 root),首先创建自己的管理员账户并锁定 root:

Terminal window
# 创建用户
sudo adduser deploy
# 加入 sudo 组
sudo usermod -aG sudo deploy
# 确认 deploy 用户可以 sudo
# 在另一个终端测试:ssh deploy@server,然后 sudo whoami → 应返回 root
# 锁定 root 账户的密码(禁止密码登录)——和 sshd_config 中的 PermitRootLogin 配合使用
sudo passwd -l root

2. sudoers 精细控制#

/etc/sudoers 不建议直接编辑,应在 /etc/sudoers.d/ 下创建配置文件:

Terminal window
sudo visudo -f /etc/sudoers.d/10-deploy
# 默认 sudo 行为
Defaults env_reset
# 记录所有 sudo 命令到日志
Defaults logfile="/var/log/sudo.log"
# sudo 时要求输入密码(提高安全性)
Defaults timestamp_timeout=5
# deploy 用户可执行所有命令
deploy ALL=(ALL:ALL) ALL
# 运维组成员可执行所有命令
%sudo ALL=(ALL:ALL) ALL
# 可选:限制某用户只能重启特定服务
# webadmin ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx

timestamp_timeout=5 表示输完密码后 5 分钟内再次 sudo 无需再输。设为 0 则每次都要输。

3. PAM 密码强度策略#

Terminal window
# 安装密码质量模块
sudo apt install libpam-pwquality -y

编辑 /etc/security/pwquality.conf

# 最小密码长度
minlen = 12
# 必须包含的字符类型数量(至少 3 类:大写+小写+数字+特殊字符)
minclass = 3
# 最多连续相同字符数
maxrepeat = 3
# 密码中允许的最长单调序列(如 abcd、1234 等)
maxsequence = 4
# 启用字典检查
dictcheck = 1
# 禁止用户名出现在密码中
usercheck = 1
# 新密码与旧密码的差异字符数
difok = 5
# 如果 root 给其他用户设密码,强制执行复杂度检查
enforce_for_root

应用 PAM 配置——编辑 /etc/pam.d/common-password,找到包含 pam_pwquality.so 的那行,确认它包含 retry=3

password requisite pam_pwquality.so retry=3

4. 账户过期与锁定策略#

编辑 /etc/login.defs

# 密码最大有效期(天)
PASS_MAX_DAYS 90
# 密码最小使用期(天)——防止用户立刻改回旧密码
PASS_MIN_DAYS 7
# 密码过期前几天开始警告
PASS_WARN_AGE 14

账户锁定策略——编辑 /etc/pam.d/common-auth,在 pam_unix.so 行之前添加:

# 连续 5 次登录失败后锁定账户 30 分钟(root 除外)
auth required pam_tally2.so deny=5 unlock_time=1800 onerr=fail audit even_deny_root

pam_tally2 在较新的发行版中可能被 pam_faillock 替代。Debian 12+ / Ubuntu 24.04 请改用:

auth required pam_faillock.so preauth silent audit deny=5 unlock_time=1800
auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=1800

sysctl 内核参数加固#

内核参数决定系统如何处理网络包、内存和进程隔离。以下配置来自 CIS Level 2 和 NSA 指南。

编辑 /etc/sysctl.d/99-security.conf

# ========== 地址空间布局随机化 (ASLR) ==========
# 0=禁用 1=部分随机化 2=完全随机化(推荐)
kernel.randomize_va_space = 2
# ========== 限制内核信息泄漏 ==========
# 禁止非特权用户查看内核指针
kernel.kptr_restrict = 2
# 禁止非特权用户查看 dmesg
kernel.dmesg_restrict = 1
# 禁止非特权用户加载 eBPF 程序
kernel.unprivileged_bpf_disabled = 1
# 禁止非特权用户创建用户命名空间(减少内核攻击面)
kernel.unprivileged_userns_clone = 0
# 限制 perf_event 访问(防止侧信道攻击)
kernel.perf_event_paranoid = 3
# ========== 网络层加固 ==========
# IP 伪造包过滤(反向路径过滤)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# 不响应 ICMP 广播
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 忽略 ICMP 重定向(防止中间人攻击)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
# 不发送 ICMP 重定向(非路由器无需发送)
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# 忽略源路由包(攻击者可能用它绕过防火墙)
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
# SYN flood 防护——启用 SYN Cookie
net.ipv4.tcp_syncookies = 1
# 记录 Martian 包(来源地址不合法的包,可能来自 IP 伪造攻击)
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# 不转发 IP 包(非路由器应关闭)
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0
# ========== 进程与内存安全 ==========
# 限制 ptrace 范围(防止非 root 用户调试其他用户的进程)
kernel.yama.ptrace_scope = 1
# 禁止 core dump 中的 ELF 首部(防止信息泄漏)
fs.suid_dumpable = 0

应用配置:

Terminal window
sudo sysctl -p /etc/sysctl.d/99-security.conf
# 验证
sudo sysctl -a | grep -E "randomize_va_space|kptr_restrict|tcp_syncookies"

自动安全更新#

CIS Level 1 要求自动化安全补丁。攻击者扫描新 CVE 并在数小时内发起攻击已成为常态。手工更新根本来不及。

1. unattended-upgrades#

Terminal window
sudo apt install unattended-upgrades -y
# 启用自动安全更新
sudo dpkg-reconfigure -plow unattended-upgrades
# 在弹窗中选择 "Yes"

编辑 /etc/apt/apt.conf.d/50unattended-upgrades

Unattended-Upgrade::Allowed-Origins {
# 仅自动安装安全更新(不会装普通功能更新,降低风险)
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
};
# 自动删除不再需要的依赖
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
# 自动重启(仅在需要时,且会检查是否有用户登录)
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
# 禁止在有人登录时自动重启
Unattended-Upgrade::Automatic-Reboot-WithUsers "false";

运行一次验证配置:

Terminal window
sudo unattended-upgrades --dry-run --debug

2. 内核热补丁(Livepatch)#

安全更新中最烦人的是内核更新——需要重启服务器。Livepatch 技术可以在不重启的情况下应用内核安全补丁。

方案一:Canonical Livepatch(Ubuntu 官方)

Terminal window
# 需要 Ubuntu One 账号,个人用户免费 3 台机器
sudo snap install canonical-livepatch
sudo canonical-livepatch enable <your-token>

注意:Canonical Livepatch 客户端是开源的,但补丁本身由 Canonical 私有维护。

方案二:kpatch(Red Hat 系,开源)

Terminal window
# RHEL/AlmaLinux/Rocky Linux
sudo dnf install kpatch kpatch-dnf
sudo dnf kpatch auto

方案三:TuxTape(开源,开发中)

GEICO 在 2025 年 FOSDEM 发布的 TuxTape 是一个完全开源(Apache 2.0)的内核热补丁生态系统,包含 CVE 追踪、补丁生成和分发。目前仍处于原型阶段,但值得持续关注。

对于不想依赖任何商业服务的用户,最简单的做法是:启用无人值守安全更新 + 每月定时重启一次服务器(在凌晨低峰时段)。


文件系统加固#

1. /tmp 分区隔离#

/tmp 是攻击者最常利用的目录——任何人都可以写入,很多自动化工具也会在此下载和执行脚本。

/etc/fstab 中为 /tmp 添加限制:

tmpfs /tmp tmpfs defaults,noexec,nosuid,nodev,size=2G 0 0
选项作用
noexec禁止在 /tmp 下执行任何程序
nosuid忽略 suid 位(防止提权攻击)
nodev禁止解释设备文件
tmpfs使用内存文件系统(重启自动清空,速度快)

应用:

Terminal window
# 如果 /tmp 已在 tmpfs 上,需要重新挂载
sudo mount -o remount,noexec,nosuid,nodev /tmp
# 验证
mount | grep /tmp
# 应该看到 noexec,nosuid,nodev 选项

2. /var 和 /home 分区隔离#

Terminal window
# /var 不包含设备文件,不设 suid 权限
# /home 同理。在 /etc/fstab 中:
# /dev/sda3 /var ext4 defaults,nodev,nosuid 0 2
# /dev/sda4 /home ext4 defaults,nodev,nosuid 0 2

3. 保护关键系统文件#

Terminal window
# 给关键文件加上不可变标记(连 root 也不能直接修改,必须先去掉标记)
sudo chattr +i /etc/ssh/sshd_config
sudo chattr +i /etc/sudoers
sudo chattr +i /etc/passwd
# 需要修改时先去掉标记
# sudo chattr -i /etc/ssh/sshd_config
# 修改完成后记得加回去
# 查看哪些文件被加了特殊属性
lsattr /etc/ssh/sshd_config /etc/sudoers

chattr +i 是最后一道防线。即使攻击者拿到了 root,也无法直接替换被保护的配置文件。但这不能替代前面的所有防线——真的 root 攻击者可以 chattr -i 之后修改。

4. SSH 密钥和敏感文件权限#

Terminal window
# SSH 主机密钥——仅 root 可读
sudo chmod 600 /etc/ssh/ssh_host_*_key
# authorized_keys——仅文件所有者可写
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
# crontab 目录
sudo chmod 700 /var/spool/cron/crontabs

验证清单#

☐ deploy 用户可以 sudo,直接 root 登录被拒绝
☐ 密码策略生效:尝试创建弱密码(如 "abc"),系统应拒绝
☐ sudo 命令被记录到 /var/log/sudo.log
☐ sysctl -a 确认 kernel.randomize_va_space=2、kernel.kptr_restrict=2
☐ unattended-upgrades --dry-run 无报错
☐ mount | grep /tmp 显示 noexec,nosuid,nodev
☐ lsattr /etc/ssh/sshd_config 显示 immutable (i) 标记

速查表#

Terminal window
# ===== 用户与 sudo =====
sudo adduser <username> # 创建用户
sudo usermod -aG sudo <username> # 加入 sudo 组
sudo passwd -l root # 锁定 root
sudo visudo -f /etc/sudoers.d/10-deploy # 编辑 sudoers
sudo cat /var/log/sudo.log # 查看 sudo 日志
# ===== 密码策略 =====
chage -l <username> # 查看密码过期信息
chage -M 90 <username> # 设置密码最大有效期
# ===== sysctl =====
sudo sysctl -p /etc/sysctl.d/99-security.conf # 应用内核参数
sudo sysctl -a | grep <keyword> # 查看特定参数
# ===== 自动更新 =====
sudo unattended-upgrades --dry-run --debug # 模拟运行
sudo systemctl status unattended-upgrades # 检查服务状态
grep "unattended-upgrades" /var/log/dpkg.log # 查看安装历史
# ===== 文件系统 =====
mount | grep /tmp # 查看挂载选项
sudo chattr +i <file> # 添加不可变标记
lsattr <file> # 查看文件属性
sudo chattr -i <file> # 移除不可变标记

延伸阅读#

下一篇:Linux 服务器安全防护手册(三):强制访问控制与审计——AppArmor 进程隔离与 Auditd 内核级审计追溯。

Linux 服务器安全防护手册(二):系统层加固 —— 用户、内核、更新与文件系统
https://blog.syomega.top/posts/linux-security-2/
作者
酱w
发布于
2026-05-17
许可协议
CC BY-NC-SA 4.0