Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use PHP script for access control in Apache

I am looking for a way to use a PHP script to control access to resources in Apache. I want to have access control that does not depend on the target resource; i.e. it will work for html, files, other scripts and cgi programs, just as an "Allow from" or "Deny from" directive would do -- except using custom logic.

I've looked at several ways to try to manage this:

  1. Use an apache module like mod_auth_script (ok but this module is old and I assume does not scale well)
  2. Use FastCGI directive FastCgiAccessChecker
  3. Create my own apache module to invoke php and do whatever I need

Of these #2 looked most promising, and also most portable given the popularity of FastCGI. So, I managed to swap out the usual linux php module and get php working via fastcgi instead. It was harder than on Windows but got it to work eventually as an external server, i.e. using Apache directive

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

and starting php daemon

php-cgi -q -b 192.168.0.11:9000 &

The trouble came in trying to find a way to invoke a PHP script using FastCgiAccessChecker.

I've tried various ways to try to pass in the script name I want to run by changing the filename in the FastCGIExternalServer and/or FastCgiAccessChecker directives -- doesn't work. I've also tried starting php-cgi with a script specifier, i.e.

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

Nothing works. I can tell apache recognizes my directives, sort of, because when I include FastCgiAccessChecker then visit a php page, content-type changes to text/plain and I lose the first ~8000 bytes of content from the page served if it's a script (no idea why). But it does not call the PHP script I want to run.

As far as I can figure, what is happening is that FastCgiAccessChecker assumes that the specified fastcgi server is compiled specifically to act as an access checker. There is no way to tell the fastcgi server (PHP in my case) what script to run to do the access check.

I've searched the web and as far as I can tell no one has ever tried to use a PHP script for this before, or no one has written about it.

So my question: what should I be doing? I can see a few possibilities:

1) I am missing something, and there is some magic way to make FastCgiAccessChecker do what I want: run a PHP script to control apache access control

2) I write my own FastCGI server in c and embed PHP, so I can specify the PHP script I want to run (I spent a few minutes looking in to this; it looks complicated and scary, and I haven't worked in c since 1995)

3) I give up on FastCGI and write an apache module to call my PHP script directly to control access. (Also looks complicated; and this technique would require a new process to be spawned for every request to exec PHP.)

Does anyone have any advice, either on how to get FastCGI to do what I want, or a (reasonably) simple alternative to FastCGI?

Thanks for anything you can suggest

like image 755
Achronos Avatar asked Aug 19 '11 04:08

Achronos


People also ask

Can we run PHP on Apache?

PHP and MySQL both are compatible with an Apache server. These two are open source and easy to set up. PHP runs on many platforms like Windows, Linux, and Unix.

What is Apache Mod_php?

mod_php means PHP, as an Apache module. Basically, when loading mod_php as an Apache module, it allows Apache to interpret PHP files (those are interpreted by mod_php ).


1 Answers

My approach to these types of situations is to use mod_xsendfile in combination with mod_rewrite. These may not appear to do what you want a first, but if you:

  1. Use mod_rewrite rules to create a front controller (a single PHP script that handles all incoming requests).
  2. Determine what file is being requested by looking at the contents of $_SERVER (probably $_SERVER['PATH_INFO']).
  3. Insert your access control / security layer here.
  4. Use mod_xsendfile to send the contents of the file, if security passes.

You can essentially implement any security system you want in this manner.

mod_xsendfile essentially just sends a file in the exact same manner that Apache would, had the file been accessed directly. It's stable and works great in every situation I've thrown at it. It should also 'just work' without a huge burden of setup, which you seem to be struggling with a little.

like image 85
ezzatron Avatar answered Sep 21 '22 08:09

ezzatron