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
>Resistance No edit summary |
changed /var/lib/znc to /var/lib/znc/.znc in several examples to better reflect common paths used in ZNC packages. noted by predicament in #znc |
||
(29 intermediate revisions by 11 users not shown) | |||
Line 1: | Line 1: | ||
Signed SSL certificates are recommended when more than one person uses the ZNC instance. Signed SSL certificates are generated by third-party companies, such as [https://letsencrypt.org/ Let's Encrypt], [http://www.positivessl.com/ PositiveSSL], [http://www.verisign.com/ VeriSign], or others, and will not cause "self-signed certificate" errors when used with an IRC client. | |||
== General advice == | |||
Make sure that the certificate private key file is not encrypted and does not have password protection on it, ZNC is unable to properly handle encrypted private key files. | |||
=== ZNC 1.7.0+ === | |||
Since 1.7, you can configure ZNC to read different parts of the certificate from different files: | |||
SSLCertFile = /path/to/combined/cert.pem | |||
SSLKeyFile = /path/to/private/key.pem | |||
SSLDHParamFile = /path/to/DH/file.pem | |||
Read [[Configuration]] about how to edit config. | |||
The old way (described below) still works. | |||
== | === Before ZNC 1.7 === | ||
This is how I created a Positive SSL certificate for znc. | <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: | |||
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.<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. | |||
== 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) | |||
=== PositiveSSL === | |||
This is how I ([[User:Wayne_Arthurton|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 27: | Line 52: | ||
# <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 | # <code>cat PositiveSSLCA2.crt >> ~/.znc/znc.pem</code> | ||
# <code>cat | # <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). | |||
==== Certbot ==== | |||
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 2 files together): | |||
cat /etc/letsencrypt/live/example.org/{privkey,fullchain}.pem > znc.pem | |||
If you are using an older version of the Let's Encrypt client that does not create fullchain.pem, use this one: | |||
cat /etc/letsencrypt/live/example.org/{privkey,cert,chain}.pem > znc.pem | |||
You need to repeat this every time you obtain a new certificate. | |||
===== Automating znc.pem creation ===== | |||
You can automate the process of creating a <code>znc.pem</code> file every time your certificate is renewed by adding a deploy hook to <code>/etc/letsencrypt/renewal-hooks/deploy</code> like so: | |||
<pre> | |||
$ cd /etc/letsencrypt/renewal-hooks/deploy | |||
$ touch update-znc.pem | |||
$ chmod +x update-znc.pem | |||
$ vim update-znc.pem | |||
</pre> | |||
<pre> | |||
#!/bin/bash | |||
YOURDOMAIN="example.com" | |||
[[ $RENEWED_LINEAGE != "/etc/letsencrypt/live/$YOURDOMAIN" ]] && exit 0 | |||
echo "Updating certs" | |||
cat /etc/letsencrypt/live/$YOURDOMAIN/{privkey,fullchain}.pem > /var/lib/znc/.znc/znc.pem | |||
</pre> | |||
==== 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/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/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. | |||
=== CACert === | |||
To use a [http://www.cacert.org CACert] certificate, you need to do several things. Within a dedicated folder for this, do the following steps: | |||
#. Create an '''unencrypted''' key for the server and the corresponding CSR: <code>openssl req -nodes -newkey rsa:2048 -keyout server.key -out server.csr</code> | |||
#. Send the CSR to CACert and wait for them to issue you a certificate. Once you retrieve the certificate in text format from their site, copy that text and put it into the file called <code>server.crt</code> | |||
#. Download both the [https://www.cacert.org/certs/root.crt CACert Root CA certificate] and the [https://www.cacert.org/certs/class3.crt CACert Intermediate certificate] to the same folder. | |||
#. As per the 'general' advice above, create DH parameters to include with the certificate ('''Warning: this will take some time to complete'''): <code>openssl dhparam 2048 -out dh2048.pem</code> | |||
#. Concatenate all the certificates and the key together with the following code: <code>cat server.key server.crt class3.crt root.crt dh2048.pem > znc.pem</code> | |||
#. Take the complete <code>znc.pem</code> file and put it in the ZNC configuration directory, overwriting any preexisting <code>znc.pem</code> file in the directory (or move the <code>znc.pem</code> file to another name and create a new <code>znc.pem</code> file with the certificate from CACert). | |||
Once this is completed you can now use the CACert certificate for your ZNC. |
Latest revision as of 17:19, 25 February 2022
Signed SSL certificates are recommended when more than one person uses the ZNC instance. Signed SSL certificates are generated by third-party companies, such as Let's Encrypt, PositiveSSL, VeriSign, or others, and will not cause "self-signed certificate" errors when used with an IRC client.
General advice
Make sure that the certificate private key file is not encrypted and does not have password protection on it, ZNC is unable to properly handle encrypted private key files.
ZNC 1.7.0+
Since 1.7, you can configure ZNC to read different parts of the certificate from different files:
SSLCertFile = /path/to/combined/cert.pem SSLKeyFile = /path/to/private/key.pem SSLDHParamFile = /path/to/DH/file.pem
Read Configuration about how to edit config.
The old way (described below) still works.
Before ZNC 1.7
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)
PositiveSSL
This is how I (Wayne_Arthurton) created a Positive SSL certificate for znc.
openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out server.csr
- Submit server.csr to PositiveSSL
- Once you receive your SSL Bundle zip, uncompress
cat myserver.key > ~/.znc/znc.pem
cat host_domain_com.crt >> ~/.znc/znc.pem
cat PositiveSSLCA2.crt >> ~/.znc/znc.pem
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).
Certbot
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 2 files together):
cat /etc/letsencrypt/live/example.org/{privkey,fullchain}.pem > znc.pem
If you are using an older version of the Let's Encrypt client that does not create fullchain.pem, use this one:
cat /etc/letsencrypt/live/example.org/{privkey,cert,chain}.pem > znc.pem
You need to repeat this every time you obtain a new certificate.
Automating znc.pem creation
You can automate the process of creating a znc.pem
file every time your certificate is renewed by adding a deploy hook to /etc/letsencrypt/renewal-hooks/deploy
like so:
$ cd /etc/letsencrypt/renewal-hooks/deploy $ touch update-znc.pem $ chmod +x update-znc.pem $ vim update-znc.pem
#!/bin/bash YOURDOMAIN="example.com" [[ $RENEWED_LINEAGE != "/etc/letsencrypt/live/$YOURDOMAIN" ]] && exit 0 echo "Updating certs" cat /etc/letsencrypt/live/$YOURDOMAIN/{privkey,fullchain}.pem > /var/lib/znc/.znc/znc.pem
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/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/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.
CACert
To use a CACert certificate, you need to do several things. Within a dedicated folder for this, do the following steps:
- . Create an unencrypted key for the server and the corresponding CSR:
openssl req -nodes -newkey rsa:2048 -keyout server.key -out server.csr
- . Send the CSR to CACert and wait for them to issue you a certificate. Once you retrieve the certificate in text format from their site, copy that text and put it into the file called
server.crt
- . Download both the CACert Root CA certificate and the CACert Intermediate certificate to the same folder.
- . As per the 'general' advice above, create DH parameters to include with the certificate (Warning: this will take some time to complete):
openssl dhparam 2048 -out dh2048.pem
- . Concatenate all the certificates and the key together with the following code:
cat server.key server.crt class3.crt root.crt dh2048.pem > znc.pem
- . Take the complete
znc.pem
file and put it in the ZNC configuration directory, overwriting any preexistingznc.pem
file in the directory (or move theznc.pem
file to another name and create a newznc.pem
file with the certificate from CACert).
Once this is completed you can now use the CACert certificate for your ZNC.