我已经设置了一个用于生产的 Web 服务器。操作系统是 Windows Server,它以 Apache 模块的形式运行 Apache 2.0 和 PHP 5.3(还有 MySQL...)。它用于托管属于不同客户的多个虚拟主机(Apache vhosts)。
此时 PHP 以系统用户身份运行。将来可能会向客户授予 FTP 访问权限,因此默认情况下,每个客户都可以通过 PHP 访问整个系统。这显然是不可接受的。
我知道我可以在 PHP 中设置 open_basedir,但我不确定它是否足够全面和可靠,可以被视为一种解决方案 - 它是否限制了对所有 PHP 函数(例如 include...)的访问?PHP 流怎么样?
我也知道 IIS 提供了解决该问题的解决方案,但我更喜欢保留 Apache。
我理想中想要建立的解决方案能够满足以下要求(主要):
- 优雅且自动化。我正在手动管理服务器 - 我希望每个虚拟主机的设置尽可能少地涉及设置和配置编辑。
- 允许例外。大多数托管网站都是我自己开发的,我想将它们全部链接到一个库文件夹,因此应该允许对该文件夹进行只读访问,尽管它位于虚拟主机的根目录之外。
那么,如果有的话,有哪些可用的选项?我已经做了一些研究,似乎该领域的大多数工作都是在 Linux 系统上完成的。
答案1
PHP 和 FTP 彼此无关。FTP
是一种在机器之间移动文件的方式(糟糕、不安全、过时)。PHP
是一种由 Web 服务器执行的脚本语言。
您可以(也可能应该)使用 IIS FTP 功能授予对您服务器的 FTP 访问权限,同时拒绝您的用户访问根卷(C:\
)和共享库目录等内容。
安全问题的另一半是 PHP 本身——mod_php
它不擅长多租户安全,并且open_basedir
不是一个包罗万象的解决方案(但总比没有好)。
如果你想要真正的安全,你几乎需要给每个人一个自己的 Apache,在 chroot 中。
这很不愉快(对于管理员来说),但很安全。它也很灵活,因为您可以为每个站点修改 php.ini。您的下一个最佳选择是 PHP 作为 CGI。
您可以将 PHP 的 CGI 解释器作为网站所有者的用户 ID 来调用 - 这使您能够享受操作系统的文件权限功能,并避免必须为每个站点维护单独的 Apache/PHP 实例。
主要缺点是必须将 PHP 作为 CGI 来调用,因此您将失去任何依赖于 PHP 作为 Web 服务器模块的功能。你的第三个最佳选择
open_basedir
是disable_functions
/disable_classes
.
open_basedir
并不能真正保证任何东西,因为它只会影响PHP:您的用户仍然可以上传/执行二进制文件来访问其他人的数据。php.ini中的和
指令允许您关闭某些disable_functions
disable_classes
不安全的功能(您可以自行获取可利用类别的列表)。- 但问题是:这些都是黑名单和黑名单使得可怕安全性,因为如果你错过了一个可利用/易受攻击的功能,你仍然容易受到攻击。
你可以用这种方式掩盖明显的漏洞,但你基本上用手指戳堤坝的荷兰小男孩。你的手指只有这么多,而且总会有一个洞……
- 但问题是:这些都是黑名单和黑名单使得可怕安全性,因为如果你错过了一个可利用/易受攻击的功能,你仍然容易受到攻击。
你确实不应以Local System
任何具有提升权限的帐户身份运行 Apache。
在将此服务器投入生产之前,请确保已配置根据 Apache 文档中的最佳实践。
答案2
我通过以下组合解决了该问题:
- 使用 Apache 配置中的 apache_admin_value 为每个 vhost 设置 open_basedir
- 以具有有限权限的普通用户身份运行 Apache(@voretaq7:感谢提供链接)
- 禁用 php.ini 中的某些功能:disable_functions = shell_exec、symlink、exec、system、passthu、popen、proc_open
这绝不是最安全的解决方案,但通过定期备份,它足以托管一些低调的网站。
更新(大约一年后):这个设置拯救了我——如果可以这么说的话。我的一个虚拟主机是一个过时的 Wordpress 安装,它被感染了。我可以看到在 PHP 日志中创建了奇怪的临时文件。虚拟主机通过 open_basedir 受到限制,我推测问题就出在这里——如果不是这样,我担心我的所有文件(而不仅仅是这个虚拟主机的文件)都会受到损害。