Shadowserver has announced that they found over 3.6 million MySQL servers exposed to the web, following their Accessible MySQL Server Report.
At Vettabase we have no way to verify their data (it would be quite surprising if we had!), but we have no reasons to think they lied or exaggerated. And, alas, their numbers don’t surprise us.
Here I want to share some hints about avoid exposing MySQL/MariaDB servers to the internet, and some security features related to this problem.
About versions and forks
They show statistics about the MySQL versions they found. The version numbers show it is MySQL, not MariaDB. But it could very well include Percona Server or cloud vendor forks. That said, I don’t suspect that the percentage of MariaDB insecure installations is much different.
Some of the versions they found are no longer supported. Specifically: 5.5 and 5.6. Security fixes are not released anymore for those versions. This makes the problem worse.
How to avoid exposing a server to the internet
In some rare cases, MySQL/MariaDB don’t need to use the network at all. This happens if they are only used by an application that runs on the local host. For example, if it’s used by a desktop application that runs on the user’s laptop, or if it’s used by a mail server to store emails.
In that case, just set bind_address=localhost
or bind_address=127.0.0.1
. MySQL/MariaDB will refuse connections from the network.
However, most servers need to communicate with application servers. No worries: they can do it safely inside a private network. Setting up a secure network is a task for a network engineer or a system administrator. When in-premise, this is done with a firewall that blocks connections unless they adhere to certain rules. For example, it can only allow connections to a specific address on the port 80, and forward them to a web proxy. Cloud vendors offer some native form of isolated networks, such as AWS security groups or network ACLs. One still needs to configure them properly.
Virtual private networks are a plus. Remember: just like traditional networks, they are only safe until an attacker gains access to them. There is a common misconception that this is nearly impossible with a VPN. But VPNs have bugs, and even more importantly, they are used by humans. Humans send VPN configuration files insecurely to save some minutes, and are vulnerable to social engineering attacks. And stealing your VPN configuration file could be as simple as stealing your employer’s laptop at the airport/on the train/at a cool industry event. So, while VPNs are great, we recommend to use them in combination with all traditional security practices.
Where applicable, also use iptables or equivalent technologies to make sure that most ports do not accept any incoming connections. Use MySQL Guide to Ports and Galera network ports as a reference, and make sure that other hosts can’t reach unexpected ports.
MySQL and MariaDB features that mitigate or increase the risks
Some MySQL/MariaDB features can mitigate security risks or increase them. While the basic thing to remember is that MySQL/MariaDB should never be exposed to the internet, knowing the pros and cons of these features is also very important.
This list is not intended to be exhaustive.
Good: Bound users to specific hostnames or subnets
When you create a user, you can specify from which hostnames/IPs the user can connect:
CREATE USER 'web-app'@'web-%';
CREATE USER 'web-app'@'198.51.100.0/255.255.255.0';
In my contents, I try to use two terms in an unambiguous way: username and account. In this example the user web-app has two accounts: one can connect from any server with a hostname starting with web-
, the other can connect from a subnet with an IPv4 in the specified subnet.
This is generally an excellent practice. If it is used methodically, it protects databases from internal attackers (e.g., employees secretly working for a competitor) and external attackers (in the unfortunate case you expose your server to the internet, voluntarily or by mistake). But don’t rely on this feature alone: avoid exposing your server to the internet.
Bad: MySQL password locking
MySQL 8 has a password locking feature. An account can be created in this way:
CREATE USER 'john.doe'@'%'
IDENTIFIED BY RANDOM PASSWORD
FAILED_LOGIN_ATTEMPTS 4
PASSWORD_LOCK_TIME 1;
This means that, if the user enters a wrong password 4 times, the account gets locked for 1 day. This makes DoS attacks trivial, especially if the server is exposed to the web.
Of course, one should also guess an existing username. But that could be quite easy, in many cases. One could start by root
, admin
(RDS), wordpress
, wp
… did you already blush or should I add some guesses to the list? 🙂
We can say that using this feature is a tradeoff that I don’t recommend. It makes brute force attacks impossible, but in exchange it enables trivially easy DoS attacks against a user. And that user may be a web application or the DBAs.
Good: Password validation plugins
Both MySQL and MariaDB support password validation plugins. By enabling them, you can make passwords more secure. Again: this won’t be enough if your server is exposed to the internet.
Good: Password expire
In MySQL 8, a user can be created in this way:
CREATE USER 'john.doe'@'%'
IDENTIFIED BY RANDOM PASSWORD
PASSWORD EXPIRE INTERVAL 30 DAY;
The user will be forced to choose a new password after 30 days. Other options can be used to prevent a user from re-using a password that was already used in the past. In this way, any attacker that may have found their password won’t be able to access the database again.
But it’s worth stressing again that this only mitigates a problem. Database servers should not be exposed to the internet.
Good: MariaDB unix_socket
By default, MariaDB comes with the unix_socket
plugin enabled for root
. This means that the DBAs need to log into the Linux system in order to be allowed to connect MariaDB. No other password will be required. That is a very good practice, because it avoids allowing superuser accesses from the internet.
Allowing an authenticated Linux user to access MariaDB without further authentication is not a security risk, because root
users can do whatever they want anyway: uninstall MariaDB, take a copy of the database, erase data, manipulate data…
With unix_socket
you connect as root
locally, but you have other users who can connect MariaDB via a network. So, security good practices are still needed.
Conclusions
The Shadowserver report shows that many organisations don’t follow the most basic database security rule: don’t expose a database server to the internet. We discussed several MySQL/MariaDB features that can mitigate this problem or make it worse – and, in any case, they are very important aspects of database security.
Security is a huge topic and I could have mentioned many other features – but, for example, there’s not point in granting granular permissions if anyone with an internet connection can attempt to find your root
password.
If you have troubles implementing these recommendations, or if you need advice related to your particular circumstances, consider our Database Health Checks. This service analyses every aspect of database and system configuration, including security.
Hi,
What is your opinion about adopting cis benchmarks for mysql?
How much does that help?
Regards,
Satsuah
Regards
Hi Satsuah,
We never used CIS benchmarks, so I don’t know how good they are. I’ll try to take a look at them soon if I have some time, but this is not a promise.
Cheers,
Federico