Database audit fixes

Transport Encryption: fixing all 5 checks

The transport encryption audit asks each engine whether TLS is required and when its server certificate expires, so a failure means credentials and query results cross the network in clear text.

The two certificate checks skip in the case that sounds worst: MySQL with no ssl_cert set reports "No server certificate configured" and PostgreSQL with ssl off reports "TLS is off", so a server with no TLS at all produces a SKIP here plus a finding on the matching enforcement check. The three enforcement checks skip when the engine is not installed, when mongod.conf cannot be found, or when the audit account has no root socket login to query MySQL or PostgreSQL.

5
checks in this audit
0
rated high severity
5
need root or sudo
~11s
automated run time

Transcribed from the database-security-transport-encryption audit script. For what the audit covers rather than how to fix it, see the Transport Encryption checklist.

Every check

Find your finding

Listed in the order the audit runs them. Take the check name from the third field of the result line and open its page.

  • MySQL TLS Enforcement

    Soon

    Checks whether MySQL has TLS available and requires encrypted client connections

    MediumNeeds root4 results
  • MySQL Certificate

    Soon

    Checks the MySQL server certificate for upcoming expiry

    MediumNeeds root3 results
  • PostgreSQL TLS

    Soon

    Checks whether PostgreSQL has ssl on, weighted against whether it listens beyond localhost

    MediumNeeds root4 results
  • PostgreSQL Certificate

    Soon

    Checks the PostgreSQL server certificate for upcoming expiry

    MediumNeeds root3 results
  • MongoDB TLS

    Soon

    Checks whether MongoDB requires TLS for client connections, weighted against its bind address

    MediumNeeds root4 results
Shared script behaviour

How the Transport Encryption 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.

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: 5 of the 5 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

Transport Encryption questions

This is a known false FAIL on MySQL 8.4 and 9.x. The check reads have_ssl and falls back to have_openssl, and both variables were removed in 8.4.0 after being deprecated in 8.0.26, so the query returns no row and the script concludes that TLS is unavailable. Verify by hand with SHOW VARIABLES LIKE "tls_version" or SHOW STATUS LIKE "Ssl_server_not_after", where a non-empty result means TLS is working. MariaDB still exposes have_ssl, so on MariaDB a DISABLED value there is a genuine finding.
It proves the server certificate has more than 30 days left, which is all that openssl x509 -checkend 2592000 tests. It says nothing about who issued it, and the Debian default snakeoil certificate passes the date test while offering no identity assurance at all. The CA file and any client certificates are not examined, and an already-expired certificate produces the same "expires within 30 days" wording as one that is merely close. Trust is settled on the client side, so point the application at a CA you control and use sslmode=verify-full, or --ssl-mode=VERIFY_IDENTITY on MySQL.
Immediately, for any client that connects with --ssl-mode=DISABLED or an old driver that never negotiates TLS. Test first by connecting with mysql --ssl-mode=REQUIRED, then read Ssl_cipher from performance_schema.session_status inside the application's own session to confirm it is already using TLS before you enforce it. The PostgreSQL equivalent is switching pg_hba.conf host lines to hostssl, with the same effect and the same risk. Neither applies to Unix socket connections, which are never encrypted and do not need to be.
Audit your fleet

Run all 5 Transport Encryption 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