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

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

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

答案1

在决定使用什么权限时,您需要确切了解您的用户是谁以及他们需要什么。网络服务器与两种类型的用户交互。

已认证用户在服务器上拥有用户账户,并可获得特定权限。这通常包括系统管理员、开发人员和服务账户。他们通常使用 SSH 或 SFTP 对系统进行更改。

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


Linux 权限注意事项

Linux 和其他符合 POSIX 标准的系统使用传统的 unix 权限。维基百科上有一篇关于文件系统权限所以我不会在这里重复所有内容。但有几件事你应该注意。

执行位
解释型脚本(例如 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,其用户名可能是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

这种配置的好处是,系统上的其他用户更难(但并非不可能*)窥探,因为只有用户和组所有者才能浏览您的网站目录。如果您的配置文件中有秘密数据,这将非常有用。请小心您的 umask!如果您在此处创建新文件,权限值可能默认为 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
drwxrwsr-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。因此,您创建的任何新文件都将无法被 Apache 读取,除非您对其进行 chown。


Apache 权限分离

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

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


其他注意事项

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

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

对于要求更复杂的网站,您可能需要考虑使用访问控制列表. 这些使得权限控制变得更加复杂。

如果您的网站有复杂的要求,您可能需要编写一个脚本来设置所有权限。彻底测试它,然后妥善保管。如果您出于某种原因发现自己需要重建网站,那么它可能非常有价值。

答案2

我想知道为什么这么多人使用(或推荐)Linux 权限的“其他”(o)部分来控制 Apache(和/或 PHP)可以做什么。通过将此右侧部分设置为“0”以外的其他值,您就允许全世界对文件/目录执行某些操作。

我的方法如下:

  • 我创建了两个独立的用户。一个用于 SSH/SFTP 访问(如果需要),它将拥有所有文件,另一个用于 PHP FastCGI 用户(网站将以该用户身份运行)。我们分别称这些用户为鲍勃bob-www
  • 鲍勃将享有充分的权利(读写在文件夹上,rw-拥有对文件进行编辑的权限后,他/她便可以阅读和编辑整个网站。
  • PHP FastCGI 进程需要接收文件夹权限和r--文件的权限,除了非常特殊的文件夹(如cache/或 )uploads/,这些文件夹也需要“写入”权限。要赋予 PHP FastCGI 此功能,它将作为bob-www, 和bob-www将被添加到自动创建的鲍勃团体。
  • 我们现在确保所有目录和文件的所有者和组都是鲍勃鲍勃
  • AllowOverride缺少了一些东西:即使我们使用 FastCGI,但 Apache 仍然需要读取权限,对于静态内容或 .htaccess 文件,如果设置为 以外的值,它将尝试读取这些文件None。为了避免使用o部分权利,我补充www-数据用户鲍勃团体。

现在:

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

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

    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, 和鲍勃只能读取它。也许在目录上设置 setuid 可以解决这个问题。

答案3

考虑到上述优秀答案的谷歌排名,我认为有一件事应该注意,而且我似乎无法在答案后留下注释。

继续这个例子,如果你打算使用 www-data 作为所有者,使用 dev-fabrikam 作为组,对目录(或文件)拥有 570 个权限,那么需要注意的是Linux 忽略 setuid在目录中,因此所有新文件将归创建它们的用户所有。这意味着在创建新目录和文件后,您必须使用类似于以下内容的内容:

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

在适用于 Rackspace OpenStack 的 Ubuntu 12.04 中,我遇到了一个奇怪的问题,我无法让权限 570 工作,直到我重新启动服务器,这才奇迹般地解决了这个问题。因为这个看似简单的问题,我的头发掉得越来越快……

答案4

我使用这个配置:

  1. 除上传之外的所有目录都设置为所有者root和组root,权限为0755
  2. 所有文件设置为所有者root和组root,权限为0644
  3. 将目录设置为 所有者root、 组www-data,权限为1770。粘性位不允许组所有者删除或重命名目录和其中的文件。
  4. 在上传文件夹内有一个新目录,其中包含www-data所有者用户和组,以及每个上传文件的用户0700的权限。www-data
  5. Apache 配置:

拒绝AllowOverrideIndexuploads 目录中,这样 Apache 就不会读取.htaccess文件,Apache 用户也无法索引 uploads 文件夹的内容:

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

<Directory /siteDir/uploadDir>
   AllowOverride none
</Directory>
  1. 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您还可以控制最大文件大小、最大帖子大小以及同一请求中要上传的最大文件数。

相关内容