To create new wiki account, please join us on #znc at Libera.Chat and ask admins to create a wiki account for you. You can say thanks to spambots for this inconvenience.

Signed SSL certificate: Difference between revisions

From ZNC
Jump to navigation Jump to search
>Resistance
Added a general recommendation that if you're not the only person using the ZNC instance, you may want to consider using signed SSL certificates. Also added link to a few SSL certificate providers, including those which have instructions here.
MAGIC (talk | contribs)
Update to latest version provided by archive.org
(10 intermediate revisions by 5 users not shown)
Line 3: Line 3:
== General advice ==
== General advice ==


<code>znc.pem</code> '''must''' contain everything in order from the "most private" to the "most public" key.
<code>znc.pem</code> '''must''' contain everything in order from the "most private" to the "most public" entries, except for the root certificate.


E.g. it may be something like this, if CA provides only 1 root cert in the chain:
E.g. it may be something like this:


  cat your-certificate-private.key > znc.pem
  cat your-certificate-private.key > znc.pem
  cat your-certificate.crt >> znc.pem
  cat your-certificate.crt >> znc.pem
  cat ca-root.crt >> znc.pem
  cat intermediate-certificate-of-ca.crt >> znc.pem  # If your certificate wasn't signed by CA root certificate directly.
# cat ca-root.crt >> znc.pem # Possible, but useless. If client knows this CA, this is redundant. If client doesn't know this CA, it's not trusted anyway.
 
You should also generate the Diffie–Hellman key exchange parameters, also appended to znc.pem:
 
openssl dhparam -out dhparam.pem 2048
cat dhparam.pem >> znc.pem
 
The dhparam file doesn't have to be kept secret, and can be used multiple times; substitute 2048 for your private key's bit size.
 
To apply this new certificate file to ZNC, just put (replace) it in ZNC's work folder.<br/>
As of 1.6.2, ZNC will reload <code>znc.pem</code> each time a client connects, but it'll be fixed in future.


Below you may find more specific instructions how to configure certs from few CAs, contributed by various people.
Below you may find more specific instructions how to configure certs from few CAs, contributed by various people.


== StartSSL ==
== CA-specific application of the general advice above ==
:Why this section is even needed?... --[[User:DarthGandalf|DarthGandalf]] ([[User talk:DarthGandalf|talk]]) 09:11, 4 December 2015 (UTC)
 
=== StartSSL ===


If you want to use your StartSSL web server certificate in ZNC, you need to put your private key and the your certificate into ~/.znc/znc.pem:
If you want to use your StartSSL web server certificate in ZNC, you need to put your private key and then your certificate into ~/.znc/znc.pem:


<code>cat server.key znc.pem > znc.pem</code>
cat server.key server.pem > znc.pem


Remember to replace server.key and znc.pem with the correct filenames and relevant paths.
Remember to replace server.key and znc.pem with the correct filenames and relevant paths.


The certificate now gets validated, but the validation fails, since the root certificate is properly not know on your machine (while most browser come built-in with the root certificate). So you either make the certificate known to your machine (and all your ZNC users) or your put the root cert into your znc.pem file like the following:
While the StartSSL root certificate is known on most recent machines, the intermediate certificate isn't, so it has to be appended to your personal certificate:
 
wget https://www.startssl.com/certs/sub.class1.server.ca.pem
cat sub.class1.server.ca.pem >> znc.pem
 
Then add the dhparam file, as generated above:


# <code>cd ~/.znc/</code>
cat dhparam.pem >> znc.pem
# <code>wget https://www.startssl.com/certs/sub.class1.server.ca.pem -O startssl.com.root.pem</code>
# <code>cat startssl.com.root.pem >> znc.pem</code>


It seems the order in your znc.pem must be "key", "own cert" and "root cert". If you get connection errors, make sure you done it right. You can test your certificate without connecting to znc with the following command:
You can test your certificate without connecting to znc with the following command:


  <code>openssl s_client -showcerts -connect domain.tld:6667</code>
  openssl s_client -showcerts -connect hostname:port
Change the domain and port to your domain and znc's listening port.


== PositiveSSL ==
Make sure to connect using the correct hostname, or the test won't be useful.


This is how I created a Positive SSL certificate for znc.
=== PositiveSSL ===
 
This is how I ([[User:Wayne_Arthurton]]) created a Positive SSL certificate for znc.


# <code>openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out server.csr</code>
# <code>openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out server.csr</code>
Line 41: Line 59:
# <code>cat myserver.key > ~/.znc/znc.pem</code>
# <code>cat myserver.key > ~/.znc/znc.pem</code>
# <code>cat host_domain_com.crt >> ~/.znc/znc.pem</code>
# <code>cat host_domain_com.crt >> ~/.znc/znc.pem</code>
# <code>cat PositiveSSLCA.crt >> ~/.znc/znc.pem</code>
# <code>cat PositiveSSLCA2.crt >> ~/.znc/znc.pem</code>
# <code>cat UTNAddTrustServerCA.crt >> ~/.znc/znc.pem</code>
# <code>cat AddTrustExternalCARoot.crt >> ~/.znc/znc.pem</code>


