Laravel 5(及其他)的文件权限

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

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

官方文件说:

Laravel可能需要configuration一些权限: storagevendor内的文件夹需要Web服务器的写入权限。

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

我认为有什么更好的,是改变所有者而不是权限。 我将所有Laravel的文件权限recursion地更改为_www:_www ,这使得该网站正常工作,就像我将chmod更改为777 。 问题是,现在我的文本编辑器要求我input密码,每次我想保存任何文件,如果我尝试在Finder中更改任何内容,例如复制文件,也会发生同样的情况。

什么是解决这些问题最stream行的方法?

  1. 改变chmod
  2. 更改文件的所有者以匹配networking服务器的文件,也许设置文本编辑器(和Finder?)跳过询问密码,或者让他们使用sudo
  3. 更改Web服务器的所有者以匹配OS用户(我不知道后果)
  4. 别的东西

只是为了说明任何人查看这个讨论….如果你给你的任何文件夹的777权限,你允许任何人读,写和执行该目录中的任何文件….这是什么意思是你已经给任何人(全世界任何黑客或恶意的人)都有权上传任何文件,病毒或任何其他文件,然后执行该文件…

如果您将您的文件夹权限设置为777,则您已将服务器打开到可以find该目录的任何人。 清楚了吗? 🙂

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

作为所有者的networking服务器(大多数人这样做):

假设www-data是你的web服务器用户。

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

如果你这样做,networking服务器拥有所有的文件,也是组,你会遇到一些问题上传文件或通过FTP使用文件,因为你的FTP客户端将login为你,而不是你的networking服务器,所以添加您的用户转到Web服务器用户组:

  sudo usermod -a -G www-data ubuntu 

当然,这里假定你的web服务器是以www-data(Homestead默认值)的forms运行的,而你的用户是ubuntu(如果你使用的是Homestead,那么这个用户是无用的)。

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

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

SET目录权限

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

您的用户作为所有者

我更喜欢拥有所有的目录和文件(这使得所有的工作更容易),所以我这样做:

  sudo chown -r my-user:www-data / path / to / your / laravel / root /目录 

然后我给自己和Web服务器的权限:

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

然后让networking服务器有权读取和写入存储和caching

无论你如何设置,那么你需要给Web服务器提供读写权限,以便存储,caching以及web服务器需要上传或写入的任何其他目录(取决于你的情况),所以从上面的bashy运行命令:

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

现在,你是安全的,你的网站工作,你可以很容易地处理文件

由于安全原因, 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 

注:最常见的, groupNamewww-data但在你的情况下,用_wwwreplace它

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

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

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

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

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

我发现唯一的安全解决scheme就是使用Linux ACL。 这个解决scheme的目标是:

  1. 允许拥有/部署应用程序的用户读写Laravel应用程序代码(我们使用名为deploy的用户)。
  2. 允许www-data用户读取Laravel应用程序代码,但不能写入访问。
  3. 防止任何其他用户访问Laravel应用程序代码/数据。
  4. 要允许www-data用户和应用程序用户( deploy )写入对存储文件夹的访问权限,无论哪个用户拥有该文件(例如, deploywww-data都可以写入相同的日志文件)。

我们做到这一点如下:

  1. application/文件夹中的所有文件都使用0022的默认umask创build,这将导致具有drwxr-xr-x权限的文件夹和具有-rw-r--r--
  2. sudo chown -R deploy:deploy application/ (或者简单地将应用程序deploydeploy用户,这就是我们所做的)。
  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/文件夹和所有子文件夹的默认权限。 存储文件夹中创build的任何新文件夹/文件都将inheritance这些权限( rwx用于www-datadeploy )。
  6. setfacl -Rm u:www-data:rwX,u:deploy:rwX application/storage/在任何现有文件/文件夹上设置上述权限。

已经发布了

所有你需要做的就是把文件夹的所有权给予Apache:

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

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

Laravel需要一些文件夹可写入Web服务器用户。 你可以在基于Unix的操作系统上使用这个命令。

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

bgles发布的解决scheme对于我来说正确地设置权限(我使用第二种方法),但它对Laravel仍然有潜在的问题。

默认情况下,Apache将创build具有644权限的文件。 所以这几乎是所有的存储/。 所以,如果你删除storage / framework / views的内容,然后通过Apache访问一个页面,你会发现caching视图已经被创build,如:

 -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创build一个随后需要被用户写入的文件,它将会失败。 这可以应用于使用login用户和手工进行部署时的caching文件,caching视图和日志。 一个容易的例子是“artisancaching:清除”,将无法删除任何caching文件是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' 

