Secure PHP installation on unix/linux systems

With the growing concerns regarding comment SPAM, XSS attacks, security breaches, etc, we should spend some time learning how to defend ourselves against such threats. We already know everything about input validation, code and SQL injection attacks, error logging, vulnerability scanning, etc., don't we? ;-) So, let's focus on securing our PHP server, thus barring most of the attacks from the start.

I. Install Apache

Get the latest version of the Apache source code from the Apache Software Foundation , put the file somewhere and extract the archive:

$ wget http://mirrors.publicshout.org/apache/httpd/httpd-2.2.3.tar.bz2
$ tar xjvf httpd-2.2.3.tar.bz2
$ cd httpd-2.2.3

NB: even if in the examples I don't show how to check the signatures of the downloaded files, you should do it for obvious security reasons (how-to ).
Now let's prepare for building, replacing [path] with your own path, such as /usr/local/apache2 (without trailing slash), and enabling mod_so, which will allow Apache to use DSOs.

$ ./configure --prefix=[path] --enable-module=so
$ make
$ sudo make install

Now configure the httpd.conf file, setting the root directory, etc. If you don't want a directory under the document root to be public, remember to restrict its access to the allowed IPs or domains:

<Directory /usr/local/apache2/share/htdocs/protected>
  order deny,allow
  deny from all
  # only the computers with an IP address starting
  # with 10.10.63 are allowed to access this directory:
  allow from 10.10.63
  # or, allow only to computers in your domain:
  # allow from .yourdomain.com 127.0.0.1
</Directory>

NB: Avoid "Basic authentication" if you need to protect your pages, since the password (even if it's stored on the server in encrypted format) is passed from the client to the server in plain text across the network. Quoting the Apache manual: "Basic authentication should not be considered secure for any particularly rigorous definition of secure".

II. Install mod_security

ModSecurity is an open source intrusion detection and prevention engine for web applications. Operating as an Apache Web server module, the purpose of ModSecurity is to increase web application security, protecting web applications from known and unknown attacks.

$ wget http://www.modsecurity.org/download/modsecurity-apache_1.9.4.tar.gz
$ tar -xzf modsecurity-apache_1.9.4.tar.gz
$ cd modsecurity-apache_1.9.4/apache2/
$ sudo /usr/local/apache2/bin/apxs -cia mod_security.c

Now point your browser to the official documentation and to the ModSecurity Rules page, where you can also find many links to external articles that explain how to configure mod_security.
This one is particularly interesting. I won't repeat here what is already well explained there.
Also have a look at Noel Jackson's mod_security rule generator .

III. Install PHP + HardenedPHP patch

The Hardening-Patch is a patchset that adds security hardening features to PHP to protect your servers on the one hand against a number of well known problems in PHP applications and on the other hand against potential unknown vulnerabilities within those applications or the PHP core itself.

You could download the PHP tarball from php.net and then apply the Hardened-PHP patch, but since the nice guys at hardened-php.net offer a tarball with the patch already integrated, we thank them for they save us a few steps.

$ wget http://www.hardened-php.net/files/hardening-patch-5.1.4-0.4.11.tar.bz2
$ tar xjvf hardening-patch-5.1.4-0.4.11.tar.bz2
$ cd hardening-patch-5.1.4-0.4.11

Now you can configure PHP with the options you need. Have a look at available ones with

$ ./configure --help

Here's a sample configure with Apache2 and Firebird SQL (which we suppose is installed in /usr/firebird) support:

$ ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-interbase=/usr/firebird
$ make
$ sudo make install 
$ cp php.ini-dist /usr/local/lib/php.ini

Now configure your php.ini to suit your needs (remember to leave register_globals=Off !), and edit your Apache httpd.conf file adding these lines to enable PHP:

LoadModule php5_module modules/libphp5.so
AddType application/x-httpd-php .php .phtml
AddType application/x-httpd-php-source .phps

Then [re]start apache:

$ /usr/local/apache2/bin/apachectl start

The behavior of Hardened-PHP's variable filter can be modified from within php.ini. There are currently 4 directives that control several aspects of variable filtering:

# The maximum number of variables that can be passed per request (default: 200)
varfilter.max_request_variables 200
 
# The maximum length for a variable name (default: 64)
varfilter.max_varname_length 64
 
# The maximum length for a variable value (default: 10000)
# NB: if you run an application that will have to handle strings longer
# than 10000 Bytes, you will have to set an higher value than the default
varfilter.max_value_length 10000
 
# The maximum depth of an Array (default: 100)
varfilter.max_array_depth 100

For an extensive description of the Hardening-PHP patch, please refer to the official manual .

IV. Always code with security in mind

It goes without saying that having a (more) secure server doesn't excuse you to code carelessly. All the coding security practices must be followed, always. I won't list them here since they're out of the scope of this tutorial, but you can find most of them with a simple web search, or in printed references like Ilia Alshanetsky's or Chris Shiflett's book.

V. Read security-related news and act accordingly

In order to keep your server secure, read the latest security advisories , promptly patch your software as soon as a fix or a new release is available.
There are also security mailing lists and forums to help you to stay up-to-date.

VI. Final note

In this tutorial, I've just scratched the surface of the topic. There are countless other precautions you can take to have a more secure server, like chroot-ing Apache and using Apache with suExec to jail the user and the www processes, and using PHP in safe_mode and with open_basedir set.
I strongly suggest you to take this guide just as a "security-awareness" starting point, and to start searching, reading and learning about the risks involved and about possible preventions and solutions.

Have fun.




Lorenzo Alberton

Lorenzo Alberton Lorenzo PHP5 ZCE - Zend Certified Engineer has been working with large enterprise UK companies for the past years and is now Chief Tech Architect at DataSift. He's an international conference speaker and a long-time contributor to many open source projects. Lorenzo Alberton's profile on LinkedIN View Lorenzo Alberton's Twitter stream

Lorenzo Alberton - Sun Certified MySQL 5 Developer

Tags

AJAX, Apache, Book Review, Charset, Cheat Sheet, Data structures, Database, Firebird SQL, Hadoop, Imagick, INFORMATION_SCHEMA, JavaScript, Kafka, Linux, Message Queues, mod_rewrite, Monitoring, MySQL, NoSQL, Oracle, PDO, PEAR, Performance, PHP, PostgreSQL, Profiling, Scalability, Security, SPL, SQL Server, SQLite, Testing, Tutorial, TYPO3, Windows, Zend Framework

Buy me a book - Joel On Software