跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

ThinkPHP项目目录权限设置的最佳实践_Linux安全权限分配

ThinkPHP在Linux报Permission denied,主因是PHP进程用户(如www-data、nginx)对路径某级目录缺少x执行权限,无法进入;应先用ps aux查实际用户,再chown -R该用户并设755/644权限,禁用777以防SELinux或安全策略拦截。 ThinkPHP 在 Linux 上报
Permission denied
,八成不是权限数字太小,而是 PHP 进程用户根本进不了那层目录——比如
/var/www/html/runtime
报错,你只改了
runtime
的权限,却漏了
/var/www
对
www-data
缺少
x
(执行)权限,导致连路径都 traverse 不进去。 怎么确认 PHP 进程实际运行用户 别猜,直接查。不同环境用户名不同:
www-data
(Ubuntu/Debian)、
nginx
(CentOS/RHEL)、
apache
(旧版 Apache)。命令如下:
ps aux | grep php-fpm | head -1
—— 看
php-fpm
工作进程的 USER 列
ps aux | grep nginx | head -1
—— 若用 Nginx,看主进程或 worker 进程用户
ps aux | grep apache2 | head -1
—— Apache 场景下同理 拿到用户名后,后续所有属主、属组操作都以它为准。别用
root
或当前登录用户硬套,CLI 和 Web 模式用户常不一致。 runtime 目录为什么不能 chmod 777
777
在多数生产环境反而触发拦截:SELinux 默认拒绝
httpd_sys_rw_content_t
上下文外的写入;Nginx+PHP-FPM 组合在启用
security.limit_extensions
或
open_basedir
时也会静默拒写;cPanel 类托管平台会主动拦截全局可写目录。 立即学习 “ PHP免费学习笔记(深入) ”; 正确做法是:先
chown -R www-data:www-data runtime/
(把
www-data
替换为你查到的实际用户) 再统一设权限:
find runtime/ -type d -exec chmod 755 {} \;
和
find runtime/ -type f -exec chmod 644 {} \;
若需子目录自动继承组(如日志轮转新建目录),加
chmod g+s runtime/
注意:
755
对目录意味着“所有者可读写执行,组和其他仅可读+执行”,
x
是进入目录的关键,缺它就
cd
失败,
fopen
必然报错。 PHP 8.5.5 PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。 下载 public/ 必须是 Web 根目录,且不能混放敏感目录 把整个 ThinkPHP 项目根目录(含
app/
、
config/
、
runtime/
)直接扔进 Nginx 的
root
,等于把数据库配置、路由定义全暴露在 HTTP 下。攻击者访问
http://example.com/config/database.php
就可能拿到明文密码。 Nginx 配置中
root
必须指向
public/
子目录,不是项目根目录
public/
下的
index.php
权限应为
644
,禁止写权限(防被覆盖为 webshell) 上传目录(如
public/uploads/
)要单独授权:
chown -R www-data:www-data public/uploads/
+
chmod -R 755 public/uploads/
Nginx 中必须禁用上传目录下的 PHP 执行:
location ~ ^/uploads/.*\.php$ { deny all; }
别把上传目录建在
runtime/
里——TP 的部署脚本或缓存清理逻辑可能随时清空它,上传文件就丢了。 日志写不进 runtime/log/ 的真实原因 常见错误日志:
file_put_contents(): failed to open stream: Permission denied
。你以为是
log/
权限不够,其实可能是: 路径解析错位:CLI 模式下
runtime/log/
落在当前工作目录,而 Web 模式落在项目根目录;
config/log.php
里没写绝对路径 父级某一层缺失
x
权限:用
namei -l /var/www/myapp/runtime/log
逐级检查 owner/group/perm,卡在哪一级一目了然 SELinux 拦截:临时关掉验证
sudo setenforce 0
,若恢复写入则需
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/myapp/runtime(/.*)?"
+
sudo restorecon -Rv /var/www/myapp/runtime
最易忽略的一点:日志轮转时新建文件,依赖的是父目录的属组和
g+s
位。如果
runtime/
属组没设对、没加
g+s
,新生成的
2024-04-21.log
文件可能属主是
www-data
,但属组是
root
,导致后续写入失败。

相关文章