Shell script to create and sign certificates ============================================ Modern web browsers lament the absence of encryption when they access local web services on the home network. Adding certificates to these services gain sigificance. Mkcert ------ Mkcert creates signed locally trusted certificates. It makes managing and operating a local CA much easier. Mkcert is written in Go and available for Linux, Mac OS and Windows. My home network's systems are running FreeBSD. I had some dependency issues when compiling Mkcert, so I installed Mkcert it in a Linux virtual machine. It is excessive to start a virtual machine (VM) merely to generate few certificates. Shell script ------------ After some trial and error, I created a shell script to generate signed certificates. The script signs using the rootCA key generated by Mkcert, which is already trusted on my systems. Mkcert creates certificates with the parameter: subjectAltName=DNS:<FQDN of the subdomain>,IP:<ip-address of the server> I also set out to accomplish this with the script. Structure --------- * The script asumes that the rootCA.key and the rootCA.crt are in the directory ~/certs/rootcert. * For every subdomain a subdirectory is created under ~/certs/keys/ This is how it looks: certs |-- keys | |-- first.example.com | | |-- first.example.com.crt | | `-- first.example.com.key | `-- second.example.com | |-- second.example.com.crt | `-- second.example.com.key `-- rootcert |-- rootCA-key `-- rootCA.crt The idea is that you can either put ~/certs or the subdirectory ~/certs/keys into a versioning system like Git. Choose any versioning system, the key and certificate are text files. Not a security solution ----------------------- Always evaluate your thread model before selecting a security solution. The purpose of the certificates is to prevent browsers from complaining about the lack of encryption. Perhaps in the future, browsers will not allow users to log in to sites that do not use encryption. It's best to have things ready before that happens. The traffic is now encrypted, providing some protection against eavesdropping; nonetheless, do not use this method when security is critical. Where to install the certificates --------------------------------- Your FreeBSD workstation trust the certificates when you place the rootCA certificate in: /usr/local/share/certs Next, run certctl rehash Configuriation of your subdomains in NGINX: server { listen *:443 ssl; server_name subdomain.example.com; ssl_certificate /path/to/subdomain.crt; ssl_certificate_key /path/to/subdomain.key; location / { ... } } The script ---------- Here's the script: #!/bin/sh if [ $# -ne 2 ]; then echo "Usage: $0 <subdomain> <ip-address>" exit fi subdomain=$1 IP=$2 echo "Creating certifcate for FQDN: <$subdomain> on IP: <$IP> ..." echo "" myrootcertpath=${HOME}/certs/rootcert/ mypath=${HOME}/certs/keys/$subdomain mkdir -p $mypath cd $mypath # Create conf file: echo "[req]" > $subdomain.conf echo "distinguished_name=req" >> $subdomain.conf echo "[SAN]" >> $mypath/$subdomain.conf echo "subjectAltName=DNS:$subdomain,IP:$IP" >> $subdomain.conf echo "subjectAltName=DNS:$subdomain,IP:$IP" > $subdomain.ext # Check if key exists, if not, create if [ -e $subdomain.key ]; then echo "Key $mypath/$subdomain.key available, not generated" else openssl genrsa -out $subdomain.key 2048 echo "Created key $mypath/$subdomain.key" fi # Create a new csr from the key openssl req -new -sha256 -key $subdomain.key -subj /CN=$subdomain -out $subdomain.csr # Sign the key openssl x509 -req -extfile $subdomain.ext -in $subdomain.csr \ -CA $myrootcertpath/rootCA.crt -CAkey $myrootcertpath/rootCA.key \ -CAcreateserial -out $subdomain.crt -days 500 -sha256 # Clean up rm $subdomain.conf rm $subdomain.ext rm $subdomain.csr echo "Certificate $mypath/$subdomain.crt created" echo "view with: openssl x509 -noout -text -in $mypath/$subdomain.crt" Have fun! Last edited: $Date: 2024/03/31 19:34:07 $