这是一个有关Linux Web服务器上文件权限的规范问题。


我有一个运行Apache2的Linux Web服务器,该服务器承载多个网站。每个网站在/ var / www /中都有自己的文件夹。

/var/www/contoso.com/
/var/www/contoso.net/
/var/www/fabrikam.com/


基本目录/ var / www /由root:root拥有。 Apache作为www-data:www-data运行。 Fabrikam网站由两个开发人员Alice和Bob维护。这两个Contoso网站均由一名开发人员Eve维护。所有网站都允许用户上传图像。如果网站遭到入侵,则影响应尽可能有限。

我想知道设置权限的最佳方法,以便Apache可以提供内容,防止网站受到攻击以及开发人员仍然可以进行更改。其中一个网站的结构如下:

/var/www/fabrikam.com
    /cache
    /modules
    /styles
    /uploads
    /index.php


应如何在这些目录和文件上设置权限?我读过某个地方,您永远不应在网站上使用777权限,但我不明白这可能会导致什么问题。在繁忙时段,网站会自动缓存某些页面并将结果存储在缓存文件夹中。网站访问者提交的所有内容都保存到上载文件夹中。

评论

这旨在作为对有关网站权限的所有问题的规范答案。

“我读过某个地方,您永远不应该在网站上使用777权限,但我不理解...”-那么读者是否可以理解或至少能够在这里比较答案的优劣?任何解决方案都应基于特定要求-这里的要求还不够具体(什么是威胁模型)

我喜欢您问的是Apache,但使用的是Microsoft通常用作示例的域。

另请参阅/ var / www中为apache2的用户www-data处理权限的最佳方法是什么?

您可以在此处参考有关linuxserverfault.com/questions/124800/…中网站文件和文件夹所需要的权限的完整详细信息。

#1 楼

在决定使用什么权限时,您需要确切地知道您的用户是谁,以及他们需要什么。 Web服务器与两种类型的用户进行交互。

经过身份验证的用户在服务器上具有用户帐户,并且可以被赋予特定的特权。这通常包括系统管理员,开发人员和服务帐户。他们通常使用SSH或SFTP对系统进行更改。

匿名用户是您网站的访问者。尽管他们没有直接访问文件的权限,但是他们可以请求一个网页,并且Web服务器代表他们进行操作。您可以通过注意Web服务器进程具有的权限来限制匿名用户的访问。在许多Linux发行版中,Apache以www-data用户身份运行,但可以有所不同。使用ps aux | grep httpdps aux | grep apache查看Apache在系统上使用的用户。


关于Linux权限的说明

Linux和其他与POSIX兼容的系统使用传统的unix权限。 Wikipedia上有一篇关于文件系统权限的出色文章,因此在此我将不再赘述。但是您应该注意一些事情。

执行位
没有执行权限的情况下解释的脚本(例如Ruby,PHP)也可以正常工作。只有二​​进制文件和Shell脚本需要执行位。为了遍历(输入)目录,您需要对该目录具有执行权限。网络服务器需要此权限才能列出目录或在其中提供任何文件。但是有时您希望新文件继承创建它们的文件夹的组ID,因此您将在父文件夹上启用SGID位。

默认权限值取决于您的umask。 umask会从新创建的文件中减去权限,因此022的通用值会导致使用755创建文件。与组协作时,将umask更改为002很有用,这样您创建的文件可以由组成员修改。而且,如果您要自定义上传文件的权限,则需要更改apache的umask或在文件上传后运行chmod。


777的问题

当您访问网站时,便没有任何安全保障。系统上的任何用户都可以更改或删除您网站中的任何文件。但更重要的是,请记住,Web服务器代表您网站的访问者,现在,Web服务器可以更改正在执行的文件。如果您的网站中存在任何编程漏洞,它们可能会被利用来破坏您的网站,进行网络钓鱼攻击或在您不知情的情况下从服务器中窃取信息。

另外,如果您的服务器运行在众所周知的端口(该端口应防止非root用户生成世界可访问的侦听服务),这意味着您的服务器必须由root启动(尽管任何理智的服务器将在以下情况下立即转为特权较低的帐户:端口已绑定)。换句话说,如果您正在运行一个Web服务器,其中主要可执行文件是版本控制的一部分(例如CGI应用程序),则保留其权限(或就此而言,包含目录的权限,因为用户可以重命名)可执行文件)在777处允许任何用户以root用户身份运行任何可执行文件。