这已经足够好了,不会以任何方式影响安全。 但是在开发机器上,运行testing和卫生脚本使得这个很笨拙,除非你想设置别名来使用“sudo -u www-data”来运行phpunit和其他一切你检查你的版本,这可能会导致文件被创build。

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

 umask 002 

这将强制Apache默认创build文件为664。 这本身就可能带来安全风险。 但是,在这里大部分讨论的Laravel环境(Homestead,Vagrant,Ubuntu)中,Web服务器作为www-data组下的用户www-data运行。 因此,如果您不擅自允许用户joinwww-data组,那么不应该有额外的风险。 如果有人设法打破networking服务器,他们无论如何都有www数据访问级别,所以没有丢失(虽然这不是与安全性有关的最佳态度)。 所以在生产上它是相对安全的,在单用户开发机器上,这不是问题。

最终,因为你的用户在www-data组中,并且包含这些文件的所有目录都是g + s(该文件总是在父目录的组下创build的),用户或www-data创build的任何内容都将是r / W为另一个。

这就是这个目标。

编辑

在调查上述进一步设置权限的方法,它仍然看起来不错,但一些调整可以帮助:

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

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

我们所做的第一件事就是阻止对其他人的访问,并使该组成为万维网数据。 只有www数据的所有者和成员才能访问该目录。

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

允许Web服务器根据官方Laravel安装指南的build议创buildservices.json和compiled.php。 设置组粘贴位意味着这些将由创build者拥有一组万维网数据。

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

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

您可能需要重新应用任何可执行的标志,并删除供应商/ *和重新安装composer php依赖关系重新创build链接phpunit等,例如:

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

而已。 除了上面解释的Apache的umask之外,这些都是需要的,而不需要使用www-data来编写整个项目,这是其他解决scheme所发生的。 所以这样做比较安全,因为入侵者作为万维网数据运行有更多的写访问权限。

结束编辑

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 

我决定写我自己的脚本来缓解设置项目的一些痛苦。

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

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

等待bootstrapping完成,你很好走。

使用前查看脚本 。

Laravel 5.4文档说:

安装Laravel后,您可能需要configuration一些权限。 storage的目录和bootstrap/cache目录应该可以通过Web服务器写入,否则Laravel将不能运行。 如果您正在使用Homestead虚拟机,则应该已经设置了这些权限。

在这个页面上有很多答案提到使用777权限。 不要这样做。 你会把自己暴露给黑客。

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

如果您没有使用sudo权限,那么许多其他答案需要…

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

(就我而言,我已经将我的Laravel应用程序克隆到了我的第二台Cloudways服务器上,但是由于storagebootstrap/cache目录的权限被搞乱了,所以还没有完全正常工作。)

我需要使用:

Cloudways Platform > Server > Application Settings > Reset Permission

然后我可以运行php artisan cache:clear在terminalphp artisan cache:clear

我已经在EC2实例上安装了laravel,并花了3天的时间修复权限错误,最后修复了这个错误。 所以我想和其他人分享这个经验。

  1. 用户问题当我loginec2实例时,我的用户名是ec2-user,usergroup是ec2-user。 而且该网站在httpd用户下工作:apache:apache,所以我们应该为apache设置权限。

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

    存储

    • 骨架
      • 高速caching
      • 会议
      • 意见
    • 日志根据您使用的laravel版本,文件夹结构可能会有所不同。 我的laravel版本是5.2,你可以根据你的版本find合适的结构。

B.权限首先,我看到在存储下设置777的指示,以删除file_put_contents:未能打开stream错误。 所以我设置权限777存储chmod -R 777存储但错误是不固定的。 在这里,你应该考虑一个:谁写文件到存储/会话和视图。 这不是ec2用户,而是apache。 是的,对。 “apache”用户将文件(会话文件,编译视图文件)写入会话和查看文件夹。 所以你应该给apache写这些文件夹的权限。 默认情况下:SELinux说/ var / www文件夹应该由apache deamon只读。

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

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

您可以使用以下设置将读写上下文设置到存储文件夹:(记住要setenforce 1来testing它)

 chcon -Rt httpd_sys_content_rw_t storage/ 

那么你的问题将被修复。

  1. 并不要忘记这个composer php更新PHP的工匠caching:清除

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

    我希望你节省你的时间。 祝你好运。 克勤

我发现了一个更好的解决scheme。 它造成的,因为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