RHEL 8中auditd插件脚本降权失败:setuid设置无效求助
问题原因与解决建议
核心问题
Linux系统默认忽略脚本文件的setuid位,这是安全设计:脚本依赖解释器(如/bin/sh、/usr/bin/python)执行,而解释器不会继承脚本的setuid权限,避免恶意脚本利用该机制提权。因此即便给脚本添加u+s位,root运行时仍会保持root权限。
解决方案
方案1:用C语言编写SetUID包装程序(最可靠)
二进制可执行文件的setuid位是有效的,可通过轻量C程序作为中间层,切换到目标用户后执行脚本:
- 编写C代码(示例
run_as_mike.c):
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> int main() { // 替换为mike用户的实际UID/GID(用`id mike`命令查询) uid_t uid = 1000; gid_t gid = 1000; // 先切换组ID,再切换用户ID(顺序不可颠倒) if (setgid(gid) != 0) { perror("setgid failed"); exit(1); } if (setuid(uid) != 0) { perror("setuid failed"); exit(1); } // 执行目标脚本 execl("/path/to/listerner.sh", "listerner.sh", NULL); perror("execl failed"); return 1; }
- 编译并配置权限:
gcc run_as_mike.c -o run_as_mike chown root:root run_as_mike chmod u+s run_as_mike
- 让auditd调用该二进制程序,它会自动切换到mike用户执行脚本。
方案2:在脚本内部主动切换权限
Shell脚本版本
使用runuser命令(root执行无需密码,比su更安全):
修改listerner.sh内容:
#!/usr/bin/sh # 以mike身份执行后续逻辑 runuser -l mike -c ' whoami echo "Test file" > /path/to/listener.bash.log '
确保mike用户对日志文件所在目录有写入权限。
Python脚本版本
在代码中主动切换UID/GID:
import os import pwd # 获取mike用户的UID/GID user_info = pwd.getpwnam('mike') os.setgid(user_info.pw_gid) os.setuid(user_info.pw_uid) # 后续代码以mike身份运行 print(os.popen('whoami').read()) with open('/path/to/listener.python.log', 'w') as f: f.write("Test file\n")
注意:必须先切换组ID再切换用户ID,否则切换用户后将无权限修改组ID。
方案3:排查系统级限制(可能性低)
- 检查分区挂载选项:执行
mount | grep nosuid,若脚本所在分区带有nosuid挂载参数,setuid位会失效。需修改/etc/fstab移除该参数,重新挂载分区。 - 检查SELinux:RHEL8默认开启SELinux,可临时关闭测试(
setenforce 0),若问题解决,需配置SELinux规则允许程序切换权限。
内容的提问来源于stack exchange,提问作者Maikol
相关产品推荐
相关产品推荐

