AWS RDS SSL import inside Dockerfile
TLDR; Here is my Dockerfile
FROM openjdk:8-jdk
MAINTAINER Brayton
# create a temp dir in which to work
RUN OLDDIR="$PWD"
RUN mkdir /tmp/rds-ca && cd /tmp/rds-ca
# download the AWS RDS SSL bundle
RUN wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
# split the bundle into individual certs (prefixed with xx)
RUN csplit -sz rds-combined-ca-bundle.pem '/-BEGIN CERTIFICATE-/' '{*}'
# import each cert individually
RUN for CERT in xx*; do keytool -import -keystore /etc/ssl/certs/java/cacerts -storepass changeit -noprompt -alias rds$CERT -file "$CERT"; done
# back out of the temp dir and delete it
RUN cd "$OLDDIR"
RUN rm -r /tmp/rds-ca
# list the imported rds certs as a sanity check
RUN keytool -list -keystore /etc/ssl/certs/java/cacerts -storepass changeit -noprompt | grep -i rds
# copy application JAR to container
COPY target/*.jar /app/myApp.jar
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/myApp.jar"]
These days everyone should be using encryption for all internet traffic. Since Amazon has preconfigured their RDS instances to support secure connections we just need to make sure we utilize the provided PEM certificate when establishing a connection to our RDS instance. Using this blog post I was able to adapt the shell script into single line RUN commands in my Dockerfile to download the amazon certificate, split it, and import it into the keystore. There are some additional commands to create and cleanup the working directory but the important parts are explained below.
Download the AWS CA certificate bundle for Amazon RDS databases:
RUN wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
Split the PEM cert into individual files:
RUN csplit -sz rds-combined-ca-bundle.pem '/-BEGIN CERTIFICATE-/' '{*}'
Import individual certificates into the cacerts keystore:
RUN for CERT in xx*; do keytool -import -keystore /etc/ssl/certs/java/cacerts -storepass changeit -noprompt -alias rds$CERT -file "$CERT"; done
In order to establish a secure connection from a Java microservice I am adding ?verifyServerCertificate=true&useSSL=true&requireSSL=true to the JDBC connection string in my Java app's application.yml/application.properties file:
spring:
datasource:
url: jdbc:mysql://myDatabaseServer:3306/my_db_schema?verifyServerCertificate=true&useSSL=true&requireSSL=true
username: mysql-user
password: mysql-password
jpa:
hibernate:
ddlAuto: none
eureka:
client:
serviceUrl:
defaultZone: ${EUREKA_URL}