Product: StreamSets Transformer
Scenario:
19/12/09 16:30:10 ERROR DataTransformerRunner: Error while sending State, javax.ws.rs.ProcessingException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Goal:
Setting up Truststore for Transformer
Solution:
When Transformer is configured for HTTPS using a certificate that is not signed by a "well-known" CA, or when using a self-signed-cert, it is necessary to set a Truststore in Transformer's config so that the callback from Spark to Transformer can be made successfully.
Here are the steps to generate and configure a truststore so that the Spark environment will trust Transformer's cert:
1) Export the certificate from the keystore
For this example, here will use the self-signed-cert in the Keystore included with the Transformer located at $TRANSFORMER_CONF/keystore.jks
Run the following command to list the contents and aliases in the Keystore as well as to confirm the keystore's export password :
$ keytool --list --keystore keystore.jks
Here is the sample output in my test environment:
$ keytool --list --keystore keystore.jks
Enter keystore password:
Keystore type: jks
Keystore provider: SUN
Your keystore contains 1 entry
sdc, Mar 12, 2015, PrivateKeyEntry
Certificate fingerprint (SHA1):
9C:33:52:82:6A:92:EE:D0:89:6C:73:BE:FC:1E:EF:02:28:44:D2:2F
From the output above we can see Keystore contains a single key and cert with the alias sdc.
Run the following command to export the cert from the Keystore. In this case, I am executing the command from within the directory that contains the Keystore keystore.jks and exporting the cert to the file localhost.cer using the Keystore password password:
$ keytool -export -alias sdc -storepass password -file localhost.cer -keystore keystore.jks
That will create the file localhost.cer
2) Create a trust store and import the certificate
The following example command creates a truststore named my-custom-truststore.jks with the password my-custom-truststore-password and imports the certificate. Run the command from the local directory where the localhost.cer file is located. Specify the desired truststore name in the -keystore argument and the desired truststore password in the -storepass argument:
$ keytool -import -v -trustcacerts -alias localhost -file localhost.cer -keystore my-custom-truststore.jks -storepass my-custom-truststore-password -noprompt
That will create the file my-custom-truststore.jks
3) Add existing CA certs to the truststore
Run the following command to copy the CA certs from jre/lib/security/cacerts to my-custom-truststore.jks . Make sure JAVA_HOME is set and the password for the truststore is set in the -destorepass argument:
$ keytool -importkeystore -srckeystore $JAVA_HOME/jre/lib/security/cacerts -srcstorepass changeit -destkeystore my-custom-truststore.jks -deststorepass my-custom-truststore-password
That command will modify my-custom-truststore.jks.
4) Move the truststore to Transformer's conf dir
Move the truststore to Transformer's conf dir using a command like this:
$ mv my-custom-truststore.jks $TRANSFORMER_CONF
5) Update Transformer's properties
Update the truststore location and password in the file $TRANSFORMER_CONF/transformer.properties by setting these two properties:
https.truststore.path=my-custom-truststore.jks
https.truststore.password=${file("truststore-password.txt")}
Set the truststore's password in the file truststore-password.txt
6) Restart Transformer
Restart Transformer for the new properties to be picked up
Conclusion: You should now be able to use the transformer with the custom Truststore.