LAMP setup: Apache and PHP

After finishing all tasks from the previous post LAMP setup, now is time to move on. LAMP server is secured and waiting for Apache and PHP configuration. Here goes agenda:

  1. HTTP header
  2. Hide Apache version
  3. Hide PHP version
  4. Turn off needless Apache modules processed as Apache configuration files
  5. Turn off needless Apache modules loaded in httpd.conf by LoadModule directive
  6. Turn off directory browsing
  7. Make webalizer logs accessible only to your IP
  8. Conclusion

1. HTTP header
Communication between browser and Web server goes through HTTP protocol. Client sends request, and server respondes. Every HTTP respond has HTTP header and HTTP body. In server response, HTTP body is actually HTML interpreted by browser (we can see that). Browser knows that HTTP body comes after empty newline – everything before empty newline is HTTP header. HTTP header is somehow hidden because browser doesn’t display any of data contained in header, but there are tools and more important bad bots that focuses especially to HTTP header. In HTTP header you can see how Apache by default presents himself and not only himself but also the operating system, PHP version and included modules.

HTTP/1.0 200 OK
Date: Thu, 31 Jul 2008 06:16:22 GMT
Server: Apache/2.2.8 (Fedora) mod_ssl/2.2.9 OpenSSL/0.9.8b
X-Powered-By: PHP/5.2.6
Connection: close
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...>
<html xmlns="" dir="ltr">
<head profile="">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="author" content="Darko Bunić"/>
<title>Redips | spideR Net</title>

HTTP header can be explored by FireFox add-ons Firebug and Web Developer, command line utility wget with -d switch and so on.

2. Hide Apache version
Open httpd.conf file. In Linux/Unix installations it should be placed inside /etc directory and in RedHat family it is in /etc/httpd/conf/httpd.conf. Two lines have to be changed: ServerTokens and ServerSignature. Edit them to look like:

# return only "Server: Apache" in HTTP header instead of Apache version, OS and modules
ServerTokens Prod

# hide line containing the server version and virtual host
# name to server-generated pages (internal error documents, FTP directory
# listings, mod_status and mod_info output etc)
ServerSignature Off

3. Hide PHP version
php.ini is PHP configuration file usually located at /etc/php.ini. Open file and try to find expose_php directive. By default, it is turned on and to completely remove PHP version from HTTP header write “Off” and save php.ini file.

# Decides whether PHP may expose the fact that it is installed on the server
# (e.g. by adding its signature to the Web server header).  It is no security
# threat in any way, but it makes it possible to determine whether you use PHP
# on your server or not.
expose_php = Off

4. Turn off needless Apache modules processed as Apache configuration files
In RedHat family, inside /etc/httpd/conf.d directory, Apache holds module-specific configuration files. Any files in this directory which have the “.conf” extension will be processed as Apache configuration files. After fresh Apache installation inside conf.d you will find:

> cd  /etc/httpd/conf.d
> ls -la 
drwxr-xr-x 2 dbunic dbunic 4096 2008-07-11 08:01 .
drwxr-xr-x 4 dbunic dbunic 4096 2008-06-04 13:34 ..
-rw-r--r-- 1 dbunic dbunic  295 2005-12-07 17:45 manual.conf    # adds URL /manual to Web site
-rw-r--r-- 1 dbunic dbunic 1796 2005-04-22 14:53 perl.conf      # Perl module
-rw-r--r-- 1 dbunic dbunic  560 2008-05-08 16:26 php.conf       # PHP module
-rw-r--r-- 1 dbunic dbunic  566 2005-12-05 18:26 proxy_ajp.conf # brings support for Tomcat
-rw-r--r-- 1 dbunic dbunic 1671 2008-02-25 13:05 python.conf    # Python module
-rw-r--r-- 1 dbunic dbunic  392 2008-02-25 13:09 README
-rw-r--r-- 1 dbunic dbunic  332 2008-07-02 11:32 squid.conf     # uses squid as caching system
-rw-r--r-- 1 dbunic dbunic 9677 2005-12-05 18:26 ssl.conf       # provides SSL support
-rw-r--r-- 1 dbunic dbunic  352 2004-09-09 16:22 webalizer.conf # defines access to Web statistics
-rw-r--r-- 1 dbunic dbunic  299 2004-09-09 08:16 welcome.conf   # enables "Welcome" page

