We’ll show you, How to secure LAMP server. The LAMP stack which stands for Linux, Apache, MySQL/MariaDB and PHP/Python/Perl is a very popular combination of free and open-source software used to run millions of websites today. Although many opt for the much efficient LEMP stack based on Nginx instead of Apache, there are still a significant number of users that choose LAMP for their projects. In fact, more than 30% of the active websites today run on top of LAMP. The stack is considered as reliable and very suitable for running high-performance high-availability web applications. Securing LAMP server is not complicated but it is a long process and it should take 15-20 minutes to secure every aspect of the LAMP stack. Let’s dive in!
Table of Contents
1. Enable automatic updates
Having in mind that the LAMP stack is based on Linux and the whole open-source community works on improvements, it is considered as secure too. On an Ubuntu VPS, all security updates and patches are available as an automatic unattended install as soon as they become available in the Ubuntu repos, and therefore, make sure you configure your system to automatically install the security updates if you are concerned about the security. In case this feature is not enabled on your server and you are not installing the latest upgrades and patches manually, you are putting your server at risk of being exploited.
To enable automatic unattended upgrades you should install the unattended-upgrades package.
sudo apt-get install unattended-upgrades
To configure which category of packages to be automatically upgraded you should edit the /etc/apt/apt.conf.d/50unattended-upgrades file.
2. Configure firewall
Having a properly configured firewall is another thing that is very important for the overall security. ufw is the default firewall configuration tool for Ubuntu and it is initially disabled. To enable ufw you can use:
sudo ufw enable
Enable access to the basic services like OpenSSH and Apache:
sudo ufw allow 22 sudo ufw allow 80 sudo ufw allow 443
Enabling access to other services is pretty easy. Just replace the port number in the examples above with the port number of the service which you want to enable access to and that’s it. The firewall rules will be active even after system reboot.
3. Disable unused services
If you have active services which you are not using, you can simply disable them. For example, if you have service like Dovecot up and running on your server and you are not using it at all, stop and disable the service using the following commands:
sudo systemctl stop dovecot.service sudo systemctl disable dovecot.service
4. Install Fail2ban
Fail2ban is a service which scans the log files for too many login failures and blocks the IP address which is showing malicious signs. This service is very useful if you are not using two factor or public/private authentication mechanisms on services like OpenSSH. To install Fail2ban, run this command:
sudo apt-get install fail2ban
Create a copy of the default configuration file so you can safely make changes without them being overwritten by system upgrades:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Edit the jail.local file:
sudo nano /etc/fail2ban/jail.local
The [sshd] block should look like the following one:
[sshd] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 5 bantime = 600
Save the file and restart Fail2ban for the changes to take effect:
sudo systemctl restart fail2ban.service
Enable Fail2ban on system boot:
sudo systemctl enable fail2ban.service
5. Hide Apache sensitive information
The default Apache configuration provides much sensitive information which can be used against the service. Making this information hidden is crucial so go ahead and create a configuration file for your new settings:
sudo nano /etc/apache2/conf-available/custom.conf
Paste the following content:
ServerTokens Prod ServerSignature Off TraceEnable Off Options all -Indexes Header unset ETag Header always unset X-Powered-By FileETag None
Enable the headers Apache module if it is not already enabled:
sudo a2enmod headers
Enable the configuration:
sudo a2enconf custom.conf
Restart Apache for the changes to take effect:
sudo systemctl restart apache2.service
6. Install and enable mod_security
Mod_security is a web application firewall (WAF) which can be installed as an additional module for Apache. It can be used to protect the web server from numerous attacks like SQL injections, session hijacking, cross site scripting, bad user agents and many others. To install and enable mod_security run the commands below:
sudo apt-get install libapache2-modsecurity2 sudo a2enmod security2
Once it is installed you should configure the module and enable the OWASP ModSecurity Core Rule Set (CRS).
sudo mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
Then, open the /etc/modsecurity/modsecurity.conf file and edit/add the following settings:
SecRuleEngine On SecResponseBodyAccess Off SecRequestBodyLimit 8388608 SecRequestBodyNoFilesLimit 131072 SecRequestBodyInMemoryLimit 262144
Save and close the file. Remove the current CRS and download the OWASP CRS by using the following commands:
sudo rm -rf /usr/share/modsecurity-crs sudo git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git /usr/share/modsecurity-crs cd /usr/share/modsecurity-crs sudo mv crs-setup.conf.example crs-setup.conf
Edit the /etc/apache2/mods-enabled/security2.conf file. It should look like the one below:
<IfModule security2_module> SecDataDir /var/cache/modsecurity IncludeOptional /etc/modsecurity/*.conf IncludeOptional "/usr/share/modsecurity-crs/*.conf" IncludeOptional "/usr/share/modsecurity-crs/rules/*.conf </IfModule>
Finally, restart Apache for the changes to take effect:
sudo systemctl restart apache2.service
7. Install and enable mod_evasive
Mod_evasive is an Apache module which can be used to protect the web server from DoS (Denial of Service), DDoS (Distributed Denial of Service) and brute-force attacks. To install mod_evasive on your server, run this command:
sudo apt-get install libapache2-mod-evasive
Open the default configuration file /etc/apache2/mods-enabled/evasive.conf and edit the settings to look like those below:
<IfModule mod_evasive20.c> DOSPageCount 5 DOSSiteCount 50 DOSPageInterval 1 DOSSiteInterval 1 DOSBlockingPeriod 600 DOSLogDir "/var/log/mod_evasive" </IfModule>
Save and close the file. Create a directory for the log files:
sudo mkdir /var/log/mod_evasive sudo chown -R www-data: /var/log/mod_evasive
Restart Apache:
sudo systemctl restart apache2.service
8. Secure the MySQL server deployment
The first thing you need to do to secure the MySQL service is to run the mysql_secure_installation script.
sudo mysql_secure_installation
The script will help you to perform important security tasks like setting up root password, disable remote root login, remove anonymous users etc.
9. Disable remote MySQL access
If you don’t perform remote operations over your MySQL server then disabling the remote access to the service is a very important thing to do. You can do this by editing the /etc/mysql/mysql.conf.d/mysqld.cnf file and changing the bind-address to 127.0.0.1.
bind-address = 127.0.0.1
Restart the service for the changes to take effect.
sudo systemctl restart mysql.service
10. Create separate MySQL users
Another thing you need to consider is creating separate MySQL users for each database and application.
Log in to MySQL as root:
mysql -u root -p
You can create MySQL database and grant all privileges to a new user using the following commands:
mysql> CREATE DATABASE new_db; mysql> GRANT ALL PRIVILEGES on new_db.* to 'new_user'@'localhost' identified by 'PaSsW0rD'; mysql> FLUSH PRIVILEGES; mysql> EXIT
Then, you can use the newly created database and user for your application.
11. Disable LOCAL INFILE
If you explicitly don’t use LOCAL INFILE then it is good to disable it. Again, edit the MySQL configuration file and add the following line under the [mysqld] block:
local-infile=0
Restart the MySQL service for the changes to take effect.
12. Secure PHP
If you performed the steps above, your server should be already secure. The last part of securing the LAMP server is securing PHP, which is a pretty straightforward process. Find the location of your PHP ini file:
php --ini | grep "Loaded Configuration File"
All changes we will be making into this file.
13. Hide PHP basic information
The first step is to hide the information provided by PHP which some attackers may find useful. Open the php.ini file and change the settings to match the following:
expose_php = Off display_errors = Off mail.add_x_header = Off
Save the file and restart Apahce:
sudo systemctl restart apache2.service
14. Disable dangerous PHP functions
The disable_functions directive allows you to disable some functions that could be harmful to your system. Edit the directive in your php.ini file to match the following:
disable_functions = show_source,system,shell_exec,passthru,exec,phpinfo,popen,proc_open,allow_url_fopen,curl_exec,curl_multi_exec
While you are here, disable the remote PHP code execution by using the following settings:
allow_url_fopen=Off allow_url_include=Off
15. Restrict file uploads
If you don’t use file uploading features it is totally safe to restrict the file uploads in PHP. Open the php.ini file and set the following setting:
file_uploads=Off
In case you are using file uploading features you can set the following:
file_uploads=On upload_max_filesize=1M
where upload_max_filesize is the upload size limit.
Restart Apache after making these changes.
16. Set maximum execution time
Again, edit the php.ini file and change the following settings:
max_execution_time = 30 max_input_time = 30 memory_limit = 40M
This sets the maximum time in seconds a script is allowed to run or parse data as well as will set the maximum amount of memory that a script is allowed to allocate.
17. Enable open_basedir
The open_basedir directive allows you to set the location from which PHP is allowed to access files. Edit the php.ini file and set the correct location to match your current configuration:
open_basedir="/path/to/the/directory/"
Don’t forget to restart Apache so the changes can take effect.
Of course, if you are one of our LAMP Hosting customers, you don’t have to secure your LAMP server, simply ask our admins, sit back and relax. Our admins will secure your LAMP server for you immediately.
PS. If you liked this post, on how to secure your LAMP server, please share it with your friends on the social networks using the buttons below or simply leave a comment in the comments section. Thanks.
This command doesn’t work (shows php cli ini):
php –ini | grep “Loaded Configuration File”
Make sure that you can access the PHP Command Line Interface using the
php
command. You can use the TAB key to auto-complete the command and check if the php binary is under different name likephp5
orphp7.0
for example..
Excellent article mate, implementing this suggestions right now.
Perfect! 10/10 will use again!
very useful thanks for sharing :V
This is very useful. Does this apply equally to PHP 7.2? Thanks,.
Yes, you should be able to implement this on a server with PHP 7.2
This is the very useful for me, thx for sharing :)
Anyone getting to this page from Google for the newest Ubuntu version, 20.04, step 6 fails:
sudo apt-get install libapache2-modsecurity
E: Unable to locate package libapache2-modsecurity
The correct package/command:
sudo apt-get install libapache2-mod-security2
Haven’t researched specifically why
The tutorial has been updated.
Thanks.