How To Secure Apache Web Server

Sarath Pillai's picture
Methods to secure apache web server

Apache and Nginx together contribute to at least 80 percent of the websites running on the entire internet. If you are a customer of a hosting service provider or a company, then also you are using Apache most of the time to run your website (because most of the hosting companies run cpanel Apache at the backend. Although, you cannot customize and configure Apache in such cases to your own wish ).

In this post we will be discussing actions and methods that need to be taken to secure your Apache web server to a certain extent. According to me you really cannot completely secure any server (primarily because each day some or the other vulnerabilities are discovered).  I remember the below line which I read somewhere…


“If you need your server to be really secure. Then do not connect it to a network”


It’s not at all a good idea to rely only on your checklist of actions to secure your Apache web server. Because, the things done by humans manually are always error prone. So I will never recommend to only do things like the ones mentioned in this article, for securing your web server. 

I strongly believe there must be an automated routine scan (which is both internal scan and external), to keep your system double checked of any known vulnerabilities. There are paid products like Qualys, and open source products like Nessus etc, to help you keep your servers and applications routinely checked.   

These days a cloud server instance has become so cheap that, it’s a good idea to go with a cloud instance, rather than a shared hosting provider (especially because of the flexibility and resources that you get). There are many cheap VPS and Cloud instance providers like Linode, Digital Ocean etc. I believe these steps mentioned here in this article, can prove helpful to people who have a few of their servers running in their own dedicated hardware/cloud server. For large organizations and companies having very big architectures, I really do not recommend this kind of manual check list for implementing security. They must really go for something like Nessus or Qualys for a routine check.  But yeah, some of the points that we discuss here can also help you to fix vulnerabilities identified by products like qualys and Nessus.


The topic of web security is beyond the web server package itself(We will only be discussing the Apache web server package and its related security configuration on a Linux server). Configuring web server package and scrutinizing it is only a starting point. Also other web security vulnerabilities do not directly rely on the web server. For example, Firewalls, DNS for your web server, Network security etc are all part of web security. Discussing all of those aspects of web security is beyond the scope of this article. 



1. Unprivileged User for your Apache Web Server. 


Most of the Linux distribution has got a default user named nobody (which of course is unprivileged user used to run some daemons securely ). The main idea behind running a process like Apache with an unprivileged user is that, even if somebody compromises your web server, he should only be able to do whatever that user(with which your web server process was running) is permitted to do. 


But as nobody is a default unprivileged user, most of the daemons and applications, uses it by default. Hence i do not recommend running Apache as user nobody. Create a new unprivileged user of your own wish to run Apache. 

#groupadd apache
#useradd apache -g apache -d /dev/null/ -s /sbin/nologin


The above shown commands will do the following things.

  • It will create a group named apache.
  • It will create a user named apache as part of that group (group Apache we created with the first command), and make its home directory as /dev/null and login shell as /sbin/nologin (Basically the user will not get a shell or say will not be able to login)

Now once, that is done, modify your Apache configuration file with the following content.


User httpd
Group httpd



There is a term in information security, or i must say security in general called as compartmentalization. The idea behind compartmentalization is that a whole system, like a Linux server (which of course can have many different services running at one time), but all of them must be separated from each other in a good manner, so that if something happens to any of them should never affect the other. Having a unique isolated user for each of your running services on your server can ensure this from a privilege perspective in case something happens.


2. Install Apache from Binary for more security


I know there are two school of thoughts regarding how to install Apache for better security. Some might not agree with me regarding my suggestion of installing it from binary but i recommend installing Apache from binary because of the following reasons.

  • Installing from binary is much easier compared to installing from source. Due to its simplicity of installation procedure, its less error prone. Given the fact that most of the organizations employ novice administrators to get such tasks done ( people who are new to security and system administration, often aim at finishing the task rather than getting it done in a secure way).
  • The vendor of your operating system, who provides the binary package might have already customized it to fit well with your environment.
  • All Linux distribution vendors, does go through a rigorous testing before releasing an upgrade or a package to its official repository. Hence i must say, it must have already went through a lot of testing before you install.
  • Updates to critical security issues, are provided by the vendor itself, and are easier to apply(Most of the times you can apply these updates automatically)


3.Small and minimalist HTTP configuration File

A couple of months back, i was reading some security related white papers, and one of their suggestion appealed a lot to me. Its nothing but....

Keep your configuration file small and short, and you must be aware of what is enabled and what is not...small files are easier to read and digest..


You must be aware of the fact that the default Apache configuration file is too long (Probably because of too much comments ). And when the file is too long, you are sure to miss some options which are enabled/disabled, while skipping through the file. Hence my recommendation for is to start from an empty Apache configuration file and then start adding configuration options, which are really required for your website to function properly.


4. Only Allow DocRoot To be Served

Apache can serve any file that it can access. Although its a nice feature, but from a security stand point its a risky thing. If a file has read permission for Apache, then that file can be opened by the end user by url encoding the request with characters like ..%2f & %2e%2e%5c to traverse directories and directly access the intended file.


Hence its a nice habit to only allow the docroot to be served to all, and deny the rest. The below code snippet will only allow our doc root and deny / directory altogether.

<Directory />
Order Deny,Allow
Deny from all
<Directory /var/www/html>
Order Allow,Deny
Allow from all


5. Do not Reveal Apache server information

Collecting information about a web server is the first thing that an intruder does. The more amount of information he has, more is the chance of a successful break in. Hence system administrators needs to configure their web server in such a way that it reveals less amount of information about itself.

Apache by default will show its own version and system details, when it encounters a 404 or other such errors. The below configuration will not show those version information to others. 


ServerSignature Off
ServerTokens Prod


6.Allow only required HTTP methods

There are different types of HTTP methods, that a user agent sents to a server for different purposes. Some example's of HTTP methods are mentioned below.

  • GET
  • POST
  • PUT
  • HEAD

The point to note here is to only allow those methods that are really required for proper functioning of your web site. You can disable/enable different method types using ModSecurity in Apache. But as ModSecurity is a big topic in itself, we will using LimitExcept(Which is a directive in apache config file).


Deny from all


Unfortunately TRACE method cannot be disabled using the above shown method.


HTTP trace is basically used to debug server side issues. It will basically return the request received by the server back to the client. Hence the client will know exactly how the server sees the request.


You can disable TRACE Method in apache as shown below.


TraceEnable Off



7. Put Apache inside a chroot Jail environment

A good security measure that must be taken for any publicly available services like ftp or http is to enable chroot environment.


Chroot is nothing but a method used to limit access to the file system when accessed by a particular process. This works by simply by selecting a folder and making it the new file system root.  Chroot has several advantages, which are mentioned below.

  • Even if somebody manages to get in, he will be only able to access the restricted environment (or say part of the file system, which we made as root for that process. in our case apache). Intruder will not be able to touch other files.
  • No shell and no other tools like compiler will be available to an intruder, if he gets inside a chrooted environment. Due to which the things that he can execute will be minimal. I must say, he will have only the things available inside that chroot environment(files and executables inside that part of the file system)

As we just discussed, putting an application inside chroot has a main advantage of limited access. This is because you can only run things which are inside that chroot directory. which means if i want to run apache inside a chroot jail env, then i will need to copy all shared library files to the chroot directory, so that apache can run it. if i need php, then i will have to copy all php required libraries to my chroot directory, similarly perl etc.

Chroot is nothing but making a new root directory (/ directory for your process to run...Hence all config files, library files will now be inside your new root directory)

Read: Chroot apache in ubuntu


8. Show Custom Error Messages


Each and every web server has its own style of showing error messages. Sometimes attackers can purposely request a page that does not exist on the web server to check the error message (because they can identify the default error message and find the web server version)

To avoid such loopholes, i recommend to provide custom error messages for all well known HTTP error status codes. Like for example show our own message for 400, 401, 500, 404 etc.

This can be done in apache as shown below.


ErrorDocument 400 /mycute400.html
ErrorDocument 401 /mycute401.html
ErrorDocument 403 /mycute401.html
ErrorDocument 404 /mycute404.html
ErrorDocument 405 /mycute405.html
ErrorDocument 500 /mycute500.html


9.Delete Default Files in Apache


Almost all web server's comes with some default files, which can be helpful to the system administrator to set the server up initially. Although they can be informative and helpful in the beginning, then can cause security problems later down the line.

This is because, these files can reveal a lot of information about the web server to an outsider. The files that we need to remove from the web server are mentioned below.

  • Default HTML files. These files are sometimes used by Apache to show a default web page to system administrator. This can act as a confirmation message to a system administrator that the web server is working as expected.
  • Default CGI scripts. Apache comes with a couple of default CGI scripts. CGI scripts always had a bad reputation in the security arena. By default Apache comes with printenv and test-cgi scripts. Both of these should be removed or renamed.
  • Also remove apache manual directory.


#rm -rf /usr/local/apache2/htdocs/*
#rm –rf /usr/local/apache2/cgi-bin/*
#rm –rf /usr/local/apache2/manual


10. Disable Directory listing in apache


If you do not have an index file inside your docroot, the default behavior of apache is to list the contents of that directory. Which means it will show all files inside that directory inside the browser itself. Like click and open/download them.

This behavior should be turned off, as it can reveal hell lot of details about your docroot.

The below options directive can be used to disable directory listing in Apache.

<Directory /var/www/html>
Options -Indexes


Once you have done the above configuration, the default directory listing for that directory will be replaced by a HTTP forbidden message.


11. Only Allow known versions of HTTP protocol


Its a good idea to not to respond to a request that has an unknown http protocol version number. Simple curl like programs can send malformed http protocol version numbers to a web server to see how a server responds to such requests. Such things basically proves useful to a person trying to collect information from a target server.

So we need to restrict the versions of HTTP prtocol's that are allowed. This can be done as shown below.

RewriteEngine On
RewriteCond %{THE_REQUEST} !HTTP/(0\.9|1\.[01])$
RewriteRule .* - [F]


12. Limit types of files that are allowed in apache


There can be files inside your document root, that contains critical code internal's and other details. Those files, when requested directly should be forbidden for an end user. This can be achieved by restricting the types of files that are allowed to server. Or say, let's put a limitation on the file extentions that are allowed to be served.


We system administrator's do name files like .backup, or .old etc for making another copy or backup, so let's not allow those common extention types.


<Files ~ "(.bak|.config|.old)">
Order allow,deny
Deny from all


So go on adding the extentions, which you do not want to be served.


13. Some level of protection against DOS attacks in apache.


Although a complete protection against a DDOS attack is not at all possible with the below methods, you can still survive against small bandwidth attacks. Protecting your server from large and huge ddos attacks are beyond the scope of apache (and any web server for that matter). This is primarily because web servers are not made to solve that problem, and cannot go beyond a certain extent to protect themselfs against such attacks.

A strong traffic filtering based on packet size, packet headers etc must be in place before the traffic even hits your web server. Such things are carried out by network providers who has the hardware for deep packet inspection and fast processing/filtering based on the critieria given by the end user. Discussing such measures is beyond the scope of this article.

Hence let's discuss the things, that a system administrator can do to protect his apache web server, or i must say a minimal level of protection against such small attacks.


Related: How to protect and secure Apache from Slowloris attack

Opening a connection to a web server will consume its server resources. Too many connections means too many resources (at least in case of apache, if there are too many active connections, then too much resources are being used.)

Read: Primary difference between Nginx and Apache


Attackers can take advantage of this and can consume server resources by opening too many connections and never close them. Due to which your web server will then not be able to serve other legitimate requests. You can prevent this from happening to a certain extent by tweaking the TimeOut value in apache.

Timeout Value in apache tells the amount of time in seconds to wait(before closing the connection), before the server receives a message from the client.

The default timeout value is 300 seconds. That's too long a time to wait for each connection made to the server. So let's reduce it to something like 10 seconds.


Timeout 10


Whenever a client requests a page, there can be multiple resources inside the page. All of those resources, needs to be fetched by seperate requests. So if Apache closes a connection after serving a requested resource, then another request from the same client has to begin with again creating a connection first. this is a heavy cpu intensive task(well if the server is high traffic). Also it will be slow in performance for the client.

So there is a mechanism in apache to keep the connections alive for a certain amount of time, so that once the client has successfully established a connection, he can get his subsequent requests served faster (because he does not have create the connection again). This setting is called as keepAlive.

Although its recommended to turn keepalive setting on, for performance reasons, the time in seconds for which the server will wait should be less, because an attacker can otherwise make a lot of connections and unnecessarily keep on resetting the timer, by sending junk requests. Hence lower the keepalive, higher the RAM on the server for new connections.


KeepAlive On
KeepAliveTimeout 15


14.Limit HTTP Request Body, Field & Size in Apache


Limiting request body is a good thing to do, as it adds a level of restriction on the client in the amount of data that it can send to the server. For example, if you have a web server which accepts forms and data files back from the clients. In other words, HTTP POST and PUT requests.


<Directory "/var/www/html">
    LimitRequestBody 102400



The above setting will only allow 10Kbytes to be the maximum size. Now if you want you can increase it as per requirement. The value shown in the above configuration is in bytes.

Another thing that we need to limit on the server side is the amount of additional headers, that a client can send to the server. This can be done on apache web server as shown below.


LimitRequestFields 20



The above shown example will only limit the number of additional headers, but let's go ahead and fine tune it, so that there is a limitation in the size of the headers that the server will accept.


LimitRequestFieldSize 7000


15. Restrict access to required network

Sometimes you do not want your website to be accessible to the external world. Or say one specific directory (doc root ) to be accessible to only one specific subnet, then its better to configure the docroot to allow only access to those subnet.

This can be done with Allow, Deny parameters inside your required directory definition as shown below.


<Directory /var/www/html>
  Options None
  AllowOverride None
  Order deny,allow
  Deny from all
  Allow from


16. Disable unwanted modules, while compiling from source

Installing apache from binary is my choice, but there are times when you require modification on the default set of features included in apache. In such cases, people find installing from source package useful.

There are few modules that can be disabled, for security reasons as shown below.


./configure --disable-userdir --disable-autoindex --disable-status --disable-negotiation



userdir: User related directories in will be visible in URL. In other words, username's in the URL will get converted to user's directory path

autoindex: This will right away disable directory listing during the installation itself. Rather than disabling it by the earlier method we have seen.

Status: This is a module that is generally used to display apache server current status

negotiation: This will disable content negotiation in apache server


17.Disable Htaccess if not required

There is a feature in apache where each document root directory can have its own configuraion file. This is an awesome feature where the user, who is responsible for that specific directory can have his own set of configuration, without modifying the main httpd.conf file.

This becomes handy, where your apache web server is being used by different users for their own personal web sites. A configuration which is most highly used by shared webhosting companies.

For example cpanel. Where a webserver can be used to host so many websites, each having their own document root, with their own specific configuration. This specific configuration will override the server wide configuration file http.conf

But its always better to disable this feature if not actually required.


<Directory /var/ww/html>
  Options None
  AllowOverride None
  Order allow,deny
  Allow from all


18. Force X-XSS-Protection

Almost all major browsers has a feature to protect from cross site scripting. However this is not enabled by default or sometimes disabled by the user. This can be enabled on the server side, and force the client to use it.

This can be done by adding the below configuration inside your apache configuration file.


<IfModule mod_headers.c>
    Header set X-XSS-Protection: "1; mode=block"



19. Disable Etag


Etags (Entity Tags) are used to verify whether the component in the web browsers cache is same as the one in the web server. I must say etag's are used to identify a specific version of the content. So basically browser compares the etag returned by the server with the version of the document it already has in its cache. 

After the comparison, browser returns the etag back to the web server, and if the server finds that the etags matches with the etag given by the web server, then the server will return a 304 response, saying not modified.

By default apache uses inode numbers and timestamp to create Etags. There is a vulnerability in apache with regard to its etag, where an attacker can get inode details, child process id's etc.


Refer: ETAG vulnerability cve

This can be secured by disabling etag headers altogether on apache web server. Please note the fact that, the caching capabilities will then depend on the web server.


FileETag none


20. Use higher key length for SSL


If you are using SSL, its always better to use higher key length for your keys. Although its not at all an easy task to compromise SSL, i would recommend the use of high key length.


Read: SSL working Explained


A 2048 bit key can be created, while you create the SSL key and csr, before submiting to your Certificate Authority, as shown below


openssl genrsa -des3 -out myservere.key 2048
openssl req -new -key myserver.key -out myserver.csr


Now submit the myserver.csr file to your CA to get signed.


21. Disable SSL version 2 in apache for more security


SSL version 2 is allowed by default on almost all web servers. SSL version 2 has many known vulnerabilities, and must be disabled. You can disable SSL version 2 on your apche web server as shown below.


SSLProtocol –ALL +SSLv3 +TLSv1



22. Disable weaker SSL ciphers


SSL ciphers and their allowed list is mentioned on the web server. Almost all web servers by default allows all common ssl ciphers out there. This is probably because of compatibility reasons, so that even older web browsers can work with any of the allowed list of ciphers allowed by the server.

However some ciphers like RC4 have very well known vulnerabilities, and must be disabled to prevent from man in the middle attacks, or other data tampering.

Each web server (no matter whether its Apache or not) has a list of ciphers that it allows. The order in which these ciphers are mentioned on the web server plays a major role in the selection process. 

So its always better to force Higher secure ciphers, and should come first in the order. The below apache configuration will enforce high order ciphers, and will disable RC4 ciphers, and other weaker onces.




23. Disable modules that are not required for your website.

It is possible that many of the modules which you have currently enabled on your server, is not really required for your website. Disabling as much features as possible can really save your server from unknown loopholes.


A quick grep on your web server configuration file can reveal all the modules loaded (apart from default ones embedded into apache itself).


grep LoadModule httpd.conf


Hope this tutorial was helpful in achieving a basic security on your apache web server. I will modify this article from time to time, to add more points as i learn them.

Rate this article: 
Average: 2.8 (120 votes)


item number one states to create a user/group "apache", then edit apache config file to include User httpd / Group httpd - - shouldn't this be User apache / Group apache ? also take out the "#" so noobs don't actually use that.

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.