Skip to content

Commit

Permalink
Enabled RDS Certs for Oracle DB (#2473)
Browse files Browse the repository at this point in the history
Co-authored-by: AbdulRehman Faraj <arfaraj@amazon.com>
  • Loading branch information
AbdulR3hman and AbdulRehman Faraj authored Dec 16, 2024
1 parent d0376e4 commit c8371be
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
33 changes: 33 additions & 0 deletions athena-oracle/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,42 @@
FROM public.ecr.aws/lambda/java:11

# Install necessary tools
RUN yum update -y && yum install -y curl perl openssl

ENV truststore=${LAMBDA_TASK_ROOT}/rds-truststore.jks
ENV storepassword=federationStorePass

# Download and process the RDS certificate
RUN curl -sS "https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem" > ${LAMBDA_TASK_ROOT}/global-bundle.pem && \
awk 'split_after == 1 {n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1}{print > "rds-ca-" n ".pem"}' < ${LAMBDA_TASK_ROOT}/global-bundle.pem

# Import certificates into the truststore
RUN for CERT in rds-ca-*; do \
alias=$(openssl x509 -noout -text -in $CERT | perl -ne 'next unless /Subject:/; s/.*(CN=|CN = )//; print') && \
echo "Importing $alias" && \
keytool -import -file ${CERT} -alias "${alias}" -storepass ${storepassword} -keystore ${truststore} -noprompt && \
rm $CERT; \
done

# Clean up
RUN rm ${LAMBDA_TASK_ROOT}/global-bundle.pem

# Optional: List the content of the trust store (for verification)
RUN echo "Trust store content is: " && \
keytool -list -v -keystore "$truststore" -storepass ${storepassword} | grep Alias | cut -d " " -f3- | while read alias; do \
expiry=$(keytool -list -v -keystore "$truststore" -storepass ${storepassword} -alias "${alias}" | grep Valid | perl -ne 'if(/until: (.*?)\n/) { print "$1\n"; }'); \
echo " Certificate ${alias} expires in '$expiry'"; \
done

# Copy function code and runtime dependencies from Maven layout
COPY target/athena-oracle-2022.47.1.jar ${LAMBDA_TASK_ROOT}
# Unpack the jar
RUN jar xf athena-oracle-2022.47.1.jar

# Clean up JAR
RUN rm ${LAMBDA_TASK_ROOT}/athena-oracle-2022.47.1.jar

# Command can be overwritten by providing a different command in the template directly.
# No need to specify here (already defined in .yaml file because legacy and connections use different)
# Set the CMD to your handler by removing the following comment for manual testing
# CMD [ "com.amazonaws.athena.connectors.oracle.OracleCompositeHandler" ]
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import java.sql.SQLException;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class OracleJdbcConnectionFactory extends GenericJdbcConnectionFactory
{
Expand All @@ -42,8 +41,6 @@ public class OracleJdbcConnectionFactory extends GenericJdbcConnectionFactory
private final DatabaseConnectionInfo databaseConnectionInfo;
private final DatabaseConnectionConfig databaseConnectionConfig;
private static final Logger LOGGER = LoggerFactory.getLogger(OracleJdbcConnectionFactory.class);
private static final String SSL_CONNECTION_STRING_REGEX = "jdbc:oracle:thin:\\$\\{([a-zA-Z0-9:_/+=.@-]+)\\}@tcps://";
private static final Pattern SSL_CONNECTION_STRING_PATTERN = Pattern.compile(SSL_CONNECTION_STRING_REGEX);

/**
* @param databaseConnectionConfig database connection configuration {@link DatabaseConnectionConfig}
Expand All @@ -64,10 +61,12 @@ public Connection getConnection(final JdbcCredentialProvider jdbcCredentialProvi
Properties properties = new Properties();

if (null != jdbcCredentialProvider) {
if (SSL_CONNECTION_STRING_PATTERN.matcher(databaseConnectionConfig.getJdbcConnectionString()).matches()) {
//checking for tcps (Secure Communication) protocol as part of the connection string.
if (databaseConnectionConfig.getJdbcConnectionString().toLowerCase().contains("@tcps://")) {
LOGGER.info("Establishing connection over SSL..");
properties.put("javax.net.ssl.trustStoreType", "JKS");
properties.put("javax.net.ssl.trustStorePassword", "changeit");
properties.put("javax.net.ssl.trustStore", "rds-truststore.jks");
properties.put("javax.net.ssl.trustStorePassword", "federationStorePass");
properties.put("oracle.net.ssl_server_dn_match", "true");
if (System.getenv().getOrDefault(IS_FIPS_ENABLED, "false").equalsIgnoreCase("true") || System.getenv().getOrDefault(IS_FIPS_ENABLED_LEGACY, "false").equalsIgnoreCase("true")) {
properties.put("oracle.net.ssl_cipher_suites", "(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)");
Expand All @@ -84,7 +83,6 @@ public Connection getConnection(final JdbcCredentialProvider jdbcCredentialProvi
final String secretReplacement = String.format("%s/%s", jdbcCredentialProvider.getCredential().getUser(),
password);
derivedJdbcString = secretMatcher.replaceAll(Matcher.quoteReplacement(secretReplacement));
LOGGER.info("derivedJdbcString: " + derivedJdbcString);
return DriverManager.getConnection(derivedJdbcString, properties);
}
else {
Expand Down

0 comments on commit c8371be

Please sign in to comment.