macOS Monterey下launchd启动的php-fpm无法访问外接磁盘文件
根因说明
macOS 12 Monterey的TCC(透明权限管控)机制对launchd托管的系统守护进程有独立的权限校验逻辑,和终端手动启动进程的权限判定规则完全不同:
- 手动在终端执行
sudo php-fpm启动时,进程会直接继承终端App已经获得的「完全磁盘访问权限」,所以可以正常读写外接磁盘文件 - 由launchd拉起的php-fpm属于系统级守护进程,不会继承任何终端的权限;自编译的二进制默认没有做本地签名,你之前直接把php-fpm二进制拖进权限列表的操作不会稳定生效——TCC无法固定识别未签名二进制的身份,会直接拦截其对外接可移动磁盘的访问,抛出
Operation not permitted错误 - 你之前执行的
sudo diskutil disableOwnership /Volumes/Storage仅能关闭Unix文件系统层面的所有权校验,完全管不到TCC权限层,所以操作后问题不会消失 - nginx可以正常服务外接盘上的静态文件,是因为静态请求由nginx主进程直接响应,你给nginx配置的权限刚好匹配了它的启动上下文;PHP请求会反向代理给php-fpm的worker进程处理,自然受php-fpm自身的权限限制。
解决步骤
- 清理无效旧权限
打开「系统偏好设置→安全性与隐私→隐私→完全磁盘访问」,删除之前添加的php、php-fpm、launchd相关所有权限条目,重启系统清空TCC缓存。 - 给自编译的php-fpm做本地ad-hoc签名
执行以下命令给php-fpm二进制签本地权限,不需要付费开发者账号,签名后TCC可以固定识别进程身份:sudo codesign --force --deep --sign - /你实际安装的php-fpm二进制绝对路径 - 重新授予完全磁盘访问权限
把刚完成签名的php-fpm二进制重新拖进「完全磁盘访问权限」列表,确保条目对应的权限开关处于勾选状态。 - 重载launchd托管的php-fpm服务
执行命令重新加载php-fpm的launchd配置,替换成你自己存放的php-fpm plist文件实际路径(通常在/Library/LaunchDaemons/目录下):
重载完成后触发PHP读写外接磁盘的请求,即可验证权限恢复正常。sudo launchctl unload /你的php-fpm.plist文件绝对路径 sudo launchctl load /你的php-fpm.plist文件绝对路径
备用排查方案
如果上述操作完成后仍存在权限报错,按以下步骤处理:
- 执行命令重置可移动磁盘的TCC权限库:
sudo tccutil reset SystemPolicyRemovableVolumes - 重启系统后首次访问外接磁盘的PHP请求触发时,系统会弹出权限申请弹窗,点击允许即可。
- 不要通过关闭系统完整性保护(SIP)的方式绕过权限校验,会大幅降低系统安全性,以上所有操作均不需要关闭SIP即可生效。
内容的提问来源于stack exchange,提问作者Paolo
相关产品推荐
相关产品推荐

