As with any server, whether it be a web server, file server, database server, etc, hardening is an important step in information security and protecting the data on your systems. This guide will show you some basics when it comes to hardening a MySQL Server. Most of these changes are simple lines to add into your my.cnf configuration file, then a simple restart of the MySQL Server for the changes to take effect.
By default MySQL connections are not encrypted and everything flows over network in open text. If you are using MySQL over a network, it is suggested to use encryption. You can refer to the MySQL documentation to understand how to configure an encryption mechanism. If your MySQL Server is on the same system as your web (or application) server and you won’t be transmitting data to and from the database over a network, then this step isn’t as important. However, if you have a standalone MySQL Server and a separate web server, then you’ll definitely want to encrypt your connection.
MySQL comes with an hardening script to check database server security and remove some default settings. You can run it with the command:
It will ask you for your desired hardening level through some questions.
Connection Error Limit
It is suggested to apply host ban to clients with many unsuccessful authentications. As stated in the MySQL documentation. Without specifying a value, the default is 100, which is on the high side. I would suggest a setting of 5.
If there are more than this number of interrupted connections from a host, that host is blocked from further connections. You can unblock blocked hosts with the FLUSH HOSTS statement. If a connection is established successfully within fewer than max_connect_errors attempts after a previous connection was interrupted, the error count for the host is cleared to zero. However, once a host is blocked, the FLUSH HOSTS statement is the only way to unblock it.
Edit the configuration file my.cnf and set max_connect_errors:
max_connect_errors = 5
Disable LOAD DATA LOCAL INFILE
The LOAD DATA LOCAL INFILE command allows users, or an attacker, to read local files and even access other files on the operating system. It is also a common command used by attackers exploiting by methods such as SQL injection. It is suggested to disable the command, edit the configuration file my.cnf and set local-infile:
Disable SHOW DATABASES
SHOW DATABASES is a command used by users, or attackers, to list all databases available. Stripping remote attackers of their information gathering capabilities is critical to a secure security posture. It is suggested to disable the command, so edit the configuration file my.cnf and add skip-show-database to the [mysqld] section:
If you don’t need to access your database from another machine it is suggested to bind MySQL service on localhost only, edit the configuration file my.cnf and set bind-address:
bind-address = 127.0.0.1
You should carefully manager users and privileges, it is suggested to follow at least these best practices:
- Each application that uses MySQL should have its own user that only has limited privileges and only has access to the databases it needs to run.
- Never use ALL TO ..
- Never use % for a hostname
- Application user permissions should be restrictive as possible
- Only allow super privileges to dba accounts, and localhost
- Never ever give users global privileges, except for root, backup user, monitoring user, replication user
Take extra caution when granting SUPER or FILE privileges: SUPER can modify runtime configuration and become other users, FILE allows reading or writing files as MySQL process
Rename root User
It is suggested to change the root login name. If an attacker is trying to access the root MySQL login, they will need to perform the additional step of finding the username.
The root login can be changed with the following SQL commands:
RENAME USER 'root'@'localhost' TO 'foobar'@'localhost';