关键在于分层启用系统级隔离机制:服务进程用privatetmp,php-fpm按pool配upload_tmp_dir,普通用户走xdg_runtime_dir+sticky bit,租户级补acl,禁用手动chmod或拼接路径。

多用户服务器上隔离用户缓存数据,关键不是“建几个子目录”,而是分层启用系统级隔离机制:服务进程用 PrivateTmp,Web应用(如PHP)按实例配 upload_tmp_dir,普通用户走 XDG_RUNTIME_DIR + sticky bit,特殊租户补 ACL。手动 chmod 或拼接用户名的临时路径既不安全也不可靠。
服务进程:用 systemd 的 PrivateTmp 自动隔离
所有以 systemd 管理的后台服务(如 API、定时任务、数据库代理),都应启用私有命名空间:
- 在服务单元文件(如 /etc/systemd/system/myapp.service)的 [Service] 段添加:
PrivateTmp=yes - 无需创建目录或设权限,systemd 启动时自动挂载独立 tmpfs,该服务内所有进程看到的
/tmp和/var/tmp完全与其他用户/服务隔开 - 验证方式:
sudo nsenter -t $(pgrep -f myapp) -m -p ls /tmp—— 只应列出本服务产生的文件
PHP-FPM 多租户:每个 pool 必须独占 upload_tmp_dir
PHP 上传临时文件名不跨进程唯一,共用目录极易导致覆盖、丢失或权限冲突:
- 在每个 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 - 禁用 NFS 路径和全局
/tmp;重启对应 pool 后,用echo ini_get('upload_tmp_dir')确认生效
普通用户登录会话:依赖 XDG_RUNTIME_DIR 与 /tmp 权限加固
用户间无内核命名空间,但可通过运行时环境和基础权限控制风险:
- 确保
/tmp设置 sticky bit:chmod 1777 /tmp(防删他人文件,但不防读) - 敏感脚本强制使用
$XDG_RUNTIME_DIR(通常是/run/user/$(id -u)),该路径由 pam_systemd 自动创建,仅属主可访问 - 清理非必要开放权限的
/var/tmp子目录;禁止用户对他人临时目录执行chown或chmod
租户级专用缓存区:用 ACL 精确划界
当需要为特定用户组(如 tenant-a、tenant-b)提供共享但互不可见的临时工作区时:
- 创建目录并清空默认继承:
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 - 用
getfacl /srv/tmp/tenant-a查看规则,用sudo -u tenant-a ls /srv/tmp/tenant-b测试是否拒绝访问










