wake-up-neo.com

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

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

324
Nic

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

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

匿名用户是您网站的访问者。尽管他们没有直接访问文件的权限,但是他们可以请求一个网页,并且Web服务器代表他们进行操作。您可以通过注意Web服务器进程具有的权限来限制匿名用户的访问。在许多Linux发行版中,Apache以www-data用户,但可以不同。采用 ps aux | grep httpd 要么 ps 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处的可执行文件)允许any用户以root身份运行any可执行文件。


定义要求

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

由一个用户维护

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

在您的情况下,夏娃(其用户名可能为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不在的目录中。对于包含机密的配置文件,这也是一种好方法。

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

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

347
Nic

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

我的方法如下:

  • 我创建了两个单独的用户。一个用于SSH/SFTP访问(如果需要),它将拥有所有文件,另一个用于PHP FastCGI用户(网站将以该用户身份运行))。我们分别称这些用户bobbob-www
  • bob将具有完整权限(文件夹上为rwx,文件上为rw-),以便他/她可以阅读和编辑整个网站。
  • PHP FastCGI进程需要r-x文件夹权限和r-文件权限,除了非常特定的文件夹,例如cache/ 要么 uploads/,还需要“写”权限。为了给PHP FastCGI)此功能,它将以bob-www运行,并且bob-www将添加到自动创建的- bob组。
  • 现在,我们确保所有目录和文件的所有者和组为bob bob
  • 缺少某些内容:即使我们使用FastCGI,但Apache仍需要对静态内容或.htaccess文件的读取访问权限,如果AllowOverride设置为None以外的其他内容,它将尝试读取。为了避免使用o部分权限,我将www-data用户添加到bob组中。

现在:

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

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

    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 {} \;

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

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

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

14
Fox

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

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

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

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

9
Paul

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

此命令将leo作为所有者,将组作为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
3
Krishan Gopal

我要使用以下配置:

  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
Manolo

IMO必须考虑:

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

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

“测试”用户具有:

  • 他在_$HOMEDIR_中的数据
  • 他在_$MAIL_中的邮件
  • 他在_/var/www/test_中用于网络的数据

现在让我们考虑一下:

  • 一个Web应用程序在test用户(PHP-FPM)下运行-它可以删除他的任何文件!
  • 一个Web应用程序在test组(PHP-FPM)下运行-它可以删除他的目录中带有“ 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。我强烈建议在具有_noexec,nodev,nosuid_ upload选项的文件系统上使用mount目录,并对该目录中的任何新bizzare文件进行持续监视,并且还要监视_test-www_ uid。

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

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

1
Jiri B