如何设置Laravel的文件权限?


233

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

Laravel 5要求/storage文件夹可写。我发现了很多不同的方法来使其正常工作,而我通常以777递归方式使其成为chmod。我知道这不是最好的主意。

官方文件说:

Laravel可能需要配置一些权限:Web服务器中的文件夹, storage并且vendor需要Web服务器进行写访问。

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

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

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

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

4
我认为777自由太多了,因为它包含了所有人的所有权限。
Robo Robok 2015年

从Laravel文档中:storagebootstrap/cache目录中的目录应该可由您的Web服务器写入
joshuamabina

1
使用fcgi,您可以将755/644用于所有(包括公共/存储)
Jeffz

@jww同意我们可以将问题移到serverfault而不是搁置吗?
wp78de

Answers:


587

只是为了表明查看此讨论的任何人的明显点。...如果您给任何文件夹777权限,则表示允许任何人读取,写入和执行该目录中的任何文件....这意味着您已经得到了任何人(全世界的任何黑客或恶意人士)都有权上传任何文件,病毒或任何其他文件,然后执行该文件...

如果您将文件夹权限设置为777,那么您已经向任何可以找到该目录的人打开了服务器。足够清楚了吗???:)

基本上有两种方法来设置您的所有权和权限。您要么赋予自己所有权,要么使Web服务器成为所有文件的所有者。

作为所有者的Web服务器(大多数人的操作方式以及Laravel文档的方式):

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

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

如果这样做,则网络服务器将拥有所有文件,并且也是该组的成员,并且通过FTP上传文件或使用文件会遇到一些问题,因为FTP客户端将以您而不是网络服务器的身份登录。您的用户到Web服务器用户组:

sudo usermod -a -G www-data ubuntu

当然,这假设您的网络服务器以www-data(Homestead的默认值)运行,并且您的用户是ubuntu(如果您使用Homestead则无所适从)。

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

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

SET目录权限

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

您的用户作为所有者

我更喜欢拥有所有目录和文件(这使得处理所有内容变得更加容易),所以我这样做:

sudo chown -R我的用户:www-data / path / to / your / laravel / root / directory

然后,我同时给自己和Web服务器权限:

sudo查找/ path / to / your / laravel / root / directory -type f -exec chmod 664 {} \;    
sudo查找/ path / to / your / laravel / root / directory -type d -exec chmod 775 {} \;

然后授予Web服务器读取和写入存储和缓存的权限

无论采用哪种方式进行设置,都需要授予Web服务器读写权限,以存储,缓存以及Web服务器也需要上传或写入的任何其他目录(具体取决于您的情况),因此请从上面的bashy运行命令:

sudo chgrp -R www数据存储引导程序/缓存
sudo chmod -R ug + rwx存储引导程序/缓存

现在,您很安全,您的网站可以正常运行,并且可以轻松地使用文件


4
很好的例子,如果没有www数据用户,请使用apache:apache代替www数据(在某些发行版上)
Denis Solakovic

53
我认为人们对这个anyone概念误解太多了。Linux的anyone标志表示任何用户,而不是任何人。您仍然需要服务器访问权限。
MarcoAurélioDeleu '16 -10-8

3
@ andreshg112第一个www数据是用户的名称,第二个www数据是组的名称。因此,这意味着所有者是apache和(此组)apache。使用www-data:www-data或将您的用户添加到该组。(CLI:useradd -G {group-name} username),然后您可以将其
改成

2
@fs_tigre我认为安全性没有什么区别……除了我猜有两个用户在猜测密码而不是一个,当然我一直使用我的用户帐户登录,所以如果我以不安全的方式(例如普通的FTP和使用密码)进行了操作,它可能会破坏站点,但是我只使用Putty和SSH登录,而当我使用FTP时,它是SFTP,因此完全没有问题。建议使用bashy建议的命令,因为它们设置了粘性位,因此,如果您的网络服务器创建子目录,则它们将具有与父目录相同的所有者/权限
bgies'Apr

3
在第一种方法中,由于您没有write授予组权限,用户是否仍无法上传文件?
法赫米

44

出于明显的安全原因,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

注意:最常见的groupName是,www-data但根据您的情况,将其替换为_www


10
+1我喜欢这种方法。但是我相信chown命令应该包含-R标志。另外,在laravel 5.1和5.2中,应该提供对bootstrap / cache目录的访问权,而不是vendor目录。
杰森·惠勒