定义需求


开发人员需要对文件的读/写访问权限这样他们就可以更新网站
开发人员需要对目录进行读/写/执行,以便可以浏览
Apache需要对文件和解释脚本的读访问权限
Apache需要对可服务目录的读/执行访问权限
Apache需要对上载内容的目录具有读/写/执行访问权限


由单个用户维护

如果只有一个用户负责维护站点,请设置他们作为网站目录上的用户所有者,并向用户授予完整的rwx权限。 Apache仍然需要访问权限以便它可以提供文件,因此将www-data设置为组所有者并授予组rx权限。在您的情况下,用户名可能为chmod 777的Eve是只有维护eve的用户:

chown -R eve contoso.com/
chgrp -R www-data contoso.com/
chmod -R 750 contoso.com/
chmod g+s contoso.com/
ls -l
drwxr-s--- 2 eve      www-data   4096 Feb  5 22:52 contoso.com


如果您有需要Apache写入的文件夹,则可以修改组所有者的权限值,以便www-数据具有写权限。用户和组所有者可以浏览您的网站目录。如果配置文件中包含机密数据,这将很有用。注意您的蒙版!如果在此处创建新文件,则权限值可能默认为755。您可以运行contoso.com,以便新文件的默认值为640(umask 027)。

如果有多个用户负责维护站点,则需要创建一个组来分配权限。优良作法是为每个网站创建一个单独的组,然后以该网站命名该组。

chmod g+w uploads
ls -l
drwxrws--- 2 eve      www-data   4096 Feb  5 22:52 uploads


在前面的示例中,我们使用组所有者授予特权到Apache,但现在用于开发人员组。由于用户所有者不再对我们有用,因此将其设置为root是确保没有特权泄漏的简单方法。 Apache仍然需要访问权限,因此我们授予对世界其他地方的读取访问权限。

groupadd dev-fabrikam
usermod -a -G dev-fabrikam alice
usermod -a -G dev-fabrikam bob


如果您有需要Apache写入的文件夹,则可以将Apache设置为用户所有者或组所有者。无论哪种方式,它都将具有所需的所有访问权限。就个人而言,我更希望成为用户所有者,以便开发人员仍可以浏览和修改上传文件夹的内容。

是一个缺点。由于系统上的所有其他用户都具有与Apache相同的网站特权,因此其他用户可以轻松浏览您的站点并读取可能包含机密数据的文件,例如配置文件。

您也可以吃蛋糕也可以食用

还可以进一步改善。拥有者拥有比组少的特权是完全合法的,因此,与其通过将用户分配给root来浪费用户拥有者,我们还可以使Apache成为您网站中目录和文件上的用户拥有者。这是单个维护程序方案的逆转,但效果同样好。

chown -R root fabrikam.com
chgrp -R dev-fabrikam fabrikam.com
chmod -R 775 fabrikam.com
chmod g+s fabrikam.com
ls -l
drwxrwxr-x 2 root     dev-fabrikam   4096 Feb  5 22:52 fabrikam.com


如果您有需要Apache写入的文件夹,则只需修改用户所有者的权限值,以便www-data具有写访问权限。匹配创建者,而不是设置为www-data。因此,您创建的任何新文件都必须经过chown后才能被Apache读取。无论您使用哪种特权,其他用户都可以窥探您的网站。默认情况下,所有Apache进程都以同一www-data用户身份运行,因此任何Apache进程都可以从同一服务器上配置的所有其他网站读取文件,有时甚至可以进行更改。任何可以让Apache运行脚本的用户都可以获得与Apache本身相同的访问权限。

为了解决这个问题,Apache中有多种方法来进行权限分离。但是,每种方法都具有各种性能和安全性缺点。我认为,任何对安全性有更高要求的站点都应在专用服务器上运行,而不是在共享服务器上使用VirtualHosts。


其他注意事项

