Securing your MySQL installation

The MySQL installation package takes care of most of the things automatically but we still need to do some extra manual steps to make sure that our MySQL database is safe from outside attacks as it is going to be on a server directly connected to the internet.
Copy the example configuration file from the MySQL source, ‘/usr/local/mysql/support-files/my-medium.cnf’, to ‘/etc/my.cnf’ and set the appropriate permissions:

chmod 644 /etc/my.cnf

Next, we must remove the sample database (test) and all accounts except the local root account because we don’t need them and they pose a security risk as everyone knows they are there to abuse. Please note that you should only do this if you install a new instance and not if you are upgrading or you will loose all your current users.

Start mysql from the terminal and enter the following commands:

mysql> drop database test;
mysql> use mysql;
mysql> delete from db;
mysql> delete from user where User = '';
mysql> flush privileges;

This will prevent the database from establishing anonymous connections and removes the test database with the accompanying permissions.

To change the password for the ‘root’ account you can use the following commands from the MySQL terminal:

mysql> update user set Password=PASSWORD('new_password')
        where User='root';
mysql> flush privileges;

Don’t forget to flush privileges; to make the privileges effective.
It is also recommended to change the default name of administrator’s account (root), to a different, harder to guess one. Such a change will make it difficult to perform brute-force and dictionary attacks on the administrator’s password. In this case the intruder will have to guess not only the password, but first and foremost, the name of the administrator’s account.

mysql> update user set user="mydbadmin" where user="root";
mysql> flush privileges;

Another change applies to the 3306/tcp port, on which MySQL listens by default. Because, according to the initial assumptions, the database will be used only by locally installed PHP applications, we can freely disable listening on that port. This will limit possibilities of attacking the MySQL database by direct TCP/IP connections from other hosts (This can also be accomplished by blocking this port using the Firewall). Local communication will be still possible through the mysql.sock socket. In order to disable listening on the mentioned port, the following parameter should be added in the [mysqld] section of ‘/etc/my.cnf’:

skip-networking

If, for some reason, remote access to the database is still required (e.g. to perform remote data backup), the SSH protocol can be used to connect to the server and execute a command locally, for example to create a backup you could type:

otherhost$ ssh mysqlserver /usr/local/mysql/bin/mysqldump -A
        > backup

Administer your MySQL server

You will need to administer your server, you could use the Terminal commands but that is a bit tedious. There are nice administration tools available even from MySQL, or web based like phpMyAdmin. The installation of the MySQL administrator is just like a regular application, the installation of phpMyAdmin will be discussed elsewhere because you need to install PHP first.

7 Responses to “Securing your MySQL installation”

  1. Paul Says:

    Most (if not all) the above can be done by running the script that comes with MySql:

    cd /usr/local/mysql/bin
    sudo mysql_secure_installation

    Answer the questions that are put to you and thats pretty much it.

  2. Michael Says:

    Another way to make mysql more secure, if you’re keeping the networking, is to use a port other than 3306. Pick a random number, like 13579 and use that. You won’t get a logfile full of password crack attempts.

  3. Richard5 Says:

    @Michael, security by obscurity is never a serious solution. A serious hacker always does a complete portscan and will notice the difference in portnumber.

  4. Michael Says:

    Richard5, absolutely, but it does keep the trivial scripts from hitting it. It protects against script kiddies and not much else. If you choose to keep it open, it doesn’t hurt to change the port.

    It’s no substitute for good security, or a firewall rule that restricts access to a limited range of domains.

  5. James Brown Says:

    Small typo Richard: in second last sentence of third last paragraph it reads:

    Local communication will be still possible throw the mysql.sock socket.

    Should be:

    Local communication will be still possible through the mysql.sock socket.

  6. Richard5 Says:

    @James, thanks typo is fixed !

  7. TigerKR Says:

    I was not able to run mysql from the terminal. I would get the error:

    ~: mysql
    ERROR 1045 (28000): Access denied for user ‘username’@'localhost’ (using password: NO)

    I was able to workaround this by typing

    ~: mysql -u root -p

    and then when it asks for a password, don’t enter one, just hit the return key