Security is these days extremly important, gone are the days of plain http, telnet, rtmp. Thanks to the Let's Encrypt service it is now very easy to create certificates, for free, that works with all major browsers. A bit simplified, Let's Encrypt will very that you own the domain you specifiy by asking for a secret on your server or DNS entry. That, unfortunately requires external access to the server. Unfortunately, especially when developing, you might be in a situation where using a public internet is not possible, you are on a private network space, firewalled, behind NAT or some other kind of closed network where usnig outside services is just not possible.
Note: This guide is for instructional purposes only and we do not claim these instructions to be fully secure or suitable for a particular purpose.
Rationale for writing this guide
Just as an example, we needed to test how to stream from OBS using RTMPS to our own RTMP private server. This obviously required trusted certificates on the server side and trusting the CA on the client side. OBS won't prompt to ignore unknown CAs so the CA used needs to be trusted by the system. The network used is closed, using the private IP address space of 192.168.0.0, no DNS and of course not visible to the public Internet. So using something like Let's Encrypt was not an option.
We will be using openssl for doing the work and assumme you have it already installed. Most Linux distros and OSX will have openssl installed by default already and ready to go. If you are under Windows then.. well, install WSL :)
To keep it simple, we won't encrypt the keys with a passphrase, but good security would be to do that, especially for the CA. But encrypted certificates can get annoying really quickly, as you need to somehow provide them to any software that uses them, for example apache will prompt you when started.
For these quick cirtificates, the only important information is the CN, it should match the hostname or IP that your server is using. Using a plain IP is sort-of wrong, but in a test environment with no DNS it should work just fine.
Quick and dirty, self-signed certificate
If your client can be told to ignore/trust unknown CAs (browser, mail clients for example) and the problems with self-signed certificates and just trust the certificate anyway, then you can use a self-signed certificate, where basically you sign and yourself. This is obviously only OK for internal use or development purposes.
For example this is handy when developing locally and you need a https connection for testing.
- Create a self-signed key
openssl req -x509 -nodes -newkey rsa:4096 -keyout server-key.pem -out server-cert.pem -sha256 -days 365 -subj "/C=FI/CN=hostname"
Now you can setup your software with private key server-key.pem, and certificate server-cert.pem
Be your own simple CA
If you can't trust yourself, then who can you trust ? If you do trust yourself, then you can be your own CA. This is a bit different from a self-signed certificate as now the certificate is signed by someone you trust. Yourself.
A bit more complex, but with this option you can actually simluate how it should work properly. You can import your own CA into your system certificate store or browser store. This way applications will trust certificates signed by your CA just like any other CA in the collection. Security and encryption wise this is just as secure as using some external signing CA, just that You trust Yourself instead of someone else.
But this also means that Nobody else will trust You! Unless, of course, you provide them with your CA public key, then they can trust certificates signed by you.
Create Your CA key & certificate
openssl genrsa -out YourCA.key 4096 openssl req -x509 -nodes -sha256 -key YourCA.key -out YourCA.pem -days 3650 -subj "/C=FI/CN=YourOwnCA-CommonName"
Keep the YourCA.key secure!
Create certificate signed by your CA
- Create a private key
openssl genrsa -out stunnel.key 4096
- Create a CSR (Certificate Signing Request) for the key
openssl req -new -sha256 -key stunnel.key -subj "/CN=192.168.9.123" > stunnel.csr
- Sign the CSR with your CA certificate
openssl x509 -sha256 -req -in stunnel.csr -out stunnel.crt -CA YourCA.pem -CAkey YourCA.key -CAcreateserial -days 3650
Make a P12 bundle
openssl pkcs12 -inkey key.pem -in cert.pem -export -out certificate.p12
To make your operating system and applications trust your CA, you need to add the YourCA.pem to your system wide CA store.
System wide trusted certificates are stored in /etc/ssl/certs, so to make most applications trust your CA you just need to add the certificate there.
Copy the YourCA.pem file to /etc/ssl/certs and run c_rehash to update the certificate hash links.
Windows & OS X
In case your application can't use separate certificates or files and instead requires a PFX archive (or you need to send all the details somewhere in a secure package)
openssl pkcs12 -export -out stunnel-export.pfx -inkey stunnel.key -in stunnel.crt