Last active
February 16, 2017 14:15
-
-
Save inittab/1e52e4500f139221e8ce2a20509b0a79 to your computer and use it in GitHub Desktop.
acme_tiny shell wrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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