That should do it.  Drop a note on my Wiki Page if you need any more help.
That should do it.  Drop a note on my Wiki Page if you need any more help.


To use a PositiveSSL, this seemed to be the recipe
To use a PositiveSSL, this seemed to be the recipe
=== LetsEncrypt ===
'''Caveat:''' Let's Encrypt does not currently support IP addresses, if you want to use a Let's Encrypt certificate you'll need to be on a (sub-)domain. Additionally, they have a 90-day expiry, so it's a good idea to set up a cron job to reissue a cert every so often (monthly works).
==== Official Client ====
If you're using the official Let's Encrypt client, assuming you have your certificate in ''/etc/letsencrypt/live/example.org/'', here is how you can make a ''znc.pem'' from it (concatenate the 3 files together):
cat /etc/letsencrypt/live/example.org/{privkey,cert,chain}.pem > znc.pem
You need to repeat this every time you obtain a new certificate.
==== Caddy ====
[https://caddyserver.com/ Caddy] is a web server (alike Apache or nginx) with automatic HTTPS through LetsEncrypt.
The certificate files generated through Caddy can be used for ZNC, although they have to be concatenated just like with the official client.
Here's how you can make a ''znc.pem'' from them:
cat /etc/ssl/caddy/.caddy/acme/acme-v01.api.letsencrypt/sites/example.org/example.org.{key,crt} > /var/lib/znc/znc.pem
Just like with the official client, you will need to repeat this every time Caddy obtains a new certificate.
This can be automated to copy every month using a cronjob, like so:
0 0 1 * * cat /etc/ssl/caddy/.caddy/acme/acme-v01.api.letsencrypt/sites/example.org/example.org.{key,crt} > /var/lib/znc/znc.pem
==== Alternative Setup ====
This is a very quick install using a small, dependency-free, auditable python script: [https://github.com/diafygi/acme-tiny acme-tiny]. I recommend working in a separate directory, and then moving/symlinking the final cert into the config file afterward.
First, generate some RSA keys. The account key is your letsencrypt account, and can be reused for multiple domain keys if you're managing a lot of servers. For a private install it's easiest to just generate a new throwaway. Do replace <nowiki>yoursite.com</nowiki> with the appropriate value, here.
openssl genrsa 4096 > account.key
openssl genrsa 4096 > domain.key
openssl req -new -sha256 -key domain.key -subj "/CN=yoursite.com" > domain.csr
Next, we need to set up a challenge-response folder available from port 80. If your server has a web server available you'll need to hook into it temporarily (see the docs on the acme-tiny repo). If you do not have a web server, you can spin up a temporary one with python:
mkdir -p .well-known/acme-challenge/
sudo python -m SimpleHTTPServer 80 &
Now, download that script (and audit it if you're paranoid about malicious code), and run it get your signed cert. Then, we pull down the cross-signed cert to build our certificate chain, and smush all the files together for our final znc.pem:
python acme_tiny.py \
  --account-key ./account.key \
  --csr ./domain.csr \
  --acme-dir ./.well-known/acme-challenge/ \
  > ./signed.crt
wget <nowiki>https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem</nowiki>
cat domain.key signed.crt lets-encrypt-x3-cross-signed.pem > znc.pem
Don't forget to kill the temporary web server if you started it up, and then copy/symlink the certificate into place.
If you want/need to set up automatic renewals, you'll probably need to set up a permanent web server hosting the acme-challenge folder, and otherwise the shell script is identical to the last code block above, except with absolute paths.

Revision as of 13:39, 31 March 2017

If you're not going to be the only person using the ZNC instance, you may want to consider using signed SSL certificates. Signed SSL certificates are generated by third-party companies, such as StartSSL, PositiveSSL, VeriSign, or others, and will not cause "self-signed certificate" errors when used with an IRC client.

General advice

znc.pem must contain everything in order from the "most private" to the "most public" entries, except for the root certificate.

E.g. it may be something like this:

cat your-certificate-private.key > znc.pem
cat your-certificate.crt >> znc.pem
cat intermediate-certificate-of-ca.crt >> znc.pem  # If your certificate wasn't signed by CA root certificate directly.
# cat ca-root.crt >> znc.pem  # Possible, but useless. If client knows this CA, this is redundant. If client doesn't know this CA, it's not trusted anyway.

You should also generate the Diffie–Hellman key exchange parameters, also appended to znc.pem:

openssl dhparam -out dhparam.pem 2048
cat dhparam.pem >> znc.pem

The dhparam file doesn't have to be kept secret, and can be used multiple times; substitute 2048 for your private key's bit size.

To apply this new certificate file to ZNC, just put (replace) it in ZNC's work folder.
As of 1.6.2, ZNC will reload znc.pem each time a client connects, but it'll be fixed in future.

Below you may find more specific instructions how to configure certs from few CAs, contributed by various people.

CA-specific application of the general advice above

Why this section is even needed?... --DarthGandalf (talk) 09:11, 4 December 2015 (UTC)

StartSSL

If you want to use your StartSSL web server certificate in ZNC, you need to put your private key and then your certificate into ~/.znc/znc.pem:

cat server.key server.pem > znc.pem

Remember to replace server.key and znc.pem with the correct filenames and relevant paths.

While the StartSSL root certificate is known on most recent machines, the intermediate certificate isn't, so it has to be appended to your personal certificate:

wget https://www.startssl.com/certs/sub.class1.server.ca.pem
cat sub.class1.server.ca.pem >> znc.pem

Then add the dhparam file, as generated above:

cat dhparam.pem >> znc.pem

You can test your certificate without connecting to znc with the following command:

openssl s_client -showcerts -connect hostname:port

Make sure to connect using the correct hostname, or the test won't be useful.

PositiveSSL

This is how I (User:Wayne_Arthurton) created a Positive SSL certificate for znc.

  1. openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out server.csr
  2. Submit server.csr to PositiveSSL
  3. Once you receive your SSL Bundle zip, uncompress
  4. cat myserver.key > ~/.znc/znc.pem
  5. cat host_domain_com.crt >> ~/.znc/znc.pem
  6. cat PositiveSSLCA2.crt >> ~/.znc/znc.pem
  7. cat AddTrustExternalCARoot.crt >> ~/.znc/znc.pem

That should do it. Drop a note on my Wiki Page if you need any more help.

To use a PositiveSSL, this seemed to be the recipe

LetsEncrypt

Caveat: Let's Encrypt does not currently support IP addresses, if you want to use a Let's Encrypt certificate you'll need to be on a (sub-)domain. Additionally, they have a 90-day expiry, so it's a good idea to set up a cron job to reissue a cert every so often (monthly works).

Official Client

If you're using the official Let's Encrypt client, assuming you have your certificate in /etc/letsencrypt/live/example.org/, here is how you can make a znc.pem from it (concatenate the 3 files together):

cat /etc/letsencrypt/live/example.org/{privkey,cert,chain}.pem > znc.pem

You need to repeat this every time you obtain a new certificate.

Caddy

Caddy is a web server (alike Apache or nginx) with automatic HTTPS through LetsEncrypt. The certificate files generated through Caddy can be used for ZNC, although they have to be concatenated just like with the official client.

Here's how you can make a znc.pem from them:

cat /etc/ssl/caddy/.caddy/acme/acme-v01.api.letsencrypt/sites/example.org/example.org.{key,crt} > /var/lib/znc/znc.pem

Just like with the official client, you will need to repeat this every time Caddy obtains a new certificate. This can be automated to copy every month using a cronjob, like so:

0 0 1 * * cat /etc/ssl/caddy/.caddy/acme/acme-v01.api.letsencrypt/sites/example.org/example.org.{key,crt} > /var/lib/znc/znc.pem

Alternative Setup

This is a very quick install using a small, dependency-free, auditable python script: acme-tiny. I recommend working in a separate directory, and then moving/symlinking the final cert into the config file afterward.

First, generate some RSA keys. The account key is your letsencrypt account, and can be reused for multiple domain keys if you're managing a lot of servers. For a private install it's easiest to just generate a new throwaway. Do replace yoursite.com with the appropriate value, here.

openssl genrsa 4096 > account.key
openssl genrsa 4096 > domain.key
openssl req -new -sha256 -key domain.key -subj "/CN=yoursite.com" > domain.csr

Next, we need to set up a challenge-response folder available from port 80. If your server has a web server available you'll need to hook into it temporarily (see the docs on the acme-tiny repo). If you do not have a web server, you can spin up a temporary one with python:

mkdir -p .well-known/acme-challenge/
sudo python -m SimpleHTTPServer 80 &

Now, download that script (and audit it if you're paranoid about malicious code), and run it get your signed cert. Then, we pull down the cross-signed cert to build our certificate chain, and smush all the files together for our final znc.pem:

python acme_tiny.py \
  --account-key ./account.key \
  --csr ./domain.csr \
  --acme-dir ./.well-known/acme-challenge/ \
  > ./signed.crt

wget https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem
cat domain.key signed.crt lets-encrypt-x3-cross-signed.pem > znc.pem

Don't forget to kill the temporary web server if you started it up, and then copy/symlink the certificate into place.

If you want/need to set up automatic renewals, you'll probably need to set up a permanent web server hosting the acme-challenge folder, and otherwise the shell script is identical to the last code block above, except with absolute paths.