linux无自动限制sudo权限机制,须通过脚本主动识别90天未登录的普通用户,移出sudo组、删除sudoers.d文件,并清理crontab和ssh密钥等提权路径。

Linux 没有“自动限制 sudo 权限”的内置机制,必须通过组合工具和脚本实现——核心思路是:先识别闲置账户,再主动回收其 sudo 授权,而非依赖密码过期或 shell 禁用等间接手段。关键在于区分“账户登录状态”和“sudo 权限状态”:禁用 shell(如 usermod -s /sbin/nologin)不影响已有 sudo 规则生效;chage 设置的密码过期也不自动撤销 sudo 权限。
识别真正闲置的账户
只看 /etc/shadow 或文件时间戳不可靠。唯一可信依据是系统级登录记录:
- 运行
lastlog -b 90列出 90 天内未登录的用户 - 过滤掉系统账号(如
daemon、syslog、nobody等 UID - 用
awk '$5 != "Never" && $5 !~ /[^0-9\-]/ {print $1}' /var/log/lastlog提取有效日期字段(避免字段错位)
回收该用户的 sudo 权限
不能只改密码或锁 shell,必须清除其 sudo 授权来源:
- 若用户通过
sudo组获得权限(Debian/Ubuntu 默认):deluser username sudo(Ubuntu/Debian)或gpasswd -d username sudo(通用) - 若用户通过
/etc/sudoers主文件直授权限:
用sed -i '/^username[[:space:]]/d' /etc/sudoers删除对应行(操作前务必备份) - 若权限在
/etc/sudoers.d/下独立文件中(推荐方式):rm /etc/sudoers.d/username(文件名需与用户名一致或可识别) - 所有操作后,运行
sudo visudo -c验证语法,避免整系统 sudo 失效
同步清理关联权限与残留项
sudo 权限移除后,还需处理可能被复用的其他提权路径:
- 清空用户 crontab:
crontab -u username -r - 删除用户级 systemd 服务:
sudo -u username systemctl --user list-units --type=service --all | grep '\.service' | awk '{print $1}' | xargs -r sudo -u username systemctl --user disable --now - 检查并删除
/etc/sudoers.d/中以该用户命名或标注的临时规则文件 - 不要遗漏
~username/.ssh/authorized_keys——密钥仍可绕过密码登录并执行 sudo(若规则未回收)
自动化建议(非开机即生效,需定时触发)
将上述逻辑写成脚本,配合 cron 定期执行(例如每月初):
#!/bin/bash
INACTIVE_DAYS=90
for user in $(lastlog -b $INACTIVE_DAYS | awk '$5 != "Never" && $1 !~ /^(daemon|syslog|sync|games|nobody)$/ {print $1}'); do
# 跳过 UID /dev/null | grep -q '^[0-9]\{1,3\}$' && continue
# 移出 sudo 组
deluser "$user" sudo 2>/dev/null || true
# 删除 sudoers.d 中对应文件
rm -f "/etc/sudoers.d/$user"
# 清理 cron 和 ssh 密钥(按需启用)
done
注意:该脚本需 root 权限运行,且首次部署前应人工验证匹配逻辑,避免误删。
不复杂但容易忽略:sudo 权限回收是主动操作,必须显式删除规则或组成员关系,没有任何后台服务会替你完成这件事。











