Creating an EMR with Presto SSL
Tags: aws, devops, emr, presto
Published: 2019-11-26 02:13:40

This article focuses on adding SSL to an existing Presto environment. The configuration of Presto and a Hive metastore is assumed as complete.
We also cover how to connect to it with JDBC.

We had been using Presto without SSL for a while, however, we needed to connect our MicroStrategy analytics platform to Presto and that required the use of a SSL connection.

* Create self signed cert
* EMR Security Configuration
* Create EMR
* Connect and download truststore
* Connect using JDBC

## Create Self Signed Cert
Follow the instructions [here](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-encryption-enable.html#emr-encryption-certificates) to create a self signed certificate.
I also needed a Route53 DNS alias address for the EMR, presto.mydomain.com. This allows me to configure the JDBC client to use presto.mydomain.com as the URL without having to update the client when I rebuild the EMR.
The EMR will update the Route53 entry with its master node IP during bootstrap.
I've extended the certificate request to include this extra domain.
```console
cp /etc/ssl/openssl.cnf .
echo '[ subject_alt_name ]' >> openssl.cnf
echo 'subjectAltName = DNS:presto.mydomain.com, DNS:*.us-west-2.compute.internal'>> openssl.cnf
openssl req -x509 -newkey rsa:1024 -keyout privateKey.pem -out certificateChain.pem -days 365 -nodes -config openssl.cnf -extensions subject_alt_name -subj '/C=US/ST=Washington/L=Seattle/O=MyOrg/OU=MyDept/CN=*.us-west-2.compute.internal'
cp certificateChain.pem trustedCertificates.pem
zip -r -X prestosslcerts.zip certificateChain.pem privateKey.pem trustedCertificates.pem
```
Now upload the cert to a S3 location the EMR can read from.
```console
aws s3 cp prestosslcerts.zip s3://my-emr-bucket/prestosslcerts.zip
```
## EMR Security Configuration
Create a new EMR Security Configuration that uses the certificate zip for In-transit encryption.
![EMR Security Configuration](https://thepracticaldev.s3.amazonaws.com/i/9jx99hq5xwdg7ivd0r4r.png)
## Create EMR
Create your EMR but have it use your new security configuration.
## Connect and download truststore
SSH to your EMR master node
```console
[hadoop@ip-10-100-10-10 ~]$ cat /etc/hadoop/conf/ssl-client.xml
<configuration>

  <property>
    <name>ssl.client.keystore.keypassword</name>
    <value>xxxxxxxxxx</value>
  </property>

  <property>
    <name>ssl.client.truststore.reload.interval</name>
    <value>10000</value>
  </property>

  <property>
    <name>ssl.client.keystore.location</name>
    <value>/usr/share/aws/emr/security/conf/keystore.jks</value>
  </property>

  <property>
    <name>ssl.client.truststore.password</name>
    <value>xxxxxxxxxx</value>
  </property>

  <property>
    <name>ssl.client.truststore.type</name>
    <value>jks</value>
  </property>

  <property>
    <name>ssl.client.truststore.location</name>
    <value>/usr/share/aws/emr/security/conf/truststore.jks</value>
  </property>

  <property>
    <name>ssl.client.keystore.password</name>
    <value>xxxxxxxxxx</value>
  </property>

  <property>
    <name>ssl.client.keystore.type</name>
    <value>jks</value>
  </property>
</configuration>
```
Note the following:
* `ssl.client.truststore.location`
* `ssl.client.truststore.password`

The same truststore.jks file can be used to connect to any EMR as long as they are using the same Security Configuration.

#### View truststore
Optional: Use the command below to view the truststore certificate
``` console
keytool -list -v -keystore /usr/share/aws/emr/security/conf/truststore.jks
[ssl.client.truststore.password]
```

#### Change truststore password
Optional: Should you require, the truststore password can be changed. This is useful if you want to download the cert again without having to update client passwords.
```console
cp /usr/share/aws/emr/security/conf/truststore.jks /root/truststore.jk
keytool -storepasswd -keystore /root/truststore.jks 
Enter keystore password:  <== ssl.client.truststore.password
New keystore password:   <== user specified password 
```

## Connect using JDBC
Copy the truststore.jks file from the truststore.location, usually `/usr/share/aws/emr/security/conf/truststore.jks` to your client.

Either download the presto jdbc driver https://prestosql.io/download.html
Or copy from the EMR /usr/lib/presto/presto-jdbc/

The Connection URL will look like
`jdbc:presto://presto.mydomain.com:8446/hive/product_usage?SSL=true&SSLTrustStorePath=<local/path/truststore.jks>&SSLTrustStorePassword=<ssl.client.truststore.password>;`

### Using SQL Workbench/J
Open SQL Workbench/J
File > Manage Drivers
* Create a new entry
* Name: Presto JDBC Driver
* Library: C:\local\path\presto-jdbc-0.228.jar
* OK

File > Connect window
* Name: PrestoSSL
* Driver: Presto JDBC Driver
* URL: jdbc:presto://presto.mydomain.com:8446/catalog/schema
* Username: hadoop
* Password: blank

Extended Properties
* SSL true
* SSLTrustStorePath C:\local\path\truststore.jks
* SSLTrustStorePassword [ssl.client.truststore.password]