Pencarian

Rss Posts

 

 

 

Stage 2: http:BL with Apache2 mod_perl – Paul Gregg

Dec 02, 2010


After my earlier post
Referrer and Comment spammers are a PITA I came up with two mod_perl plugins to Apache and an “apache level” firewall.

The reason for the apache-level firewall is two-fold.? There is no direct way for the Apache user to manipulate an iptables chain (as it doesn’t run as root), and second; I was not happy with suid root access or other forms of message passing to a daemon which would manipulate the firewall for me.

Architecture is thus, in httpd.conf place the following two lines:

PerlPreConnectionHandler PGREGG::httpBLBlock
PerlLogHandler PGREGG::httpBLLog

The first tells apache to run the handler in my httpBLBlock.pm module when a connection is received (before the request has been sent by the client).? In this handler, I am simply looking for a filename matching that IP in a directory that is writable by the apache user.? The contents of the file are a SCORE:httpBL_answer:[LIST].? Based on this, the module checks the mtime of the filename is in the last SCORE days, then the firewall is in effect. If so, we simply tell apache to drop the connection.? If the file has expired, we delete the file.

The second line is more interesting, and what creates the firewall filenames. In order to not impede the general speed of request handling, processing is performed in the Logging section of the Apache process. Our module is called by apache after the response has been sent, but before the access_log entry has been written.? In our module we perform the http:BL API call and compute the above SCORE based upon the Threat* level and Age* of the API response. (* both Threat and Age are octets in the DNS lookup).? We merely discount the Threat down to zero based on the Age (0-255) where an entry 255 days old reduces the SCORE to zero.
If the SCORE is larger than our trigger level (3) then we create the firewall filename, log the entry in our own httpbl.log and return Apache2::Const::FORBIDDEN.? This causes Apache to not log the entry in the normal access_log.? Otherwise, if all is ok, we return Apache2::Const::OK and Apache logs the hit as normal.

I have a bit of code tidy up, restructure the config/firewall directory and pull some common code out to a shared module before I can release to the world.

An interesting side effect to publishing the last story out through Planet PHP and other news sources along with the Project Honey Pot image is that when browsers viewed those sources, they all asked for the image off my server. In several cases, these were known spammer, Comment spammer, and other abusers. My server then created the firewall entry blocking them before they were able to follow the links back to my server.
?
I have been reading up more on Apache Bucket Brigades in an attempt to allow the firewall filter to be placed immediately after the request has been received and allow a custom response to the browser. This may help an otherwise unsuspecting user if their machine had been trojaned. I don’t mind admitting I’m thoroughly confused right now :)

Running Apache with a dozen PHP versions – Christian Weiske

Mar 12, 2010

After showing you how to set up
multiple PHP versions on a single
machine
, it’s time to explain how to stuff all those compiled
php-cgi executables into a single Apache web server instance.

Idea

  • Instead of using mod_php, mod_fastcgi is going
    to be utilized.
  • Every single PHP version runs its own CGI server
  • Configuration of used PHP version is made per virtual host.

Installation of FastCGI

Debian

The Debian setup is painless:

aptitude install libapache2-mod-fastcgi apache2-mpm-worker apache2-suexec
a2enmod actions fastcgi suexec

CentOS

The open source version of Redhat’s operating system does not provide
the fastcgi module for Apache, which is why one needs to install it
by hand. It’s trivial.

Assuming phpfarm is installed in /root/phpfarm,
you need to chmod +x /root. Last but not least is
setting up permissions for the fastcgi state files:
chmod +x /var/log/httpd.

FastCGI setup

After mod_fastcgi is available, we need to prepare the FastCGI
servers. Open /etc/{apache2,httpd}/{apache2,httpd}.conf
and make it load conf/php-cgisetup.conf before including
server.conf. Put the following
lines into conf/php-cgisetup.conf:

#php-cgi setup
#used for multiple php versions
FastCgiServer /var/www/cgi-bin/php-cgi-5.2.12
FastCgiServer /var/www/cgi-bin/php-cgi-5.3.0
FastCgiServer /var/www/cgi-bin/php-cgi-5.3.1
ScriptAlias /cgi-bin-php/ /var/www/cgi-bin/

PHP-CGI setup

For each single php version you installed with
phpfarm,
you need to create a file
/var/www/cgi-bin/php-cgi-$version and make
it executable. Example for php-cgi-5.3.2:

#!/bin/sh
PHPRC="/etc/php5/cgi/5.3.2/"
export PHPRC

PHP_FCGI_CHILDREN=3
export PHP_FCGI_CHILDREN

PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_MAX_REQUESTS

exec /root/phpfarm/inst/bin/php-cgi-5.3.2

Activating a PHP version in a virtual host

If you followed all of the previous steps, everything is
setup now and ready to be used. In your
/etc/{apache2,httpd}/conf/server.conf, put the following
code in each section that you
like to switch to a certain version of PHP:

  
    AddHandler php-cgi .php
    Action php-cgi /cgi-bin-php/php-cgi-5.3.2
  

Conclusion

With the simple steps listed above and the help of phpfarm,
you are able to test your web applications in a dozens or more
PHP versions easily.

As as side note: The CGI versions of PHP are only used on the vhosts
that you determine. All others are still served by mod_php
that was probably setup before, making it trivially easy to keep your
server’s main web sites up-to date with your distribution’s
package manager.