应从/etc/sudoers中彻底移除普通用户执行su、sudo -i等提权命令的权限,显式拒绝/bin/su、/bin/bash等危险路径,启用requiretty并审计日志,确保sudo -l无敏感命令且sudo su失败。

直接禁止普通用户通过 sudo 切换身份,核心不是“关掉某个开关”,而是从 /etc/sudoers 的授权规则中彻底移除其执行 su、sudo -i、sudo su 等提权登录类命令的权限,并堵住常见逃逸路径。
明确禁用所有 shell 登录类命令
在 /etc/sudoers 或 /etc/sudoers.d/ 下的配置文件中,**不授予**以下命令的执行权限(尤其不能写 ALL):
-
/bin/su及其变体(如/usr/bin/su) -
/bin/bash、/bin/sh、/usr/bin/zsh等任意交互式 shell -
/usr/bin/sudo自身(避免嵌套提权) -
/usr/bin/ssh(防止通过密钥或代理跳转)
如果已有用户被授予了宽泛权限(如 ALL=(ALL) ALL),必须将其替换为精确的、仅限业务所需的命令白名单,例如只允许 /usr/bin/systemctl restart nginx,而非整个 systemctl。
用叹号(!)显式拒绝危险命令
即使用户有部分命令权限,也可用否定语法阻止切换行为。例如:
%developers ALL=(ALL) /usr/bin/journalctl, !/bin/su, !/bin/bash, !/usr/bin/python3 -c "*"
注意:感叹号前必须有空格,且被拒绝的命令也需写绝对路径;带参数的命令(如 python3 -c)要整体匹配,否则可能绕过。
启用 requiretty 并禁用无终端调用
在 /etc/sudoers 文件顶部添加:
Defaults requiretty
该设置强制所有 sudo 操作必须在真实终端(TTY)中进行,可有效拦截 Web 后台、定时任务、SSH 非交互式调用等场景下的静默提权尝试。配合日志记录(Defaults logfile="/var/log/sudo.log"),便于事后审计异常行为。
验证是否真正生效
切换到目标用户后,运行以下命令测试:
-
sudo -n su -→ 应立即报错a password is required或command not allowed -
sudo -n -l→ 查看输出中是否完全不包含su、bash、sh等关键词 -
sudo -n /bin/sh -c 'id'→ 若返回结果,说明仍有逃逸风险,需继续收紧
只要没出现在 sudo -l 的允许列表里,且 requiretty 生效,普通用户就无法通过 sudo 完成身份切换。











