如何在Apache中使用PHP脚本进行访问控制


How to use PHP script for access control in Apache

我正在寻找一种使用PHP脚本来控制对Apache资源的访问的方法。我想有访问控制,不依赖于目标资源;也就是说,它将适用于html,文件,其他脚本和cgi程序,就像"Allow from"或"Deny from"指令一样——除了使用自定义逻辑。

我已经研究了几种方法来尝试处理这个问题:

  1. 使用apache模块,如mod_auth_script(好的,但这个模块是旧的,我认为不扩展好)
  2. 使用FastCGI指令FastCgiAccessChecker
  3. 创建我自己的apache模块来调用php和做任何我需要的
其中

#2看起来最有前途,而且考虑到FastCGI的流行,也是最可移植的。所以,我设法换出通常的linux php模块,并通过fastcgi获得php工作。这比在Windows上更难,但最终让它作为外部服务器工作,即使用Apache指令

FastCGIExternalServer /var/www/html/thing -host 192.168.0.11:9000

和启动PHP守护进程

php-cgi -q -b 192.168.0.11:9000 &

麻烦来了,试图找到一种方法来调用PHP脚本使用FastCgiAccessChecker。

我已经尝试了各种方法来尝试通过改变FastCGIExternalServer和/或FastCgiAccessChecker指令中的文件名来传递我想要运行的脚本名称-不工作。我也试过用脚本说明符启动php-cgi,即

php-cgi -q -b 192.168.0.11:9000 -f /var/www/html/thing/access.php &

没有效果。我可以告诉apache识别我的指令,有点,因为当我包括FastCgiAccessChecker然后访问php页面,内容类型更改为文本/plain,我失去了从页面服务的第一个~8000字节的内容,如果它是一个脚本(不知道为什么)。但是它不会调用我想要运行的PHP脚本。

据我所知,发生的事情是FastCgiAccessChecker假设指定的fastcgi服务器被专门编译为作为访问检查器。没有办法告诉fastcgi服务器(在我的例子中是PHP)运行哪个脚本来进行访问检查。

我已经在网上搜索过了,据我所知,没有人曾经尝试过使用PHP脚本来实现这一点,或者没有人写过关于它的文章。

所以我的问题是:我该怎么做?我可以看到一些可能性:

1)我错过了一些东西,有一些神奇的方法使FastCgiAccessChecker做我想要的:运行一个PHP脚本来控制apache访问控制

2)我写我自己的FastCGI服务器在c和嵌入PHP,所以我可以指定PHP脚本我想要运行(我花了几分钟看这个;它看起来既复杂又可怕,而且我从1995年就没用过c了)

3)我放弃了FastCGI和写一个apache模块调用我的PHP脚本直接控制访问。(看起来也很复杂;这种技术需要为每个执行PHP的请求生成一个新进程。

有没有人有任何建议,无论是如何得到FastCGI做我想要的,或一个(合理)简单的替代FastCGI?

感谢您的任何建议

我对这些类型的情况的方法是使用mod_xsendfile与mod_rewrite相结合。这些可能看起来不是你想要的,但是如果你:

  1. 使用mod_rewrite规则创建一个前端控制器(一个PHP脚本,处理所有传入的请求)。
  2. 通过查看$_SERVER(可能是$_SERVER['PATH_INFO'])的内容来确定正在请求的文件。
  3. 在这里插入您的访问控制/安全层。
  4. 如果安全通过,使用mod_xsendfile发送文件内容。

你基本上可以用这种方式实现任何你想要的安全系统。

mod_xsendfile实际上只是以与Apache在文件被直接访问时完全相同的方式发送文件。它很稳定,在我遇到的任何情况下都能很好地工作。它也应该"刚刚工作",没有设置的巨大负担,这似乎是你挣扎一点。

感谢您的回复!我非常喜欢ezzatron的技术,它应该适用于任何Apache,不需要自定义工具。

碰巧的是,在我阅读任何回复之前,我最终选择了我的第三个选项:

我写了一个Apache模块来做这项工作。它使用子请求将访问控制分配给apache可以提供服务的任何文档,因此它适用于任何脚本语言或CGI程序。对于使用php_module或fastcgi的典型PHP配置,这可以很好地扩展,因为不需要额外的进程。

事实证明Apache的模块API并不太难使用,我猜C就像骑自行车——你永远不会真正忘记怎么骑。

您可能想要查看shell_exec()system()。这将允许您执行linux shell命令,只要您在您的cfg中启用它。另外,对于FastCGI,我建议您安装php5-fpm。非常容易做到# apt-get install php5-fpm

我目前正在处理一个类似的问题——在我的情况下,我需要在PHP中设置(经过身份验证的)远程用户。简单地说,您从PHP脚本中将会话cookie和经过身份验证的用户名推送到memcache中(请查看非常可扩展的系统的couchdb版本),然后mod在Apache中设置用户,并可以使用标准的Apache访问控制规则应用这些信息。

这避免了启动额外进程/在PHP代码中包装所有访问的开销。

参见从PHP会话中在apache日志文件中填充远程用户的问答