/tmp 目录加固实战:noexec 挂载防 WebShell

适用场景

  • Web 服务器曾出现 WebShell 落地后利用 /tmp 中转执行的入侵事件
  • 等保测评或安全基线扫描要求 /tmp 分区以 noexec 方式挂载
  • 希望封堵「上传文件到临时目录—执行—反弹 Shell」这条最常见的入侵链

前置条件

  • 一台 Linux 服务器(本文以 CentOS 7/8、Ubuntu 20.04 为例),root 权限
  • 已确认 /tmp 当前挂载状态(独立分区还是落在根分区)
  • 有服务器控制台或带外管理入口,防止 fstab 写错后无法救援

原理说明

大量入侵案例中,攻击者通过文件上传漏洞、命令注入或反序列化漏洞把恶意 ELF 或脚本先写入 /tmp、/dev/shm 这类全局可写目录,再执行获得反弹 Shell。原因在于这些目录默认权限为 1777(sticky bit),任何用户可写,且多数发行版默认挂载选项不带执行限制。noexec 使挂载在该分区上的二进制文件无法直接执行,nosuid 忽略 SUID 位,nodev 禁止创建设备文件,三项组合可把「写入临时目录」从高危降级为基本无害——文件写得进去,但跑不起来。

需要明确:noexec 只拦截直接执行二进制,通过动态链接器间接执行(如 /lib64/ld-linux-x86-64.so.2 ./payload)仍可能绕过,因此它是纵深防御的一层,不能替代权限收敛与入侵检测。

操作步骤

1. 确认当前挂载状态

findmnt /tmp
df -hT /tmp /dev/shm

记录 /tmp 是独立分区还是根分区的一部分,决定后续走哪种方案。

2. 方案一:/tmp 为独立分区,修改 fstab

cp /etc/fstab /etc/fstab.bak.$(date +%F)
# 找到 /tmp 对应行,在第四列挂载选项中追加:
# defaults,noexec,nodev,nosuid

若该行原本指向磁盘分区(如 LABEL=xxx /tmp xfs defaults 0 0),只追加 ,noexec,nodev,nosuid,不要整行替换成 tmpfs,避免内存盘占满 RAM。

3. 方案二:/tmp 在根分区,启用 systemd tmp.mount

最简单的方式是把 /tmp 变成内存盘:

systemctl unmask tmp.mount
systemctl enable --now tmp.mount
# 确认 /usr/lib/systemd/system/tmp.mount 的 Options 包含:
# mode=1777,strictatime,noexec,nodev,nosuid

同时同步加固 /dev/shm,在 /etc/fstab 追加:

tmpfs /dev/shm tmpfs defaults,noexec,nodev,nosuid 0 0
mount -o remount /dev/shm

4. 使磁盘分区方案立即生效

mount -o remount,noexec,nodev,nosuid /tmp

5. 验证执行是否被拦截

cp /bin/ls /tmp/ls_test
/tmp/ls_test
# 期望输出:bash: /tmp/ls_test: Permission denied

配置验证

findmnt -no OPTIONS /tmp      # 期望含 noexec,nodev,nosuid
findmnt -no OPTIONS /dev/shm

重启服务器一次,确认 fstab 或 tmp.mount 配置在重启后依然生效,这是该基线项验收的关键步骤。

常见问题

FAQ 1:启用 noexec 后部分服务异常怎么办?

常见受影响项:MySQL 临时表目录(在 my.cnf 设置 tmpdir = /var/lib/mysql-tmp 并新建目录赋权)、PHP 的 session 与上传临时目录(确认 session.save_pathupload_tmp_dir 不指向 /tmp)、解压到 /tmp 再执行的安装脚本。逐项把依赖目录迁出 /tmp 即可,不要为迁就服务放弃 noexec。

FAQ 2:tmpfs 方案会占用多少内存?

tmp.mount 默认上限为物理内存的一半,且只按实际使用量占用。内存紧张的小规格机器可显式限制:mount -o remount,size=512M /tmp,并把 size 选项固化到 tmp.mount 配置或 fstab 中。

FAQ 3:写错 fstab 重启进不去系统了?

开机时 systemd 会因挂载失败进入 emergency shell,根分区默认只读,先执行 mount -o remount,rw /,然后注释或修正 /etc/fstab 中的错误行再重启。这也是操作前要求保留带外控制台的原因。

总结

/tmp 与 /dev/shm 加固以极低的性能代价切断了临时目录执行恶意文件这条主流入侵路径:独立分区走 fstab 追加 noexec、nodev、nosuid,根分区场景启用 systemd tmp.mount,二者择一即可,但 /dev/shm 必须同步处理。上线前先盘点 MySQL tmpdir、PHP session 等目录依赖,上线后用 findmnt 与执行测试完成验收,并纳入定期基线核查。