4

关于在Laravel PHP 中目录文件权限问题解决的思考

 1 year ago
source link: http://surest.cn/archives/230/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

关于在Laravel PHP 中目录文件权限问题解决的思考

Published on Feb 23, 2023 in PHP with 0 comment
最近维护系统的时候,总是会有一些预料之外的错误
  • 某日志权限不足
  • 某 sql 输出日志的时候权限不足
  • 某文件缓存的时候权限不足

大抵他们都会是这个样子:

failed to open stream: Permission denied

这个问题,其实非常简单,按照常规做法,chmod -R 777 对应目录/* 即可

这种做法最多只能从表面上快速解决问题,同时也为日后埋下了隐患.

我们需要关注的是,为什么会产生如此低层次的问题, 经过当前项目,我再衍生了一些可能导致的原因

  • 我们使用的是常规 PHP-FPM 模式运行,其默认归属权限组为 www
  • 有人通过终端,如 root、user 用户身份登录,并在服务器手动执行了相关命令, 其归属权限组可能为 root、other
  • 运维在服务器终端使用了 类似 pm2, supervisor 等工具, 其归属权限组可能为 root、other、www
  • 运维在服务器配置了定时任务,如 cron, 那么其归属权限组可能为 root、other、www
  • 我们使用的是常驻脚本进程,其可能默认归属权限为 root、other、www

好了,通过如上整理,我们大概理清楚了思绪,大概能表达出基本的跟原因

再通过其上原因根据需求,具体分析解决

统一归属权限,统一归属权限组

再 Linux 中,我们可以列出我们的权限和权限组的所具备的功能

图片描述...
图片描述...
图片描述...

当然,我们可以使用 Linux 命令 来了解我们当前的目录和文件情况: ls -alh

图片描述...

我们要区分好这三者

根据如上,我们可以总结出,我们针对其可以用什么权限了

因为我们这里的使用场景比较单一,开发则运维,运维则开发,所以我们设置如下权限

rw-rw-rw- 其对应权限代码 为 666 (所有用户都有文件读、写权限)

并且我们的用户组/用户,统一设置为: www/www

具体的 设置 定时任务、运维工具的权限,这里就不细说了,官方会提供文档,告知如何设置执行权限

这里参考 supervisor

图片描述...

运维方面级别

由于运维即开发,开发为运维,那么,我们应该分离职责。

当需要全局服务器配置的时候,允许使用 root 进行连接, 当只是调查 bug,如查询日志,执行命令的时候,我们应该规范的是使用 跳板机 和 指定用户组用户进行登录,并且可以将其用户组划分至 www 用户组

这个涉及到一些 基础的 linux 命令,如创建用户,创建用户组等等,这里不详细解释,可以查看一些基础命令

代码层面控制

我们已经根据如上,把外部问题解决了,那么我们可以开始解决第内部层面的问题

在代码层面,由于我们已经严格控制了外部的问题,只要是用户组运行对应环境,那么我们基本上可以杜绝权限相关的问题了。但是我们也可以按需对我们的一些基本功能日志进行划分,尽可能的避免出现外部影响内部

  • 执行通用日志输出包,输出日志文件后,将指定文件动态修改其权限
  • 日志功能分离,如 cli 下,日志名称使用 log-cli.log 否则 为 log.log
  • 文件输出权限设置,动态修改权限

我们可以根据实际代码来解决

  • 日志功能分离,如 cli

这里我们针对 mysql 输出 日志,我们在 AppServiceProvider 中, 设置了 日志监听

    \DB::connection('mysql')->listen(
        function ($query) {
            $prefix = is_cli() ? "logs/sql-cli-" : "logs/sql-";
            $url = "";
            if(request()) {
                $url = request()->fullUrl();
            }
            $tmp = str_replace('?', '"'.'%s'.'"', $query->sql);
            try {
                $tmp = vsprintf($tmp, $query->bindings);
            }catch (\Throwable $e) {}
            $file = $prefix . date("Y-m-d") .".log";
            $tmp = str_replace("\\", "", $tmp) . PHP_EOL;
            $msg = '--' . $query->time .'ms | ' . format_now() . "; url:$url|" . PHP_EOL . $tmp . PHP_EOL;

            error_log($msg, '3', storage_path($file));
        }
    );
  • 执行通用日志输出包

我们可以尝试使用 monolog, 也可以尝试我的日志包: https://github.com/surest-sky/laravel-echo-log

  • 文件输出权限设置,动态修改权限
图片描述...

请注意: chgrp、chown 都是危险的函数,没必要不要开。没开的话,可以按照 运维方面级别方面解决问题,尽量不要使用其他用户在服务器操作

图片描述...

本文由 邓尘锋 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Feb 23, 2023 at 10:40 am


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK