cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

ThingBerry - Secure Connections with TLS

Highlighted
Pearl

ThingBerry - Secure Connections with TLS

About

This is the third part of a ThingBerry related blog post series.

ThingBerry is ThingWorx installed on a RaspBerry Pi, which can be used for portable demonstrations without the need of utilizing e.g. customer networks. Instead the ThingBerry provides its own custom WIFI hotspot and allows Things to connect and send / receive demo data on a small scale.

In this particual blog post we'll discuss on how to setup the ThingBerry for encrypted communication and trust via certificates. We will create a custom Root and Intermediate Certificate Authority as well as a server specific certificate.

More information on the theory of Trust & Encryption can be found here: Trust & Encryption - Theory

As the ThingBerry is a highly unsupported environment for ThingWorx, please see this blog post for all related warnings.

Preparing the environment

To get started and keep all the working materials safe and secure within the scope of the pi user account, let's start creating a workspace directory and then install the openssl package

cd ~

mkdir certs

chmod 700 certs

cd certs

sudo apt-get install openssl

Troubleshooting Tips

Keytool

To look at a specific certificate use the keytool and specify the .crt file to look at

keytool -printcert -file rootca.crt

This will show information on the certificate's configuration, such as signing authority or validity.

Timestamps

It's important, that the Chain of Trust follows a timely fashion.

The Root CA has the longest expiration date. Within its validity the Intermediate CA must be valid. The server specific certificate must be valid in the timeframe of the Intermediate CA validity.

As the validity is calculated based on seconds of the current (signing) action, I'm using valid days of

  • Root CA 999 days
  • Intermediate CA 888 days
  • Server specific certificate 777 days

Any other times, that make sense can be used, as long as the time constraints are followed.

Otherwise the certificate will not be recognized as valid and will therefore not be trusted.

Creating a Chain of Trust

For this example we'll create a Root and Intermediate Certificate Authority (CA) as well as the server specific certificate. In a first step we can create all of the required keys.

openssl genrsa -des3 -out rootca.key 4096

openssl genrsa -out intermediateca.key 4096

openssl genrsa -out server.key 4096

The -des3 option for the rootca will store a password and encrypt it within the key for more secure access.

This tightens up security, so that the key for the rootca is not easily corrupted or exposed.

Root Certificate Authority

Having the keys, we now create the Root CA itself

openssl req -new -x509 -sha256 -days 999 -key rootca.key -reqexts v3_req -extensions v3_ca -out rootca.crt

Enter the information, starting with the password for the Root CA key.

Use a easy to identify name for the Common Name (CN), e.g. "My Root CA"

Intermediate Certificate Authority

As the Intermediate CA needs to be signed / approved by the Root CA, we need a Certficiate Signing Request (CSR)

openssl req -new -key intermediateca.key -reqexts v3_req -extensions v3_ca -out intermediateca.csr

The v3_ca extension will mark this certificate as CA itself.

This means that we can use the intermediate CA to sign other certificates as well.

The CSR will be signed with the Root CA's key and certificate.

For this the CSR must be sent to the whoever own the Root CA.

In our case, we're the owner ourselves and have everything in the same directory, so no need to send it off to Let's Encrypt, Google or VeriSign.

For signing the Intermediate CA as an actual CA, the Root CA must have a specific configuration to allow the v3_ca extension. This needs to be created via

nano v3_ca.ext

Into this new file, copy & paste the following:

basicConstraints        = CA:TRUE

subjectKeyIdentifier    = hash

authorityKeyIdentifier  = keyid:always,issuer:always

keyUsage                = cRLSign, dataEncipherment, digitalSignature, keyCertSign, keyEncipherment, nonRepudiation

Save and exit.

Finally, the Root CA is signing the Intermediate CA, using the v3_ca extension via:

openssl x509 -req -in intermediateca.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -CAserial intermediateca.srl -extfile v3_ca.ext -days 888 -sha256 -out intermediateca.crt

Certificate Authority Chain

Having now two CAs, they need to be chained together.

This is required for later to create the keystore used in Tomcat.

Creating the Chain is probably the easiest part of this blog:

cat intermediateca.crt rootca.crt > cachain.crt

Server Specific Certificate

The server specific certificate has to be signed and obtained by the Intermediate CA; for this a CSR is required.

openssl req -new -key server.key -out server.csr

The request is then signed with the Intermediate CA's key and certificate.

For commerical certificates this signing process will be done by publicly trusted CAs, like Let's Encrypt, VeriSign or Google.

In our case, we're the Intermediate CA ourselves and can sign the CSR.

openssl x509 -req -in server.csr -CA intermediateca.crt -CAkey intermediateca.key -CAcreateserial -CAserial server.srl -days 777 -sha256 -out server.crt

Creating Keystores

For the keystore as used in Tomcat we need the CA Chain as well as the server specific certificate and the corresponding key.

To generate a keystore that can be used in Tomcat, we first need to create a PKCS12 type keystore with openssl

openssl pkcs12 -export -certfile cachain.crt -in server.crt -inkey server.key -out server.p12

This PKCS12 keystore can now be transformed into a JKS keystore, by importing the PKCS12 information into a new JKS keystore

keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS

Important: the passwords for the PKCS12 keystore and the JKS keystore must match!

Tomcat requires those passwords to be same - in case they are different, the configuration will not work and ThingWorx cannot be accessed through a secure connection.

Configuring ThingWorx

For ThingWorx, only the keystore is required.

It can be copied over e.g. to certificates area in the storage directory.

sudo cp keystore.jks /thingworx/storage/certificates

sudo chmod 640 /thingworx/storage/certificates/keystore.jks

sudo chown tomcat:tomcat /thingworx/storage/certificates/keystore.jks

To enable it, Tomcat's server.xml needs to be updated.

sudo nano $CATALINA_HOME/conf/server.xml

Find the connector for port 80 and add a new connector after the port 80 connector:

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"

           maxThreads="150" connectionTimeout="20000"  redirectPort="8443"

           SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLSv1.2" enableLookups="false"

           keystoreFile="/thingworx/storage/certificates/keystore.jks" keystorePass="<keystorePass>" />

Don't forget to update the password.

Stop Tomcat

sudo service tomcat stop

Ensure Tomcat is actually down with

ps -ef | grep tomcat

If it's still running, just sudo kill it and start Tomcat again to activate the new configuration

sudo service tomcat start

And now?

Congratulations!

ThingWorx is now running on your ThingBerry using a secure channel.

Access it via https://<thingberry>/Thingworx

As HTTPS is automatically using port 443, you will automatically connect to the port configured in the server.xml

Classic HTTP connections on port 80 can still be used.

For more information about setting up ThingWorx with (self-signed) certificates also see https://support.ptc.com/appserver/cs/view/solution.jsp?n=CS193947 - there's also a note on forwarding all HTTP traffic to HTTPS.

See also https://support.ptc.com/appserver/cs/view/solution.jsp?n=CS246292 for more information about using specific SSL protocols or cipher suites.

Tags (1)
Announcements