Linux SUID权限位设置后shell脚本执行无权限,遗漏了哪些规则?
问题核心原因
Linux等主流类Unix系统默认会忽略Shell脚本的SUID/SGID权限位,该权限位仅对编译后的二进制可执行文件生效,这是你遇到问题的根本原因。
具体逻辑说明
内核执行不同类型文件时的处理逻辑完全不同:
- 执行二进制可执行文件时:内核会直接读取文件的权限位,如果检测到SUID位被设置,会将进程的有效用户ID(EUID)修改为该文件的所有者,以此获得对应权限。
/usr/bin/passwd就是编译好的二进制文件,符合该规则,所以可以正常获得root权限修改系统用户配置文件。 - 执行Shell脚本时:内核首先识别到这是脚本文件,会读取首行的shebang(
#!/usr/bin/bash),随后启动bash解释器进程,把脚本路径作为参数传给bash执行。这个过程中内核只会校验脚本的读、执行权限,完全忽略脚本本身的SUID位,最终运行脚本的bash进程的EUID依然是执行脚本的普通用户,自然没有权限写入root所有的owned_by_root文件。
为什么要禁用脚本SUID
脚本的SUID存在极高的安全风险,攻击者可以通过篡改环境变量、构造路径注入、符号链接劫持等多种方式实现提权,所以主流Linux发行版都默认在内核层面禁用了脚本的SUID功能。
替代实现方案
如果需要实现普通用户执行脚本获得root权限的效果,推荐两种更安全的方式:
- 配置sudo规则,允许指定用户免密执行该脚本,这是生产环境最常用的方案。
- 将脚本的功能逻辑改写为C/C++等编译型语言的二进制可执行文件,再给二进制文件设置SUID位,注意要做好参数校验、路径硬编码等安全处理,避免出现提权漏洞。
内容的提问来源于stack exchange,提问作者bool3max
相关产品推荐
相关产品推荐

