DBAtlas · Database operations atlas

MySQL security hardening (status audit, network, TLS, authentication, privileges, audit, encryption)

MySQLLevel: IntermediateDuration: 5 min (audit) – 3 hours (full hardening)

This is not an installation guide: it finds and closes the gaps of a running MySQL 8.4 / 8.0 server. First the read-only Status audit lists the findings by severity and tells you which card each finding leads to; then you close the areas one by one or all of them in order: bind_address, firewall and host restrictions on accounts; TLS, require_secure_transport and VERIFY_IDENTITY on the client; caching_sha2_password, password policy, remote root and anonymous accounts; roles and an application account without DDL; audit; InnoDB tablespace encryption (keyring component); encrypted backups; operating system; version tracking. Audit is not available in Community: it requires MySQL Enterprise (paid subscription) or Percona Server (free); TDE is available in Community too. At the end the audit runs again.

Topology: Single MySQL server + application server (client verification); replica/InnoDB Cluster in the notes

Scenarios

  • Status audit: what are my gaps? (read-only) — The scan to run first: anonymous, passwordless and remote root accounts, access from anywhere (%), weak authentication plugin, global privileges, TLS, audit, encryption, file permissions and firewall; it changes nothing.
  • Full hardening (all in order) — Newly installed or never hardened server: all areas are applied in a safe order; MySQL is restarted several times (a maintenance window is required).
  • Network and connections: who can connect from where? (bind_address, firewall, host restriction) — MySQL listens on all interfaces, accounts have host '%', the port is open to everyone. Changing bind_address requires a restart.
  • Encrypt connections (TLS, require_secure_transport, VERIFY_IDENTITY) — The automatically generated self-signed certificate is in use, unencrypted connections are accepted, or clients do not verify the certificate. No downtime with ALTER INSTANCE RELOAD TLS.
  • Authentication and passwords (caching_sha2, password policy, root) — mysql_native_password accounts, no password policy, remote root, anonymous accounts and the test database. No downtime.
  • Least privilege: roles and an application account without DDL — CREATE/ALTER/DROP or . privileges on the application account, accounts with FILE/SUPER; read/write/DDL roles and a privilege report. No downtime.
  • Audit: who did what? — The auditor wants session and query logging. MySQL Community has no built-in audit: Enterprise Audit, the Percona Server Audit Log Filter, or limited options for Community. License: Enterprise Audit comes only with a MySQL Enterprise subscription; the Percona Audit Log Filter is free.
  • Encrypt data at rest (InnoDB tablespace encryption, keyring) — Table, redo, undo and binlog encryption against theft of the disk or a backup copy; one restart to install the keyring component, ALTER time on large tables. It needs no license in Community either; the encrypted/KMS keyrings are Enterprise.
  • Backup security (encrypted backups, login-path, permissions) — Backups unencrypted or in a world-readable directory, plain-text password in scripts; mysqldump + GPG or XtraBackup --encrypt, a backup account and login-path.
  • Operating system side (service account, permissions, core dump, SELinux) — Data directory or certificate files are open to others, secure_file_priv is empty, local_infile is on, SELinux is disabled. Some settings take effect on restart.
  • Patches and versions: am I on a supported version? — Version, end of support (8.0 ended in April 2026) and pending updates; links to the upgrade guide for applying them. Read-only.

Before you start

  • MySQL … is running and, as root on the server, the mysql command logs in without a password (root@localhost with auth_socket, or a client login-path set with mysql_config_editor). If the installation was done with the MySQL installation guide, this is already in place. The SQL in the steps runs as root through mysql -t.
  • Two separate SSH sessions are open to the server; in one of them the mysql client stays open. After changing account hosts, require_secure_transport and the firewall, test a new connection in a separate session; do not close the old sessions until you see it succeed. The root@localhost socket login never changes in this guide: it always remains as the way back.
  • Maintenance window: in the areas you select, MySQL will be restarted (bind_address, keyring component, audit plugin, core dump limit). In an environment with replicas, apply it on the replicas first.
  • A list of all applications that connect to MySQL (server IPs, accounts, driver versions). The audit step shows the current connections; a client that is not on the list cannot connect after the restriction.
  • A current backup with a tested restore exists (logical or XtraBackup). The encryption (TDE) step makes the data unreadable if the keyring file is lost: take the backup BEFORE the keyring.

