如何为Laravel设置文件权限?

How to set up file permissions for Laravel?

我正在使用所有者设置为 _www:_www 的 Apache Web 服务器。我永远不知道什么是文件权限的最佳实践,例如当我创建新的 Laravel 5 项目时。

Laravel 5 要求 /storage 文件夹可写。我发现了很多不同的方法来让它工作,我通常以递归地使它 777 chmod 结束。我知道这不是最好的主意。

官方文档说:

Laravel may require some permissions to be configured: folders within storage and vendor require write access by the web server.

这是否意味着 Web 服务器也需要访问 storagevendor 文件夹本身或只是它们的当前内容?

我认为更好的是更改 owner 而不是权限。我将所有 Laravel 的文件权限递归更改为 _www:_www,这使网站正常工作,就像我将 chmod 更改为 777 一样。问题是,现在每次我想保存任何文件时,我的文本编辑器都会要求我输入密码,如果我尝试在 Finder 中更改任何内容(例如复制文件),也会发生同样的情况。

解决这些问题的正确方法是什么?

  1. 改变chmod
  2. 更改文件的所有者以匹配 ose Web 服务器并可能将文本编辑器(和 Finder?)设置为跳过 询问密码,或让他们使用 sudo
  3. 更改 Web 服务器的所有者以匹配 os 用户(我不 知道后果)
  4. 其他

更改项目文件夹的权限,为拥有该目录的组中的任何用户启用 read/write/exec(在您的情况下是 _www):

chmod -R 775 /path/to/your/project

然后将您的 OS X 用户名添加到 _www 组以允许其访问目录:

sudo dseditgroup -o edit -a yourusername -t user _www

出于明显的安全原因,storagevendor 文件夹的权限应保持在 775

但是,您的计算机和服务器 Apache 都需要能够写入这些文件夹。例如:当您 运行 命令如 php artisan 时,您的计算机需要在 storage.

中写入日志文件

您需要做的就是将文件夹的所有权授予 Apache :

sudo chown -R www-data:www-data /path/to/your/project/vendor
sudo chown -R www-data:www-data /path/to/your/project/storage

然后您需要将您的用户(由 username 引用)添加到服务器 Apache 所属的组。像这样:

sudo usermod -a -G www-data userName

注意: 最常见的组名称是 www-data 但在您的情况下,将其替换为 _www

只是向所有查看此讨论的人说明一个显而易见的问题....如果您授予您的任何文件夹 777 权限,您将允许任何人读取、写入和执行该目录中的任何文件....这是什么意味着您已授予任何人(全世界任何黑客或恶意人士)上传任何文件、病毒或任何其他文件的权限,然后执行该文件...

IF YOU ARE SETTING YOUR FOLDER PERMISSIONS TO 777 YOU HAVE OPENED YOUR SERVER TO ANYONE THAT CAN FIND THAT DIRECTORY. Clear enough??? :)

基本上有两种方法可以设置您的所有权和权限。您要么给自己所有权,要么让网络服务器成为所有文件的所有者。

作为所有者的网络服务器(大多数人这样做的方式,以及 Laravel 文档的方式):

假设 www-data(它可能是其他东西)是您的网络服务器用户。

sudo chown -R www-data:www-data /path/to/your/laravel/root/directory

如果你这样做,网络服务器拥有所有文件,也是组,你上传文件或通过 FTP 处理文件时会遇到一些问题,因为你的 FTP 客户端将以您的身份登录,而不是您的网络服务器,因此请将您的用户添加到网络服务器用户组:

sudo usermod -a -G www-data ubuntu

当然,这假设您的网络服务器是 运行ning 作为 www-data(Homestead 默认值),并且您的用户是 ubuntu(如果您使用 Homestead,它就是 vagrant)。

然后您将所有目录设置为 755,将文件设置为 644... 设置文件权限

sudo find /path/to/your/laravel/root/directory -type f -exec chmod 644 {} \;    

设置目录权限

sudo find /path/to/your/laravel/root/directory -type d -exec chmod 755 {} \;

您的用户作为所有者

我更喜欢拥有所有的目录和文件(它使处理一切变得更容易),所以,转到您的 laravel 根目录:

