Lorenzo Alberton
« Articles
Secure PHP installation on unix/linux systems
Abstract: Simple guide to a more 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.
Related articles
Latest articles
- On batching vs. latency, and jobqueue models
- Updated Kafka PHP client library
- Musings on some technical papers I read this weekend: Google Dremel, NoSQL comparison, Gossip Protocols
- Historical Twitter access - A journey into optimising Hadoop jobs
- Kafka proposed as Apache incubator project
- NoSQL Databases: What, When and Why (PHPUK2011)
- PHPNW10 slides and new job!
Filter articles by topic
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 FrameworkFollow @lorenzoalberton