fix: SSL/TLS connection failures for PostgreSQL 17 with Route 53 CNAME endpoints + Python 3.12 runtime upgrade#173
Open
tejadonthu wants to merge 1 commit into
Conversation
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.
Problem
The
SecretsManagerRDSPostgreSQLRotationSingleUserrotation Lambda fails to connect to RDS PostgreSQL 17 instances when the hostname in the secret is a Route 53 CNAME pointing to the RDS cluster endpoint. This worked on PostgreSQL 16 and earlier, but PostgreSQL 17's stricter SSL/TLS enforcement exposes three issues in the sample code:Hardcoded CA certificate path —
sslrootcert='/etc/pki/tls/cert.pem'is not guaranteed to exist or contain current certificates across Lambda runtime versions.verify-fullincompatible with Route 53 CNAMEs —sslmode='verify-full'requires the server certificate's CN/SAN to match the connection hostname. Route 53 CNAMEs (e.g.db.internal.example.com) don't match the RDS-issued certificate (e.g.mydb.abc123.us-east-1.rds.amazonaws.com). PostgreSQL 16 was lenient about this; PostgreSQL 17 rejects it.Silent SSL-to-plaintext fallback — When the
sslkey is omitted from the secret JSON, the code attempts SSL first, then silently retries without encryption if SSL fails. With PostgreSQL 17 rejecting SSL handshakes more often, credential rotation traffic that was previously encrypted can silently downgrade to plaintext.This is a common enterprise pattern — many customers upgrading from PostgreSQL 16 to 17 with DNS aliasing (Route 53 CNAMEs) in front of RDS endpoints will encounter the same failures.
Changes
Driver: PyGreSQL (
pg/pgdb) →pg8000pg8000, simplifying Lambda packaging and enabling native Python SSL context control.SSL/TLS: verify-ca via system trust store
sslrootcert='/etc/pki/tls/cert.pem', sslmode='verify-full'withssl.create_default_context()+check_hostname = False.create_default_context()loads the Lambda runtime's system CA bundle (always present and up-to-date).check_hostname = Falsegivesverify-casemantics: the server's certificate chain is fully validated, but the certificate hostname does not need to match the connection hostname. This allows Route 53 CNAMEs that differ from the RDS certificate CN/SAN.Removed silent SSL-to-plaintext fallback
get_ssl_config()now returns a singleboolinstead of a(use_ssl, fall_back)tuple.sslis omitted from the secret JSON, SSL is required with no fallback. Users who need plaintext connections must explicitly set"ssl": false.set_secretimprovementsusernameandhostmatch between AWSCURRENT and AWSPENDING before attempting any database connection.quote_ident()+ parameterized query with PostgreSQL'sformat('%I ... %L', ...), which is more reliable across drivers for DDL statements.Other improvements
aurora-postgresqlto supported engine types.ERRORtoWARNING(expected control flow, not terminal errors).28P01) andpg_hba.confrejections.get_input_map_value()— printable-ASCII validation was unnecessary for trusted Secrets Manager service inputs.Breaking changes
sslkey now require SSL. If the DB doesn't support SSL, the connection will fail instead of silently downgrading to plaintext."ssl": falseexplicitly in the secret JSON.pg8000instead ofPyGreSQL.requirements.txt/ Lambda layer.Testing
aurora-postgresqlengine type ✅