Linux 账号安全加固是服务器防入侵的第一道关卡,其中 sudo 最小权限配置直接决定提权攻击的难度。本文面向多用户共管的云服务器与 VPS 运维场景,系统讲解密码策略、登录失败锁定、sudoers 最小权限授权与审计四层加固,所有命令在 RHEL 系(CentOS/Rocky/Alma)与 Debian 系(Ubuntu/Debian)均可直接执行。
适用场景
- 服务器存在多个运维账号,部分账号权限过大(如直接加入 wheel 组)
- /var/log/secure 或 journalctl 中出现大量 SSH 爆破失败记录
- 审计要求明确:谁在什么时间执行了什么特权命令需要可追溯
- 需要满足等保 2.0 三级对身份鉴别与访问控制的要求
前置条件
- 具备 root 权限或可切换到 root 的账号
- 系统:RHEL 8/9、CentOS Stream、Rocky、Alma、Ubuntu 20.04+、Debian 11+
- 执行前建议开启一个保留会话(如 screen/tmux),防止配置错误后失联
原理说明
账号安全加固围绕三个机制展开:pam_pwquality 负责密码强度校验(长度、复杂度、复用),pam_faillock 在登录失败达到阈值后锁定账号防止爆破,sudoers 通过授权规则把特权操作限制到最小命令集。三层各自独立又相互配合:即使密码被猜中,账号锁定机制拖延了爆破速度;即使拿到普通账号,sudoers 的最小授权也让提权路径大幅收窄;审计日志则保证任何特权操作都可追溯。
操作步骤
步骤一:密码策略加固
# 密码复杂度(RHEL8+/Debian 系)
cat > /etc/security/pwquality.conf.d/99-hardening.conf <<'EOF'
minlen = 14
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
minclass = 3
EOF
# 密码有效期(/etc/login.defs 中修改)
sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs
sed -i 's/^PASS_MIN_LEN.*/PASS_MIN_LEN 14/' /etc/login.defs
sed -i 's/^PASS_WARN_AGE.*/PASS_WARN_AGE 7/' /etc/login.defs
# 检查空口令账号与 UID 0 账号
awk -F: '($2 == "") {print "EMPTY PASSWORD: " $1}' /etc/shadow
awk -F: '($3 == 0 && $1 != "root") {print "UID 0: " $1}' /etc/passwd
步骤二:登录失败锁定(pam_faillock,RHEL 8+)
# 写入 faillock 配置:5 次失败锁 15 分钟,解锁时间 15 分钟
cat > /etc/security/faillock.conf <<'EOF'
deny = 5
unlock_time = 900
even_deny_root
silent
EOF
# 将 faillock 接入 system-auth / password-auth(RHEL8+ 由 pam 模块自动读取 faillock.conf)
# 验证配置加载
pam-auth-update --enable 2>/dev/null || true # Debian/Ubuntu 需装 libpam-faillock
步骤三:sudoers 最小权限授权
# 用 visudo 创建独立授权文件(语法检查自动执行)
visudo -f /etc/sudoers.d/ops
# 内容示例:运维组仅允许 systemctl/日志/进程管理命令
# %ops ALL=(root) /usr/bin/systemctl, /usr/bin/journalctl, /usr/bin/ps, /usr/bin/top, /usr/bin/kill
# 开启输入输出日志与命令审计
cat > /etc/sudoers.d/audit <<'EOF'
Defaults log_input, log_output
Defaults !requiretty
Defaults timestamp_timeout=5
Defaults syslog=authpriv
EOF
# 校验语法
visudo -c
步骤四:SSH 侧加固衔接
# 禁止 root 直接 SSH 登录,改为 sudo 提权(/etc/ssh/sshd_config)
sed -i 's/^#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart sshd
步骤五:审计与监控
# 查看 sudo 使用记录(RHEL 系 /var/log/secure,Debian 系 /var/log/auth.log)
grep sudo /var/log/secure | tail -20
# 查看近期失败登录来源
grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head
配置验证
# 1. 验证 sudoers 授权生效(应只显示被授权的命令)
sudo -l
# 2. 验证被拒命令(未被授权的命令应报 "not allowed to run")
sudo cat /etc/shadow
# 3. 验证登录锁定:连续 5 次输错密码后应提示 Account locked
# 4. 验证审计:执行一次 sudo systemctl status nginx 后查看 sudo 日志
grep systemctl /var/log/secure | tail -3
常见问题
Q1:sudoers 写错导致所有账号都无法 sudo,如何修复?
不要重启。在保留的 root 会话中直接修正:若 root 也无法使用 sudo 命令本身,用 pkexec visudo -f /etc/sudoers.d/xxx 或通过救援模式挂载后修复;日常最佳实践是用 visudo 编辑(保存前强制语法校验),并先在一个测试账号上验证再批量应用。
Q2:faillock 与 fail2ban 的锁定机制会冲突吗?
不冲突,互补。faillock 在 PAM 层针对账号锁定(含本地与 SSH 登录),fail2ban 在网络层按来源 IP 封禁;两者同时启用可形成「账号+IP」双重防护。注意 faillock 的 even_deny_root 会导致 root 也被锁定,需在救援环境使用单用户模式解锁。
Q3:团队账号多,如何避免每个账号单独配 sudoers?
用组授权:把成员加入 %ops 组,sudoers.d 只写一条组规则,新成员加入组即获得相同权限,离职时移出组即可。如需更细粒度,可叠加命令别名(Cmnd_Alias)与时间窗(sudo 本身支持 HOSTS/CMDS/时间限制)。
总结
Linux 账号安全加固四步走:密码策略提高口令门槛,faillock 遏制在线爆破,sudoers 最小授权收窄提权路径,审计日志保证可追溯。完成配置后务必用 sudo -l 与登录测试验证,并保留一个可用的 root 应急通道(如云厂商救援模式),防止误配置导致失联。