Create a gist now

Instantly share code, notes, and snippets.

@inittab /new_cert
Last active Feb 16, 2017

What would you like to do?
acme_tiny shell wrapper
#!/bin/bash
## Usage: new_cert example.net www.example.net images.example.net
##
## Creates o renews a let's encrypt certifcate using acme-tiny
## Files' names for certs/keys will be based on the first domain
## if multiple are specified as arguments
##
## Depends: openssl, acme-tiny, an account key: openssl genrsa 4096 > account.key
## Recommends: let's encrypt intermediat cert:
## wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > $PARENT_CERT
## config start ##
ACME_TINY=/usr/local/bin/acme_tiny.py
WORKING_DIR=/etc/ssl/letsencrypt # where certs and keys will be kept
ACCOUNT_KEY="$WORKING_DIR/account.key"
PARENT_CERT="$WORKING_DIR/lets-encrypt-x3-cross-signed.pem"
CHALLENGES_DIR=/var/www/letsencryptchallenges/ # published by webserver
# as /.well-known/acme-challenge/
APPEND_PARENT_CERT=1 # concats let's encrypt cert to resulting
# cert (i.e. for nginx)
## config end ##
error() {
echo "ERROR: $1"
[ "$2" -ne 0 ] && exit $2
}
# Sanity checks
[ "$#" -ge 1 ] || error "Usage: $0 domain [domain ...]" 1
[ -f "$ACME_TINY" ] || error "$ACME_TINY not found" 10
[ -d "$WORKING_DIR" ] || error "$WORKING_DIR not found" 11
[ -w "$WORKING_DIR" ] || error "$WORKING_DIR not writeable" 12
[ -d "$CHALLENGES_DIR" ] || error "$CHALLENGES_DIR not found" 13
[ -w "$CHALLENGES_DIR" ] || error "$CHALLENGES_DIR not writeable" 14
[ -f "$ACCOUNT_KEY" ] || error "$ACOUNT_KEY not found" 15
[ "$APPEND_PARENT_CERT" -eq 1 -a ! -f "$PARENT_CERT" ] && error "$PARENT_CERT not found" 16
DOMAIN="$1"
KEY_FILE="${WORKING_DIR}/${DOMAIN}.key"
CSR_FILE="${WORKING_DIR}/${DOMAIN}.csr"
CRT_FILE="${WORKING_DIR}/${DOMAIN}.crt"
# Do we have a private key for the domain already?
if [ ! -f "$KEY_FILE" ] ; then
echo "Generating key for $DOMAIN"
openssl genrsa 4096 > "$KEY_FILE" || error "Creating key for domain" 21
chmod 600 "$KEY_FILE"
fi
## Create CSR file
if [ $# -gt 1 ] ; then
ALT_SUBJECT="[SAN]\nsubjectAltName=DNS:$1"
while [ $# -gt 1 ] ; do
ALT_SUBJECT="${ALT_SUBJECT},DNS:$2"
shift
done
openssl req -new -sha256 -key $KEY_FILE -subj "/" -reqexts SAN \
-config <(cat /etc/ssl/openssl.cnf <(printf "$ALT_SUBJECT")) > "$CSR_FILE" || error "Creating CSR file" 22
else
echo "Generating CSR for $DOMAIN"
openssl req -new -sha256 -key $KEY_FILE -subj "/CN=$DOMAIN" > "$CSR_FILE" || error "Creating CSR file" 23
fi
chmod 644 "$CSR_FILE"
# Save existing certificate, just in case something goes wrong
[ -f "$CRT_FILE" ] && mv "$CRT_FILE" "$CRT_FILE.back"
## Call acme-tiny
python "$ACME_TINY" --account-key "$ACCOUNT_KEY" --csr "$CSR_FILE" \
--acme-dir "$CHALLENGES_DIR" > "$CRT_FILE" ||
{ [ -f "$CRT_FILE.back" ] && mv "$CRT_FILE.back" "$CRT_FILE" ; error "Executing acme_tiny" 23 ; }
if [ "$APPEND_PARENT_CERT" -eq 1 ] ; then
CRT_CHAIN_FILE="${WORKING_DIR}/${DOMAIN}_chained.crt"
cat "$CRT_FILE" "$PARENT_CERT" > "$CRT_CHAIN_FILE"
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment