#!/bin/bash # RSA 3072-bit # Tested - works for me. Line number notes assume first line is line 1 # Modify lines 85-88, 90 for your own identity (leave ${FQDN} line alone) # Modify line 19 for your openssl/libressl binary path # Modify line 20 for your certbot path # Example Usage: # # sudo sh letsencrypt.sh example.org www.example.org support.example.org # (all arguements need DNS records pointing to server running on) # # Stop web server daemon before running this script. OPENSSL="/usr/bin/libressl" CERTBOT="/usr/bin/certbot" if [ ! -x ${OPENSSL} ]; then echo "Please edit script and define your OpenSSL API implementation (line 19)." exit 1 fi [ "$(id -u)" != "0" ] && exit 1 FQDN="$1" DATE="`date +%Y%m%d`" CSR="${FQDN}-EFFLE-${DATE}.csr" CFG="${FQDN}-EFFLE.cfg" X509="${FQDN}-EFFLE-${DATE}.crt" CAB="${FQDN}-EFFLE-cab-${DATE}.crt" umask 0277 [ ! -d /etc/pki/tls/eff_private ] && mkdir -p /etc/pki/tls/eff_private pushd /etc/pki/tls/eff_private > /dev/null 2>&1 # if existing key is less than 320 days old, use it. Otherwise generate a fresh NEWKEY=0 keycount=`find . -type f -print |grep "^\./${FQDN}-" |wc -l` if [ $keycount -eq 0 ]; then NEWKEY=1 else LATEST=`find . -type f -print |grep "^\./${FQDN}-" |tail -1 |sed -e s?"^\./"?""?` AGE=`echo $(($(date +%s) - $(date +%s -r ${LATEST})))` let "DAYS = ${AGE} / 86400" if [ ${DAYS} -ge 320 ]; then NEWKEY=1 else PVT="${LATEST}" fi fi if [ ${NEWKEY} -eq 1 ]; then PVT="${FQDN}-EFFLE-${DATE}.key" ${OPENSSL} genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out "${PVT}" fi if [ ! -f "${PVT}" ]; then echo "Something went wrong, no suitable private key" exit 1 fi umask 0022 popd > /dev/null 2>&1 # generate CSR [ ! -d /etc/pki/tls/csr ] && mkdir /etc/pki/tls/csr pushd /etc/pki/tls/csr > /dev/null 2>&1 [ -f "${CFG}" ] && rm -f "${CFG}" [ -f "${CSR}" ] && rm -f "${CSR}" cat < "${CFG}" [req] distinguished_name = req_distinguished_name req_extensions = ext prompt = no [ req_distinguished_name ] C = YourCountryCode ST = YourState L = YourCity O = Your Organization Name CN = ${FQDN} emailAddress = user@example.org [ext] basicConstraints = critical,CA:FALSE keyUsage = critical,digitalSignature extendedKeyUsage = serverAuth,clientAuth subjectAltName = @san [san] EOF COUNTER=0 for arg in $@; do ((COUNTER++)) echo "DNS.${COUNTER} = ${arg}" >> "${CFG}" done ${OPENSSL} req -new -key "../eff_private/${PVT}" -out "${CSR}" -config "${CFG}" if [ $? -ne 0 ]; then echo "Problem creating CSR" exit 1 fi popd > /dev/null 2>&1 if [ ${NEWKEY} -eq 1 ]; then echo "New Private Key Generated: /etc/pki/tls/eff_private/${PVT}" fi echo "CSR file: /etc/pki/tls/csr/${CSR}" if [ -x ${CERTBOT} ]; then [ ! -d /etc/pki/tls/eff_certs ] && mkdir -p /etc/pki/tls/eff_certs ${CERTBOT} certonly --standalone --csr /etc/pki/tls/csr/${CSR} \ --cert-path /etc/pki/tls/eff_certs/${X509} \ --chain-path /etc/pki/tls/eff_certs/${CAB} fi if [ -f "/etc/pki/tls/eff_certs/${X509}" ]; then pushd /etc/pki/tls/eff_certs/ # generate DANE FINGERPRINT="`${OPENSSL} x509 -noout -fingerprint -sha256 < "${X509}" |tr -d : |cut -d"=" -f2`" echo "" echo "TLSA from Cert:" echo "3 0 1 ${FINGERPRINT}" echo "" echo "TLSA from PubKey:" FINGERPRINT="`${OPENSSL} x509 -in ${X509} -noout -pubkey \ |${OPENSSL} pkey -pubin -outform DER \ |${OPENSSL} dgst -sha256 -binary \ |hexdump -ve '/1 "%02x"'`" FINGERPRINT=${FINGERPRINT^^} echo "3 1 1 ${FINGERPRINT}" fi exit 0