最稳妥的做法是分层控制:用 /etc/sudoers 做命令级白名单授权,用 shell 替换切断交互入口,再辅以文件权限或 ACL 防止本地绕过。

禁止普通用户执行特定敏感命令,关键不是“堵住所有门”,而是“只留一道可控的门”。直接删命令、改权限或全局禁用,容易引发系统异常或被绕过。真正稳妥的做法是分层控制:用 /etc/sudoers 做命令级白名单授权,用 shell 替换 切断交互入口,再辅以 文件权限或 ACL 防止本地绕过。
用 sudoers 精确控制可执行命令
这是最常用也最推荐的方式,核心是白名单思维——没写进规则的,一律不许执行。
- 必须用
visudo编辑/etc/sudoers,避免语法错误导致整个 sudo 失效 - 写绝对路径,例如
devuser ALL=(root) /usr/bin/systemctl restart nginx,漏掉/usr/bin/或写成systemctl都会失败 - 禁止某条命令加
!前缀,如alice ALL=(ALL) !/bin/rm, !/sbin/shutdown -
NOPASSWD:必须紧贴命令前,格式为bob ALL=(root) NOPASSWD: /bin/ls, !/bin/cp;写成NOPASSWD: ALL是无效的 - 规则从上到下匹配,第一条命中即停止,确保你的限制行在通用规则(如
%sudo ALL=(ALL:ALL) ALL)之前
用 shell 替换阻止交互式执行
即使用户有账号,也不意味着他能登录敲命令。把 shell 换成 /sbin/nologin 或 /bin/false,是最干净的“禁用登录”方式。
- 执行
sudo usermod -s /sbin/nologin username,SSH 登录会立即退出,并提示 “This account is currently not available.” - 该操作不影响 cron、systemd --user 或其他非交互服务,只要它们不依赖 shell 启动
- 若需保留 rsync/scp 等非交互访问,可用
/bin/false,提示更简短但效果类似 - 恢复登录只需
sudo usermod -s /bin/bash username,无需重设密码
用文件权限或 ACL 封死本地绕过路径
有些用户可能绕过 sudo,直接调用二进制。这时需从文件层面加固:
- 撤销执行权限:
sudo chmod -x /usr/bin/reboot,普通用户执行时会报 “Permission denied” - 用 ACL 精确屏蔽单个用户:
sudo setfacl -m u:unwanted:r-x /usr/bin/rm改为只读可执行,或sudo setfacl -m u:unwanted:--- /usr/bin/rm完全禁止 - 慎用
alias rm=:这类 .bashrc 方式——仅对交互式 bash 生效,脚本、sh 或其他 shell 下完全无效 - 避免直接删或重命名命令(如
mv /bin/rm /bin/rm.bak),很多系统工具依赖这些路径,易引发意外故障
额外提醒:避开常见陷阱
很多看似生效的配置,其实存在隐蔽漏洞:
-
env_reset默认开启,$PATH、$HOME 等变量会被重置,脚本里硬编码路径才可靠 - 通配符(如
/usr/bin/*)和符号链接可能被用于逃逸,尽量用具体路径 - 别依赖
rbash作主防线——它容易被exec bash或sh -c绕过 - 验证权限是否生效:用目标用户执行
sudo -l查看允许命令列表,再实测允许与禁止项


















