Installing and maintaining a secure web server on Linux can be a challenge. It requires in-depth knowledge of Linux, Apache, and PHP server-side options. One of the main problems is to find the balance between security and productivity and usability. The best solution depends on the specific project requirements, but all installations share certain common characteristics. Here are some best practices for securing a LAMP server, from the server configuration to fine-tuning PHP settings.
The task of securing a web server should begin with hardening the Linux operating system. Hardening Linux could be a whole article of its own, but certain concepts are especially important in regards to serving web content:
Once you've secured the Linux operating system you can begin to take care of the Apache web server. The following instructions are specifically for Apache but may also apply for other web servers, such as LiteSpeed and nginx. Very often differences between them are just in the names of the modules or the configuration directives.
To harden Apache go through these steps:
Install mod_security, an Apache module that works as application firewall. It filters all parts of a web request and stops malicious code. It works before any actual processing by the web server and thus is web application-independent. Mod_security is good for filtering anything from SQL injections to XSS attacks. It is the fastest and easiest way to protect a vulnerable web application. The software has various ready-to-use rules publicly available, but you can also write your own easily. Imagine for example that you have an outdated version of Joomla and you are worried about SQL injection attacks. This simple rule filters any POST and GET content containing jos_ (the default Joomla tables' prefix): SecFilter "jos_".
Install mod_evasive, another important Apache module that protects web applications against denial of service (DOS) requests. Its effectiveness is limited by the fact that it works on the application level, meaning Apache accepts the connections anyway, thus consuming bandwidth and system resources. Still, it can help in cases of weaker DOS attacks that originate from a small number of remote hosts. Once mod_evasive is loaded you might configure it thusly:
DOSPageCount 2DOSSiteCount 30DOSBlockingPeriod 120
This instructs the server to block (return HTTP error 403 Forbidden by default) any host that hits the same page twice or has a total of 30 requests within one second (the default time interval). The intruder will be blocked for 120 seconds.
Filter visitors' IP addresses. This might be considered drastic action but it is very effective. First, consider installing mod_httpbl, an Apache implementation for Project Honeypot. Once installed and enabled it blocks IP addresses that have a proven record of malicious activities. Another option is to use mod_geoip, which can be used to allow visitors from only certain countries to pages that accept input such comments, registration, and login information. It can even block and allow server-wide visitors from certain countries.
Other recommended Apache options include setting a low Timeoutoption, such as 15 seconds. This limits the effect of DOS attacks by lowering the time the web server waits for certain events. A good source for further reading is the official Apache documentation and its security tips.
PHP is the most popular server-side language in the open source world. The fact that it is server-side means you need to set clear rules and limitations for its access to server resources via directives such as memory_limit, execution_timeout, and disable_functions. However, PHP configuration directives can be defined and redefined in various places, as explained here. Make sure that you are aware of the scope of these settings when enforcing them globally.
If you have the latest version of PHP installed with its default settings, your environment is already up to some decent security standard. Dangerous options such as register_globals and allow_url_include have been disabled by default. Still, this is not enough. One of the most important options to consider tweaking is disable_functions, which, as its name suggests, disables PHP functions. Here is an example of how to prevent dangerous shell code executions:
There have been many attempts to bring additional security to PHP, both from inside and outside its development team. One unsuccessful attempt was PHP's Safe Mode, the main idea of which was to restrict files' access depending on their owners. This feature proved to be incorrectly designed and has been deprecated since PHP 5.3. However, an external security project called Suhosin has proven its worthiness. It is bundled with PHP in popular Debian-based distributions.
Suhosin can be installed in two ways. One is by patching the original PHP source code before the actual PHP compilation. This method is recommended because it makes Suhosin an integrated part of PHP, allowing Suhosin to protect the PHP core through its Engine protection features. The second option, which is easier, is by adding it as a regular PHP extension. Suhosin's extensive features apply to many security aspects, such as session data encryption, request payload limits, and even, as an experimental feature, SQL injections prevention.
By default PHP runs as an Apache module under the Apache user, which ensures the best performance and compatibility with applications' requirements. However, if a site has more than one vhost it could cause serious security problems, especially if vhosts belong to different users. In such cases a script from one vhost may be able to read, write, and execute scripts from other vhosts, which compromises security, not to mention privacy.
To mitigate this you can use another Apache module, called mod_suphp, which allows PHP scripts to run under a predefined user. Such a module is a must for shared hosting servers. With mod_suphp in place scripts from one vhost cannot even read files from other vhosts, let alone write to them. Disallowing reading of foreign vhosts' files is essential for configuration files, which is why such files must have permissions of 600. Without that, your database details could be easily discovered, and that's the least of the trouble you could find yourself in.
In mod_suphp's configuration file (by default /etc/suphp.conf) you can enforce global safe files' permissions policies with the options allow_file_group_writeable, allow_file_others_writeable, allow_directory_group_writeable, and allow_directory_others_writeable. Under normal circumstances all of them should be defined as false. Executing scripts that do not obey these restrictions produces an HTTP Error 500 Internal server error.
When securing a web server, also consider the following:
All of the information above serves as a road map for keeping a web server secure. Doing the job right requires a lot of time and effort. If you're not prepared to invest that time, you might be better off using shared hosting or fully managed servers.
Allowed tags: <a> link, <b> bold, <i> italics