Repository navigation
feat(minimal): ship the AWS RDS CA bundle and verify the database server's certificate - #182
Merged
Merged
Conversation
…ver's certificate
The setup/delete Jobs and the entrypoint's mysql calls encrypt to RDS but never verify the server
(--ssl-mode=REQUIRED / --skip-ssl-verify-server-cert), and the app passes PDO no TLS option unless
SIMPLERISK_DB_SSL_CERT_PATH is set, which the README now says plainly.
- Vendor AWS's RDS global bundle (114 certificates, 174,560 bytes, every region) at
common/etc/ssl/rds/global-bundle.pem, so the existing 'COPY common/ /' ships it to
/etc/ssl/rds/global-bundle.pem. rds-global-bundle.sha256 pins it (AWS publishes no checksum);
test_rds_bundle.sh checks the pin, that every certificate parses, that the us-east-1, eu-central-1
and ca-central-1 RSA2048 G1 roots are present, that nothing expires within 3 years, and that no
private key is in the file. rds-bundle-drift.yml compares it with AWS's file every Monday and tells Slack.
- set_db_ssl_flags: with DB_SSL_ENABLED=true and the bundle present, verify chain and host name:
--ssl-mode=VERIFY_IDENTITY --ssl-ca=<bundle> (Oracle's client) or --ssl-ca=<bundle>
--ssl-verify-server-cert (MariaDB's, the arm64 image). DB_SSL_VERIFY=false returns to
encrypt-without-verify without a rebuild; a missing bundle falls back the same way and logs it.
Without DB_SSL_ENABLED=true nothing changes.
- apply_mail_setting uses app_db_tls_flags: with SIMPLERISK_DB_SSL_CERT_PATH set it verifies against that
CA like the app does (and does not fall back to plaintext if the file is missing); without it MariaDB's
client now skips verification as Oracle's default already does, which fixes its failure against servers
whose certificate it cannot chain ('self-signed certificate in certificate chain').
- README documents DB_SSL_VERIFY, RDS_CA_BUNDLE and what an empty SIMPLERISK_DB_SSL_CERT_PATH means.
Verified: the real functions, lifted from the file, drive the real mysql clients (Oracle 8.4.13 on amd64,
MariaDB 11.8.6 on arm64 under emulation) against a MySQL 8.4 with a private CA: right CA connects over
TLS; an unrelated CA, and a right CA with a name not in the certificate, are refused; the kill switch and a
missing bundle connect unverified. Against a real RDS instance the bundle verifies the server certificate
and the Oracle-client flags log in with an IAM token. 38 + 13 checks, the other minimal tests, ShellCheck
and actionlint pass.
No app or template change here: the app only uses TLS when SIMPLERISK_DB_SSL_CERT_PATH is set.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The privileged setup/delete client connects to RDS over TLS but does not verify the server certificate, and the app only uses TLS when
SIMPLERISK_DB_SSL_CERT_PATHis set. This ships AWS's CA bundle in the image and makes the setup client verify against it.common/etc/ssl/rds/global-bundle.pem; the existingCOPY common/ /places it at/etc/ssl/rds/global-bundle.pem, so there is no Dockerfile or generator change. Pinned byrds-global-bundle.sha256(AWS publishes no checksum).rds-bundle-drift.ymlcompares it with AWS's file every Monday.set_db_ssl_flags: withDB_SSL_ENABLED=trueand the bundle present, verify chain and host name:--ssl-mode=VERIFY_IDENTITY --ssl-ca=<bundle>with Oracle's client,--ssl-ca=<bundle> --ssl-verify-server-certwith MariaDB's (the arm64 image).DB_SSL_VERIFY=falsereturns to encrypt-without-verify with no rebuild; a missing bundle falls back the same way and logs it. WithoutDB_SSL_ENABLED=truenothing changes.apply_mail_setting: withSIMPLERISK_DB_SSL_CERT_PATHset it verifies against that CA like the app does, and does not fall back to plaintext if the file is missing. With it unset, MariaDB's client now skips verification as Oracle's default already does; before, it failed against any server whose certificate it could not chain.DB_SSL_VERIFY,RDS_CA_BUNDLE, and that an emptySIMPLERISK_DB_SSL_CERT_PATHmeans the app connects without TLS.What it does not do
It does not make the app use TLS: that stays opt-in through
SIMPLERISK_DB_SSL_CERT_PATH(point it at the bundle to get TLS with chain and host-name verification).Verification
mysqlclients (Oracle 8.4.13 on amd64, MariaDB 11.8.6 on arm64 under emulation) against a MySQL 8.4 with a private CA. Both clients: the right CA connects over TLS; an unrelated CA, and a right CA with a name not in the certificate, are refused; the kill switch and a missing bundle connect unverified; the mail-call flags behave the same.test_db_ssl_flags.sh38 checks (the original 31 historical-behaviour checks unchanged, with the bundle absent and, separately, present at the default path) andtest_rds_bundle.sh13 checks (pin, all certificates parse, the us-east-1, eu-central-1 and ca-central-1 RSA2048 G1 roots present, none expiring within 3 years, no private key, shipped path), plus the other minimal tests. Both are wired intocontainer-validation.yml. ShellCheck (severity error, as CI) and actionlint are clean.test_escaping.shgrepsapply_mail_settingfor the literal DISABLED ssl-mode flag, so comments there must not spell it out.Trade-off worth a look
Without a CA configured, MariaDB's client skips verification in
apply_mail_settingso it behaves like Oracle's default (and like the app, which does no TLS without a CA). Verifying by default would break arm64 against any server with a self-signed certificate, including MySQL 8's auto-generated one; verification is available by settingSIMPLERISK_DB_SSL_CERT_PATH.Not verified
The MariaDB client's verifying flags against a real RDS instance on an arm64 node (lab only), and a full image build with a deployment from it.
🤖 Generated with Claude Code