我没有之前没有提及,但是让开发人员直接编辑网站通常是一个坏习惯。对于较大的站点,最好使用某种版本的发布系统从版本控制系统的内容更新Web服务器。单一维护者方法可能是理想的选择,但是您不需要自动化的软件,而不必花一个人。根。否则,您可能会发现人们正在下载旨在保密的文件。例如,如果允许学生提交作业,则应将其保存到Apache不在的目录中。对于包含机密的配置文件,这也是一种好方法。

对于具有更复杂要求的网站,您可能需要研究访问控制列表的使用。这些使对特权的控制更加复杂。

如果您的网站有复杂的要求,则可能需要编写一个脚本来设置所有权限。对其进行彻底测试,然后确保其安全。如果您出于某种原因需要重建网站,那么用它来算是黄金吧。

评论


“ chmod -R 775 fabrikam.com”。大多数网站中的文件很少可以执行。例如,PHP脚本可以是0640,只要Web服务器可以读取它们即可。 chmod -R a + X fabrikam.com将仅对目录授予所有人可执行权限。

–user130370
2012年8月18日在20:47

请注意,Apache在Red Hat衍生系统上以用户apache的身份运行。

–迈克尔·汉普顿
2012年11月18日,下午3:55

这个答案虽然全面,但仅涉及DAC权限。我认为还应该考虑MAC权限。

–dawud
2013年5月1日23:00

这是一个很棒的帖子。这是我的贡献:将www-data用作所有者,将dev-fabrikam用作组的不利之处(如您所言,也可以食用)也适用于(相反)单个用户维护中提供的方案。情况下,每当Apache创建文件夹或文件时,用户将无权访问该文件或文件夹,因此需要将文件重新锁定给原始用户。我没有更新答案,因为我不确定自己的陈述是否100%我希望其他人在修补答案之前先进行确认。

–user181503
13年7月14日在0:43

@PatrickM-实际上,我不同意上个月的评论。 eve不必位于www-data中才能编辑文件,但是如果您希望eve能够编辑由Apache创建的文件,例如eve一定要位于www-data中。上传。

–张德祥
2014年5月20日在18:14

#2 楼

我想知道为什么有这么多人使用(或推荐)Linux权限的“其他”(o)部分来控制可以做什么的Apache(和/或PHP)。通过将此正确的部分设置为除“ 0”之外的其他内容,您只允许整个世界在文件/目录上执行某些操作。

我的方法是:


我创建了两个分开的用户。一个用于SSH / SFTP访问(如果需要),它将拥有所有文件,另一个用于PHP FastCGI用户(网站将以该用户身份运行)。让我们分别将这些用户称为bob和bob-www。 /> PHP FastCGI进程需要对文件夹具有rx权限,对文件具有r--权限,除了非常特殊的文件夹(例如cache/uploads/)之外,这些文件夹也需要“写”权限。为了使PHP FastCGI具备此功能,它将以bob-www的身份运行,并将bob-www添加到自动创建的bob组中。
我们现在确保所有目录和文件的所有者和组均为bob bob。
缺少什么:即使我们使用FastCGI,但Apache仍需要对静态内容或.htaccess文件的读取访问权,如果AllowOverride设置为None以外的其他内容,它将尝试读取。为避免使用权利的O部,我将www-data用户添加到bob组中。

现在:


要控制开发人员可以执行的操作可以,我们可以使用权利的u部分(但这是下面的注释)。
要控制Apache和PHP可以做什么,我们可以使用权利的g部分。
o part始终设置为0,因此服务器上的其他任何人都无法读取或编辑网站。
bob用户创建新文件时没有问题,因为它将自动属于其主要组(bob)。

回顾一下,但是在这种情况下,bob被允许使用SSH。如果不应该允许任何用户修改网站(例如,客户仅通过CMS管理面板修改网站,并且不具备Linux知识),则无论如何都要创建两个用户,但也请给/bin/false作为bob的外壳,并禁用其登录。

    adduser --home /var/www/bobwebsite --shell /bin/bash bob
    adduser --no-create-home --shell /bin/false --disabled-login --ingroup bob bob-www
    adduser www-data bob
    cd /var/www/bobwebsite
    chown -R bob:bob .
    find -type d -exec chmod 750 {} \;
    find -type f -exec chmod 640 {} \;


