这是关于Linux Web服务器上文件权限的规范性问题 。
我有一个运行Apache2的Linuxnetworking服务器,它承载了几个网站。 每个网站在/ var / www /中都有自己的文件夹。
/var/www/contoso.com/ /var/www/contoso.net/ /var/www/fabrikam.com/
基本目录/ var / www /由root:root拥有。 Apache正在以www-data:www-data的forms运行。 Fabrikam网站由两个开发人员Alice和Bob维护。 两个Contoso网站都由一个开发人员Eve维护。 所有的网站都允许用户上传图片。 如果一个网站受到攻击,其影响应尽可能有限。
我想知道设置权限的最佳方法,以便Apache可以提供内容,网站可以免受攻击,开发人员仍然可以进行更改。 其中一个网站的结构是这样的:
/var/www/fabrikam.com /cache /modules /styles /uploads /index.php
应该如何在这些目录和文件上设置权限? 我读了一个地方,你永远不应该在网站上使用777权限,但我不明白可能会导致什么问题。 在繁忙时段,网站会自动caching一些页面,并将结果存储在caching文件夹中。 网站访问者提交的所有内容都保存到上传文件夹中。
在决定使用什么样的权限时,您需要确切知道您的用户是谁以及他们需要什么。 networking服务器与两种types的用户进行交互。
经过身份validation的用户在服务器上有一个用户帐户,可以提供特定的权限。 这通常包括系统pipe理员,开发人员和服务帐户。 他们通常使用SSH或SFTP对系统进行更改。
匿名用户是您网站的访问者。 虽然他们没有直接访问文件的权限,但他们可以请求一个网页,而Web服务器代表他们的行为。 您可以通过小心Web服务器进程的权限来限制匿名用户的访问。 在许多Linux发行版中,Apache以www-data
用户身份运行,但可能不同。 使用ps aux | grep httpd
ps aux | grep httpd
或ps aux | grep apache
ps aux | grep apache
来查看Apache在系统上使用的用户。
Linux和其他符合POSIX的系统使用传统的Unix权限。 Wikipedia上有一篇关于文件系统权限的优秀文章,所以我不会在这里重复一遍。 但有几件事情你应该知道。
执行位
解释脚本(如Ruby,PHP)没有执行权限就可以正常工作。 只有二进制文件和shell脚本需要执行位。 为了遍历(input)目录,您需要在该目录上具有执行权限。 Web服务器需要此权限才能列出目录或提供其中的任何文件。
默认的新文件权限
创build文件时,通常会inheritance创build文件的组标识。 但是有时候你需要新的文件来inheritance创build它们的文件夹的组ID,所以你需要启用父文件夹的SGID位。
默认权限值取决于你的umask。 umask从新创build的文件中减去权限,所以共同的值为022会导致文件被创build为755.当与一个组合作时,将你的umask改为002是有用的,这样你创build的文件就可以被组成员修改了。 如果你想自定义上传文件的权限,你可能需要更改apache的umask,或者在file upload后运行chmod。
当你chmod 777
你的网站,你没有任何安全。 系统中的任何用户都可以更改或删除网站中的任何文件。 但更重要的是,请记住,Web服务器代表您的网站的访问者,现在Web服务器能够更改它正在执行的相同文件。 如果您的网站存在任何编程漏洞,则可能会利用这些漏洞来污染您的网站,插入钓鱼攻击或从您的服务器上窃取信息而无需知道。
另外,如果你的服务器运行在一个众所周知的端口上 (它应该防止非root用户产生世界可访问的监听服务),这意味着你的服务器必须由root启动(尽pipe任何理智的服务器会立即丢弃一旦端口被绑定,将其转移到权限较低的账户)。 换句话说,如果您正在运行主要可执行文件是版本控制(例如,CGI应用程序)的一部分的networking服务器,则将其权限(或者对于包含的目录的权限)保留,因为用户可以重命名可执行文件)在777允许任何用户以root身份运行任何可执行文件。
如果只有一个用户负责维护站点,请将其设置为网站目录中的用户所有者,并为用户提供完整的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
这种configuration的好处是,对于系统上的其他用户来说,变得越来越困难(但不是不可能*),因为只有用户和组的所有者才能浏览你的网站目录。 如果您的configuration文件中有秘密数据,这非常有用。 小心你的umask! 如果你在这里创build一个新文件,权限值可能会默认为755.你可以运行umask 027
这样新的文件默认为640( rw- r-- ---
)。
如果多个用户负责维护该站点,则需要创build一个用于分配权限的组。 为每个网站创build一个单独的组,并在该网站之后命名组是很好的做法。
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相同的权限,因此其他用户可以轻松浏览您的站点并读取可能包含秘密数据的文件,例如您的configuration文件。
你可以吃你的蛋糕,也可以吃
这可以进一步改进。 对于拥有者而言,拥有比群组更less的权限是完全合法的,所以我们可以让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
这个解决scheme需要注意的一点是,新文件的用户拥有者将与创build者匹配,而不是被设置为www-data。 所以你创build的任何新文件在Apache中都不能被Apache读取。
我之前提到,无论您使用的是什么types的权限,其他用户实际上都可以窥探您的网站。 默认情况下,所有Apache进程都以相同的www-data用户身份运行,所以任何Apache进程都可以从同一台服务器上configuration的其他所有网站中读取文件,有时甚至可以进行更改。 任何可以让Apache运行脚本的用户都可以获得与Apache本身相同的访问权限。
为了解决这个问题,有许多方法可以在Apache中进行特权分离 。 但是,每种方法都有各种性能和安全缺陷。 在我看来,任何具有更高安全要求的站点都应该在专用服务器上运行,而不是在共享服务器上使用虚拟主机。
我之前没有提到它,但是让开发者直接编辑网站通常是不好的做法。 对于大型网站来说,拥有某种从版本控制系统的内容更新networking服务器的版本系统会更好。 单一的维护人员的方法可能是理想的,而不是一个人,你有自动化软件。
如果您的网站允许上传,而这些上传不需要提供,那么这些上传应该存储在网页根目录之外的某处。 否则,您可能会发现人们正在下载旨在保密的文件。 例如,如果允许学生提交作业,则应将其保存到Apache不提供的目录中。 对于包含秘密的configuration文件来说,这也是一个好方法。
对于具有更复杂要求的网站,您可能需要考虑使用访问控制列表 。 这些可以实现更复杂的特权控制。
如果您的网站有复杂的要求,您可能需要编写一个设置所有权限的脚本。 彻底testing,然后保持安全。 如果你发现自己需要重build你的网站出于某种原因,这可能是值得黄金的重量。
我想知道为什么这么多人使用(或推荐)Linux权限的“其他”(o)部分来控制Apache(和/或PHP)的function。 通过将这个正确的部分设置为“0”以外的东西,你可以让整个世界在文件/目录上做一些事情。
我的方法如下:
cache/
或uploads/
。 为了给PHP FastCGI这个能力,它将以bob-www的方式运行,并且bob-www将被添加到自动创build的bob组中。 AllowOverride
设置为None
以外的值,它将尝试读取。 为了避免使用部分权限,我将www-data用户添加到bob组中。 现在:
这是一个回顾,但在这种情况下, 鲍勃被允许SSH。 如果不应该有任何用户允许修改网站(例如,客户只通过CMSpipe理面板修改网站,并且不具备Linux知识),则创build两个用户,但是将/bin/false
为shell以及,并禁用其login。
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%确定的,但这是我正在使用的。
我认为这个configuration有一个问题:当PHP / Apache创build一个新文件(例如上传)时,它将属于bob-www:bob ,而bob将只能读取它。 也许setuid目录可以解决这个问题。
考虑到上述优秀答案的谷歌排名,我认为有一点应该注意,我似乎无法在答案后留下一个注释。
继续这个例子,如果你计划使用www-data作为owner和dev-fabrikam作为组在目录(或文件)上有570个权限,注意到Linux忽略 setuid
是很重要的,所有的新文件将由创build它们的用户。 这意味着在创build新的目录和文件后,您将不得不使用类似于:
chown -R www-data /newdirectory/ chmod -R 570 /newdirectory/
在Rackspace OpenStack的Ubuntu 12.04中,我有一个奇怪的问题,我无法获得权限570的工作,直到我重新启动服务器,这奇迹般地解决了问题。 在这个看似简单的问题上正在以越来越高的速度失去头发….
我将使用这个configuration:
root
和组root
,权限为0755
。 root
和组root
,权限为0644
。 root
,组www-data
,权限为1770
。 粘性位不允许组主人删除或重命名里面的目录和文件。 www-data
拥有者用户和组,和0700
权限为每个上传文件的www-data
用户。 在上传目录中拒绝AllowOverride
和Index
,以便Apache不读取.htaccess
文件,并且Apache用户不能索引上传文件夹的内容:
<Directory /siteDir> Options -Indexes </Directory> <Directory /siteDir/uploadDir> AllowOverride none </Directory>
6. php.ini
configuration:
open_basedir = /siteDir:/tmp:/usr/share/phpmyadmin post_max_size = 5M file_uploads = On upload_max_filesize = 3M max_file_uploads = 20
使用此configuration, www-data
用户将无法进入除siteDir/
/tmp
和/usr/share/phpmyadmin
。 您也可以在相同的请求中控制最大文件大小,最大文章大小和最大file upload。
当你有一个名为“leo”的FTP用户时,需要将file upload到example.com的web目录,并且你还需要你的“apache”用户能够在cache目录下创builduploa-files / sessions / cache文件,然后执行如下操作:
该命令将leo作为所有者和组作为apache分配给example.com,apache用户是apache组的一部分,因此它将inheritanceapache组的权限
chown -R leo:apache example.com
另一个保证正确的许可和安全问题的命令。
chmod -R 2774 example.com
在这里,第一个数字2是目录,并确保每个新创build的文件将保持在同一组和所有者权限。 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