AWS RDS SSL import inside Dockerfile

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}