Browse Source

Support views. Also, avoid hangs interrogating remote.

rdbath suggested how to implement a timeout on s_client probes.
Unfortunately, wait -n is a bash 4.3 feature.  So this requires
bash 4.3.  CHECK_CERT_TIMEOUT can be used to override the default, which
is 4 seconds.  Fallback is provided for older versions.

Views may require the 'nslookup' process to do somthing special, usually
provide a TSIG key or bind to a specific local address.  Add a
hook for that - export the VARIABLE DNS_CHECK_FUNC_OPTIONS with the
desired options._Set DNS_CHECK_FUNC to the desired command, which
must be one of the supported ones: 'dig', 'drill', 'host' or 'nslookup'.


However, this turned up the fact that the dig/drill code had the domain
and record type arguments in the wrong order on the command line.
(The domain comes first, see the man page.)  Fixed.

In some cases defining the previously undocumented PUBLIC_DNS_SERVER
may work.  This commit adds it to the template file, and exports it
for the benefit of DNS_UPDATE scripts.  Also AUTH_DNS_SERVER.

Squashed awk complaints about curl.header in some cases with debugging on.

Support older curl (--trace-time is somewhat recent)
pull/289/head
Timothe Litt 9 years ago
parent
commit
e5702045b0
2 changed files with 82 additions and 24 deletions
  1. +2
    -1
      dns_scripts/dns_godaddy
  2. +80
    -23
      getssl

+ 2
- 1
dns_scripts/dns_godaddy View File

@ -193,8 +193,9 @@ if [ -n "$TRACE" ]; then
}
timestamp 'Info' "$PROG" "V$VERSION" 'Starting new protocol trace'
timestamp 'Args' "$@"
curl --help | grep -q -- --trace-time && CURL_TFLAGS="--trace-time" # 7.14.0
function curl {
command curl --trace-time --trace-ascii % "$@" 2>>"$TRACE"
command curl ${CURL_TFLAGS} --trace-ascii % "$@" 2>>"$TRACE"
}
[ -n "$VERB" ] && echo "Appending protocol trace to $TRACE"
fi


+ 80
- 23
getssl View File

