Apache 防止一个 VirtualHost 虚拟主机站点的PHP脚本访问另外一个 VirtualHost 虚拟主机站点文件,防止 Apache HTTP Server 跨站点访问,让每一个虚拟主机只能访问自己的文件。
对于静态文件来说,主站点或者虚拟主机能够访问到的最顶层目录是Apache DocumentRoot 指令指定的文件夹,在此范围以外的上级或者同级目录中的静态文件无法直接访问。
对于 PHP 脚本文件,在没有限制的情况下,PHP可以通过读写函数或者相应的类来操作主站点或者虚拟主机以外的文件,也可以通过exec, shell_exec, system, passthru等函数调用系统内部命令或者外部命令来读取文件,或者做其他操作。这样的配置很危险。
PHP可以通过 php.ini 配置中的 open_basedir 来限制 PHP 执行文件操作的路径范围,open_basedir 的值为一个或多个目录路径,如果配置多个目录路径,需要使用英文分号;来分隔,对于 Windows 以外的操作系统,使用英文冒号分隔。
- open_basedir = "C:/server/wuxiancheng.cn/;C:/server/temp/"
复制代码 如果将 open_basedir 写死在 php.ini 配置文件里面,那么所有站点都只能在配置的目录范围内操作文件。
对于主站点和不同的 VirtualHost来说,肯定需要配置不同的目录范围。可以结合 mod_fcgid 的一些配置参数来实现。对于将 PHP 作为 mod_php 来运行,这样的思路无法实现。
第一种方法的思路是在 php.ini 中将 open_basedir 的值设置为一个自定义环境变量,然后在 Apache 中设置该环境变量。
在 php.ini 中 配置 open_basedir
- open_basedir = "${PHP_INI_OPEN_BASEDIR}"
复制代码 在 httpd.conf 中主站点或者每个虚拟主机对应的 VirtualHost 配置片段中指定不同的 PHP_INI_OPEN_BASEDIR 环境变量的值
- FcgidInitialEnv PHP_INI_OPEN_BASEDIR "C:/server/wuxiancheng.cn/;C:/server/temp/"
复制代码 方法二:通过为主站点或者每个虚拟主机的 FcgidWrapper 指定的 php-cgi.exe 的 -d 命令行参数实现。
open_basedir嵌套了"和'两层引号,是因为第一层引号是传递给php-cgi.exe的,第二层php-cgi.exe传递给PHP配置文件的,加引号是为了避免路径中包含空格或者其他引起参数值改变的特殊字符导致实际的参数值和预期的结果不一致。如果能够确定参数的值不包空格或其他含特殊字符,可以不使用引号。
- FcgidWrapper "'C:/Program Files/wuxiancheng.cn/php/7.3/php-cgi.exe' -d open_basedir=\\\\"'C:/Program Files/wuxiancheng.cn/server/www/'\\\\"" .php
复制代码 同理,可以为 php.ini 配置项 disable_functions disable_classes 来做更多的限制。
更多关于 FcgidWrapper 及 FcgidInitialEnv 的细节可以参阅这篇关于 FcgidWrapper 的文章。 |