有什么方法可以测试是否可以正常工作?我的意思是,如果在具有正确权限的storage / logs目录中创建了新日志文件,该如何检查?
Chaudhry Waqas

20

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

我发现唯一理智而安全的解决方案是使用Linux ACL。该解决方案的目标是:

  1. 为了允许拥有/部署应用程序的用户对Laravel应用程序代码进行读写访问(我们使用名为的用户deploy)。
  2. 允许www-data用户读取对Laravel应用程序代码的访问权限,但不允许写入访问。
  3. 完全禁止任何其他用户访问Laravel应用程序代码/数据。
  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用户读/写,该www-data用户为只读并删除对任何其他用户的所有权限。
  5. setfacl -Rdm u:www-data:rwx,u:deploy:rwx application/storage/storage/文件夹和所有子文件夹上设置默认权限。在存储文件夹中创建任何新的文件夹/文件将继承这些权限(rwx两个www-datadeploy)。
  6. setfacl -Rm u:www-data:rwX,u:deploy:rwX application/storage/ 在任何现有文件/文件夹上设置以上权限。

15

更改项目文件夹的权限,以为拥有该目录的组中的任何用户启用读/写/执行(在您的情况下为_www):

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

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

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

dseditgroup您提供我提供的服务时,出现错误:Username and password must be provided.
Robo Robok 2015年

我的错误,您需要以具有适当权限的用户运行该命令,因此只需sudo在开头添加即可。
Bogdan 2015年

那么,我需要那些文件的所有者更改为_www:_wwwmyuser:_www呢?
Robo Robok

您可以保留它_www:_www,因为775表示该组中的任何用户_www都具有对该文件夹中的读/写/执行权限,而您只是将用户名添加到该组中。
Bogdan 2015年

你能告诉我一件事吗?这是什么意思chown myuser:_www?我知道第一个是用户,第二个是组,但这是否意味着“此用户和该组中的任何人”或“该用户但仅是相信此组而已”?
Robo Robok

8

如已发布

您需要做的就是将文件夹的所有权授予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


3
为什么我们必须授予供应商目录权限?存储有意义,可以写入日志文件等。但是供应商呢?为什么?
阿里·哈里斯

正如上面的评论中所述:“但是,您的计算机和服务器Apache都必须能够在这些文件夹中进行写入。例如:当您运行php artisan之类的命令时,您的计算机需要将日志文件写入存储中。”
Stanislav Potapenko '16

Mac上的错误:chown:www-data:非法的群组名称
Sunil Kumar,


7

大多数文件夹应为普通的“ 755”,文件应为“ 644”

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

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

6

Laravel 5.4文档说:

安装Laravel之后,您可能需要配置一些权限。内的目录storagebootstrap/cache目录应该是可写的Web服务器或Laravel将无法运行。如果使用的是Homestead虚拟机,则应该已经设置了这些权限。

此页面上有很多答案提到使用777权限。不要那样做 您可能会将自己暴露给黑客。

相反,请遵循其他人关于如何设置755(或更严格)的权限的建议。您可能需要通过whoami在终端中运行来确定您的应用正在运行的用户,然后使用来更改某些目录的所有权chown -R

如果您无权使用sudo其他答案,则需要...

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

(就我而言,我已经将Laravel应用程序克隆到了我的第二个Cloudways服务器中,由于storageand bootstrap/cache目录的权限被弄乱了,所以它不能完全正常工作。)

我需要使用:

Cloudways Platform > Server > Application Settings > Reset Permission

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


6

添加到composer.json

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

composer install


2
这是一个不好的答案。如果正确配置了Web服务器,则永远不需要对任何文件夹使用777。使用777可以打开服务器,让任何黑客上传文件,并在知道文件夹存在的位置执行该文件。
mbozwood

2
好的。你提供什么?
达夫隆·阿奇洛夫

如果是这样,这是对的吗?chown -R $ USER:
www-

看到正确的答案,它包含您可以绝对在更新后放入的所有必要信息:)
mbozwood

4

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

默认情况下,Apache将创建具有644权限的文件。因此,存储/中几乎所有内容。因此,如果删除存储/框架/视图的内容,然后通过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 cache:clear”,它将无法删除任何www-data:www-data 644的缓存文件。

通过将artisan命令作为www-data运行,可以部分缓解这种情况,因此您将在执行/编写如下脚本:

sudo -u www-data php artisan cache:clear

