symphonyoss / bot-unfurl

A small Symphony bot that attempts to unfurl URLs posted to any chat or room the bot is invited to.
Apache License 2.0
4 stars 5 forks source link

Get rid of custom server.truststore #27

Closed maoo closed 6 years ago

maoo commented 7 years ago

Currently, the bot-unfurl needs a Java truststore to run; however, it should not be necessary, since the intermediate SSL certificates of all the endpoints hosted by Symphony (specifically, *.symphony.com) are included in the default cacerts file that is bundled with Oracle (and most likely OpenJDK) Java runtimes.

Steps to Reproduce:

No specific steps to reproduce it, other than following the bot-unfurl readme without the use of trust-store configuration item - https://github.com/symphonyoss/bot-unfurl/blob/master/resources/config.edn#L9

Expected Result:

Being able to use bot-unfurl without providing a server.truststore file

Actual Result:

In order to use bot-unfurl, it is mandatory to provide a server.truststore file

Environment:

Description of Problem:

The problem was triggered by an SSL certificate change on the foundation-dev.symphony.com (and related) endpoints, causing all bots to fail, since the server.truststore used by some of the bots did not include the new certificates (or their intermediate ones), leading to SSL peer shut down incorrectly Java exception.

Since the SSL server-side certificate can (and probably will) change in the future, it is advised to move away from custom server.truststore certificates and rely on the ones shipped with the JRE.

/CC @ftbb , to understand which constructors to use on symphony-java-client in order to use the default server.truststore.

chrisfabri commented 6 years ago

cacerts in java does not contain the correct godaddy root. it's necessary (at this point) to add one of the intermediates or the correct root to a truststore that is used by the client side process.

my understanding is that the client side process did have its own truststore and that this truststore trusted the old, expiring wildcard cert - but did not trust 1) any of the intermediaries 2) the correct root. If so, then when the old cert expired, the client side process would have failed immediately to trust the new (renewed) certificate.

https://perzoinc.atlassian.net/wiki/spaces/ES/pages/147338240/ES+Security+-+SSL+Certificates+-+Current+Artifacts

maoo commented 6 years ago

Thanks for your response @chrisfabri . My tests with the latest Oracle JDK cacerts seem to work; here's how I reproduced it:

  1. Download and uncompress latest Oracle JDK 9
  2. git clone git@github.com:symphonyoss/symphony-java-sample-bots.git
  3. mkdir symphony-java-sample-bots/certs
  4. cp ./jdk-9/lib/security/cacerts ./symphony-java-sample-bots/certs/server.truststore
  5. [add certs in the ./certs folder and cp env.sh.sample env.sh]
  6. cd symphony-java-sample-bots; ./run-bot.sh org.symphonyoss.simplebot.EchoBot

As you can see at step 4, we are using the cacerts file shipped in the JDK distro. I've tested this only against foundation-dev.symphony.com, but I assume the same configuration (and outcome) on foundation.symphony.com.

pmonks commented 6 years ago

Furthermore, this is a limitation of symphony-java-client, specifically the CustomHttpClient class.

Perhaps this issue should be raised there, so that all SJC users (not just those using clj-symphony, a rather small number 😉 ) benefit?

maoo commented 6 years ago

@pmonks , agreed that SJC could use the default JRE cacerts, if none is provided via configuration (will open an issue on SJC), but I think there could also be a quick fix on config.edn to actually set the truststore as ${JAVA_HOME}/jre/lib/security/cacerts, wdyt?

pmonks commented 6 years ago

This doesn't require any changes to config.edn - just set the following environment variables before starting the bot and the existing config.edn will pick up Java's default cacerts file:

  1. export TRUSTSTORE_FILE=${JAVA_HOME}/jre/lib/security/cacerts
  2. export TRUSTSTORE_PASSWORD=changeit
ftbb commented 6 years ago

The problem is the default JVM certificate store is always limited, so you have to point to a truststore that has an appropriate root and intermediate certs regardless.

SJC does support loading your own cert/truststore directly using the CustomHttpClient in case you want to handle in a bespoke way. In fact you can even load a ks through a standard InputStream.

pmonks commented 6 years ago

@ftbb yeah the question is more how to use CustomHttpClient with the JVM's default cacerts file. I don't see a way to do that.

chrisfabri commented 6 years ago

if the default cacerts for Java 9 works then use it.

pmonks commented 6 years ago

@chrisfabri I can confirm that the Java 8 cacerts works, at least with the Foundation's dev pod (part of the ODP). That said, it's a business tier pod so it has a simpler architecture than most (all?) "real world" pods, meaning that it's not necessarily the most comprehensive test case. YMMV! 😉

chrisfabri commented 6 years ago

which version of java 8?

pmonks commented 6 years ago

1.8.0_131-b11

chrisfabri commented 6 years ago

ok - that's a later one, prior ones did not have the correct root.