注意:人们倾向于忘记限制u(所有者)权限在大多数情况下是无用和不安全的,因为a的所有者该文件可以运行chmod命令,即使权限是000。

如果我的方法存在一些安全问题,请告诉我,因为我不确定100%,但这是我正在使用的。 br />
我认为此配置有问题:当PHP / Apache创建新文件(例如上载)时,它将属于bob-www:bob,而bob将只能读取它。也许目录上的setuid可以解决问题。

评论


Linux会忽略setuid。新文件始终归创建者所有。

– Paul
13年8月20日在2:35

我什么都不懂当更多的开发人员同时在网站上工作时,似乎并没有合并这种情况,因为唯一的用户就是bob。你怎么处理那件事呢?例如。通过ssh,两个用户都以bob身份登录。鲍勃(1)感到他/她不记得密码,而是将其更改为另一个密码,但仍然安全。鲍勃(2)尝试下次登录,但他/她无法登录。

–n611x007
13-10-23在7:50



@naxa任何微不足道的系统都不应让任何开发人员直接修改网站。理想情况下,网站受版本控制,以便用户帐户“ bob”自动提取并部署每个(稳定的)发行版。因此,开发人员可以在异地进行开发,并将更改推送到部署服务器后即可进行部署。 “ bob”是系统用户,应该具有非常有限的网络权限,其中不包括远程登录; iptables实际上允许您通过UID过滤类似这样的内容。

–Parthian Shot
2014年7月15日在3:16



“我想知道为什么这么多人使用(或推荐)“其他”(o)部分?那么也许您应该将其发布为问题而不是答案。故意以最低的特权级别运行网络服务器(作为系统中最容易暴露的部分),而支持,开发和管理员帐户也需要不同的访问权限

–symcbean
18年1月24日在23:59

@ParthianShot您不能将其强制给第三方(当该站点不是由您维护,而是该文件夹存在于您的服务器中时)。有时,他们唯一知道的操作是使用ftp。

– Peregring-lk
19 Mar 23 '19 at 20:03

#3 楼

鉴于google在上述最佳答案上的排名,我认为应该注意一件事,并且我似乎无法在答案后留下注释。

继续示例,如果您如果计划使用www-data作为所有者,并将dev-fabrikam作为组使用对目录(或文件)具有570个权限,则需要注意的是Linux会忽略setuid,因此所有新文件将由创建它们的用户拥有。这意味着在创建新目录和文件后,您将必须使用类似于以下内容的东西:

chown -R www-data /newdirectory/
chmod -R 570 /newdirectory/


在用于Rackspace OpenStack的Ubuntu 12.04中,我遇到了一个奇怪的问题:在重新启动服务器之前,没有获得权限570才能工作,这神奇地解决了该问题。在这个看似简单的问题上,脱发的速度越来越快....

评论


请对此进行谷歌搜索:在Raspbian(也称为树莓派)中,如果您想在lighttpd(或其他网络浏览器)下更改/ var / www的所有权,则必须重新启动。

–gbronner
2015年1月9日23:30

@gbronner如果这是很难找到解决方案的问题,则可以考虑将其发布为问题并提供问题的答案。但是,在其他SE Q&A网站中可能更合适。我的猜测是Unix和Linux可能是这样做的好地方。

– Paul
2015年1月9日在23:44



还有raspberrypi.stackexchange.com; SE网站似乎使知识有些分散。

–gbronner
2015年1月10日,0:05

@gbronner哈哈。我不知道那一个! U&L上的Raspbian标签有120个问题。

– Paul
2015年1月10日,0:06

#4 楼

我要使用以下配置:


除上载到所有者root和组root的所有目录外,所有目录都具有对0755的权限。
所有文件都设置为所有者root和组root的权限到0644
上载设置为所有者root的目录,组www-data和对1770的权限。粘性位不允许组所有者删除或重命名其中的目录和文件。
内部将文件夹www-data的所有者用户和组上载到新目录,并为每个上传文件的0700用户赋予www-data权限。 > Apache配置:

在上载目录中拒绝AllowOverrideIndex,以便Apache不读取.htaccess文件,并且Apache用户无法索引上载文件夹的内容:

<Directory /siteDir>
   Options -Indexes
</Directory>

