:orphan: TLS Certificates ================ This page provides some information about how to create and use TLS certificates for secure connections with Crossbar.io. For configuring TLS in Crossbar.io in principle, see :doc:`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, they are OK. The following provides a recipe for creating a new server key and self-signed certificate for use with Crossbar.io. First, check your OpenSSL version: .. code:: console 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. ``server23.tavendo.com`` (or ``62.146.25.40``). 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 `Let's Encrypt `__ - see the specific instructions further below. 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 ../sub.class1.server.sha2.ca.pem >> 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 serveruser@server.example.com:/home/serveruser 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 Crossbar.io 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 -------------- Testing ------- You can use ``openssl client`` command to check your server in the end: .. code:: console oberstet@corei7ub1310:~/scm/3rdparty/openssl$ ~/openssl/bin/openssl s_client -brief -connect demo.crossbar.io:443 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 CONNECTION ESTABLISHED Protocol version: TLSv1.2 Ciphersuite: ECDHE-RSA-AES128-GCM-SHA256 Peer certificate: description = 3FfmiF3b24n8r1Hz, C = DE, CN = demo.crossbar.io, emailAddress = postmaster@crossbar.io 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 Crossbar.io ----------------------------------- `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 Crossbar.io nodes. So let's encrypt and get busy;) Installation ~~~~~~~~~~~~ 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 git@github.com:letsencrypt/letsencrypt.git cd letsencrypt git checkout v0.1.0 python setup.py install Create server key and certificate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Assume your server will be reachable under the fully qualified hostname ``box1.example.com``, 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 box1.example.com The tool will ask you for an Email address, but that's it. Here is the output when successful: :: IMPORTANT NOTES: - If you lose your account credentials, you can recover through e-mails sent to tobias.oberstein@tavendo.de. - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/box1.example.com/fullchain.pem. 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: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le 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 Crossbar.io under that user, you would need to: .. code:: console sudo chown -R ubuntu:ubuntu /etc/letsencrypt The files in that folder are: .. code:: console (cpy2_1)ubuntu@ip-172-31-4-183:~$ sudo find /etc/letsencrypt/ /etc/letsencrypt/ /etc/letsencrypt/archive /etc/letsencrypt/archive/box1.example.com /etc/letsencrypt/archive/box1.example.com/cert1.pem /etc/letsencrypt/archive/box1.example.com/chain1.pem /etc/letsencrypt/archive/box1.example.com/fullchain1.pem /etc/letsencrypt/archive/box1.example.com/privkey1.pem /etc/letsencrypt/csr /etc/letsencrypt/csr/0000_csr-letsencrypt.pem /etc/letsencrypt/live /etc/letsencrypt/live/box1.example.com /etc/letsencrypt/live/box1.example.com/privkey.pem /etc/letsencrypt/live/box1.example.com/fullchain.pem /etc/letsencrypt/live/box1.example.com/cert.pem /etc/letsencrypt/live/box1.example.com/chain.pem /etc/letsencrypt/renewal /etc/letsencrypt/renewal/box1.example.com.conf /etc/letsencrypt/keys /etc/letsencrypt/keys/0000_key-letsencrypt.pem /etc/letsencrypt/accounts /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/0417840b9724dff8a342834a0e82b72e /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/0417840b9724dff8a342834a0e82b72e/private_key.json /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/0417840b9724dff8a342834a0e82b72e/regr.json /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/0417840b9724dff8a342834a0e82b72e/meta.json 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **optional** 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): .. code:: console openssl dhparam -2 4096 -out /etc/letsencrypt/live/box1.example.com/dhparam.pem Again, make sure that file is readable by the user Crossbar.io is run under. Configure Crossbar.io ~~~~~~~~~~~~~~~~~~~~~ Alright, awesome. We have server keys and a certificate. To use that on a Crossbar.io listening transport, you'll need a transport configuration with a ``tls`` attribute giving the paths to ``key``, ``certificate`` and ``chain_certificates``: .. code:: json "endpoint": { "type": "tcp", "port": 443, "tls": { "key": "/etc/letsencrypt/live/box1.example.com/privkey.pem", "certificate": "/etc/letsencrypt/live/box1.example.com/cert.pem", "chain_certificates": ["/etc/letsencrypt/live/box1.example.com/chain.pem"], "dhparam": "/etc/letsencrypt/live/box1.example.com/dhparam.pem", "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): .. code:: console oberstet@thinkpad-t430s:~$ openssl s_client -CApath /etc/ssl/certs/ -showcerts -connect demo.crossbar.io:443 CONNECTED(00000003) 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 = cbdemo-eu-central-1.crossbar.io verify return:1 --- Certificate chain 0 s:/CN=cbdemo-eu-central-1.crossbar.io i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1 -----BEGIN CERTIFICATE----- MIIFNDCCBBygAwIBAgISAWvkTNHswSHEDMW/5kJc5MaDMA0GCSqGSIb3DQEBCwUA MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTAeFw0xNTEyMjAxMDE3MDBaFw0x NjAzMTkxMDE3MDBaMCoxKDAmBgNVBAMTH2NiZGVtby1ldS1jZW50cmFsLTEuY3Jv c3NiYXIuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCZYgp9QNnQ phT7r+hbP1TxVCdKdkECyhXW0sLd8qXHGokHZ3HvXbsOc1gLeMPEJtqeMsOW2z0C aU2dOh4ZzRCO0fCJJqX8wvAgqI3sndubDLUgNI0fbOtrJBnCjLCUPxBqTv+/+KYy ZOuT3no0l+DZ8E42OG91YRkk+kviJh/MxBpTHrFAcZXuRoeqz6LtyYGIX/+TMcts kUvtCSVwym1rRYKsGPCCeGv0quBUoOfQtA3rpFuahnFgTS3AK0C2v7jMroGeJavu B3VeiWe2E4TiSrLaIF1vrKldJKcM3E0sO8mSGIKEg4/dqNusW7KKIPB4/bmFfHt6 g02ey1ALtOk3AgMBAAGjggIyMIICLjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw FAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFII3 EyHm6bBFbgjDpUoT/GSEQ6fMMB8GA1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/z qOyhMHAGCCsGAQUFBwEBBGQwYjAvBggrBgEFBQcwAYYjaHR0cDovL29jc3AuaW50 LXgxLmxldHNlbmNyeXB0Lm9yZy8wLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0Lmlu dC14MS5sZXRzZW5jcnlwdC5vcmcvMDwGA1UdEQQ1MDOCH2NiZGVtby1ldS1jZW50 cmFsLTEuY3Jvc3NiYXIuaW+CEGRlbW8uY3Jvc3NiYXIuaW8wgf4GA1UdIASB9jCB 8zAIBgZngQwBAgEwgeYGCysGAQQBgt8TAQEBMIHWMCYGCCsGAQUFBwIBFhpodHRw Oi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCBqwYIKwYBBQUHAgIwgZ4MgZtUaGlzIENl cnRpZmljYXRlIG1heSBvbmx5IGJlIHJlbGllZCB1cG9uIGJ5IFJlbHlpbmcgUGFy dGllcyBhbmQgb25seSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIENlcnRpZmljYXRl IFBvbGljeSBmb3VuZCBhdCBodHRwczovL2xldHNlbmNyeXB0Lm9yZy9yZXBvc2l0 b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAZZzfsXv7SKNPzsot2vFN7tRnRml7P/YC JMgRFwdpqcdKKsAhld4vcJPv3kaRMCyfb/02/ckLG4qrvLdply22LBtTyV+/9yJ1 cmiIRRGtplSEVpU9Aqanao4kxG9ZIASdQ9vkv4botYK2x8kWvrtt4eUg9rb68q0x I0ecFPy3iT3AlFCkf5Ph4SorJvG/y4LyatAMM5sZF0C5XFe35o2ORWjToMAzEBAl bcCgXLK30+FmHFsHnTultF8zJ358EYtpbNmwLu6CkRB8YV6GI4gjsgOXBCX3KQk2 FNcHRMD7RrXdeS1+vrFMolcRK48jeIpd6E2R9+SSTzkD3mQz7siHYw== -----END CERTIFICATE----- 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 -----BEGIN CERTIFICATE----- MIIEqDCCA5CgAwIBAgIRAJgT9HUT5XULQ+dDHpceRL0wDQYJKoZIhvcNAQELBQAw PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD Ew5EU1QgUm9vdCBDQSBYMzAeFw0xNTEwMTkyMjMzMzZaFw0yMDEwMTkyMjMzMzZa MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAJzTDPBa5S5Ht3JdN4OzaGMw6tc1Jhkl4b2+NfFwki+3uEtB BaupnjUIWOyxKsRohwuj43Xk5vOnYnG6eYFgH9eRmp/z0HhncchpDpWRz/7mmelg PEjMfspNdxIknUcbWuu57B43ABycrHunBerOSuu9QeU2mLnL/W08lmjfIypCkAyG dGfIf6WauFJhFBM/ZemCh8vb+g5W9oaJ84U/l4avsNwa72sNlRZ9xCugZbKZBDZ1 gGusSvMbkEl4L6KWTyogJSkExnTA0DHNjzE4lRa6qDO4Q/GxH8Mwf6J5MRM9LTb4 4/zyM2q5OTHFr8SNDR1kFjOq+oQpttQLwNh9w5MCAwEAAaOCAZIwggGOMBIGA1Ud EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAy BggrBgEFBQcwAYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5j b20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMv ZHN0cm9vdGNheDMucDdjMB8GA1UdIwQYMBaAFMSnsaR7LHH62+FLkHX/xBVghYkQ MFQGA1UdIARNMEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUH AgEWImh0dHA6Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUw MzAxoC+gLYYraHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JM LmNybDATBgNVHR4EDDAKoQgwBoIELm1pbDAdBgNVHQ4EFgQUqEpqYwR93brm0Tm3 pkVl7/Oo7KEwDQYJKoZIhvcNAQELBQADggEBANHIIkus7+MJiZZQsY14cCoBG1hd v0J20/FyWo5ppnfjL78S2k4s2GLRJ7iD9ZDKErndvbNFGcsW+9kKK/TnY21hp4Dd ITv8S9ZYQ7oaoqs7HwhEMY9sibED4aXw09xrJZTC9zK1uIfW6t5dHQjuOWv+HHoW ZnupyxpsEUlEaFb+/SCI4KCSBdAsYxAcsHYI5xxEI4LutHp6s3OT2FuO90WfdsIk 6q78OMSdn875bNjdBYAqxUp2/LEIHfDBkLoQz0hFJmwAbYahqKaLn73PAAm1X2kj f1w8DdnkabOLGeOVcj9LQ+s67vBykx4anTjURkbqZslUEUsn2k5xeua2zUk= -----END CERTIFICATE----- --- Server certificate subject=/CN=cbdemo-eu-central-1.crossbar.io 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 SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES128-GCM-SHA256 Session-ID: 688D6B2F826CCFEEC48AE4E17E351D55AF2138762FCF8906E23047E97A1304B4 Session-ID-ctx: 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) --- ^C Updating Certificates ===================== After updating Crossbar.io TLS server certificates and/or keys, you must restart Crossbar.io for the new certificates/keys to take effect. The certificates/keys are cached when loading the first time, and hence without restarting Crossbar.io, the old certificates/keys would still be used despite the new ones already being stored on disk. Updating LetsEncrypt with certbot --------------------------------- Once you have configured LetsEncrypt, you can periodically run `certbot `_ to update your certificates. You may wish to restart Crossbar.io if a new certificate is generated. Certbot has a `--deploy-hook` which is run once for every generated certificate, with the domains in `$RENEWED_DOMAINS`. Thus you can create something like .. code:: bash #!/bin/bash if [[ "$RENEWED_DOMAINS" =~ "wamp.my.domain" ]]; then systemctl restart crossbar # or however your router is run echo "restarted server" > /tmp/log fi And then pass it to certbot, e.g. by running `systemctl edit certbot` and adding `--deploy-hook=/path/to/restart.sh`.