A Complete Guide on Securing Your MySQL Server

MySQL security guide ubuntu debian redhat centos

MySQL is one of the most popular open source database management systems in the world. It powers many of the web applications and sites we use every day. However, like any powerful technology, MySQL can be vulnerable if not properly secured. A compromised MySQL server can lead to leaked sensitive data, corrupted databases, and even entire websites or applications being taken offline.

Fortunately, MySQL offers a robust set of security features that, when used properly, can protect your databases from most threats. In this comprehensive guide, we will cover all the major steps you need to take to lock down MySQL and keep your data safe.

1. Use Strong Passwords

The first security step is very basic but crucial – always use strong, complex passwords for your MySQL admin accounts. Avoid simple or easily guessable passwords.

Some tips for creating better MySQL passwords:

  • Minimum 12 characters in length
  • Mix of uppercase, lowercase, numbers and symbols
  • Avoid dictionary words and personal information
  • Don’t reuse passwords across multiple accounts
  • Consider using a password manager to generate and store passwords

It’s also highly recommended to avoid using the default root account and instead create additional admin accounts with strong passwords.

In addition, don’t run your MySQL server as the root operating system user – create a separate MySQL user account for this purpose.

2. Limit Remote Access

By default, MySQL listens for connections on port 3306 from any host. This can leave your MySQL port open to attack.

A better approach is to only allow connections from trusted hosts that need to access MySQL. Here are some ways to limit remote access:

Bind to Specific IP Addresses

In your MySQL config file (my.cnf), specify bind-address directives to restrict listening to one or more IP addresses on your private network:

bind-address=192.168.1.101
bind-address=127.0.0.1

This will make MySQL only listen on the defined IP addresses.

Allow Access Only via VPN

If your remote clients connect via VPN, you can configure MySQL to only allow connections from the VPN tunnel IP subnet.

Use Firewalls

Firewall rules provide another layer of control over remote access. With iptables on Linux, for example, you can only allow connections from specified IP addresses.

The key is to limit connections to only trusted client IPs that genuinely need MySQL access.

3. Use Secure Connections

By default, MySQL transmits data insecurely in plain text. To encrypt connections, you should enable Transport Layer Security (TLS).

There are a few ways to implement TLS:

Enforce TLS for Specific Users

In MySQL, grant permission to a user account to connect via TLS:

mysql> GRANT USAGE ON *.* TO 'mysqluser'@'192.168.1.101' REQUIRE SSL;

This requires the specified user to connect using TLS encryption.

Enable TLS on MySQL Server

To make TLS mandatory for the entire MySQL server, edit your MySQL config:

[mysqld]
ssl-ca=/path/to/ca.pem
ssl-cert=/path/to/server-cert.pem 
ssl-key=/path/to/server-key.pem
require_secure_transport=ON

Restart MySQL, and all client connections will now use TLS.

Use SSH Tunneling

Another option is to tunnel your MySQL connection through SSH, which encrypts all traffic. For example:

$ ssh -L 3307:127.0.0.1:3306 [email protected] -N -f

You can then connect locally to the tunnel on port 3307.

4. Improve Authentication Security

Using passwords alone for MySQL auth has some weaknesses. Additional authentication plugins can further lock down access:

Require Two-Factor Authentication

Activate the MFA plugin for accounts:

mysql> CREATE USER 'jeffrey'@'192.168.1.101' IDENTIFIED WITH authentication_ldap_simple
  AS 'secretPassword';
mysql> ALTER USER 'jeffrey'@'192.168.1.101' 
  REQUIRE TWO_FACTOR AUTHENTICATION 
  VIA one_time_password; 

Now logging in will require both a password and one-time code.

Use LDAP Authentication

With the AUTHENTICATION_LDAP_SIMPLE plugin, MySQL can authenticate users externally against an LDAP directory.

Utilize SSH Certificates

The AUTHENTICATION_LDAP_SIMPLE plugin allows verifying clients via SSH certificates rather than passwords.

Restrict Number of Login Attempts

Use the FAILED_LOGIN_ATTEMPTS plugin to lock an account after a specified number failed logins, hindering brute force attacks.

Require Strong Passwords

The VALIDATE_PASSWORD plugin can enforce requirements like password length, complexity, expiration, and history.

5. Implement Role-Based Access Control

MySQL includes a robust permissions system. Rather than granting global privileges, you should implement role-based access control (RBAC) for more granular control.

For example, administrative tasks can be separated into roles like:

  • Database administrator – CREATEALTERDROPBACKUP
  • Application developer – SELECTINSERTUPDATE
  • Read-only analyst – SELECT

Give each user the minimum set of privileges needed for their role. Revoke any unneeded permissions.

Also consider row-level or column-level access control for limiting data visibility.

6. Monitor and Audit Activity

To detect unauthorized activity, MySQL provides auditing plugins that can log query executions, data modifications, and admin actions.

Key plugins include:

General Query Log

The General Query Log records all SQL statements executed by MySQL. To enable it, set the general_log variable to 1 in your MySQL configuration file (my.cnf) or by running the command:

mysql> SET GLOBAL general_log = 'ON';

You can specify the log file location using general_log_file.

Slow Query Log

The Slow Query Log tracks queries that exceed a defined execution time threshold. To enable it, set the slow_query_log variable to 1 and define the threshold via long_query_time (e.g. 10 seconds). For example:

mysql> SET GLOBAL slow_query_log = 'ON';
mysql> SET GLOBAL long_query_time = 10;

The log file location is controlled by slow_query_log_file.

Binary Log

The Binary Log contains SQL statements that modify data. It is enabled by default in MySQL 5.1+ (for replication purposes). To explicitly enable it, set:

mysql> SET GLOBAL log_bin = ON;

The binary logging format is set via binlog_format, and the file location is binlog_file.

Rotate and backup these logs periodically to avoid disk space issues. The logs provide an audit trail of database activity.

7. Apply the Latest Security Patches

Like any software, MySQL releases periodic security patches and version updates. To reduce vulnerabilities, always apply the latest stable MySQL version or patches as soon as possible.

Check the MySQL blog or release notes for security announcements. Major versions like MySQL 8 may receive backports of fixes for older releases like MySQL 5.7.

For Debian/Ubuntu systems, run:

$ sudo apt update
$ sudo apt upgrade mysql-server

On RHEL/CentOS use:

$ sudo yum update mysql-server

8. Avoid Exposing MySQL to Web Frontends

Never directly expose your MySQL server to the public internet. If web applications need to connect to MySQL, consider using a middleware proxy layer like Envoy or HAProxy to add a firewall and control access.

This proxy server can provide:

  • Firewall to restrict connections
  • Connection pooling to optimize performance
  • Query analysis for security monitoring
  • Caching to reduce load on database
  • Rate limiting to prevent excessive traffic

The proxy adds overhead, but gives you more control than directly exposing MySQL.

9. Take Advantage of User Permissions

As mentioned earlier, align MySQL user permissions with the principle of least privilege. Give each user only the capabilities needed for their work.

But user permissions can provide another layer of security beyond just data access:

Restrict Process Privileges

The PROCESS and SUPER privileges allow modifying MySQL server settings and processes. Limit users who absolutely require these.

Limit User Resources

The MAX_USER_CONNECTIONS resource limit prevents any one user from opening too many connections that could overload MySQL.

Restrict User Account Locking

Enable the CREATE USER or ALTER USER privileges to restrict users that can lock/unlock other accounts, preventing unauthorized changes.

Limit Users that Can Create New Users

Be cautious about granting the CREATE USER privilege since new user creation could open security holes.

10. Take Advantage of Database Privileges

Similar to user accounts, you can apply the principle of least privilege at the database level:

Limit CREATE/ALTER Database Privileges

Be careful about allowing users to create or modify the structure of databases.

Restrict DROP Database Privileges

The DROP privilege at the database level can be dangerous – limit users that have this capability.

Assign Database Roles

Roles like db_datareader or db_datawriter can define pre-configured privilege sets on a database, implementing database-level RBAC.

11. Secure Your MySQL Files and Directories

The filesystem holding your MySQL data directories, tablespaces, and log files should be locked down:

Restrict File Permissions

Never allow global read/write access to MySQL files. Revoke unnecessary permissions to keep access limited.

Enable Secure File Transfer

Consider using SFTP or SSH for secure file transfer rather than insecure FTP.

Separate Database and Log Files

Put MySQL database directories and log files on different disk volumes. This adds resilience if one disk volume fails or fills up.

Encrypt Database Files

Tools like MySQL Enterprise Edition’s Transparent Data Encryption can encrypt database files, protecting against unauthorized access.

12. Take Care When Using Replication

MySQL replication allows you to maintain identical slave databases. This powerful capability also introduces security considerations:

Use TLS for Replication Traffic

Just as you encrypt client connections, also use TLS to encrypt replication data transfer between master and slave.

Restrict Replication Privileges

Grant the REPLICATION SLAVE privilege with care, only to accounts that require it. Also consider using role-based access control.

Monitor the Binary Log

Check the binary log regularly for any potentially malicious SQL during replication.

13. Perform Regular Backups

Backups provide an important defense against catastrophic data loss due to hardware failure, data corruption, accidental deletes, and even ransomware attacks.

Consider combining:

  • Full daily or weekly backups
  • More frequent incremental backups
  • Transaction log backups

Test restores regularly to verify your backups are working properly. Encrypt your backups, and store them in multiple secured locations.

14. Take Advantage of MySQL 8 Security Features

If possible, upgrade to the latest MySQL major version 8.x to take advantage of improved security:

Better Password Protection

MySQL 8 has better password hashing via caching_sha2_password and stronger validation with expired password checking.

Role-Based Access Control

More advanced RBAC capabilities for administrative privileges and data access.

Default Authentication Plugin

New installs will have the strong caching_sha2_password plugin enabled by default.

Improved Encryption

MySQL 8 adds support for encrypted undo logs, redo logs, and data file pages.

Conclusion

Securing a MySQL database server takes diligence, but the peace of mind is worth the effort. Use the comprehensive tips provided in this guide as a blueprint to lock down your MySQL environments. Always keep security top of mind when setting up new instances.

By leveraging MySQL’s robust access control, encryption, auditing and more, you can deploy database infrastructure with confidence your data is protected from most attacks. Combine these database-level measures with system-level protections like firewalls, security groups and VPNs to implement defense in depth.

While no security regimen eliminates all risk, providing multiple layers of security makes the barrier to compromise increasingly high. With proper implementation of MySQL security along with vigilant monitoring and maintenance, you can avoid the vast majority of database threats.

LEAVE A COMMENT