<Directory /siteDir/uploadDir>
   AllowOverride none
</Directory>


6。 php.ini配置:

open_basedir = /siteDir:/tmp:/usr/share/phpmyadmin
post_max_size = 5M
file_uploads = On
upload_max_filesize = 3M
max_file_uploads = 20


使用此配置,www-data用户将无法进入siteDir//tmp/usr/share/phpmyadmin以外的目录。您还可以控制最大文件大小,最大帖子大小和要在同一请求中上传的最大文件。

#5 楼

如果您有一个名为“ leo”的FTP用户,则需要将文件上传到example.com网站目录,并且还需要您的“ apache”用户能够在缓存目录中创建uploa-files / sessions / cache文件,然后执行以下操作:

此命令将leo作为所有者,将group分配为example.com的apache,apache用户是group apache的一部分,因此它将继承apache group的权限。 /> chown -R leo:apache example.com


另一条确保权限许可并满足安全性要求的命令。


chmod- R 2774 example.com


这里的第一个数字2用于目录,并确保创建的每个新文件将保留在相同的组和所有者权限中。 77用于所有者和组,意味着他们具有完全访问权限。 4对其他人来说意味着他们只能阅读低谷。

下面的内容有助于理解权限编号

Number  Octal Permission Representation
0   No permission
1   Execute permission
2   Write permission
3   Execute and write permission: 1 (execute) + 2 (write) = 3
4   Read permission
5   Read and execute permission: 4 (read) + 1 (execute) = 5
6   Read and write permission: 4 (read) + 2 (write) = 6
7   All permissions: 4 (read) + 2 (write) + 1 (execute) = 7


#6 楼

IMO必须考虑:


您相信读取文件的过程吗?例如。 PHP?

假设您有一台服务器,该服务器下的用户“ test”下有各种数据。 br />他在$HOMEDIR中的数据

他在$MAIL中的邮件

他在/var/www/test中的网络数据


现在让我们考虑一下:


test用户(PHP-FPM)下运行的Web应用程序-它可以删除其任何文件!
test组(PHP-FPM)下运行的Web应用程序-它可以删除他的任何目录,其中该目录的目录为“ w”,并且可以修改该目录的所有文件为“ r”;并且它仍然可以读取它们-例如您的ssh密钥!

假设PHP有错误,是的,您相信它的open_basedir吗? chroot您的PHP程序吗?您不知道什么,是否希望它确实可以爬网所有文件系统?

您的Web应用程序流程,例如。 PHP-FPM,则应:


通过chroot限制为特定路径

不应在数据所有者的主要用户或主要组权限下运行

因此,您可以执行以下操作:


测试用户是:test:test

测试用户位于辅助组中,例如。 test-www

一个web应用程序(PHP-FPM)在test-www:test-www下运行

如果用户希望该Web应用程序可以读取其文件,则测试用户可以:
chmod u=rwX,g=rX,o= /var/www/test/public

测试用户是否希望Web应用程序可以将其写入Web数据路径: www组,因为目录上有setgid!)

因此,如果Web应用程序进程是虚假的,它将仅读取具有组读取功能的特定文件,并且仅能够写入chmod u=rwX,g=rwXs,o= /var/www/test/public/upload目录。我强烈建议在具有test-www:test-www upload选项的文件系统上使用upload目录,并对该目录中的任何新bizzare文件进行持续监视,并且还要监视noexec,nodev,nosuid uid下的任何新进程。

在Linux上可以使用ACL更好地调整权限。如果要由多个人上载Web数据,最好将人的帐户与用于上载Web数据文件的帐户分开。创建新帐户,例如mount,测试用户将管理ssh密钥,以限制哪些人可以在那里ssh / sftp。 test-www知道test-upload选项,因此可以配置它记录使用哪个ssh密钥上传数据。你明白了,我会说他们说谎。

评论


php-fpm允许为池设置chroot和user,group。但我不相信php_admin_value [open_basedir]选项。我还读到最好每个用户有一个单独的PHP-FPM主服务器,请参阅ma.ttias.be/a-better-way-to-run-php-fpm在大多数Linux和* BSD发行版中都可以轻松实例化守护程序。

–吉里B
19年2月17日在17:40