When working with certain AWS services that require secure connectivity over TCP, you might run into the dreaded “unable to get local issuer certificate” error. This is because the service is presenting a certificate signed by an Amazon CA that isn’t in your trust store. I’ve commonly seen this with services such as Redis, DocumentDB, RDS, etc.
With the increased focus on security and expanding services, Amazon have been issuing a lot of certificates, and it’s a bit of a pain to keep up with them all. It’s also not obvious which CA you need when talking to which service, there seem to be a CA for each service in each region with multiple variants.
There are so many certificates that AWS now issue a global certificate bundle containing all the CAs and certificates together. But if you download and inspect the global bundle, you’ll see (at the time of writing) 121 CAs, and they are confusingly named with an RDS prefix. (I can only assume RDS was the first CA they created and all the other departments have just been reusing it).
The following script will automate downloading and installing the CAs for Linux systems. It will download the global bundle, extract the CAs, copy them to the trust store and update the trust store.
certdir=/tmp/aws-certs
mkdir -p "${certdir}"
sudo mkdir -p /usr/local/share/ca-certificates/aws/
curl -sS "https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem" > ${certdir}/global-bundle.pem
awk 'split_after == 1 {n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1}{print > "aws-ca-" n+1 ".crt"}' < ${certdir}/global-bundle.pem
for cert in aws-ca-*; do
sudo mv $cert /usr/local/share/ca-certificates/aws/
done
sudo update-ca-certificates
With this in place, most connectivity to AWS services should work securely.
But note, not everything looks at the same trust store. For example, Python doesn’t look at it by default and you have to set the REQUESTS_CA_BUNDLE
environment variable.
How the script works
It first creates a temporary directory to download the bundle in. It then uses awk
(which I still don’t understand) to split the bundle into individual certificates, with the .crt
extension as that’s what the trust store expects.
The certificates are then moved to the trust store location and the update-ca-certificates
command is run to process them.