Documentation > Administration > Going to Production > TLS Certificates

TLS Certificates

This page provides some information about how to create and use TLS certificates for secure connections with

For configuring TLS in in principle, see Secure WebSocket and HTTPS.

Using Self-signed Certificates

For production use, the use of self-signed certificates is not recommended. However, for testing, development, Intranet or controlled deployments, you can of course.

The following provides a recipe for creating a new server key and self-signed certificate for use with

First, check your OpenSSL version:

C:\Users\oberstet>openssl version
OpenSSL 1.0.1f 6 Jan 2014

If running on Windows, make sure you start the command shell "as administrator". It seems OpenSSL requires this at least during key generation.

Then, create a new server key (RSA with 2048 bits in this case):

openssl genrsa -out .crossbar/server_key.pem 2048
chmod 600 .crossbar/server_key.pem

A server key must not be protected with a passphrase, since it needs to be loaded unattended. However, you should make sure that file permissions are set so that only the user under which the server starts is able to read the key.

Next, create a new certificate signing request ("CSR") for the key generated formerly:

openssl req -new -key .crossbar/server_key.pem -out .crossbar/server_csr.pem

You must set the "Common Name" (CN) to the fully qualified domain name (or IP address) of the server, e.g. (or Do NOT include a port number - a certificate is always for a server, not a service running on a specific port.

Note: to view the contents of a CSR: openssl req -text -noout -verify -in .crossbar/server_csr.pem

Finally, create a new self-signed certificate (valid for 1 year) from the CSR created formerly:

openssl x509 -req -days 365 -in .crossbar/server_csr.pem \
    -signkey .crossbar/server_key.pem -out .crossbar/server_cert.pem

Note: to view the contents of a certificate: openssl x509 -text -noout -in .crossbar/server_cert.pem


Using commercial certificates

For production use, you will usually deploy certificates issues by commercial CAs, since only for those, browsers will have the CA certificates preinstalled, and hence users won't be bothered with invalid certificate dialogs.

If you are looking for a free certificate, we recommend StartSSL.

Remove the passphrase protection from the private key with the OpenSSL (should there be any):

openssl rsa -in server_key_with_passphrase.pem -out server_key.pem

Note: This is needed since we want the server to start automatically without administrator interaction.

Append any intermediate CA certificates to the server certificate:

cat ../ >> server_cert.pem

The certificates must be in PEM format and must be sorted starting with the subject's certificate (actual client or server certificate), followed by intermediate CA certificates if applicable, but excluding the highest level (root) CA.

Upload the key and certificate to your server host:

scp server_cert.pem server_key.pem

Login to the server and make sure you restrict the key's file permissions

cd /home/serveruser
chmod 600 server_key.pem
chmod 644 server_cert.pem

This step is extremely important, especially since we removed the passphrase from the private key! The certificate file is non-critical.

Move the files to your node directory:

mv server_key.pem server_cert.pem .crossbar

Creating your own Certificate Authority

The following recipe is for creating your own root certificate authority ("CA"), and certify your server certificates with your own CA to create server certificates.

First, create a new private key for your CA:

openssl genrsa -aes256 -out ca_key.pem 4096
chmod 600 ca_key.pem

As "Common Name" (CN), you could choose something like "Tavendo Certificate Authority". This is different from servers, where CN should be the FQDN, and personal certificates, where the CN should be the Email of the person.

Next, create a certificate for your CA valid for 10 years:

openssl req -new -x509 -days 3650 -extensions v3_ca -key ca_key.pem -out ca_cert.pem

To check and view your CA certificate:

openssl x509 -in ca_cert.pem -noout -text

Create a server certificate signed by your CA:

openssl x509 -req -days 365 -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial \
   -addreject emailProtection -addreject clientAuth -addtrust serverAuth \
   -in .crossbar/server_csr.pem -out .crossbar/server_cert.pem

View the server certificate:

openssl x509 -text -noout -in .crossbar/server_cert.pem


You can use openssl client command to check your server in the end:

oberstet@corei7ub1310:~/scm/3rdparty/openssl$ ~/openssl/bin/openssl s_client -brief -connect
depth=1 C = IL, O = StartCom Ltd., OU = Secure Digital Certificate Signing, CN = StartCom Class 1 Primary Intermediate Server CA
verify error:num=20:unable to get local issuer certificate
Protocol version: TLSv1.2
Ciphersuite: ECDHE-RSA-AES128-GCM-SHA256
Peer certificate: description = 3FfmiF3b24n8r1Hz, C = DE, CN =, emailAddress =
Hash used: SHA384
Supported Elliptic Curve Point Formats: uncompressed:ansiX962_compressed_prime:ansiX962_compressed_char2
Server Temp Key: ECDH, P-256, 256 bits

Using Lets Encrypt with

Let's Encrypt, to quote Wikipedia (I am lazy), "is a certificate authority that entered public beta on December 3, 2015 that provides free X.509 certificates for Transport Layer Security encryption (TLS) via an automated process designed to eliminate the current complex process of manual creation, validation, signing, installation and renewal of certificates for secure websites."

Alright, anyone who dealt with x509 certs and "classical" CAs will have felt some pain, and should get excited about above!

And the cool thing: it works. Today. And here is how to use Let's Encrypt to secure your nodes.

So let's encrypt and get busy;)


Let's Encrypt works from a tool which is installed on the server for which TLS keys and certificates should be generated.

The client is a Python program, hence you'll need Python on the server.

The client also (at least in "standalone mode") wants to fire up a terminal dialog thing. On Ubuntu, do

sudo apt-get install dialog

Then clone the official Let's Encrypt repo (sudo apt-get install git if you need Git)

cd ~
git clone
cd letsencrypt
git checkout v0.1.0
python install

Create server key and certificate

Assume your server will be reachable under the fully qualified hostname, here is how you generate all files needs (public-private key pairs, certificate and such).

In "standalone mode", the Let's Encrypt tool will do an outgoing connection to the Let's Encrypt servers and shortly fire up an embedded Web server which the Let's Encrypt servers will contact to verify that you are actually under control of the server.

From a terminal, run

sudo `which letsencrypt` certonly --standalone -d

The tool will ask you for an Email address, but that's it. Here is the output when successful:

 - If you lose your account credentials, you can recover through
   e-mails sent to
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/ Your
   cert will expire on 2016-03-13. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - Your account credentials have been saved in your Let's Encrypt
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Let's
   Encrypt so making regular backups of this folder is ideal.
 - If like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:
   Donating to EFF:          

You should now change the owner of the Let's Encrypt folder so that your server software (that will be using the TLS keys and certificates that have been generated) can access and read those files.

E.g. assuming you are running Ubuntu on AWS in a EC2 instance from the Ubuntu official image, the default account is named ubuntu, and when you plan to run under that user, you would need to:

sudo chown -R ubuntu:ubuntu /etc/letsencrypt

The files in that folder are:

(cpy2_1)ubuntu@ip-172-31-4-183:~$ sudo find /etc/letsencrypt/

Essentially, Let's Encrypt has generated a mini-database contained in those files with all the info needed to refresh your certs as well!

Generate a new Diffie-Hellman group


We want to run modern ciphers, and one of those involves Diffie-Hellman key exchange. To use that safely, you have to generate another things (a so called group):

openssl dhparam -2 4096 -out /etc/letsencrypt/live/

Again, make sure that file is readable by the user is run under.


Alright, awesome. We have server keys and a certificate. To use that on a listening transport, you'll need a transport configuration with a tls attribute giving the paths to key, certificate and chain_certificates:

"endpoint": {
    "type": "tcp",
    "port": 443,
    "tls": {
        "key": "/etc/letsencrypt/live/",
        "certificate": "/etc/letsencrypt/live/",
        "chain_certificates": ["/etc/letsencrypt/live/"],
        "dhparam": "/etc/letsencrypt/live/",
        "ciphers": "ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:"

In above, we are also pointing dhparam to the Diffie-Hellman group generated, and we provide an explicit ciphers list. Essentially, we disallow all but 4 ciphers altogether. Those ciphers are supported by modern gear, but won't work with deprecated stuff like Windows XP. You shouldn't care much about that, instead press users to upgrade.


Tracking down issues

Tracking down TLS issues can be done using OpenSSL. Eg here is how to check the TLS opening handshake (adjust -CApath /etc/ssl/certs/ to fit your system .. this works for Ubuntu):

oberstet@thinkpad-t430s:~$ openssl s_client -CApath /etc/ssl/certs/ -showcerts -connect
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1
verify return:1
depth=0 CN =
verify return:1
Certificate chain
 0 s:/
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
Server certificate
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
No client certificate CA names sent
SSL handshake has read 3047 bytes and written 421 bytes
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: 688D6B2F826CCFEEC48AE4E17E351D55AF2138762FCF8906E23047E97A1304B4
    Master-Key: 1BCE4C7CB9DBE234220EDF789CC07FCF9BE94B369C91AACF8C81FE7886D9C1E3E5A002BDF99A8881E5DBA09E7D80224C
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1453186799
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)