Database audit fixes

Authentication: fixing all 8 checks

The authentication audit reads mysql.user, pg_hba.conf, mongod.conf and redis.conf to find the accounts and rules that let a client reach your data without proving who it is.

Six of the eight checks need a working root login to the engine itself (mysql -N -e "SELECT 1" as root, or psql as the postgres user), and the MongoDB and Redis checks need root only to read mongod.conf or redis.conf, so an engine that is up but unreachable to the audit account reports SKIP rather than PASS. The other wording, "not installed", means no client binary, running process or config directory for that engine was found on the host at all.

8
checks in this audit
7
rated high severity
8
need root or sudo
~14s
automated run time

Transcribed from the database-security-authentication audit script. For what the audit covers rather than how to fix it, see the Authentication checklist.

Shared script behaviour

How the Authentication audit reads your server

Every check in this audit runs after the same preamble, and several of its results only make sense once you know what that preamble could and could not see.

All require root for a full result.

Engine detection: HAS_MY, HAS_PG, HAS_MG, HAS_RD are set from client binaries, server processes or config directories. MYOK=1 only if mysql -N -e 'SELECT 1' works as root over the socket; PGOK=1 only if su postgres -c 'psql -X -tAc "SELECT 1"' works. RDCONF is /etc/redis/redis.conf or /etc/redis.conf; MGCONF is /etc/mongod.conf. Containerised databases are not detected by these probes; audit them with the Docker checks or exec into the container.

Why checks skip

A SKIP is never a pass

A skipped check verified nothing at all. The most common cause is privilege: 8 of the 8 checks in this audit need root for a complete result. Before every run, each script works out which of four privilege modes it is in.

The four privilege modes an audit script can run in, and what each one means for checks that need root
ModeHow it is reachedWhat it means for your results
rootThe audit runs as UID 0.Every privileged branch runs directly. No check skips for lack of permission.
nopasssudo -n true succeeds, so the account has passwordless sudo.Privileged commands run through sudo -n.
passA sudo password was supplied in the CtrlOps audit settings and accepted.Privileged commands run through sudo -S.
noneNone of the above worked.CAN_ROOT=0. Every privileged branch returns SKIP with a "Need root" message rather than guessing.

If many checks skip with a “need root” message, run the audit as root, grant the audit account sudo (with or without NOPASSWD), or supply the sudo password in the CtrlOps audit settings.

FAQ

Authentication questions

Every MySQL check in this audit is gated on one probe: mysql -N -e "SELECT 1" run as root over the local socket. It fails, and the checks behind it skip, if the audit account has no sudo, if mysqld listens on a socket path other than the client default (/var/run/mysqld/mysqld.sock versus /tmp/mysql.sock), or if root@localhost authenticates with a password rather than auth_socket and no /root/.my.cnf holds it. Run that same command by hand as root to see which of the three you have.
That check greps redis.conf for a requirepass line or a user or aclfile line, and reads nothing else. A password applied at runtime with CONFIG SET requirepass and never persisted with CONFIG REWRITE is invisible to it, and so is one set in a file pulled in by an include directive. The MongoDB check has the same shape: it looks for authorization: enabled in mongod.conf, so a server started with mongod --auth or with a keyFile in a systemd override is reported as unauthenticated even though authorization is enforced. Confirm with redis-cli CONFIG GET requirepass, or by reading the running mongod command line.
It will if the roles still hold md5 hashes, because a role hashed with md5 cannot authenticate against a scram-sha-256 line. Set password_encryption to scram-sha-256 first and reload, then re-issue the password for every role with ALTER ROLE so the stored hash is rewritten, and only then change the HBA lines and reload again. Changing password_encryption on its own re-hashes nothing, which is why the auth methods check and the password hashing check can legitimately disagree. Keep a superuser session open on the local socket while you do it.
Audit your fleet

Run all 8 Authentication checks, in one click

CtrlOps runs this audit over your existing SSH connection - no agents, no scripts to manage. $7/user/month after a 1 month free trial - no credit card required.

Start instantly· No credit card· No sneaky autorenewals