cd /var/www/html/laravel >> assuming this is your current root directory
sudo chown -R $USER:www-data .

然后我给自己和网络服务器权限:

sudo find . -type f -exec chmod 664 {} \;   
sudo find . -type d -exec chmod 775 {} \;

然后赋予webserver读写storage和cache的权限

无论你如何设置,你都需要给网络服务器读写权限,用于存储、缓存和网络服务器需要上传或写入的任何其他目录(取决于你的情况),所以运行 上面 bashy 的命令:

sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache

现在,您是安全的,您的网站可以正常工作,并且您可以相当轻松地处理这些文件

已发布

All you need to do is to give ownership of the folders to Apache :

但我为 chown 命令添加了 -R sudo chown -R www-data:www-data /path/to/your/project/vendor sudo chown -R www-data:www-data /path/to/your/project/storage

bgles 发布的解决方案在最初正确设置权限方面对我来说是正确的(我使用第二种方法),但它仍然存在 Laravel.

的潜在问题

默认情况下,Apache 将创建具有 644 权限的文件。所以这几乎是存储/中的任何东西。因此,如果删除 storage/framework/views 的内容,然后通过 Apache 访问页面,您会发现已创建缓存视图,如:

-rw-r--r-- 1 www-data www-data 1005 Dec  6 09:40 969370d7664df9c5206b90cd7c2c79c2

如果您 运行 "artisan serve" 访问不同的页面,您将获得不同的权限,因为 CLI PHP 的行为与 Apache 不同:

-rw-rw-r-- 1 user     www-data 16191 Dec  6 09:48 2a1683fac0674d6f8b0b54cbc8579f8e

这本身没什么大不了的,因为您不会在生产中执行任何这些操作。但是,如果 Apache 创建了一个随后需要用户写入的文件,它将失败。当使用登录用户和 artisan 进行部署时,此 可以 适用于缓存文件、缓存视图和日志。一个简单的例子是 "artisan cache:clear",它将无法删除任何 www-data:www-data 644.

的缓存文件

这可以通过 运行ning artisan 命令作为 www-data 来部分缓解,因此您将 doing/scripting 一切如:

sudo -u www-data php artisan cache:clear

或者您将避免这种繁琐并将其添加到您的 .bash_aliases:

alias art='sudo -u www-data php artisan'

这已经足够好了,不会以任何方式影响安全性。但是在开发机器上,运行ning 测试和卫生脚本使它变得笨拙,除非你想设置别名以使用 'sudo -u www-data' 到 运行 phpunit 和你检查的所有其他内容您的构建可能会导致创建文件。

解决方案是按照 bgles 建议的第二部分,将以下内容添加到 /etc/apache2/envvars,然后重新启动(不是重新加载)Apache:

umask 002

这将强制 Apache 默认将文件创建为 664。这本身就可能带来安全风险。但是,在此处主要讨论的 Laravel 环境(Homestead、Vagrant、Ubuntu)中,网络服务器 运行 作为 www-data 组下的用户 www-data。所以如果不随意让用户加入www-data组,应该不会有额外的风险。如果有人设法突破网络服务器,他们无论如何都具有 www-data 访问级别,因此不会丢失任何东西(尽管这不是与安全相关的最佳态度)。所以在生产中它是相对安全的,在单用户开发机器上,这不是问题。

最终由于你的用户在www-data组,所有包含这些文件的目录都是g+s(文件总是在父目录的组下创建的),任何由用户创建或由www-创建的数据将为另一个 r/w。

这就是我们的目标。

编辑

进一步研究上述设置权限的方法,它看起来仍然不错,但一些调整可能会有所帮助:

默认情况下,目录775,文件664,所有文件都有刚安装框架的用户的所有者和组。所以假设我们从那一点开始。

cd /var/www/projectroot
sudo chmod 750 ./
sudo chgrp www-data ./

我们做的第一件事是阻止其他人访问,并将该组设为 www-data。只有 www-data 的所有者和成员可以访问该目录。

sudo chmod 2775 bootstrap/cache
sudo chgrp -R www-data bootstrap/cache