Almost certainly for LAMP setup, you will need only php.conf and webalizer.conf all other files should be renamed. Add extension “.off” and they will not be processed by Apache, and if you want to have nice sort with “ls”, give them “off_” prefix. After renaming, you will have list like this:

> cd  /etc/httpd/conf.d
> ls -la 
drwxr-xr-x 2 dbunic dbunic 4096 2008-07-31 09:58 .
drwxr-xr-x 4 dbunic dbunic 4096 2008-06-04 13:34 ..
-rw-r--r-- 1 dbunic dbunic  295 2005-12-07 17:45
-rw-r--r-- 1 dbunic dbunic 1796 2005-04-22 14:53
-rw-r--r-- 1 dbunic dbunic  566 2005-12-05 18:26
-rw-r--r-- 1 dbunic dbunic 1671 2008-02-25 13:05
-rw-r--r-- 1 dbunic dbunic  332 2008-07-02 11:32
-rw-r--r-- 1 dbunic dbunic 9677 2005-12-05 18:26
-rw-r--r-- 1 dbunic dbunic  299 2004-09-09 08:16
-rw-r--r-- 1 dbunic dbunic  560 2008-05-08 16:26 php.conf
-rw-r--r-- 1 dbunic dbunic  392 2008-02-25 13:09 README
-rw-r--r-- 1 dbunic dbunic  352 2004-09-09 16:22 webalizer.conf

5. Turn off needless Apache modules loaded in httpd.conf by LoadModule directive
Apache also load modules from main httpd.conf file. There is huge list of modules to load by default. Some of them are needless for LAMP setup. Here is my excluded modules list.

#LoadModule authn_dbm_module modules/
#LoadModule authz_dbm_module modules/
#LoadModule ldap_module modules/
#LoadModule authnz_ldap_module modules/
#LoadModule deflate_module modules/
#LoadModule usertrack_module modules/
#LoadModule dav_module modules/
#LoadModule dav_fs_module modules/
#LoadModule speling_module modules/
#LoadModule proxy_module modules/
#LoadModule proxy_balancer_module modules/
#LoadModule proxy_ftp_module modules/
#LoadModule proxy_http_module modules/
#LoadModule proxy_connect_module modules/
#LoadModule cgi_module modules/

Proxy, speling, dav, ldap are candidates for sure to be turned off. I don’t use output compression so I turned off mod_deflate too. Same for mod_cgi, authn_dbm_module and authz_dbm_module. When you start to comment out needless modules be careful because of existing module dependencies. For example if you comment proxy_module only, but you leave proxy_balancer_module, proxy_ftp_module … httpd will not run after restart. Instead there will be printed error message:

httpd: Syntax error on line 189 of /etc/httpd/conf/httpd.conf: 
Cannot load /etc/httpd/modules/ into 
server: /etc/httpd/modules/ 
undefined symbol: proxy_module

To avoid such a problem, run httpd.conf test before restarting server.

# Run syntax tests for configuration files only. 
# The program immediately exits after these syntax parsing tests.
/usr/sbin/httpd -t

If httpd.conf is correct (no dependence problems), Syntax OK will be printed, otherwise you will get error message.

Anyway, why to turn off needless Apache modules? In short, Apache will start faster and will use less memory. Why is that important? Because server will be able to handle more httpd childs and that finally means: more requests per second.

6. Turn off directory browsing
In default Apache configuration, HTTP request on directory without index page will result with directory listing. This “feature” should be turned off. Open httpd.conf and find <Directory “/var/www/html”> where goes directives for document root. Inside should be Options directive with options Indexes and FollowSymLinks. Just place “-” (minus) before Indexes.

# The Options directive is both complicated and important.  Please see
# for more information.
Options -Indexes FollowSymLinks

