Step 1: Run MySQL in a chroot jail
Chroot creates a new root directory structure for an application and restricts the files it can access within the operating system. If your MySQL server gets hacked and the attacker gains a shell on your server all they will see is a restricted environment While chroot can be bypassed it does provide defence in depth and may prove to be invaluable in the event of a MySQL 0-day exploit. Most script kiddies will go for the low hanging fruit and the added difficulty of the chroot jail may just move them along to easier picking.
The steps involved in configuring a chroot jail for MySQL are outside the scope of this article but full details can be found in the article "Securing MySQL: step-by-step".
Step 2: Restrict or disable remote access
MySQL runs on a default port of 3306. If you are running your MySQL server on a separate server from the application server then you should restrict access to this port using a host-based firewall such as IPTables.
If you are running both your application server and your MySQL server on the same server then you can disable networking completely in MySQL and use Unix sockets as the communication channel instead. This stop the MySQL server listening for network connections and further reduces the attack surface of the server.
Step 3: Change default root password and change root username
By default the root MySQL account contains an empty password. This should be changed as soon as your MySQL installation is complete.
It is also a good idea to change the name of the root account to something else. This will create an additional level of obfuscation if an attacker attempts to brute force the password for the root account.
Step 4: Remove anonymous accounts and accounts with empty passwords
MySQL creates accounts with anonymous access by default and, needless to say, these should be removed.
Step 5: Remove sample database
MySQL installs a sample database by default called "test". Best practise dictates that we should remove this.
Step 6: Run MySQL as an unprivileged user
MySQL should always be run as an unprivileged user in order to reduce the potential damage to the operating system and other processes in the event of a successful attack against MySQL.
Step 7: Grant minimum privileges for database users
When making connections to the MySQL database from your application you should use an account with only the minimum permissions to perform its required actions. This is in line with the principle of least privilege.
Step 8: Enable MySQL logging and restrict access to logs
Almost all startup scripts for MySQL now have logging configured but you should always ensure that MySQL is logging to the /var/log/ directory to make analysis of logs easier in an incident response situation.
Step 9: Encrypt data stored in the database using MySQL built-in functions
If the data being stored in the database is sensitive then it should ideally be encrypted. MySQL provides inbuilt SQL functions to encrypt and decrypt data using the AES encryption protocol. The only problem with this method of encryption is that the password used to encrypt and decrypt the data must be hard coded into the SQL statements in the application. While this is a problem it does however keep the data safe if the database is backed up to a remote server. It also provides some degree of obfuscation in the event of an attacker gaining access to the operating system.
Step 10: Keep a look out for patches
While all these steps will help harden your MySQL server against attacks all your good work could go out the window if you don't keep abreast of new vulnerabilities for MySQL.
These MySQL fortifying steps are provided by Irish security company Espion. Espion provides IT security services including vulnerability assessment and penetration testing for networks & applications, IT infrastructure review and Audit, security policy & procedure review.