SSL#

Let’s Encrypt / Certbot#

See felixhummel/docker-certbot

Check a Certificate#

To check felixhummel.de:

domain=felixhummel.de
echo | openssl s_client -showcerts -connect $domain:443 | openssl x509 -inform pem -noout -text

If you have multiple servers behind a load balancer:

ip=37.120.190.133
domain=felixhummel.de
echo | openssl s_client -showcerts -servername $domain -connect $ip:443 2>/dev/null | openssl x509 -inform pem -noout -text

Self-Signed (for development)#

Mission:

  • create self signed certificate for locutus.lan

  • use it in nginx

  • import it for wget, chromium and firefox

Servername could also be fqdn, e.g. example.org or wildcard, e.g. '*.example.org'. Remember to escape the asterisk!

# as root
servername=locutus.lan
prefix=/etc/nginx/certs

stripped_host=${servername#*\*\.}
mkdir -p $prefix/$stripped_host
keyfile_path=$prefix/$stripped_host/key
signing_request_path=$prefix/$stripped_host/csr
cert_path=$prefix/$stripped_host/crt

openssl genrsa -out $keyfile_path 1024
openssl req -new\
    -key $keyfile_path\
    -out $signing_request_path\
    -subj "/CN=$servername"

openssl x509\
    -in $signing_request_path\
    -out $cert_path\
    -req -signkey $keyfile_path\
    -days 65500
# let's see those files
echo $prefix/$stripped_host && ls $prefix/$stripped_host

Use it in nginx by applying the following config:

server {
    listen 443 ssl;
    server_name  localhost;

    ssl_certificate /etc/nginx/certs/localhost/crt;
    ssl_certificate_key /etc/nginx/certs/localhost/key;

    location / {
        auth_basic "myrealm";
        auth_basic_user_file /etc/nginx/auth/deimuddi;
        root   /srv/locutus.local;
        index  index.html index.htm;
    }
}

Import for wget:

cp /etc/nginx/certs/locutus.lan/crt /usr/lib/ssl/certs/locutus.lan.pem
cd /usr/lib/ssl/certs
ln -s locutus.lan.pem $(openssl x509 -noout -hash -in locutus.lan.pem).0
# test it:
wget https://locutus.lan/

Install NSS Tools which contains the certutil binary:

sudo apt-get install libnss3-tools

Import for chromium (restart chromium afterwards):

nssdb_dir=sql:$HOME/.pki/nssdb
certutil -d $nssdb_dir -A -t "P,p,p" -n locutus.lan -i /etc/nginx/certs/locutus.lan/crt

For firefox (every profile has an nssdb, restart firefox afterwards). Note that there is no sql:-prefix on the db path:

for nssdb_dir in $(find  ~/.mozilla* -name "cert8.db" | xargs dirname); do
    certutil -d $nssdb_dir -A -t "P,p,p" -n locutus.lan -i /etc/nginx/certs/locutus.lan/crt
done

Note

Tried the same for localhost. Does not work.

Troubleshooting:

# list certs
certutil -d $nssdb_dir -L
# delete cert by nickname
certutil -d $nssdb_dir -D -n <nickname>

Add a new CA to your trusted CAs#

This is similar to the self-signed approach, but we need to tell Firefox and Chrome to use the cert as a CA that we trust to sign both server and client certs.

System#

As root: Copy your CRT file. Note that it must have the .crt extension:

cp foo.crt /usr/local/share/ca-certificates/

Run the update:

update-ca-certificates

Firefox#

About the CT,C,C. See certutil -H 2>&1 | less +/trustargs:

nickname=felix_root_ca
for nssdb_dir in $(find  ~/.mozilla* -name "cert8.db" | xargs dirname); do
    certutil -d $nssdb_dir -A -t "CT,C,C" -n $nickname -i foo.crt
done

Chrome/Chromium#

Same game, but note the sql: prefix:

nssdb_dir=sql:$HOME/.pki/nssdb
nickname=felix_root_ca
certutil -d $nssdb_dir -A -t "CT,C,C" -n $nickname -i foo.crt

Remove Passphrase From Cert File#

Passphrases are good in general, but poison for automation:

openssl rsa -in with_passphrase.key -out /tmp/without_passphrase.key