noexec从内核层拦截execve()调用,阻止./script.sh类直接执行,但不拦python script.py等解释器调用;需配合chmod清理x权限及umask/acl控制新文件权限,并通过/etc/fstab永久配置。

直接用 mount -o noexec 就能阻止挂载分区上的文件被当作程序执行,但要注意它只拦 ./script.sh 这类直接调用,不拦 python script.py 这种解释器显式加载。
noexec 的作用机制
noexec 是内核级限制,挂载时启用后,任何对该分区上文件的 execve() 系统调用都会被拒绝——哪怕文件权限是 -rwxr-xr-x,运行也会报 Permission denied。它不看文件权限,只看挂载点属性。
- ✅ 拦住
/tmp/malware、./deploy.sh、/var/www/uploads/exploit.py(直接加 x 后执行) - ❌ 不拦
sh /tmp/script.sh或python3 /var/www/uploads/payload.py,因为解释器本身在其他分区运行,只是读取目标文件内容
临时启用 noexec(测试用)
适合快速验证是否兼容业务,重启后失效:
- 新挂载:sudo mount -o noexec /dev/sdc1 /mnt/data
- 已挂载后调整:sudo mount -o remount,noexec /tmp
- 组合加固更常见:sudo mount -o remount,noexec,nosuid,nodev /var/www/uploads
永久生效要改 /etc/fstab
临时命令重启就丢,必须写进 fstab 才真正起效:
- 找到对应挂载行,例如:
UUID=abcd-1234 /tmp tmpfs defaults 0 0 - 把第 4 列(options 字段)改成:
defaults,noexec,nosuid,nodev - 保存后运行
sudo mount -a测试语法,再用findmnt -o TARGET,OPTIONS /tmp确认 noexec 出现在输出里
搭配清理才能防绕过
noexec 是基础防线,但攻击者可能提前上传带 x 权限的脚本。所以还要同步做权限收束:
- 清掉已有脚本的执行位:
find /tmp -type f \( -name "*.sh" -o -name "*.py" \) -exec chmod a-x {} \; - 控制新文件默认无 x:通过 umask(如
umask=022)或默认 ACL 设置,避免上传后自动带执行权 - 对 Web 上传目录,建议再加
ro(只读),彻底杜绝写+执行组合风险











