我的网站文件/文件夹在Linux Web服务器上应具有什么权限?


309

这是关于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权限,但我不明白这可能会导致什么问题。在繁忙时段,网站会自动缓存某些页面并将结果存储在缓存文件夹中。网站访问者提交的所有内容均保存到上载文件夹中。


6
这旨在对我们获得的有关网站权限的所有问题做出规范回答。
Nic 2012年

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

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


你可以参考这里了解更多有关权限的完整信息所需在Linux中被放在网站的文件和文件夹serverfault.com/questions/124800/...

Answers:


342

在决定使用什么权限时,您需要确切地知道您的用户是谁以及他们需要什么。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脚本需要执行位。为了遍历(输入)目录,您需要对该目录具有执行权限。Web服务器需要此权限才能列出目录或在其中提供任何文件。

默认的新文件权限
创建文件后,通常会继承创建该文件的人的组ID。但是有时您希望新文件继承创建它们的文件夹的组ID,因此您将在父文件夹上启用SGID位。

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


777的问题

chmod 777您访问网站时,就没有任何安全性。系统上的任何用户都可以更改或删除您网站中的任何文件。但更重要的是,请记住,Web服务器代表您网站的访问者行事,现在,Web服务器可以更改正在执行的文件。如果您的网站中存在任何编程漏洞,它们可能会被利用来破坏您的网站,插入网络钓鱼攻击或从服务器中窃取信息,而您却一无所知。

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


定义要求

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

由一个用户维护

如果只有一个用户负责维护站点,请将其设置为网站目录上的用户所有者,并为该用户提供完全的rwx权限。Apache仍然需要访问权限,以便它可以提供文件,因此将www-data设置为组所有者,并授予组rx权限。

在您的情况下,夏娃(其用户名可能为eve)是唯一维护contoso.com以下内容的用户:

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-data具有写访问权限。

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

这种配置的好处是,系统上的其他用户很难窥探(但并非不可能*),因为只有用户和组所有者才能浏览您的网站目录。如果配置文件中包含机密数据,这将很有用。注意您的蒙版!如果您在此处创建新文件,则权限值可能默认为755。您可以运行umask 027以使新文件的默认值为640(rw- r-- ---)。


由一组用户维护

如果负责维护站点的用户不止一个,则需要创建一个组来分配权限。最好为每个网站创建一个单独的组,并以该网站命名。

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

在前面的示例中,我们使用组所有者为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写入的文件夹,则可以将Apache设置为用户所有者或组所有者。无论哪种方式,它都将具有所需的所有访问权限。就个人而言,我更希望使其成为用户所有者,以便开发人员仍可以浏览和修改上传文件夹的内容。

chown -R www-data uploads
ls -l
drwxrwxr-x 2 www-data     dev-fabrikam   4096 Feb  5 22:52 uploads

尽管这是一种常见的方法,但也有一个缺点。由于系统上的所有其他用户都对您的网站具有与Apache相同的特权,因此其他用户很容易浏览您的站点并读取可能包含机密数据的文件,例如配置文件。

你也可以吃蛋糕

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

chown -R www-data fabrikam.com
chgrp -R dev-fabrikam fabrikam.com
chmod -R 570 fabrikam.com
chmod g+s fabrikam.com
ls -l
dr-xrwx--- 2 www-data  dev-fabrikam   4096 Feb  5 22:52 fabrikam.com

如果您有需要Apache写入的文件夹,则可以只修改用户所有者的权限值,以便www-data具有写访问权限。

chmod u+w uploads
ls -l
drwxrwx--- 2 www-data  dev-fabrikam   4096 Feb  5 22:52 fabrikam.com

此解决方案要注意的一件事是,新文件的用户所有者将与创建者匹配,而不是被设置为www-data。因此,您创建的任何新文件在被chown之前都不会被Apache读取。


* Apache权限分离

前面我提到过,无论您使用哪种特权,其他用户实际上都有可能窥探您的网站。默认情况下,所有Apache进程都以同一www-data用户身份运行,因此任何Apache进程都可以从同一服务器上配置的所有其他网站读取文件,有时甚至可以进行更改。任何可以使Apache运行脚本的用户都可以获得与Apache本身相同的访问权限。

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


其他注意事项

