我正在使用拥有者设置为_www:_www的Apache Web Server。我永远不知道文件权限的最佳做法是什么,例如当我创建新的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服务器本身也需要访问storage和vendor文件夹,还是只需要访问其当前内容?
我认为更好的是改变所有者而不是权限。我将所有Laravel的文件权限递归地更改为_www:_www,这使得网站正常工作,就像我将chmod更改为777一样。问题是,现在我的文本编辑器每次要保存任何文件时都要求我输入密码,如果我尝试在Finder中更改任何内容,就会发生同样的情况,例如复制文件。
解决这些问题的正确方法是什么?
改变chmod
更改文件的所有者以匹配
Web服务器,也许设置文本编辑器(和Finder?)跳过
要求输入密码,或者让他们使用sudo
更改Web服务器的所有者以匹配os用户(我没有
知道后果)
还有别的
-
我认为777太自由了,因为它包含了所有人的所有权限。
-
从Laravel文档:storage和bootstrap/cache目录中的目录应该可由Web服务器写入
-
使用fcgi,你可以755/644(包括公共/存储)
-
@jww同意我们可以将问题移到serverfault而不是暂停吗?
只是为任何观看此讨论的人说明显而易见....如果您给予任何文件夹777权限,则允许任何人读取,写入和执行该目录中的任何文件....这意味着您已经给出了任何人(全世界任何黑客或恶意人士)上传任何文件,病毒或任何其他文件的权限,然后执行该文件......
IF YOU ARE SETTING YOUR FOLDER PERMISSIONS TO 777 YOU HAVE OPENED YOUR
SERVER TO ANYONE THAT CAN FIND THAT DIRECTORY. Clear enough??? :)
基本上有两种方法来设置您的所有权和权限。要么给自己所有权,要么让网络服务器成为所有文件的所有者。
Web服务器作为所有者(大多数人这样做的方式,以及Laravel doc的方式):
假设www-data(可能是其他东西)是您的网络服务器用户。
1
| sudo chown -R www -data :www -data /path /to /your /laravel /root /directory |
如果你这样做,网络服务器拥有所有文件,也是组,你将有一些问题上传文件或通过FTP处理文件,因为你的FTP客户端将以你的身份登录,而不是你的网络服务器,所以添加您的用户访问网络服务器用户组:
1
| sudo usermod -a -G www-data ubuntu |
当然,这假设您的网络服务器以www-data(Homestead默认值)运行,而您的用户是ubuntu(如果您使用Homestead,它就是流浪者)。
然后将所有目录设置为755,将文件设置为644 ...
设置文件权限
1
| sudo find /path /to /your /laravel /root /directory -type f -exec chmod 644 {} \ ; |
SET目录权限
1
| sudo find /path /to /your /laravel /root /directory -type d -exec chmod 755 {} \ ; |
您的用户是所有者
我更喜欢拥有所有目录和文件(这使得更容易处理所有内容),所以我做:
1
| sudo chown -R my -user :www -data /path /to /your /laravel /root /directory |
然后我给自己和网络服务器权限:
1 2
| 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 {} \ ; |
然后授予Web服务器读取和写入存储和缓存的权限
无论您设置哪种方式,您都需要为Web服务器提供读取和写入权限,以便存储,缓存以及Web服务器需要上载或写入的任何其他目录(具体取决于您的具体情况),因此请运行上面的bashy命令:
1 2
| sudo chgrp -R www -data storage bootstrap /cache
sudo chmod -R ug +rwx storage bootstrap /cache |
现在,您是安全的,您的网站是有效的,您可以非常轻松地使用这些文件
-
很好的例子,如果没有www-data用户,请使用apache:apache代替www-data(在某些发行版上)
-
我认为人们误解了anyone概念。 Linux的anyone标志表示任何用户,而不是任何人。您仍需要服务器访问权限。
-
@DenisSolakovic,我不明白www-data是什么?用户还是组?我正在使用Ubuntu和Xampp。什么是www数据给我?
-
@ andreshg112第一个www-data是用户名,第二个www-data是组的名称。所以它意味着所有者是apache和(this-group)apache。使用www-data:www-data或将您的用户添加到该组。 (CLI:useradd -G {group-name} username),而不是用户名:www-group
-
@bgies:非常感谢您提供的好消息。问题,你提到你更喜欢你的第二个例子,比另一个更安全,755,644 vs 775,664?另外,如果你使用第二种方法,你真的需要运行bashy建议的命令吗?再次,非常感谢。
-
@fs_tigre我认为安全性没有太大区别...除了我猜有两个用户猜测密码而不是一个,当然我一直用我的用户帐户登录,所以如果我以一种不安全的方式(普通FTP和使用密码)这样做可能会损害网站,但我只使用Putty和SSH登录,当我使用FTP时它是SFTP,所以没有任何问题。建议使用bashy建议的命令,因为它们设置了粘滞位,因此如果您的Web服务器创建子目录,它们将具有与父级相同的所有者/权限
-
在第一种方法中,用户是否仍然无法上传文件,因为您没有给该组授予write权限?
-
我也尝试了第二种方法,但是当我touch一个新文件时,无论是普通用户还是www-data,新文件似乎都没有继承权限..?
-
在sudo chown -R my-user:www-data /path/to/your/root/directory之后,sudo chgrp -R www-data storage bootstrap/cache真的很有用吗?
-
@bgies你是什么意思/path/to/your/root/directory?它是Laravel应用程序的public目录,它被设置为虚拟主机的文档根目录吗?或者它是Laravel的应用程序根目录本身,即一切都在那里?
-
@SaidbakR Laravel的chown app根目录,因为大多数(所有?)Laravel文件都不在公共目录中
-
我收到此错误production.ERROR: UnexpectedValueException: The stream or file"/var/www/html/laravel/storage/job/248/import.log" could not be opened: failed to open stream: Permission denied in /var/www/html/laravel/bootstrap/cache/compiled.php
-
我发现了问题......这是我的atronan的cronjob,我必须设置我的cronjob,具有root权限,如sudo -i然后crontab -e
-
这个答案应该在介绍部分之后的官方Laravel文档中。
-
谢谢你。只是一个请求:你能不能在CentOS 7中添加一个注释用户不是'www-data',而是'apache'。
-
@bgies我正在使用Laravel 5.5 ..试图按照你的指示,但一些Laravel如何无法执行Python但得到Permission Denied错误。
-
在"您作为所有者的用户"部分中,我认为我们可以跳过sudo chgrp -R www-data storage bootstrap/cache因为它已经完成了。
-
@bgies感谢您的回答+1!我有一个问题。创建新的日志文件时,文件所有者是www-data:www-data ..如何将其自动设置为:www-data,如"您作为所有者的用户"部分所述(还有文件权限)?
-
不要运行sudo find /path/to/your/laravel/root/directory -type f -exec chmod 664 {} \;!在此之后,您将无法从命令行运行任何命令(例如,vendor/bin/中的所有命令)!我现在必须弄清楚如何让Laravel再次从命令行工作。
-
我为存储文件夹做了同样的事情,使laravel运行sudo find/path/to/your/laravel/root/directory/storage/ -type f -exec chmod 664 {} \; sudo find /path/to/your/laravel/root/directory/storage/ -type d -exec chmod 775 {} \;
-
@Fahmi它也应该是664,对吧?目前,如果权限设置为644,我无法通过FTP上传文件。这是拼写错误吗?
-
我创建了一个bash shell脚本,根据你的答案完成所有工作:github.com/marounmelhem/laravel-permissions-fix
出于明显的安全原因,storage和vendor文件夹的权限应保持在775。
但是,您的计算机和服务器Apache都需要能够在这些文件夹中写入。例如:当您运行php artisan之类的命令时,您的计算机需要在storage中的日志文件中写入。
您需要做的就是将文件夹的所有权授予Apache:
1 2
| 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所属的组。像这样:
1
| sudo usermod -a -G www-data userName |
注意:最常见的是,groupName是www-data,但在您的情况下,请将其替换为_www
-
+1我喜欢这种方法。但我相信chown命令应该包含-R标志。此外,在laravel 5.1和5.2中,您应该访问bootstrap / cache目录,而不是vendor目录。
-
有没有办法测试这是否可以正常工作?我的意思是如果在存储/日志目录中创建了新的日志文件,它具有正确的权限,我可以检查它吗?
在为Laravel应用程序设置权限时,我们遇到了许多边缘情况。我们创建一个单独的用户帐户(deploy),用于拥有Laravel应用程序文件夹并从CLI执行Laravel命令,并在www-data下运行Web服务器。这导致的一个问题是日志文件可能由www-data或deploy拥有,具体取决于谁首先写入日志文件,显然阻止其他用户将来写入日志文件。
我发现唯一合理且安全的解决方案是使用Linux ACL。该解决方案的目标是:
允许拥有/部署应用程序的用户对Laravel应用程序代码进行读写访问(我们使用名为deploy的用户)。
允许www-data用户读取对Laravel应用程序代码的访问权限,但不允许写入访问权限。
防止任何其他用户访问Laravel应用程序代码/数据。
允许www-data用户和应用程序用户(deploy)对存储文件夹进行写访问,无论哪个用户拥有该文件(因此deploy和www-data都可以写入同一个日志文件,例如)。
我们完成如下:
application/文件夹中的所有文件都使用默认的umask 0022创建,这导致文件夹具有drwxr-xr-x权限,文件具有-rw-r--r--。
sudo chown -R deploy:deploy application/(或者只是将您的应用程序部署为deploy用户,这就是我们的工作)。
chgrp www-data application/为www-data组授予对应用程序的访问权限。
chmod 750 application/允许deploy用户读/写,www-data用户只读,并删除对任何其他用户的所有权限。
setfacl -Rdm u:www-data:rwx,u:deploy:rwx application/storage/设置storage/文件夹和所有子文件夹的默认权限。在存储文件夹中创建的任何新文件夹/文件都将继承这些权限(www-data和deploy都是rwx)。
setfacl -Rm u:www-data:rwX,u:deploy:rwX application/storage/在任何现有文件/文件夹上设置上述权限。
更改项目文件夹的权限,以便为拥有该目录的组中的任何用户启用读/写/执行(在您的情况下为_www):
1
| chmod -R 775 /path /to /your /project |
然后将您的OS X用户名添加到_www组以允许它访问该目录:
1
| sudo dseditgroup -o edit -a yourusername -t user _www |
-
当我提供你提供的dseditgroup时,我收到一个错误:Username and password must be provided.。
-
我的错误是,您需要使用具有适当权限的用户运行该命令,因此只需在开头添加sudo即可。
-
那么我是否还需要将这些文件的所有者更改为_www:_www或myuser:_www?
-
您可以将其保留_www:_www,因为775表示组_www中的任何用户都具有在该文件夹中读/写/执行的完全权限,并且您刚刚将该用户名添加到该组。
-
你能告诉我一件事吗?是什么意思chown myuser:_www?我知道第一个是用户,第二个是组,但它是否意味着"这个用户和任何人来自这个组"或"这个用户,但只要他属于这个群体"?
-
组_www中的任何用户都具有该文件夹中读/写/执行的完全权限。
-
好的,所以我在一个文件夹上尝试了chmod go-rwx。它为_www组设置读/写权限,不为everyone设置访问权限。即使我现在属于_www组,我也无法从Finder访问这些文件。这是为什么?
-
如果我将所有者留给_www:_www,我无法在不输入密码的情况下从Finder进行任何更改。
-
您还需要为给定目录上的组设置执行权限,以便对其进行正确访问。读写是不够的。这就是我写775而不是765的原因。我刚刚自己测试了这个场景,它没有任何问题。
-
请你更新你的答案,一步一步地以更详细的方式解释它?我想让我的Web服务器/Documents只有尽可能少的权限。我认为775对所有文件和文件夹都太多了,不是吗?
-
另外,需要775吗? 770不够吗?
-
看看这个答案,它详细解释了如何处理Web服务器权限难题。我很好奇,你的网络服务器是否可以远程访问?因为否则,如果它是本地/开发Web服务器,则不需要所有这些权限限制。
-
我的Web服务器无法远程访问,它只是我的本地开发环境。 :)
已发布
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
-
为什么我们必须授予供应商目录的权限?存储有意义,写入日志文件等。但供应商?为什么?
-
正如上面的一些评论所写:"但是,你的计算机和你的服务器Apache都需要能够在这些文件夹中写入。例如:当你运行像php artanan这样的命令时,你的计算机需要在存储中的日志文件中写入。"
-
mac上的错误:chown:www-data:非法组名
-
请参阅stackoverflow.com/questions/8035939/
大多数文件夹应该是正常的"755"和文件,"644"
Laravel要求Web服务器用户可以写入一些文件夹。您可以在基于unix的操作系统上使用此命令。
1 2
| sudo chgrp -R www -data storage bootstrap /cache
sudo chmod -R ug +rwx storage bootstrap /cache |
Laravel 5.4文档说:
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(或更严格限制)权限的建议。您可能需要通过在终端中运行whoami然后使用chown -R更改某些目录的所有权来确定您的应用正在运行的用户。
如果您没有权限使用sudo,那么许多其他答案需要......
您的服务器可能是Cloudways等共享主机。
(在我的情况下,我已将我的Laravel应用程序克隆到我的第二个Cloudways服务器中,并且由于storage和bootstrap/cache目录的权限混乱而无法完全正常工作。)
我需要使用:
Cloudways Platform > Server > Application Settings > Reset Permission
然后我可以在终端中运行php artisan cache:clear。
bgles发布的解决方案对我来说最初是正确设置权限(我使用第二种方法),但它仍然存在Laravel的潜在问题。
默认情况下,Apache将创建具有644权限的文件。这几乎是存储/中的任何东西。因此,如果删除存储/框架/视图的内容,然后通过Apache访问页面,您会发现缓存视图已创建如下:
1
| -rw-r--r-- 1 www-data www-data 1005 Dec 6 09:40 969370d7664df9c5206b90cd7c2c79c2 |
如果您运行"artisan serve"并访问其他页面,您将获得不同的权限,因为CLI PHP的行为与Apache不同:
1
| -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运行来部分缓解,因此您将执行/编写以下所有内容:
1
| sudo -u www-data php artisan cache:clear |
或者你将避免这种繁琐,并将其添加到你的.bash_aliases:
1
| alias art='sudo -u www-data php artisan' |
这足够好,不会以任何方式影响安全性。但是在开发机器上,运行测试和卫生脚本会使这个变得难以处理,除非你想设置别名来使用'sudo -u www-data'来运行phpunit以及你检查你的构建的所有其他东西,这可能会导致文件被创建。
解决方案是遵循bgles建议的第二部分,并将以下内容添加到/ etc / apache2 / envvars,并重新启动(不重新加载)Apache:
这将强制Apache默认将文件创建为664。就其本身而言,这可能带来安全风险。但是,在这里主要讨论的Laravel环境(Homestead,Vagrant,Ubuntu)中,Web服务器作为www-data组下的用户www-data运行。因此,如果您不随意允许用户加入www-data组,则不应存在其他风险。如果有人设法打破了网络服务器,他们无论如何都有www数据访问级别,所以没有任何东西丢失(虽然这不是与安全相关的最佳态度)。所以在生产上它是相对安全的,而在单用户开发机器上,它不是问题。
最终,当您的用户位于www-data组中,并且包含这些文件的所有目录都是g + s(该文件始终在父目录的组下创建),由用户或www-data创建的任何内容都将是r / w为另一个。
这就是我们的目标。
编辑
在调查上述进一步设置权限的方法时,它仍然看起来不错,但一些调整可以帮助:
默认情况下,目录为775,文件为664,所有文件都具有刚刚安装框架的用户的所有者和组。所以假设我们从那一点开始。
1 2 3
| cd /var/www /projectroot
sudo chmod 750 ./
sudo chgrp www -data ./ |
我们做的第一件事是阻止访问其他人,并使该组成为www数据。只有www-data的所有者和成员才能访问该目录。
1 2
| sudo chmod 2775 bootstrap /cache
sudo chgrp -R www -data bootstrap /cache |
允许web服务器创建services.json和compiled.php,如官方Laravel安装指南所示。设置组粘性位意味着这些将由创建者拥有一组www数据。
1 2 3
| 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等的链接,例如:
1 2 3
| chmod +x .git /hooks /*
rm vendor/*
composer install -o |
而已。除了上面解释的Apache的umask之外,这就是所需要的,而不需要通过www-data编写整个项目,这是其他解决方案所发生的情况。所以这种方式稍微安全一点,因为作为www-data运行的入侵者具有更有限的写访问权限。
结束编辑
Systemd的变化
这适用于php-fpm的使用,但也许也适用于其他人。
需要覆盖标准systemd服务,在override.conf文件中设置umask,并重新启动服务:
1 2 3 4 5 6 7
| sudo systemctl edit php7 .0 -fpm .service
Use:
[Service ]
UMask=0002
Then :
sudo systemctl daemon -reload
sudo systemctl restart php7 .0 -fpm .service |
好。
Add to composer.json
1 2 3 4 5 6
| "scripts": {
"post-install-cmd": [
"chgrp -R www-data storage bootstrap/cache",
"chmod -R ug+rwx storage bootstrap/cache"
]
} |
composer install之后
-
这是一个糟糕的答案。如果您正确配置了Web服务器,则永远不需要将777用于任何文件夹。使用777打开服务器,让任何黑客上传文件,并在知道文件夹存在的位置时执行该文件。
-
好的。你在提供什么?
-
如果是这样,它会是正确的吗? chown -R $ USER:www-data storage,chown -R $ USER:www-data bootstrap / cache
-
看到正确的答案,它包含您在更新后绝对可以放入的所有必要信息:)
-
是的,我没有看到。)谢谢
我在EC2实例上安装了laravel,花了3天时间来修复权限错误,最后修复了它。
所以我想与其他人分享这种体验。
用户问题
当我登录ec2实例时,我的用户名是ec2-user,usergroup是ec2-user。
该网站在httpd用户下工作:apache:apache
所以我们应该设置apache的权限。
文件夹和文件权限
A.文件夹结构
首先,你应该确保你在存储下有这样的文件夹结构
存储
-
骨架
-
日志
根据您使用的laravel版本,文件夹结构可能不同。
我的laravel版本是5.2,你可以根据你的版本找到合适的结构。
B.许可
首先,我看到在存储下设置777以删除file_put_contents的说明:无法打开流错误。
所以我将权限777设置为存储
chmod -R 777存储
但错误并未修复。
在这里,你应该考虑一个:谁将文件写入存储/会话和视图。
那不是ec2用户,而是apache。
是的,对。
"apache"用户将文件(会话文件,编译的视图文件)写入会话和视图文件夹。
所以你应该给apache写这些文件夹的权限。
默认情况下:SELinux说/ var / www文件夹应该是apache deamon的只读文件。
所以为此,我们可以将selinux设置为0:
setenforce 0
这可以暂时解决问题,但这使得mysql无法正常工作。
所以这不是那么好的解决方案。
您可以使用以下方法将读写上下文设置到存储文件夹:(记得使用setenforce 1进行测试)
1
| chcon -Rt httpd_sys_content_rw_t storage/ |
然后你的问题将得到解决。
不要忘记这一点
作曲家更新
php artisan cache:清楚
这些命令在之后或之前有用。
我希望你节省你的时间。
祝好运。克勤
-
您是否尝试从Web服务器调用命令行脚本?我有问题,因为它不打印任何输出
我决定编写自己的脚本来缓解设置项目的一些痛苦。
在项目根目录中运行以下命令:
1
| wget -qO- https://raw.githubusercontent.com/defaye/bootstrap-laravel/master/bootstrap.sh | sh |
等待自举完成,你很高兴。
使用前请查看脚本。
我有以下配置:
-
NGINX(运行用户:nginx)
-
PHP-FPM
正确的应用权限@bgies在接受的答案中建议。我的问题是php-fpm配置的运行用户和组,最初是apache。
如果你使用php-fpm的NGINX,你应该打开php-fpm的配置文件:
1
| nano /etc/php-fpm.d/www.config |
并将一个NGINX配置为使用以替换user和group选项的值;就我而言,两者都是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服务。
我发现了一个更好的解决方案。
它的原因是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
-
如果网页访问者设法突破网络服务器,他们现在将拥有"拥有目录的用户"的访问权限。如果该用户是www-data,那么他们可以做的损害有限,这就是apache作为有限用户运行的原因。如果该用户不是那么有限,他们可以造成更多伤害。如果该用户拥有sudo权限,他们可以造成更大的伤害。
-
这与apache的处理方式相同。顺便说一句,我现在像一个大男孩一样经营着nignx