按照官方 Laravel 安装指南的建议,允许网络服务器创建 services.json 和 compiled.php。设置组粘性位意味着这些将由一组 www 数据的创建者拥有。

find storage -type d -exec sudo chmod 2775 {} \;
find storage -type f -exec sudo chmod 664 {} \;
sudo chgrp -R www-data storage

我们对存储文件夹做同样的事情,以允许创建缓存、日志、会话和视图文件。我们使用 find 明确地为目录和文件设置不同的目录权限。我们不需要在 bootstrap/cache 中执行此操作,因为那里(通常)没有任何子目录。

您可能需要重新应用任何可执行标志,删除 vendor/* 并重新安装 composer 依赖项以重新创建 phpunit 等链接,例如:

chmod +x .git/hooks/*
rm vendor/*
composer install -o

就是这样。除了上面解释的 Apache 的 umask 之外,这就是在不使整个项目根目录可由 www-data 写入的情况下所需要的,这是其他解决方案会发生的情况。因此,这种方式稍微安全一些,因为入侵者 运行ning 因为 www-data 具有更有限的写访问权限。

结束编辑

Systemd 的更改

这适用于 php-fpm 的使用,但也可能适用于其他。

需要覆盖标准的systemd服务,在override.conf文件中设置umask,重启服务:

sudo systemctl edit php7.0-fpm.service
Use:
    [Service]
    UMask=0002
Then:
sudo systemctl daemon-reload
sudo systemctl restart php7.0-fpm.service

在为 Laravel 应用程序设置权限时,我们 运行 遇到了许多边缘情况。我们创建一个单独的用户帐户 (deploy) 以拥有 Laravel 应用程序文件夹并从 CLI 执行 Laravel 命令,以及 运行 www-data 下的 Web 服务器.这导致的一个问题是日志文件可能属于 www-datadeploy,具体取决于谁首先写入日志文件,显然会阻止其他用户将来写入它.

我发现唯一明智和安全的解决方案是使用 Linux ACL。此解决方案的目标是:

  1. 允许 owns/deploys 应用程序读写访问 Laravel 应用程序代码的用户(我们使用名为 deploy 的用户)。
  2. 允许 www-data 用户读取 Laravel 应用程序代码,但不允许写入。
  3. 完全防止任何其他用户访问 Laravel 应用程序 code/data。
  4. 允许 www-data 用户和应用程序用户 (deploy) 对存储文件夹进行写入访问,无论哪个用户拥有该文件(因此 deploywww-data 可以写入同一个日志文件)。

我们完成如下:

  1. application/ 文件夹中的所有文件都是使用默认 umask 0022 创建的,这导致文件夹具有 drwxr-xr-x 权限,文件具有 -rw-r--r--.
  2. sudo chown -R deploy:deploy application/(或者简单地将您的应用程序部署为 deploy 用户,这就是我们所做的)。
  3. chgrp www-data application/ 授予 www-data 组访问应用程序的权限。
  4. chmod 750 application/ 允许 deploy 用户 read/write、www-data 用户只读,并删除任何其他用户的所有权限。
  5. setfacl -Rdm u:www-data:rwx,u:deploy:rwx application/storage/ 设置 storage/ 文件夹和所有子文件夹的默认权限。在存储文件夹中创建的任何新 folders/files 都将继承这些权限(www-datadeploy 都为 rwx)。
  6. setfacl -Rm u:www-data:rwX,u:deploy:rwX application/storage/ 对任何现有 files/folders.
  7. 设置上述权限

这是 2017 年为 5.1~5.2 版本编写的。在 Laravel.

的更高版本上使用它之前,请使用一些常识

我决定编写自己的脚本来减轻设置项目的一些痛苦。

运行 项目根目录中的以下内容:

wget -qO- https://raw.githubusercontent.com/defaye/bootstrap-laravel/master/bootstrap.sh | sh

等待引导完成,你就可以开始了。

Review the script 使用前

Laravel 5.4 docs 说:

After installing Laravel, you may need to configure some permissions. Directories within the storage and the bootstrap/cache directories should be writable by your web server or Laravel will not run. If you are using the Homestead virtual machine, these permissions should already be set.

此页面上有很多答案提到使用 777 权限。 不要那样做。你会成为 黑客。

而是按照其他人关于如何将权限设置为 755(或更严格)的建议进行操作。您可能需要在终端中通过 运行ning whoami 来确定您的应用是 运行ning 的哪个用户,然后使用 chown -R.[=25 更改某些目录的所有权=]

这对我有用:

cd /code/laravel_project
php artisan cache:clear
php artisan config:clear
sudo service php7.4-fpm stop
sudo service nginx stop

sudo chown -R $USER:www-data storage
sudo chown -R $USER:www-data bootstrap/cache
chmod -R 775 storage
chmod -R 755 bootstrap/cache
sudo service php7.4-fpm start && sudo service nginx start


灵感来自


如果您没有使用 sudo 的权限,因为许多其他答案需要...

您的服务器可能是共享主机,例如 Cloudways。

(就我而言,我已将我的 Laravel 应用程序克隆到我的第二个 Cloudways 服务器中,但由于 storagebootstrap/cache 目录搞砸了。)

我需要使用:

Cloudways Platform > Server > Application Settings > Reset Permission

然后我可以在终端中 运行 php artisan cache:clear

大多数文件夹应该是正常的“755”和文件,“644”

Laravel 要求某些文件夹对于 Web 服务器用户是可写的。您可以在基于 unix 的操作系统上使用此命令。

sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache

我在EC2实例上安装了laravel,花了3天时间修复权限错误,终于修复了。 所以我想把这段经历分享给其他人。

  1. 用户问题 当我登录 ec2 实例时,我的用户名是 ec2-user,用户组是 ec2-user。 该网站在 httpd 用户下运行:apache:apache 所以我们应该设置apache的权限。

  2. 文件夹和文件权限 A.文件夹结构 首先,你应该确保你在存储

    下有这样的文件夹结构

    存储

    • 框架
      • 缓存
      • sessions
      • 观看次数
    • 日志 根据您使用的 laravel 版本,文件夹结构可能会有所不同。 我的laravel版本是5.2,你可以根据自己的版本找到合适的结构

乙。允许 起初,我看到说明设置 777 under storage to remove file_put_contents: failed to open stream 错误。 所以我设置了存储权限 777 chmod -R 777 存储 但错误并未修复。 在这里,您应该考虑一个:谁将文件写入存储/sessions 和视图。 那不是ec2-user,而是apache。 对,对。 "apache" 用户将文件(session 文件,已编译的视图文件)写入 session 和视图文件夹。 所以你应该给 apache 对这些文件夹的写权限。 默认情况下:SELinux 说 /var/www 文件夹应该由 apache 守护程序 read-only。

所以为此,我们可以将selinux设置为0: setenforce 0

这可以暂时解决问题,但这会使 mysql 无法正常工作。 所以这不是很好的解决方案。

您可以通过以下方式为存储文件夹设置 read-write 上下文:(请记住设置强制 1 进行测试)

chcon -Rt httpd_sys_content_rw_t storage/

那么你的问题就解决了。

  1. 别忘了这一点 作曲家更新 php artisan cache:clear

    这些命令将在之后或之前有用。

    希望您节省时间。 祝你好运。哈肯

我找到了更好的解决方案。 这是因为 php 默认情况下是 运行 作为另一个用户。

所以要解决这个问题

sudo nano /etc/php/7.0/fpm/pool.d/www.conf

然后编辑 user = "put user that owns the directories" group = "put user that owns the directories"

然后:

sudo systemctl reload php7.0-fpm

Add to composer.json

"scripts": {
    "post-install-cmd": [
      "chgrp -R www-data storage bootstrap/cache",
      "chmod -R ug+rwx storage bootstrap/cache"
    ]
}

composer install

之后

我有以下配置:

  • NGINX(运行 用户:nginx
  • PHP-FPM

并按照@bgies 在已接受答案中的建议正确应用了权限。我的问题是 php-fpm 配置的 运行 用户和组,最初是 apache.

如果您将 NGINX 与 php-fpm 一起使用,您应该打开 php-fpm 的配置文件:

nano /etc/php-fpm.d/www.config

并将 usergroup 选项的值替换为一个配置为可以使用的 NGINX;在我的例子中,两者都是 nginx:

... ; Unix user/group of processes ; Note: The user is mandatory. If the group is not set, the default user's group ; will be used. ; RPM: apache Choosed to be able to access some dir as httpd user = nginx ; RPM: Keep a group allowed to write in log dir. group = nginx ...

保存并重启nginx和php-fpm服务

对于 Laravel 开发人员来说,目录问题可能会有点痛苦。在我的应用程序中,我正在动态创建目录并将文件成功移动到本地环境中的该目录。然后在服务器上,我在将文件移动到新创建的目录时遇到错误。

以下是我做过的事情,最后取得了成功。

  1. sudo find /path/to/your/laravel/root/directory -type f -exec chmod 664 {} \;
    sudo find /path/to/your/laravel/root/directory -type d -exec chmod 775 {} \;
  2. chcon -Rt httpd_sys_content_rw_t /path/to/my/file/upload/directory/in/laravel/project/
  3. 在动态创建新目录时,我使用了命令 mkdir($save_path, 0755, true);

在生产服务器上进行这些更改后,我成功地创建了新目录并将文件移动到其中。

最后,如果你在 Laravel 中使用 File facade,你可以这样做: File::makeDirectory($save_path, 0755, true);

这对我有用:

cd [..LARAVEL PROJECT ROOT]
sudo find . -type f -exec chmod 644 {} \;
sudo find . -type d -exec chmod 755 {} \;
sudo chmod -R 777 ./storage
sudo chmod -R 777 ./bootstrap/cache/

仅当您使用 npm(VUE、编译 SASS 等)时添加:

sudo chmod -R 777 ./node_modules/

它的作用:

  • 将所有文件权限更改为 644
  • 将所有文件夹权限更改为 755
  • 对于存储和 bootstrap 缓存(laravel 用于创建和执行文件的特殊文件夹,外部无法访问)将权限设置为 777,对于内部的任何内容
  • 对于nodeJS可执行文件,同上

注意:也许您不能或不需要使用 sudo 前缀来执行此操作。这取决于您的用户权限、组等...

我会这样做:

sudo chown -R $USER:www-data laravel-project/ 

find laravel-project/ -type f -exec chmod 664 {} \;

find laravel-project/ -type d -exec chmod 775 {} \;

最后,您需要授予网络服务器修改 storagebootstrap/cache 目录的权限:

sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache
sudo chown -R $USER:www-data your_directory_name_under_storage_app

它将为服务器用户和服务器授予访问文件所需的权限。

Mac OS 大苏尔

  1. 在我的情况下 artisan 无法访问
    /var/www/{project_name}/storage
    创建文件,例如。在 /logs 文件夹中 所以我不得不手动去 /var 并创建 Laravel 需要建立符号链接的文件夹结构。

  2. 添加对文件夹的访问权限 sudo chgrp -R $USER /var/www/project_name

  3. 那我就可以用了 php artisan storage:link没有任何问题。

如果您对某些文件进行了一些代码更改,然后更改了一些权限,那么设置正确的权限并再次提交可能比尝试选择具有权限更改的文件更容易。 您将只剩下代码更改。

我也按照这种方式让用户成为所有者,并且用户是www-data的成员。

我的命令顺序有点不同:

cd /var/www/html/laravel-project-root 
sudo chown -R $USER:www-data .

sudo find . -type f -exec chmod 664 {} \;   
sudo find . -type d -exec chmod 775 {} \;

sudo find . -type d -exec chmod g+s {} \;  <----- NOTE THIS

sudo chgrp -R www-data storage bootstrap/cache 
sudo chmod -R ug+rwx storage bootstrap/cache

请注意这个答案的特殊性:我是唯一(在这里)将组位添加到每个文件夹的人。这样,如果某人或某事创建了一个新的子文件夹,它会自动拥有 www-data as group

this happens when we are forced to deploy some userland files, preloaded using ftp, and so new subfolders folders are always owned from www-data group even if created by ftp client

Note also that the

sudo chgrp -R www-data storage bootstrap/cache >

is not needed if you do ALL of the commands in the list. But if you want to fix a ftp deploy, for example, and you didn't execute the 2nd line, so this is needed.