有效限制运维人员通过sudo执行命令派生子进程的关键是三层隔离:sudo命令白名单、编辑器/解释器运行时限制、文件系统级noexec挂载;noexec仅对支持该特性的程序(如vim、less)生效且须绑定具体路径,sudoedit可切断提权链路,noexec挂载能阻止/tmp等目录执行恶意脚本,还需禁用高危命令并启用日志审计。

要限制运维人员通过sudo执行的命令派生不受控的子进程(比如在vim里执行!sh、在less中调用!命令、或在脚本中system()调用shell),关键不是靠sudoers里的NOEXEC标签——它只对**直接被sudo启动的二进制程序生效**,且依赖程序自身是否支持该机制。真正有效、可落地的组合策略是三层隔离:sudo命令白名单 + 编辑器/解释器运行时限制 + 文件系统级noexec挂载。
一、sudoers中正确使用NOEXEC(仅限特定二进制)
NOEXEC必须与具体命令路径绑定,且仅对支持noexec特性的程序起作用(如vim、less、man等编译时启用了+job或+terminal以外的禁用项)。配置示例如下:
- ✅ 有效写法:
alice ALL=(root) NOEXEC: /usr/bin/vim /etc/nginx/nginx.conf—— 此时:!sh会被阻断 - ❌ 无效写法:
alice ALL=(root) NOEXEC: /usr/bin/bash—— bash本身不响应NOEXEC,且sudo不允许直接授权交互式shell - ⚠️ 注意:
NOEXEC不阻止sudoedit(即sudo -e)内部调用的编辑器,它本身已运行在普通用户上下文,无需额外加NOEXEC
二、用sudoedit替代sudo vim,切断提权链路
运维人员编辑配置文件时,应强制使用sudoedit而非sudo vim。它的机制天然防提权:
- 复制目标文件到
/tmp或/var/tmp下的用户可写临时目录 - 以当前用户身份调用默认编辑器(如vim、nano)
- 保存后,sudo才以root权限将临时文件原子覆盖原文件
- 整个编辑过程无root权限,
!sh、:set shell=/bin/bash等操作完全无法逃逸
三、挂载点启用noexec,封死脚本/二进制自执行路径
很多提权行为依赖在/tmp、/var/tmp等目录写入并执行恶意二进制或脚本。启用noexec可从根本上拦截:
- 临时生效:
sudo mount -o remount,noexec,nosuid,nodev /tmp - 永久生效:编辑
/etc/fstab,在对应行添加noexec,nosuid,nodev,例如:/dev/sda2 /tmp ext4 defaults,noexec,nosuid,nodev 0 2 - 验证:
echo '#!/bin/sh; echo test' > /tmp/test.sh && chmod +x /tmp/test.sh && /tmp/test.sh→ 应报Permission denied
四、补充加固:禁用高危命令与审计留痕
即使上述三层到位,仍需堵住旁路:
- 不在
Cmnd_Alias中包含sudo su、sudo -i、sudo /bin/bash等显式提权命令 - 启用日志记录:
Defaults logfile="/var/log/sudo.log",确保所有sudo调用(含失败尝试)可追溯 - 对常用工具做二次封装(如写wrapper脚本),移除危险参数或预设
SHELL环境变量为空