Phases of the guide

  • Status audit (read-only) — List the findings inside the database · Audit the operating system side
  • Before you start: fallback point — Take a copy of the current settings, accounts and privileges · Enable the extra configuration directory
  • Privileges — 1. Diagnosis — Show the accounts' privileges
  • Privileges — 3. Apply — Create the roles and grant privileges · Create the accounts and attach them to the roles · Remove the application account's direct privileges · Privilege report
  • Privileges — 4. Verification — Verify that the effective privileges contain no DDL · DDL attempt from the application server
  • Privileges — 5. Afterwards — Keep the migration account locked when it is not in use
  • Authentication — 1. Diagnosis — Show the authentication plugins, password settings and default accounts
  • Authentication — 2. Safety net — Check driver compatibility
  • Authentication — 3. Apply — Remove the anonymous accounts, remote root and the test database · Set up the password policy (validate_password, history) · Move mysql_native_password accounts to caching_sha2_password · Create the personal DBA account
  • Authentication — 4. Verification — Verify the account state · Try logging in as root from the application server
  • TLS — 1. Diagnosis — Show the current TLS settings and unencrypted clients
  • TLS — 3. Apply — Create a test CA and a server certificate · Create the key and the certificate signing request (CSR) · Put the signed certificate in place · Verify the certificate and the key · Set the SELinux label · Switch the server to the new certificate (no downtime) …
  • TLS — 4. Verification — Verify that unencrypted connections are rejected
  • TLS — 5. Afterwards: certificate renewal — Certificate renewal procedure
  • Network — 1. Diagnosis: who connects from where? — Show the listen address, account hosts and active clients
  • Network — 3. Apply — Restrict accounts with host '%' to the application network · Restrict the listen address (takes effect at restart) · Open the port in the firewall only to the allowed networks · Restart MySQL for the listen address
  • Network — 4. Verification — Test a connection from the application server (new session)
  • Audit — 1. Diagnosis — Show the audit plugins and log settings
  • Audit — 3. Apply — Community: log failed logins and the DML statement text · Install the Enterprise Audit plugin · Define the Enterprise Audit filters · Install the Percona Audit Log Filter component · Define the Percona audit filters · Forward the audit log to the central server (rsyslog imfile) …
  • Audit — 4. Verification — Make a change and see its trail
  • Backup — 1. Diagnosis — Show the encryption state of the backups and the password files
  • Backup — 3. Apply — Create the backup account with least privilege · Save the password in a login-path · Import the GPG public key · Encrypted backup script · Encrypted backup script with XtraBackup · Key file, backup directory and manual test …
  • Backup — 4. Verification — Test that the encrypted backup can be decrypted
  • Operating system — 1. Diagnosis — Service account, permissions, file privileges and SELinux
  • Operating system — 3. Apply — Restrict file import/export · Fix the data directory and key file permissions · Disable core dumps · Reload systemd and restart MySQL · Keep passwords out of the command history · Keep SELinux in Enforcing mode
  • Operating system — 4. Verification — Verify the changes
  • Encryption — 1. Diagnosis — Show the keyring and encryption state
  • Encryption — 2. Safety net — Full backup before encryption
  • Encryption — 3. Apply — Write the keyring component manifest · Prepare the keyring directory and configuration · Restart to load the keyring · Enable encryption for redo, undo, binlog and new tables · Encrypt the tables of the application database · Back up the keyring file
  • Encryption — 4. Verification — Verify the encryption and the keyring
Open the step-by-step plan for your environment →