Secure MySQL config files and credentials
sudo chown root:mysql /etc/mysql/my.cnfsudo chmod 640 /etc/mysql/my.cnfsudo chmod 640 /etc/mysql/mysql.conf.d/*.cnf
chmod 600 ~/.my.cnfsudo chmod 750 /var/lib/mysqlSubstitute mariadb.conf.d if that’s what you’re running.
Why it matters
Section titled “Why it matters”Config files hold credentials in cleartext. ~/.my.cnf exists precisely so you
can put a password in it, and my.cnf frequently grows a [client] section for
the same reason. A world-readable one means every local account — every service
user, every deployment agent, anything that gets a shell through an unrelated bug
— can read the database password.
This is low because it needs local access first. It is on the list because it
quietly undoes the work of every other page: a perfect grant model protected by a
644 file with the password in it isn’t protecting much.
Never put a password on the command line
Section titled “Never put a password on the command line”This is the more interesting half, and it catches people who’d never chmod a config file wrong:
mysql -u app -phunter2 appdb # don'tCommand lines are world-readable on Linux. Any user on the box can run ps aux — or read /proc/<pid>/cmdline — and see it while the process runs. MySQL
warns about this (“Using a password on the command line interface can be
insecure”), and the warning is routinely suppressed rather than heeded.
It’s worse in scripts, because the password then lives in the shell history, in CI logs, and in any process listing captured by monitoring.
Use login-path instead
Section titled “Use login-path instead”MySQL ships the right answer, and it’s underused. mysql_config_editor writes an
obfuscated credential file that the client reads automatically:
mysql_config_editor set --login-path=prod --host=10.0.1.5 --user=app --password# prompts for the password, stores it in ~/.mylogin.cnf
mysql --login-path=prod appdbmysqldump --login-path=prod appdb > backup.sqlBe precise about what this does: ~/.mylogin.cnf is obfuscated, not
encrypted. Anyone who can read the file can recover the password —
mysql_config_editor print --all does it for you. It is not a secret store.
What it genuinely buys you is that the password is never in a command line, never
in shell history, and never in a CI log. Those are the leaks that actually happen.
File permissions still do the real work, and mysql_config_editor sets the file
to 600 itself.
MariaDB does not ship mysql_config_editor. Use a 600 option file with a
[client] section and --defaults-file, which achieves the same thing minus the
obfuscation.
Related
Section titled “Related”- Grant least privilege — limits what a leaked credential can do.
- Authentication plugins —
unix_socketon MariaDB needs no password at all.