Skip to content

Add optional TLS for MySQL/MariaDB connections - #281

Open
diaznet wants to merge 2 commits into
NUKIB:mainfrom
diaznet:feature/mysql_tls
Open

diaznet wants to merge 2 commits into
NUKIB:mainfrom
diaznet:feature/mysql_tls

Conversation

@diaznet

@diaznet diaznet commented Oct 30, 2026

Copy link
Copy Markdown

Summary

Adds opt-in TLS for database connections via three new environment variables, mirroring the existing REDIS_USE_TLS:

  • MYSQL_USE_TLS (bool, default false)
  • MYSQL_TLS_CA (path, default /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem)
  • MYSQL_TLS_VERIFY (bool, default true)

When enabled, both database clients in the image connect over TLS. By default the server certificate and hostname are verified.

Motivation

The image cannot currently be used with a database that enforces encryption (require_secure_transport=ON on MariaDB/MySQL), for example RDS on AWS: the startup check in misp_create_database.py connects without TLS and the container never gets past

(3159, 'Connections using insecure transport are prohibited while --require_secure_transport=ON.')

The PHP side could in theory be configured through MYSQL_FLAGS, but only with raw PDO integer constants, and there was no way to make the startup check use TLS at all.

Changes

  • bin/misp_create_database.py – when MYSQL_USE_TLS is set, connects with TLS. With verification on (default), passes ssl={"ca": MYSQL_TLS_CA} to PyMySQL, which requires TLS and verifies the certificate and hostname; with MYSQL_TLS_VERIFY=false, the connection is encrypted without certificate checks. The ssl dict form is used for compatibility with older PyMySQL versions. Bool parsing mirrors misp_redis_ready.py.
  • Config/database.php – emits 'ssl_ca' => MYSQL_TLS_CA when TLS is enabled. CakePHP's MySQL datasource maps this to PDO::MYSQL_ATTR_SSL_CA; with a CA set, mysqlnd enables verify_peer and verify_peer_name by default. With MYSQL_TLS_VERIFY=false, also emits PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false in flags, merged with any MYSQL_FLAGS.
  • bin/misp_create_configs.py – registers the variables; fails fast at startup if TLS is enabled but the CA file is missing or unreadable; prints a warning when certificate verification is disabled.
  • README.md – documents the variables.

Backwards compatibility

The default is off. With the new variables unset, the rendered database.php is byte-identical to the current one (checked with and without MYSQL_FLAGS/MYSQL_SETTINGS) and the startup connection is unchanged.

Usage

environment:
  MYSQL_USE_TLS: "true"
  MYSQL_TLS_CA: /etc/misp-db-ca/ca.pem   # omit to use the system CA bundle
volumes:
  - ./certs/ca.pem:/etc/misp-db-ca/ca.pem:ro

The server certificate must contain MYSQL_HOST in its subjectAltName.

Skipping certificate verification (not recommended): if the server certificate cannot be verified – for example the self-signed certificate MariaDB ≥ 11.4 generates automatically when no --ssl-cert is configured – set MYSQL_TLS_VERIFY: "false". The connection stays encrypted, but is no longer protected against man-in-the-middle attacks. The container logs a warning at startup when this is enabled.

Testing

Against MariaDB with require_secure_transport=ON:

Case Startup check PHP/PDO
TLS disabled rejected rejected
Trusted CA, matching hostname connects connects (TLSv1.3)
Untrusted CA certificate verify failed refused
Hostname mismatch refused refused
Untrusted certificate, MYSQL_TLS_VERIFY=false connects connects (TLSv1.3)
MYSQL_TLS_VERIFY=false combined with MYSQL_FLAGS – connects, both flags applied

Also verified:

  • database.php renders via misp_create_configs.py and passes php -l in all combinations above.
  • create() rejects a missing CA file and non-boolean MYSQL_USE_TLS/MYSQL_TLS_VERIFY with a clear error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant