Browse Source

includes existing cert on -c option

pull/1/head
srvrco 10 years ago
parent
commit
b15c2e898e
2 changed files with 52 additions and 42 deletions
  1. +1
    -1
      README.md
  2. +51
    -41
      getssl

+ 1
- 1
README.md View File

@ -3,7 +3,7 @@ get an SSL certificate via LetsEncryot. Suitable for automating the process in
This was written as an addition to checkssl for servers to automatically renew certifictes. In addition it allows the running of this script in standard bash ( on a desktop computer, or even virtualbox) and add the checks, and certificates to a remote server ( providing you have an ssh key on the remote server with access). Potentially I can include FTP as an option for uploading as well.
getssl ver. 0.1
getssl ver. 0.2
To obtain a letsencrypt SSL cert
Usage: getssl [-h|--help] [-d|--debug] [-c] [-w working_dir] domain


+ 51
- 41
getssl View File

@ -18,10 +18,11 @@
# Revision history:
# 2016-01-08 Created (v0.1)
# 2016-01-11 type correction and upload to github (v0.2)
# 2016-01-11 added import of any existing cert on -c option (v0.3)
# ---------------------------------------------------------------------------
PROGNAME=${0##*/}
VERSION="0.2"
VERSION="0.3"
# defaults
#umask 077 # paranoid umask, as we're creating private keys
@ -119,10 +120,10 @@ send_signed_request() {
sig=$(echo -n "$protected64.$payload64" | openssl dgst -sha256 -sign $ACCOUNT_KEY | base64 -w 0 | _b64)
debug sig "$sig"
body="{\"header\": $HEADER, \"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}"
debug body "$body"
if [ "$needbase64" ] ; then
response="$($CURL -X POST --data "$body" $url | base64 -w 0)"
else
@ -130,7 +131,7 @@ send_signed_request() {
fi
responseHeaders="$(sed 's/\r//g' $CURL_HEADER)"
debug responseHeaders "$responseHeaders"
debug response "$response"
code="$(grep ^HTTP $CURL_HEADER | tail -1 | cut -d " " -f 2)"
@ -154,7 +155,7 @@ copy_file_to_location() {
cp $from $to
fi
debug "copied $from to $to"
fi
fi
}
getcr() {
@ -169,7 +170,7 @@ getcr() {
}
_requires() {
result=$(which $1)
result=$(which $1 2>/dev/null)
debug checking for required $1 ... $result
if [ -z "$result" ]; then
echo "This script requires $1 installed"
@ -257,16 +258,16 @@ CA=\"https://acme-staging.api.letsencrypt.org\"
AGREEMENT=\"https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf\"
#set an email address associated with your account
#set an email address associated with your account
#ACCOUNT_EMAIL=\"me@example.com\"
ACCOUNT_KEY_LENGTH=4096
#The default directory for all your certs to be stored within ( in subdirectories by domain name )
#The default directory for all your certs to be stored within ( in subdirectories by domain name )
WORKING_DIR=~/.getssl
# the command needed to reload apache / gninx or whatever you use
#RELOAD_CMD=\"\"
#The time period within which you want to allow renewal of a certificate - this prevents hitting some of the rate limits.
#The time period within which you want to allow renewal of a certificate - this prevents hitting some of the rate limits.
RENEW_ALLOW=\"30\"
" >> $WORKING_DIR/getssl.cfg
fi
@ -278,6 +279,15 @@ RENEW_ALLOW=\"30\"
info "domain config already exists $DOMAIN_DIR/getssl.cfg"
else
info "creating domain config file in $DOMAIN_DIR/getssl.cfg"
EX_CERT=$(echo | openssl s_client -servername ${DOMAIN} -connect ${DOMAIN}:443 2>/dev/null | openssl x509 2>/dev/null)
EX_SANS="www.${DOMAIN}"
if [ ! -z "${EX_CERT}" ]; then
if [ ! -f $DOMAIN_DIR/domain.crt ]; then
echo $EX_CERT > $DOMAIN_DIR/domain.crt
fi
EX_SANS=$(echo "$EX_CERT" | openssl x509 -noout -text 2>/dev/null| grep "Subject Alternative Name" -A2 \
| grep -Eo "DNS:[a-zA-Z 0-9.]*" |sed "s@DNS:$DOMAIN@@g"| cut -c 5-)
fi
echo "# uncomment and modify any variables you need
# The staging server is best for testing
#CA=\"https://acme-staging.api.letsencrypt.org\"
@ -286,12 +296,12 @@ RENEW_ALLOW=\"30\"
#AGREEMENT=\"https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf\"
#set an email address associated with your account - generally set at account level rather than domain.
#set an email address associated with your account - generally set at account level rather than domain.
#ACCOUNT_EMAIL=\"me@example.com\"
#ACCOUNT_KEY_LENGTH=4096
# additional domains - this could be multiple domains / subdomains in a comma separated list
SANS=www.${DOMAIN}
SANS=${EX_SANS}
#Acme Challenge Location. The first line for the domain, the following ones for each additional domain
#if these start with ssh: then the next variable is assumed to be the hostname and the rest the location.
@ -305,10 +315,10 @@ SANS=www.${DOMAIN}
#CA_CERT_LOCATION=\"/etc/ssl/chain.crt\"
# the command needed to reload apache / gninx or whatever you use
#RELOAD_CMD=\"\"
#The time period within which you want to allow renewal of a certificate - this prevents hitting some of the rate limits.
#The time period within which you want to allow renewal of a certificate - this prevents hitting some of the rate limits.
#RENEW_ALLOW=\"30\"
" >> $DOMAIN_DIR/getssl.cfg
fi
graceful_exit
fi
@ -391,34 +401,34 @@ else
<(cat $SSLCONF <(printf "$SANLIST")) > $DOMAIN_DIR/${DOMAIN}.csr
fi
# use account key to register with CA
# use account key to register with CA
pub_exp=$(openssl rsa -in $ACCOUNT_KEY -noout -text | grep "^publicExponent:"| cut -d '(' -f 2 | cut -d 'x' -f 2 | cut -d ')' -f 1)
if [ "${#pub_exp}" == "5" ] ; then
pub_exp=0$pub_exp
fi
debug pub_exp "$pub_exp"
e=$(echo $pub_exp | xxd -r -p | base64)
debug e "$e"
modulus=$(openssl rsa -in $ACCOUNT_KEY -modulus -noout | cut -d '=' -f 2 )
n=$(echo $modulus| xxd -r -p | base64 -w 0 | _b64 )
jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}'
HEADER='{"alg": "RS256", "jwk": '$jwk'}'
HEADERPLACE='{"nonce": "NONCE", "alg": "RS256", "jwk": '$jwk'}'
debug HEADER "$HEADER"
accountkey_json=$(echo -n "$jwk" | sed "s/ //g")
thumbprint=$(echo -n "$accountkey_json" | sha256sum | xxd -r -p | base64 -w 0 | _b64)
info "Registering account"
regjson='{"resource": "new-reg", "agreement": "'$AGREEMENT'"}'
if [ "$ACCOUNT_EMAIL" ] ; then
regjson='{"resource": "new-reg", "contact": ["mailto: '$ACCOUNT_EMAIL'"], "agreement": "'$AGREEMENT'"}'
fi
fi
send_signed_request "$CA/acme/new-reg" "$regjson"
if [ "$code" == "" ] || [ "$code" == '201' ] ; then
@ -436,7 +446,7 @@ info "Verify each domain"
alldomains=$(echo "$DOMAIN,$SANS" | sed "s/,/ /g")
dn=0
for d in $alldomains; do
for d in $alldomains; do
info "Verifing $d"
debug "domain $d has location ${ACL[$dn]}"
if [ -z "${ACL[$dn]}" ]; then
@ -452,16 +462,16 @@ for d in $alldomains; do
http01=$(echo $response | egrep -o '{[^{]*"type":"http-01"[^}]*')
debug http01 "$http01"
token=$(echo "$http01" | sed 's/,/\n'/g| grep '"token":'| cut -d : -f 2|sed 's/"//g')
debug token $token
uri=$(echo "$http01" | sed 's/,/\n'/g| grep '"uri":'| cut -d : -f 2,3|sed 's/"//g')
debug uri $uri
keyauthorization="$token.$thumbprint"
debug keyauthorization "$keyauthorization"
echo -n "$keyauthorization" > $DOMAIN_DIR/tmp/$token
chmod 755 $DOMAIN_DIR/tmp/$token
@ -470,14 +480,14 @@ for d in $alldomains; do
wellknown_url="http://$d/.well-known/acme-challenge/$token"
debug wellknown_url "$wellknown_url"
if [ ! "$(curl --silent $wellknown_url)" == "$keyauthorization" ]; then
error_exit "for some reason could not reach $wellknown_url - please check it manually"
fi
debug challenge "$challenge"
send_signed_request $uri "{\"resource\": \"challenge\", \"keyAuthorization\": \"$keyauthorization\"}"
if [ ! -z "$code" ] && [ ! "$code" == '202' ] ; then
error_exit "$d:Challenge error: $resource"
fi
@ -487,27 +497,27 @@ for d in $alldomains; do
if ! getcr $uri ; then
error_exit "$d:Verify error:$resource"
fi
status=$(echo $response | egrep -o '"status":"[^"]+"' | cut -d : -f 2 | sed 's/"//g')
if [ "$status" == "valid" ] ; then
info "Verified $d"
break;
fi
if [ "$status" == "invalid" ] ; then
error=$(echo $response | egrep -o '"error":{[^}]*}' | grep -o '"detail":"[^"]*"' | cut -d '"' -f 4)
error_exit "$d:Verify error:$error"
fi
if [ "$status" == "pending" ] ; then
info "Pending"
else
error_exit "$d:Verify error:$response"
fi
error_exit "$d:Verify error:$response"
fi
debug "sleep 5 secs berfore testiing verify again"
sleep 5
done
debug "remove token from ${ACL[$dn]}"
if [[ "${ACL[$dn]:0:4}" == "ssh:" ]] ; then
sshhost=$(echo "${ACL[$dn]}"| awk -F: '{print $2}')
@ -519,29 +529,29 @@ for d in $alldomains; do
else
rm -f ${ACL[$dn]}
fi
done
done
info "Verification completed, obtaining certificate."
der="$(openssl req -in $DOMAIN_DIR/${DOMAIN}.csr -outform DER | base64 -w 0 | _b64)"
send_signed_request "$CA/acme/new-cert" "{\"resource\": \"new-cert\", \"csr\": \"$der\"}" "needbase64"
CertData="$(grep -i -o '^Location.*' $CURL_HEADER |sed 's/\r//g'| cut -d " " -f 2)"
if [ "$CertData" ] ; then
echo -----BEGIN CERTIFICATE----- > "$CERT_FILE"
curl --silent "$CertData" | base64 >> "$CERT_FILE"
echo -----END CERTIFICATE----- >> "$CERT_FILE"
info "Certificate saved in $CERT_FILE"
fi
if [ -z "$CertData" ] ; then
response="$(echo $response | base64 -d)"
error_exit "Sign failed: $(echo "$response" | grep -o '"detail":"[^"]*"')"
fi
IssuerData=$(grep -i '^Link' $CURL_HEADER | cut -d " " -f 2| cut -d ';' -f 1 | sed 's/<//g' | sed 's/>//g')
if [ "$IssuerData" ] ; then
echo -----BEGIN CERTIFICATE----- > "$CA_CERT"
curl --silent "$IssuerData" | base64 >> "$CA_CERT"
@ -560,7 +570,7 @@ copy_file_to_location $DOMAIN_DIR/${DOMAIN}.key $DOMAIN_KEY_LOCATION
info "copying CA certificate to $CA_CERT_LOCATION"
copy_file_to_location $CA_CERT $CA_CERT_LOCATION
# Run reload command to restart apache / gninx or whatever system
# Run reload command to restart apache / gninx or whatever system
if [ ! -z "$RELOAD_CMD" ]; then
info "reloading SSL services"


Loading…
Cancel
Save