FollowSymLinks enables Apache to follows symbolic links. If you haven’t any symbolic links inside document root turn it off too with “-” before like -FollowSymLinks.

7. Make webalizer logs accessible only to your IP
After all this settings, it is good to monitor and analyse Web traffic. Why? First of all, only owner should be able to access Web statistics to avoid “referer spam” attack. What is referer spam attack? Client with fake referer frequently accesses site with public Web statistic and his only goal is to appear on referer top list. This way they got free link. Many useful informations can be read from Web statistic. For example, when is minimum load of site then is perfect time for backup and database optimization, or you can see top list of sites by hits and KBytes etc. By default, webalizer.conf allows access only from local host. Comment this two lines and add one with your IP or name like in example:

<Location /usage>
  Order deny,allow
  Deny from all
  # Allow from
  # Allow from ::1
  Allow from
  Allow from

8. Conclusion
If you install LAMP server and run it immediately without any of steps mention here it will certainly work. On the other hand if you finish every of this steps, your site will not became unbreakable. Bottom line is, if you complete these steps, you will minimize possibility to be attacked and attacker will move on to find easier target.

Now it’s time to make it faster!

7 thoughts on “LAMP setup: Apache and PHP”

  1. I did follow your steps, but one thing is above my head, I have 2 GB ram and still its showing free memory like 100 MB most of the time don’t know why so much buffer LOL any solution to that.
    Ty for the tutorial M8

  2. You don’t need any solution to “much” buffering unless your system start to swap. Reading from a disk drive is slow compared to accessing memory. So, Linux memory management caches all disk traffic including HTML files (in case of WEB server). After WEB server boot, free command shows a lot of free memory. Few moments later (depending on system load), free memory drops to lower value and that’s normal behaviour. I would be worried only if I see used swap space all other will be fine.

  3. Hey this is an amazing guide.

    I have been searching the net for days wondering on how to configure apache to work on my website.
    I been having trouble with the ammount of processes and alot of memory being used.
    Today I have found the website was just not loading at all.
    Memory was fine also Load Averages and CPU was fine also.
    I had no idea why this was happening. I mean I woke up to find the website was unbarably slow.

    For 4 days now I have been trying to configure my VPS as best as I could monitering everything.

    Its just showing different signs all the time..

    I managed to go through everything I think I don’t need and disable it in apche and php.ini aswell as rename some of the .ini scripts.
    My memory is still high.. I dunno why this is???
    Its using like 1gb with 128 processes running. Without Apache its on 40.
    There is also only 7 users connected to the forums at the time of this reading from top.
    I’m confused..

    Is there any chance I could get some help?
    I been banging my head against walls for ages.. I dunno what todo now. I feel like I am out of options.

  4. FollowSymLinks should always be enabled, since disabling it FORCES a stat() to make sure the file _isn’t_ a symlink. If enabled, it just doesn’t care.

  5. This is really simple and useful article.

    Oh btw, why don’t you enable the http compression (deflate)?


  6. @perdurabo0 – Thanks for a tip to turn on FollowSymLinks in Apache configuration. I found a very good article which explains FollowSymLinks directive and why to turn it on. Here is article snippet:

    If you are concerned about performance, then always use Options FollowSymLinks. Options FollowSymlinks permits Apache to follow symbolic links in the manner of most Unix applications which is that Apache does not even need to check to see if the file in question is a symlink or not. Enable FollowSymLinks by default and disable it where necessary case-by-case.

    Looks like my post needs a little refreshment …

    @NanoG6 – mod_deflate can significantly reduce bandwidth but in some cases performance of the site under load can be considerably worse than without compression. Here is excellent article which measures the performance effects of mod_deflate in Apache 2.2. Anyway, I would suggest to use caching system which will compress content only once (first time). For every other request of the same page, caching system will fetch compressed page and forward to the Apache (Apache only needs to add HTTP headers). This way compressed page will be delivered many times until cache expires. The same model is used on my site. I can’t turn on mod_deflate because of shared host policy. But with WordPress cache plugin for dynamic content and manually gzipped static content (like CSS and JS files) I reduced bandwith without compromising site performance.

Leave a Comment