否则您将避免繁琐的操作,并将其添加到您的.bash_aliases中:

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

这足够好,不会以任何方式影响安全性。但是在开发机器上,运行测试和环境脚本会使此操作变得笨拙,除非您要设置别名以使用“ sudo -u www-data”来运行phpunit,否则检查构建的所有其他操作都可能导致文件创建。

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

umask 002

默认情况下,这将强制Apache将文件创建为664。就其本身而言,这可能会带来安全风险。但是,在此处主要讨论的Laravel环境(Homestead,Vagrant,Ubuntu)上,Web服务器作为用户www-data在www-data组下运行。因此,如果您不随意允许用户加入www-data组,则不会有其他风险。如果有人设法闯入Web服务器,无论如何他们都具有www数据访问级别,因此不会丢失任何内容(尽管这不是公认的与安全性有关的最佳态度)。因此,在生产中它是相对安全的,而在单用户开发计算机上,这不是问题。

最终,因为您的用户位于www-data组中,并且包含这些文件的所有目录都是g + s(该文件始终在父目录的组下创建),所以用户或www-data创建的任何内容都将为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显式设置目录和文件的目录权限。我们不需要在引导程序/缓存中执行此操作,因为其中(通常)没有任何子目录。

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

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

而已。除了上面为Apache解释的umask之外,这是所有必需的,而不会使整个projectroot可被www-data写入,这在其他解决方案中会发生。因此,这种方式在某种程度上更安全​​,因为以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

3

这为我工作:

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/

它能做什么:

  • 将所有文件权限更改为644
  • 将所有文件夹权限更改为755
  • 对于存储和引导缓存(laravel用于创建和执行文件的特殊文件夹,无法从外部获得),将内部的权限设置为777

注意:也许您不需要或不需要使用sudo前缀。这取决于您的用户的权限,组等。


2

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

在项目根目录内运行以下命令:

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

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

使用前请复查脚本


2

我在EC2实例上安装了laravel,花了3天的时间修复权限错误,最后修复了该错误。因此,我想与其他人分享这一经验。

  1. 用户问题登录ec2实例时,我的用户名是ec2-user,用户组是ec2-user。并且该网站在httpd用户apache:apache下工作,因此我们应该为apache设置权限。

  2. 文件夹和文件权限A.文件夹结构首先,应确保在存储下具有这样的文件夹结构

    存储

    • 构架
      • 快取
      • 会议
      • 意见
    • 日志根据您使用的laravel版本,文件夹结构可能有所不同。我的laravel版本是5.2,您可以根据您的版本找到合适的结构。

B.权限首先,我看到在存储下设置777以删除file_put_contents的说明:无法打开流错误。所以我将权限777设置为存储chmod -R 777的存储,但该错误未得到解决。在这里,您应该考虑一个:谁在存储/会话和视图中写入文件。那不是ec2-user,而是apache。是的,对。“ apache”用户将文件(会话文件,编译的视图文件)写入会话和视图文件夹。因此,您应该给apache写入这些文件夹的权限。默认情况下:SELinux表示/ var / www文件夹对apache deamon应该是只读的。

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

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

您可以使用以下命令对存储文件夹设置读写上下文:(请记住设置setenforce 1进行测试)

chcon -Rt httpd_sys_content_rw_t storage/

然后,您的问题将得到解决。

  1. 并且不要忘记此作曲家更新php artisan cache:clear

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

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


您是否尝试从Web服务器调用命令行脚本?我遇到问题,因为它不打印任何输出
Volatil3 '18

0

我有以下配置:

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

并按照接受的答案中的@bgies正确应用权限。在我的情况下,问题是php-fpm的配置运行用户和组,该用户和组原来是apache

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

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

并且配置了一个NGINX来替换usergroup选项的值;就我而言,两者都是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服务。


0

对于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::makeDirectory($save_path, 0755, true);


-1

我找到了一个更好的解决方案。这是因为默认情况下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


如果该网页的访问者设法脱离该Web服务器,则他们现在将具有“拥有目录的用户”的访问权限。如果该用户是www-data,则他们可以造成的损害是有限的,这就是为什么Apache作为受限用户运行的原因。如果该用户不受此限制,则可能造成更大的损失。如果该用户具有sudo权限,则他们可能造成更大的损失。
markdwhite '17

与Apache的处理相同。BTW我现在运行nignx像个大男孩
塞西尔merrel又名bringrainfire
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.