我之前没有提到过,但是让开发人员直接编辑网站通常是一个不好的做法。对于较大的站点,最好使用某种版本的发布系统从版本控制系统的内容更新Web服务器。单一维护者方法可能是理想的选择,但是您没有人,而是拥有自动化软件。

如果您的网站允许上传不需要上传的内容,则这些上传内容应存储在网络根目录之外的某个位置。否则,您可能会发现人们正在下载旨在保密的文件。例如,如果您允许学生提交作业,则应将其保存到Apache不在的目录中。对于包含机密的配置文件,这也是一种好方法。

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

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


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

7
请注意,Apache apache在Red Hat派生系统上以用户身份运行。
迈克尔·汉普顿

这非常好,但是我不了解一件事:如果文件已经具有文件组所有权,则我不了解使apache为文件目录的用户/所有者的策略的目标或优势。
idiotprogrammer

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

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

14

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

我的方法如下:

  • 我创建了两个单独的用户。一个用于SSH / SFTP访问(如果需要),它将拥有所有文件,另一个用于PHP FastCGI用户(网站将以该用户身份运行)。让我们分别将这些用户称为bobbob-www
  • 鲍勃拥有全部权利(文件夹上为rwx,文件上为rw-),因此他/她可以阅读和编辑整个网站。
  • 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部分。
  • Ø部分总是被设置为0,所以没有其他人在服务器上可以读取或编辑该网站。
  • bob用户创建新文件时没有问题,因为它将自动属于其主要组(bob)。

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

    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(所有者)权限在大多数情况下是无用且不安全的,因为文件的所有者可以运行chmod命令,即使权限为000。

告诉我我的方法是否存在一些安全问题,因为我不确定100%,但这是我正在使用的方法。

我认为此配置有一个问题:当PHP / Apache创建一个新文件(例如,上载)时,它将属于bob-www:bob,而bob将只能读取它。也许目录中的setuid可以解决问题。


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

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

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

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

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

9

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

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

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

在用于Rackspace OpenStack的Ubuntu 12.04中,我遇到了一个奇怪的问题:在重新启动服务器之前,我无法获得权限570才能工作,这神奇地解决了该问题。在看似简单的问题上,脱发的比率正在增加。


请让这个被Google搜索:在Raspbian(又名上树莓派,如果你想改变下的lighttpd的/ var / WWW的所有权(或其他Web浏览器),你必须重新启动
gbronner

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

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

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

3

我要使用以下配置:

  1. 除了上载以外,所有目录都将一组上载到所有者root和组root,将上载到0755
  2. 所有文件均设置为所有者root和组root,权限为0644
  3. 将目录上载设置为所有者root,组www-data,权限1770。粘性位不允许组所有者删除或重命名其中的目录和文件。
  4. 在上载文件夹中,新目录包含www-data所有者用户和组,以及0700每个www-data上载文件的用户的权限。
  5. 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。您还可以控制最大文件大小,最大帖子大小和要在同一请求中上传的最大文件。


3

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

此命令将leo分配为example.com的所有者,并将组作为apache分配给example.com,apache用户是apache组的一部分,因此它将继承apache组的权限

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

1

IMO必须考虑:

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

假设您有一台服务器,它在用户“ test”下处理各种数据。

“测试”用户在那里:

  • 他的数据在 $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数据路径:( chmod u=rwX,g=rwXs,o= /var/www/test/public/upload 因此该应用程序将创建新文件的方式如下:test-www:test-www-由于目录上存在setgid,因此它将具有test-www组!)

因此,如果Web应用程序进程是虚假的,它将只读取可以进行组读取的特定文件,并且upload只能写入dir。我强烈建议在具有选项upload的文件系统上使用noexec,nodev,nosuid mount该目录,并对该目录中的任何新bizzare文件进行持续监视,并且还要监视test-wwwuid 下的任何新进程。

在Linux上,可以使用ACL更好地调整权限。如果要由多个人上载Web数据,最好将人的帐户与用于上载Web数据文件的帐户分开,即。创建新帐户,例如 test-upload,而测试用户将管理ssh密钥,以限制哪些人可以在那里进行ssh / sftp。sshd_config知道ExposeAuthInfo选项,因此可以配置为记录使用哪个ssh密钥上传数据。

我真的怀疑大多数网站托管服务是否关心特权分离,当它们在没有任何信息的情况下写“安全”信息时,我会说它们在说谎。


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