@ -192,16 +192,20 @@ VERSION="2.10"
# defaults
ACCOUNT_KEY_LENGTH=4096
ACCOUNT_KEY_TYPE="rsa"
export AUTH_DNS_SERVER=""
CA="https://acme-staging.api.letsencrypt.org"
CA_CERT_LOCATION=""
CHALLENGE_CHECK_TYPE="http"
CHECK_ALL_AUTH_DNS="false"
CHECK_CERT_TIMEOUT="4"
CHECK_REMOTE="true"
CHECK_REMOTE_WAIT=0
CODE_LOCATION="https://raw.githubusercontent.com/srvrco/getssl/master/getssl"
CSR_SUBJECT="/"
DEACTIVATE_AUTH="false"
DEFAULT_REVOKE_CA="https://acme-v01.api.letsencrypt.org"
DNS_CHECK_FUNC=""
DNS_CHECK_OPTIONS=""
DNS_EXTRA_WAIT=""
DNS_WAIT=10
DOMAIN_KEY_LENGTH=4096
@ -212,7 +216,7 @@ IGNORE_DIRECTORY_DOMAIN="false"
ORIG_UMASK=$(umask)
PREVIOUSLY_VALIDATED="true"
PRIVATE_KEY_ALG="rsa"
PUBLIC_DNS_SERVER=""
export PUBLIC_DNS_SERVER=""
RELOAD_CMD=""
RENEW_ALLOW="30"
REUSE_PRIVATE_KEY="true"
@ -389,14 +393,14 @@ check_config() { # check the config files for all obvious errors
config_errors=true
fi
# check domain exist
if [[ "$DNS_CHECK_FUNC" == "drill" ]] || [[ "$DNS_CHECK_FUNC" == "dig" ]]; then
if [[ "$DNS_CHECK_FUNC" =~ ^drill ]] || [[ "$DNS_CHECK_FUNC" =~ ^dig ]]; then
if [[ "$($DNS_CHECK_FUNC "${d}" SOA|grep -c "^${d}")" -ge 1 ]]; then
debug "found IP for ${d}"
else
info "${DOMAIN}: DNS lookup failed for ${d}"
config_errors=true
fi
elif [[ "$DNS_CHECK_FUNC" == "host" ]]; then
elif [[ "$DNS_CHECK_FUNC" =~ ^host ]]; then
if [[ "$($DNS_CHECK_FUNC "${d}" |grep -c "^${d}")" -ge 1 ]]; then
debug "found IP for ${d}"
else
@ -716,20 +720,19 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n
primary_ns="$all_auth_dns_servers"
return
fi
if [[ "$DNS_CHECK_FUNC" == "drill" ]] || [[ "$DNS_CHECK_FUNC" == "dig" ]]; then
if [[ "$DNS_CHECK_FUNC" =~ ^drill ]] || [[ "$DNS_CHECK_FUNC" =~ ^dig ]]; then
if [[ -z "$gad_s" ]]; then #checking for CNAMEs
res=$($DNS_CHECK_FUNC CNAME "$gad_d"| grep "^$gad_d")
res=$($DNS_CHECK_FUNC "$gad_d" CNAME| grep "^$gad_d")
else
res=$($DNS_CHECK_FUNC CNAME "$gad_d" "@$gad_s"| grep "^$gad_d")
res=$($DNS_CHECK_FUNC "$gad_d" CNAME "@$gad_s"| grep "^$gad_d")
fi
if [[ ! -z "$res" ]]; then # domain is a CNAME so get main domain
gad_d=$(echo "$res"| awk '{print $5}' |sed 's/\.$//g')
fi
if [[ -z "$gad_s" ]]; then #checking for CNAMEs
res=$($DNS_CHECK_FUNC NS "$gad_d"| grep "^$gad_d")
res=$($DNS_CHECK_FUNC "$gad_d" NS| grep "^$gad_d")
else
res=$($DNS_CHECK_FUNC NS "$gad_d" "@$gad_s"| grep "^$gad_d")
res=$($DNS_CHECK_FUNC "$gad_d" NS "@$gad_s"| grep "^$gad_d")
fi
if [[ -z "$res" ]]; then
error_exit "couldn't find primary DNS server - please set AUTH_DNS_SERVER in config"
@ -744,7 +747,7 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n
return
fi
if [[ "$DNS_CHECK_FUNC" == "host" ]]; then
if [[ "$DNS_CHECK_FUNC" =~ ^host ]]; then
if [[ -z "$gad_s" ]]; then
res=$($DNS_CHECK_FUNC -t NS "$gad_d"| grep "name server")
else
@ -1178,6 +1181,7 @@ send_signed_request() { # Sends a request to the ACME server, signed with your p
response=$($CURL -X POST --data "$body" "$url")
fi
touch "$CURL_HEADER"
responseHeaders=$(cat "$CURL_HEADER")
debug responseHeaders "$responseHeaders"
debug response "$response"
@ -1325,6 +1329,21 @@ write_domain_template() { # write out a template file for a domain.
# an update to confirm correct certificate is running (if CHECK_REMOTE) is set to true
#SERVER_TYPE="https"
#CHECK_REMOTE="true"
# Unusual configurations (especially split views) may require these.
# If these (or any variable) apply to all your domains, put them in
# the per-domain getssl.cfg.
#
# If you must use an external DNS Server (e.g. due to split views)
# Specify it here. Otherwise, the default is to find the zone master.
# The default will usually work.
# PUBLIC_DNS_SERVER="8.8.8.8"
# If getssl is unable to determine the authoritative nameserver for a domain
# it will as you to enter AUTH_DNS_SERVER. This is the primary server that
# getssl will use to check for the acme tokens. It must be visible externally
# as well as internally. It need not be "authoritiative" in the RFC1035 sense.
# AUTH_DNS_SERVER="8.8.8.8"
_EOF_domain_
}
@ -1364,6 +1383,19 @@ write_getssl_template() { # write out the main template file
#VALIDATE_VIA_DNS="true"
#DNS_ADD_COMMAND=
#DNS_DEL_COMMAND=
# Unusual configurations (especially split views) may require these.
# If you have a mixture, these can go in the per-domain getssl.cfg.
#
# If you must use an external DNS Server (e.g. due to split views)
# Specify it here. Otherwise, the default is to find the zone master.
# The default will usually work.
# PUBLIC_DNS_SERVER="8.8.8.8"
# If getssl is unable to determine the authoritative nameserver for a domain
# it will as you to enter AUTH_DNS_SERVER. This is a server that
# can answer queries for the zone - a master or a slave, not a recursive server.
# AUTH_DNS_SERVER="10.0.0.14"
_EOF_getssl_
}
@ -1446,7 +1478,6 @@ get_os
requires which
requires openssl
requires curl
requires nslookup drill dig host DNS_CHECK_FUNC
requires awk
requires tr
requires date
@ -1497,6 +1528,12 @@ if [[ -s "$WORKING_DIR/getssl.cfg" ]]; then
. "$WORKING_DIR/getssl.cfg"
fi
if [[ -n "$DNS_CHECK_FUNC" ]]; then
requires "${DNS_CHECK_FUNC}"
else
requires nslookup drill dig host DNS_CHECK_FUNC
fi
# Define defaults for variables not set in the main config.
ACCOUNT_KEY="${ACCOUNT_KEY:=$WORKING_DIR/account.key}"
DOMAIN_STORAGE="${DOMAIN_STORAGE:=$WORKING_DIR}"
@ -1569,11 +1606,17 @@ if [[ ${_CREATE_CONFIG} -eq 1 ]]; then
if [[ -s "$DOMAIN_DIR/getssl.cfg" ]]; then
info "domain config already exists $DOMAIN_DIR/getssl.cfg"
else
info "creating domain config file in $DOMAIN_DIR/getssl.cfg"
# if domain has an existing cert, copy from domain and use to create defaults.
EX_CERT=$(echo \
| openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:443" 2>/dev/null \
| openssl x509 2>/dev/null)
info "Contacting ${DOMAIN} to inspect current certificate"
EX_CERT=$( {
if [[ "${BASH_VERSINFO[0]}${BASH_VERSINFO[1]}" -ge 43 ]]; then
openssl s_client -servername "$DOMAIN" -connect "$DOMAIN":443 </dev/null 2>/dev/null & PID=$!
sleep ${CHECK_CERT_TIMEOUT} & PIDW=$!
wait -n # Requires bash 4.3+
kill -9 "$PID" "$PIDW" 2>/dev/null
else
openssl s_client -servername "$DOMAIN" -connect "$DOMAIN":443 </dev/null 2>/dev/null
fi
} | openssl x509 2>/dev/null)
EX_SANS="www.${DOMAIN}"
if [[ ! -z "${EX_CERT}" ]]; then
EX_SANS=$(echo "$EX_CERT" \
@ -1582,6 +1625,7 @@ if [[ ${_CREATE_CONFIG} -eq 1 ]]; then
EX_SANS=${EX_SANS//$'\n'/','}
fi
write_domain_template "$DOMAIN_DIR/getssl.cfg"
info "created domain config file in $DOMAIN_DIR/getssl.cfg"
fi
TEMP_DIR="$DOMAIN_DIR/tmp"
# end of "-c|--create" option, so exit
@ -1609,6 +1653,11 @@ if [[ -s "$DOMAIN_DIR/getssl.cfg" ]]; then
. "$DOMAIN_DIR/getssl.cfg"
fi
# In case special options are needed for DNS_CHECK_FUNC, add them
# to the command. E.G. if a TSIG key or bound local IP is required...
DNS_CHECK_FUNC="${DNS_CHECK_FUNC} ${DNS_CHECK_OPTIONS}"
# from SERVER_TYPE set REMOTE_PORT and REMOTE_EXTRA
set_server_type
@ -1629,11 +1678,19 @@ URL_new_cert=$(echo "$ca_all_loc" | grep "new-cert" | awk -F'"' '{print $4}')
# if check_remote is true then connect and obtain the current certificate (if not forcing renewal)
if [[ "${CHECK_REMOTE}" == "true" ]] && [[ $_FORCE_RENEW -eq 0 ]]; then
debug "getting certificate for $DOMAIN from remote server"
info "Contacting $DOMAIN on port ${REMOTE_PORT} to inspect current certificate"
# shellcheck disable=SC2086
EX_CERT=$(echo \
| openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:${REMOTE_PORT}" ${REMOTE_EXTRA} 2>/dev/null \
| openssl x509 2>/dev/null)
EX_CERT=$( {
if [[ "${BASH_VERSINFO[0]}${BASH_VERSINFO[1]}" -ge 43 ]]; then
echo | openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:${REMOTE_PORT}" ${REMOTE_EXTRA} 2>/dev/null & PID=$!
sleep ${CHECK_CERT_TIMEOUT} & PIDW=$!
wait -n # Requires bash 4.3+
kill -9 "$PID" "$PIDW" 2>/dev/null
else
echo | openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:${REMOTE_PORT}" ${REMOTE_EXTRA} 2>/dev/null
fi
} | openssl x509 2>/dev/null )
if [[ ! -z "$EX_CERT" ]]; then # if obtained a cert
if [[ -s "$CERT_FILE" ]]; then # if local exists
CERT_LOCAL=$(openssl x509 -noout -fingerprint < "$CERT_FILE" 2>/dev/null)
@ -1980,10 +2037,10 @@ if [[ $VALIDATE_VIA_DNS == "true" ]]; then
check_result=$(nslookup -type=txt "_acme-challenge.${d}" "${ns}" \
| grep ^_acme -A2\
| grep '"'|awk -F'"' '{ print $2}')
elif [[ "$DNS_CHECK_FUNC" == "drill" ]] || [[ "$DNS_CHECK_FUNC" == "dig" ]]; then
check_result=$($DNS_CHECK_FUNC TXT "_acme-challenge.${d}" "@${ns}" \
elif [[ "$DNS_CHECK_FUNC" =~ ^drill ]] || [[ "$DNS_CHECK_FUNC" =~ ^dig ]]; then
check_result=$($DNS_CHECK_FUNC "_acme-challenge.${d}" TXT "@${ns}" \
| grep ^_acme|awk -F'"' '{ print $2}')
elif [[ "$DNS_CHECK_FUNC" == "host" ]]; then
elif [[ "$DNS_CHECK_FUNC" =~ ^host ]]; then
check_result=$($DNS_CHECK_FUNC -t TXT "_acme-challenge.${d}" "${ns}" \
| grep ^_acme|awk -F'"' '{ print $2}')
else


Loading…
Cancel
Save