核心是系统级隔离:service用systemd PrivateTmp=yes自动挂载专属tmpfs;PHP-FPM按pool配置独立upload_tmp_dir并严格赋权;普通用户依赖XDG_RUNTIME_DIR、sticky bit及ACL实现租户级隔离。

多租户服务器上设置独立临时目录,核心不是“让每个用户自己建个 tmp 文件夹”,而是通过系统机制从源头切断跨用户访问路径。临时目录一旦共享,敏感数据(如上传文件、模型缓存、API token 临时写入)就可能被意外读取甚至覆盖——这不是权限松懈的问题,是设计层面的暴露面。
服务进程用 systemd PrivateTmp 隔离
Web 服务、定时任务、后台守护进程这类长期运行的服务,最容易成为临时数据泄露入口。systemd 提供了开箱即用的隔离能力:
- 在对应服务单元文件(如 /etc/systemd/system/myapp.service)的 [Service] 段添加 PrivateTmp=yes
- 无需手动创建目录或改权限,systemd 启动时自动挂载一个专属的 tmpfs 到该服务所有进程的 /tmp 和 /var/tmp
- 验证方式:找一个该服务的进程 PID,执行 sudo nsenter -t PID -m -p ls /tmp,只应看到本服务产生的内容
PHP-FPM 租户上传目录必须按 pool 独立配置
PHP 的 upload_tmp_dir 是高频冲突点。共用 /tmp 或 NFS 路径会导致不同站点上传文件名碰撞、覆盖,甚至被其他租户进程读取。
- 在每个 pool 配置中(如 /etc/php/8.2/fpm/pool.d/site-a.conf)显式指定:
php_admin_value[upload_tmp_dir] = /var/tmp/php-site-a - 提前创建目录并严格赋权:
mkdir -p /var/tmp/php-site-a && chown www-data:www-data /var/tmp/php-site-a && chmod 700 /var/tmp/php-site-a - 禁用任何带前缀的全局路径(如 /tmp/php-site-a),PHP 内部生成的临时文件不保证跨进程唯一性
普通用户依赖 XDG_RUNTIME_DIR + sticky bit 基础防护
登录用户的临时行为(如脚本运行、CLI 工具缓存)无法靠命名空间硬隔离,但可通过运行时环境和权限策略大幅收窄风险面:
- 确保系统启用 pam_systemd,使每个用户登录后自动获得专属 $XDG_RUNTIME_DIR(通常是 /run/user/$(id -u)),该路径默认仅属主可读写
- 强制脚本或工具使用该路径,例如:
export TMPDIR="$XDG_RUNTIME_DIR" 或在命令中显式指定 --tmp-dir "$XDG_RUNTIME_DIR" - 检查并加固全局临时目录:
chmod 1777 /tmp(保留 sticky bit 防删他人文件),
清理 /var/tmp 下非必要开放权限的子目录,尤其禁止用户对他人临时目录执行 chown 或 chmod
专用沙箱场景用 ACL 实现租户级临时区
当需要为某租户提供可长期复用、且能自动继承权限的临时工作区(如 AI 训练沙箱、数据处理临时存储),ACL 是最精准的控制手段:
- 创建目录:mkdir -p /srv/tmp/tenant-a
- 清除默认继承:setfacl -b /srv/tmp/tenant-a
- 授权目标租户并屏蔽其他租户:
setfacl -m u:tenant-a:rwx /srv/tmp/tenant-a
setfacl -m u:tenant-b:--- /srv/tmp/tenant-a - 启用默认 ACL,确保新文件自动继承:
setfacl -d -m u:tenant-a:rwx /srv/tmp/tenant-a

















