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

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

官方医生说:

Laravel可能需要配置一些权限:其中的文件夹 存储和供应商要求web服务器进行写访问。

这是否意味着web服务器也需要访问存储和供应商文件夹本身,还是只需要访问它们的当前内容?

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

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

改变chmod 更改文件的所有者以匹配 web服务器,也许设置文本编辑器(和Finder?)跳过 询问密码,或者让他们使用sudo 更改web服务器的所有者以匹配操作系统用户(我不这样做 知道后果) 其他的东西


当前回答

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

user problem When I logged in ec2 instance, my username is ec2-user and usergroup is ec2-user. And the website works under of httpd user: apache: apache so we should set the permission for apache. folder and file permission A. folder structure first, you should make sure that you have such folder structure like this under storage storage framework cache sessions views logs The folder structure can be different according to the laravel version you use. my laravel version is 5.2 and you could find the appropriate structure according to your version.

B. permission At first, I see the instructions to set 777 under storage to remove file_put_contents: failed to open stream error. So i setup permission 777 to storage chmod -R 777 storage But the error was not fixed. here, you should consider one: who writes files to storage/ sessions and views. That is not ec2-user, but apache. Yes, right. "apache" user writes file (session file, compiled view file) to the session and view folder. So you should give apache to write permission to these folder. By default: SELinux say the /var/www folder should be read-only by the apache deamon.

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

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

你可以用以下方法设置一个读写上下文到存储文件夹(记得setenforce 1来测试它)

chcon -Rt httpd_sys_content_rw_t storage/

这样你的问题就解决了。

别忘了这一点 作曲家更新 PHP工匠缓存:清除 这些命令将在之后或之前使用。 我希望你节省时间。 祝你好运。Hacken

其他回答

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的缓存文件。

这可以部分缓解通过运行手工命令作为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

This will force Apache to create files as 664 by default. In itself, this can present a security risk. However, on the Laravel environments mostly being discussed here (Homestead, Vagrant, Ubuntu) the web server runs as user www-data under group www-data. So if you do not arbitrarily allow users to join www-data group, there should be no additional risk. If someone manages to break out of the webserver, they have www-data access level anyway so nothing is lost (though that's not the best attitude to have relating to security admittedly). So on production it's relatively safe, and on a single-user development machine, it's just not an issue.

最终,由于您的用户在www-data组中,并且包含这些文件的所有目录都是g+s(文件总是在父目录的组下创建),用户或www-data创建的任何内容都将是r/w。

这就是我们的目的。

edit

在进一步研究上述设置权限的方法时,它看起来仍然足够好,但一些调整可以有所帮助:

默认情况下,目录是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

允许web服务器创建服务。如官方Laravel安装指南所建议的那样。设置组粘性位意味着这些将由创建者拥有一组www-data。

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写入,这是在其他解决方案中发生的事情。因此,这种方式稍微安全一些,因为作为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

我会这样做:

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

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

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

最后,你需要给webserver修改存储和引导/缓存目录的权限:

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

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

Laravel 5.4文档说:

在安装Laravel之后,您可能需要配置一些权限。 存储和引导/缓存目录中的目录 你的web服务器应该可以写,否则Laravel将无法运行。如果你 正在使用Homestead虚拟机,这些权限应该 已经设置好了。

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

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

这对我来说很管用:

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


灵感来自https://stackoverflow.com/a/45673457/470749


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

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

(在我的例子中,我把我的Laravel应用程序克隆到我的第二台Cloudways服务器上,它不能完全工作,因为存储和引导/缓存目录的权限被弄乱了。)

我需要使用:

Cloudways平台>服务器>应用程序设置>重置权限

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

我还遵循了以用户为所有者的方式,用户是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作为组

这发生在我们被迫部署一些用户域文件时,使用ftp预加载,因此新的子文件夹文件夹总是属于www-data组,即使是由ftp客户端创建的

还要注意 sudo chgrp -R www-data storage bootstrap/cache > .使用实例 如果执行列表中的所有命令,则不需要。但如果你想修复一个ftp部署,例如,你没有执行第二行,所以这是需要的。