Skip to main content

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples in this guide work on VillageSQL. Install Now →
A default MySQL installation prioritizes ease of setup over security. Hardening a production server means removing defaults that made sense on a developer laptop but are inappropriate when the server is reachable by applications or the network.

Hardening by Deployment Context

Not every hardening step carries the same risk/friction tradeoff. Use this table to prioritize: Internet-facing means port 3306 is reachable from outside your private network, even if behind a load balancer. Apply every “Required” row without exception. Internal/private network covers servers accessible only within a VPC, private subnet, or office network. Some mitigations (CA-signed certs, SSL enforcement on every account) add operational overhead for marginal gain — but strong passwords, least privilege, and bind-address restrictions are still non-negotiable. Dev/staging machines are the most common source of credential leaks. Skipping password complexity or leaving '%' host grants in place is acceptable only if the instance is unreachable from outside your laptop or CI environment. If staging shares a network with production data, treat it as internal/private at minimum.

mysql_secure_installation

Run this immediately after installing MySQL on any server that isn’t a local dev machine:
It walks through the most critical hardening steps:
  • Set the root password (if not already set)
  • Remove anonymous users
  • Disallow remote root login
  • Remove the test database
  • Reload privilege tables
These four steps eliminate the most common attack surface on a fresh install.

Root Account Restrictions

Root should only connect from localhost. Verify and enforce this:
If root has a '%' host entry, remove it:
For remote administration, create a named DBA account with limited host access instead of using root remotely.

Remove Anonymous Users and Test Database

Password Policy

MySQL 8.0+ includes the validate_password component, which enforces password complexity rules. It must be installed before use — mysql_secure_installation offers to install it automatically. To install manually:
Verify it’s active:
Configure minimum requirements:
Policy levels: LOW (length only), MEDIUM (length + character classes), STRONG (+ dictionary check). Set password expiration for accounts that might be forgotten:

Least-Privilege User Accounts

Application accounts should have the minimum privileges needed. See MySQL User Management for the full GRANT syntax. Common patterns:
Restrict hosts as tightly as possible — use subnet notation or specific IPs, not '%'.

Auditing Existing Privileges

Review all accounts and their privileges:
Remove or lock accounts that aren’t actively used:

SSL/TLS Connections

MySQL 8.0 enables SSL/TLS by default and auto-generates certificates on startup. Verify it’s active:
Require SSL for specific accounts:
To verify a client connection is using SSL:
For production, replace the auto-generated self-signed certificates with certificates from a trusted CA.

Network Access

Restrict MySQL to listen only on necessary interfaces. In my.cnf:
If MySQL should not be reachable from the network at all (application on the same host), bind to 127.0.0.1 and never expose port 3306 externally. Firewall rules are a second layer of defense, not a substitute for restricting the bind address.

Disabling Risky Features

Turn off features your application doesn’t use:
In my.cnf:

Frequently Asked Questions

Is the default MySQL 8.4 install secure?

Better than older MySQL defaults, but still not hardened for production. MySQL 8.4 generates a random root password and enables SSL by default. You still need to: verify the root password is strong, remove anonymous users, restrict host access, and configure the validate_password component.

Should I run MySQL as root?

Never. MySQL should run as a dedicated low-privilege system user (typically mysql). Running the server process as root means a MySQL exploit could lead to full system compromise.

Troubleshooting

See also