Skip to content

Commit abc8643

Browse files
authored
v2.2.7 (#44)
Major updates * Using latest base image * Updating getssl to 2.41 Platform updates * Adding FUNDING.yml
1 parent 04800a1 commit abc8643

File tree

4 files changed

+92
-28
lines changed

4 files changed

+92
-28
lines changed

.github/FUNDING.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# These are supported funding model platforms
2+
3+
github: bfren
4+
patreon: bfren

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM bfren/nginx:alpine3.14-2.2.5
1+
FROM bfren/nginx:alpine3.14-2.2.6
22

33
# port 80 is already exposed by the base image
44
EXPOSE 443

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.2.6
1+
2.2.7

overlay/usr/lib/bf/proxy/getssl

Lines changed: 86 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,10 @@
264264
# 2021-07-12 Do not redirect outputs on remote commands when the debug option is used (atisne)
265265
# 2021-07-20 Use +noidnout to enable certificates for IDN domains (#679)(2.37)
266266
# 2021-07-22 Only pass +noidnout param to dig/drill(#682)(2.38)
267+
# 2021-07-25 Fix copy_file_to_location failures with ssh when suffix applied to file lacking an extension (tlhackque)(#686)
268+
# 2021-07-27 Support ftps://, FTPS_OPTIONS, remove default --insecure parameter to ftpes. Report caller(s) of error_exit in debug and test modes (tlhackque)(#687)(2.39)
269+
# 2021-07-30 Prefer API V2 when both offered (tlhackque) (#690) (2.40)
270+
# 2021-07-30 Run tests with -d to catch intermittent failures, Use fork's repo for upgrade tests. (tlhackque) (#692) (2.41)
267271
# ----------------------------------------------------------------------------------------
268272

269273
case :$SHELLOPTS: in
@@ -272,7 +276,7 @@ esac
272276

273277
PROGNAME=${0##*/}
274278
PROGDIR="$(cd "$(dirname "$0")" || exit; pwd -P;)"
275-
VERSION="2.38"
279+
VERSION="2.41"
276280

277281
# defaults
278282
ACCOUNT_KEY_LENGTH=4096
@@ -282,14 +286,19 @@ CA="https://acme-staging-v02.api.letsencrypt.org/directory"
282286
CHALLENGE_CHECK_TYPE="http"
283287
CHECK_REMOTE_WAIT=0
284288
CHECK_REMOTE="true"
285-
CODE_LOCATION="https://raw.githubusercontent.com/srvrco/getssl/master/getssl"
289+
if [[ -n "${GITHUB_REPOSITORY}" ]] ; then
290+
CODE_LOCATION="https://raw.githubusercontent.com/${GITHUB_REPOSITORY}/master/getssl"
291+
else
292+
CODE_LOCATION="https://raw.githubusercontent.com/srvrco/getssl/master/getssl"
293+
fi
286294
CSR_SUBJECT="/"
287295
CURL_USERAGENT="${PROGNAME}/${VERSION}"
288296
DEACTIVATE_AUTH="false"
289297
DEFAULT_REVOKE_CA="https://acme-v02.api.letsencrypt.org"
290298
DOMAIN_KEY_LENGTH=4096
291299
DUAL_RSA_ECDSA="false"
292300
FTP_OPTIONS=""
301+
FTPS_OPTIONS=""
293302
FULL_CHAIN_INCLUDE_ROOT="false"
294303
GETSSL_IGNORE_CP_PRESERVE="false"
295304
HTTP_TOKEN_CHECK_WAIT=0
@@ -327,10 +336,12 @@ DNS_WAIT_RETRY_ADD="false" # Try the dns_add_command again if the DNS recor
327336
# Private variables
328337
_CHECK_ALL=0
329338
_CREATE_CONFIG=0
339+
_CURL_VERSION=""
330340
_FORCE_RENEW=0
331341
_KEEP_VERSIONS=""
332342
_MUTE=0
333343
_NOTIFY_VALID=0
344+
_NOMETER=""
334345
_QUIET=0
335346
_RECREATE_CSR=0
336347
_REDIRECT_OUTPUT="1>/dev/null 2>&1"
@@ -559,15 +570,15 @@ check_challenge_completion_dns() { # perform validation via DNS challenge
559570
check_result=$($DNS_CHECK_FUNC $DNS_CHECK_OPTIONS TXT "${rr}" "@${ns}" \
560571
| grep -i "^${rr}" \
561572
| grep 'IN\WTXT'|awk -F'"' '{ print $2}')
562-
debug "check_result=$check_result"
573+
debug "check_result=\"$check_result\""
563574
if [[ -z "$check_result" ]]; then
564575
# shellcheck disable=SC2086
565576
debug "$DNS_CHECK_FUNC" $DNS_CHECK_OPTIONS ANY "${rr}" "@${ns}"
566577
# shellcheck disable=SC2086
567578
check_result=$($DNS_CHECK_FUNC $DNS_CHECK_OPTIONS ANY "${rr}" "@${ns}" \
568579
| grep -i "^${rr}" \
569580
| grep 'IN\WTXT'|awk -F'"' '{ print $2}')
570-
debug "check_result=$check_result"
581+
debug "check_result=\"$check_result\""
571582
fi
572583
elif [[ "$DNS_CHECK_FUNC" == "host" ]]; then
573584
check_result=$($DNS_CHECK_FUNC -t TXT "${rr}" "${ns}" \
@@ -580,8 +591,8 @@ check_challenge_completion_dns() { # perform validation via DNS challenge
580591
| grep 'text ='|awk -F'"' '{ print $2}')
581592
fi
582593
fi
583-
debug "expecting $auth_key"
584-
debug "${ns} gave ... $check_result"
594+
debug "expecting \"$auth_key\""
595+
debug "${ns} gave ... \"$check_result\""
585596

586597
if [[ "$check_result" == *"$auth_key"* ]]; then
587598
check_dns="success"
@@ -603,7 +614,7 @@ check_challenge_completion_dns() { # perform validation via DNS challenge
603614
debug "dns check failed - removing existing value"
604615
del_dns_rr "${d}" "${auth_key}"
605616

606-
error_exit "checking ${rr} gave $check_result not $auth_key"
617+
error_exit "checking \"${rr}\" gave \"$check_result\" not \"$auth_key\""
607618
fi
608619
fi
609620
done
@@ -755,7 +766,7 @@ check_getssl_upgrade() { # check if a more recent version of code is available a
755766
if [ "$TEMP_UPGRADE_FILE" == "" ]; then
756767
error_exit "mktemp failed"
757768
fi
758-
curl --user-agent "$CURL_USERAGENT" --silent "$CODE_LOCATION" --output "$TEMP_UPGRADE_FILE"
769+
curl ${_NOMETER} --user-agent "$CURL_USERAGENT" --silent "$CODE_LOCATION" --output "$TEMP_UPGRADE_FILE"
759770
errcode=$?
760771
if [[ $errcode -eq 60 ]]; then
761772
error_exit "curl needs updating, your version does not support SNI (multiple SSL domains on a single IP)"
@@ -850,7 +861,12 @@ copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
850861
IFS=\; read -r -a copy_locations <<<"$3"
851862
for to in "${copy_locations[@]}"; do
852863
if [[ -n "$suffix" ]]; then
853-
to="${to%.*}.${suffix}.${to##*.}"
864+
bname="$(basename "$to")"
865+
if [[ "${bname##*.}" == "$bname" ]]; then
866+
to="${to}.${suffix}"
867+
else
868+
to="${to%.*}.${suffix}.${to##*.}"
869+
fi
854870
fi
855871
info "copying $cert to $to"
856872
if [[ "${to:0:4}" == "ssh:" ]] ; then
@@ -933,8 +949,8 @@ copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
933949
fromfile=$(basename "$from")
934950
debug "davs user=$davsuser - pass=$davspass - host=$davshost port=$davsport dir=$davsdirn file=$davsfile"
935951
debug "from dir=$fromdir file=$fromfile"
936-
curl -u "${davsuser}:${davspass}" -T "${fromdir}/${fromfile}" "https://${davshost}:${davsport}${davsdirn}${davsfile}"
937-
elif [[ "${to:0:6}" == "ftpes:" ]] ; then
952+
curl ${_NOMETER} -u "${davsuser}:${davspass}" -T "${fromdir}/${fromfile}" "https://${davshost}:${davsport}${davsdirn}${davsfile}"
953+
elif [[ "${to:0:6}" == "ftpes:" ]] || [[ "${to:0:5}" == "ftps:" ]] ; then
938954
debug "using ftp to copy the file from $from"
939955
ftpuser=$(echo "$to"| awk -F: '{print $2}')
940956
ftppass=$(echo "$to"| awk -F: '{print $3}')
@@ -946,7 +962,13 @@ copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
946962
fromfile=$(basename "$from")
947963
debug "ftp user=$ftpuser - pass=$ftppass - host=$ftphost dir=$ftpdirn file=$ftpfile"
948964
debug "from dir=$fromdir file=$fromfile"
949-
curl --insecure --ftp-ssl -u "${ftpuser}:${ftppass}" -T "${fromdir}/${fromfile}" "ftp://${ftphost}${ftpdirn}/"
965+
if [[ "${to:0:5}" == "ftps:" ]] ; then
966+
# shellcheck disable=SC2086
967+
curl ${_NOMETER} $FTPS_OPTIONS --ftp-ssl --ftp-ssl-reqd -u "${ftpuser}:${ftppass}" -T "${fromdir}/${fromfile}" "ftp://${ftphost}${ftpdirn}:990/"
968+
else
969+
# shellcheck disable=SC2086
970+
curl ${_NOMETER} $FTPS_OPTIONS --ftp-ssl --ftp-ssl-reqd -u "${ftpuser}:${ftppass}" -T "${fromdir}/${fromfile}" "ftp://${ftphost}${ftpdirn}/"
971+
fi
950972
else
951973
if ! mkdir -p "$(dirname "$to")" ; then
952974
error_exit "cannot create ACL directory $(basename "$to")"
@@ -1146,6 +1168,9 @@ test_output() { # write out debug output for testing
11461168

11471169
error_exit() { # give error message on error exit
11481170
echo -e "${PROGNAME}: ${1:-"Unknown Error"}" >&2
1171+
if [[ ${_RUNNING_TEST} -eq 1 ]] || [[ ${_USE_DEBUG} -eq 1 ]] ; then
1172+
traceback
1173+
fi
11491174
clean_up
11501175
exit 1
11511176
}
@@ -1357,7 +1382,10 @@ for d in "${alldomains[@]}"; do
13571382
else
13581383
sleep "$HTTP_TOKEN_CHECK_WAIT"
13591384
# check that we can reach the challenge ourselves, if not, then error
1360-
if [[ ! "$(curl --user-agent "$CURL_USERAGENT" -k --silent --location "$wellknown_url")" == "$keyauthorization" ]]; then
1385+
# ACME only allows port 80 (http), but redirects may use https. --insecure is used in case
1386+
# those certificates are being renewed. Let's Encrypt does the same. In this case, we verify
1387+
# that the correct data is returned, so this is safe.
1388+
if [[ ! "$(curl ${_NOMETER} --user-agent "$CURL_USERAGENT" --insecure --silent --location "$wellknown_url")" == "$keyauthorization" ]]; then
13611389
error_exit "for some reason could not reach $wellknown_url - please check it manually"
13621390
fi
13631391
fi
@@ -1601,7 +1629,7 @@ get_certificate() { # get certificate for csr, if all domains validated.
16011629
CertData=$(awk ' $1 ~ "^Location" {print $2}' "$CURL_HEADER" |tr -d '\r')
16021630
if [[ "$CertData" ]] ; then
16031631
echo -----BEGIN CERTIFICATE----- > "$gc_certfile"
1604-
curl --user-agent "$CURL_USERAGENT" --silent "$CertData" | openssl base64 -e >> "$gc_certfile"
1632+
curl ${_NOMETER} --user-agent "$CURL_USERAGENT" --silent "$CertData" | openssl base64 -e >> "$gc_certfile"
16051633
echo -----END CERTIFICATE----- >> "$gc_certfile"
16061634
info "Certificate saved in $CERT_FILE"
16071635
fi
@@ -1621,7 +1649,7 @@ get_certificate() { # get certificate for csr, if all domains validated.
16211649
| sed 's/>//g')
16221650
if [[ "$IssuerData" ]] ; then
16231651
echo -----BEGIN CERTIFICATE----- > "$gc_cafile"
1624-
curl --user-agent "$CURL_USERAGENT" --silent "$IssuerData" | openssl base64 -e >> "$gc_cafile"
1652+
curl ${_NOMETER} --user-agent "$CURL_USERAGENT" --silent "$IssuerData" | openssl base64 -e >> "$gc_cafile"
16251653
echo -----END CERTIFICATE----- >> "$gc_cafile"
16261654
info "The intermediate CA cert is in $gc_cafile"
16271655
fi
@@ -1679,7 +1707,7 @@ get_certificate() { # get certificate for csr, if all domains validated.
16791707
cp "$gc_certfile" "$gc_fullchain"
16801708
while [[ -n "$issuer_url" ]]; do
16811709
debug Fetching certificate issuer from "$issuer_url"
1682-
issuer_cert=$(curl --user-agent "$CURL_USERAGENT" --silent "$issuer_url" | openssl x509 -inform der -outform pem)
1710+
issuer_cert=$(curl ${_NOMETER} --user-agent "$CURL_USERAGENT" --silent "$issuer_url" | openssl x509 -inform der -outform pem)
16831711
debug Fetched issuer certificate "$(echo "$issuer_cert" | openssl x509 -inform pem -noout -text | awk 'BEGIN {FS="Subject: "} NF==2 {print $2; exit}')"
16841712
echo "$issuer_cert" >> "$gc_fullchain"
16851713

@@ -1694,7 +1722,7 @@ get_certificate() { # get certificate for csr, if all domains validated.
16941722
get_cr() { # get curl response
16951723
url="$1"
16961724
debug url "$url"
1697-
response=$(curl --user-agent "$CURL_USERAGENT" --silent "$url")
1725+
response=$(curl ${_NOMETER} --user-agent "$CURL_USERAGENT" --silent "$url")
16981726
ret=$?
16991727
debug response "${response//[$'\t\r\n']}"
17001728
code=$(json_get "$response" status)
@@ -1777,7 +1805,7 @@ get_signing_params() { # get signing parameters from key
17771805
}
17781806

17791807
graceful_exit() { # normal exit function.
1780-
exit_code=$1
1808+
exit_code="${1-0}"
17811809
clean_up
17821810
# shellcheck disable=SC2086
17831811
exit $exit_code
@@ -2035,7 +2063,7 @@ obtain_ca_resource_locations()
20352063
for suffix in "" "/directory" "/dir";
20362064
do
20372065
# Obtain CA resource locations
2038-
ca_all_loc=$(curl --user-agent "$CURL_USERAGENT" "${CA}${suffix}" 2>/dev/null)
2066+
ca_all_loc=$(curl ${_NOMETER} --user-agent "$CURL_USERAGENT" "${CA}${suffix}" 2>/dev/null)
20392067
debug "ca_all_loc from ${CA}${suffix} gives $ca_all_loc"
20402068
# APIv1
20412069
URL_new_reg=$(echo "$ca_all_loc" | grep "new-reg" | awk -F'"' '{print $4}')
@@ -2052,10 +2080,11 @@ obtain_ca_resource_locations()
20522080
fi
20532081
done
20542082

2055-
if [[ -n "$URL_new_reg" ]]; then
2056-
API=1
2057-
elif [[ -n "$URL_newAccount" ]]; then
2083+
# If a directory offers both versions, select V2.
2084+
if [[ -n "$URL_newAccount" ]]; then
20582085
API=2
2086+
elif [[ -n "$URL_new_reg" ]]; then
2087+
API=1
20592088
else
20602089
error_exit "unknown API version"
20612090
fi
@@ -2216,9 +2245,9 @@ send_signed_request() { # Sends a request to the ACME server, signed with your p
22162245
CURL_HEADER="$TEMP_DIR/curl.header"
22172246
dp="$TEMP_DIR/curl.dump"
22182247

2219-
CURL="curl "
2248+
CURL="curl ${_NOMETER} "
22202249
# shellcheck disable=SC2072
2221-
if [[ "$($CURL -V | head -1 | cut -d' ' -f2 )" > "7.33" ]]; then
2250+
if [[ ! "${_CURL_VERSION}" < "7.33" ]]; then
22222251
CURL="$CURL --http1.1 "
22232252
fi
22242253

@@ -2294,7 +2323,7 @@ send_signed_request() { # Sends a request to the ACME server, signed with your p
22942323
fi
22952324

22962325
if [[ $errcode -gt 0 || ( "$response" == "" && $url != *"revoke"* ) ]]; then
2297-
error_exit "ERROR curl \"$url\" failed with $errcode and returned $response"
2326+
error_exit "ERROR curl \"$url\" failed with $errcode and returned \"$response\""
22982327
fi
22992328

23002329
responseHeaders=$(cat "$CURL_HEADER")
@@ -2393,6 +2422,17 @@ signal_exit() { # Handle trapped signals
23932422
esac
23942423
}
23952424

2425+
traceback() { # Print function traceback
2426+
local i d=1 lbl=" called"
2427+
debug "Traceback"
2428+
for ((i=$((${#FUNCNAME[@]}-1)); i>0; i--)); do
2429+
if [[ ${i} -eq 1 ]] ; then lbl=" called traceback" ; fi
2430+
debug "$(printf "%*s%s() line %d%s\n" "$d" '' "${FUNCNAME[$i]}" "${BASH_LINENO[$((i-1))]}" "$lbl")"
2431+
((d++))
2432+
done
2433+
return 0
2434+
}
2435+
23962436
urlbase64() { # urlbase64: base64 encoded string with '+' replaced with '-' and '/' replaced with '_'
23972437
openssl base64 -e | tr -d '\n\r' | os_esed -e 's:=*$::g' -e 'y:+/:-_:'
23982438
}
@@ -2448,9 +2488,11 @@ write_domain_template() { # write out a template file for a domain.
24482488
# An ssh key will be needed to provide you with access to the remote server.
24492489
# Optionally, you can specify a different userid for ssh/scp to use on the remote server before the @ sign.
24502490
# If left blank, the username on the local server will be used to authenticate against the remote server.
2451-
# If these start with ftp:/ftpes: then the next variables are ftpuserid:ftppassword:servername:ACL_location
2491+
# If these start with ftp:/ftpes:/ftps: then the next variables are ftpuserid:ftppassword:servername:ACL_location
24522492
# These should be of the form "/path/to/your/website/folder/.well-known/acme-challenge"
24532493
# where "/path/to/your/website/folder/" is the path, on your web server, to the web root for your domain.
2494+
# ftp: uses regular ftp; ftpes: ftp over explicit TLS (port 21); ftps: ftp over implicit TLS (port 990).
2495+
# ftps/ftpes support FTPS_OPTIONS, e.g. to add "--insecure" to the curl command for hosts with self-signed certificates.
24542496
# You can also user WebDAV over HTTPS as transport mechanism. To do so, start with davs: followed by username,
24552497
# password, host, port (explicitly needed even if using default port 443) and path on the server.
24562498
# Multiple locations can be defined for a file by separating the locations with a semi-colon.
@@ -2459,6 +2501,7 @@ write_domain_template() { # write out a template file for a domain.
24592501
# 'ssh:sshuserid@server5:/var/www/${DOMAIN}/web/.well-known/acme-challenge'
24602502
# 'ftp:ftpuserid:ftppassword:${DOMAIN}:/web/.well-known/acme-challenge'
24612503
# 'davs:davsuserid:davspassword:{DOMAIN}:443:/web/.well-known/acme-challenge'
2504+
# 'ftps:ftpuserid:ftppassword:${DOMAIN}:/web/.well-known/acme-challenge'
24622505
# 'ftpes:ftpuserid:ftppassword:${DOMAIN}:/web/.well-known/acme-challenge')
24632506
24642507
# Specify SSH options, e.g. non standard port in SSH_OPTS
@@ -2592,6 +2635,12 @@ write_openssl_conf() { # write out a minimal openssl conf
25922635
trap "signal_exit TERM" TERM HUP
25932636
trap "signal_exit INT" INT
25942637

2638+
# When running tests, use debug mode to capture intermittent faults
2639+
# Test harness will Save output in a temporary file, which is displayed if an error occurs
2640+
if [[ ${_RUNNING_TEST} -eq 1 ]] ; then
2641+
_USE_DEBUG=1
2642+
fi
2643+
25952644
# Parse command-line
25962645
while [[ -n ${1+defined} ]]; do
25972646
case $1 in
@@ -2687,6 +2736,17 @@ requires sed
26872736
requires sort
26882737
requires mktemp
26892738

2739+
# Make sure cURL doesn't display a progress meter (if it's new enough)
2740+
# --silent also does this, but suppresses warnings and informational messages too.
2741+
# TODO: see where --silent can be removed (if _NOMETER defaults to --silent for old versions?)
2742+
# This would help with debugging transfer errors.
2743+
2744+
_CURL_VERSION="$(curl -V | head -1 | cut -d' ' -f2 )"
2745+
# shellcheck disable=SC2072
2746+
if [[ ! "${_CURL_VERSION}" < "7.67" ]]; then
2747+
_NOMETER="--no-progress-meter"
2748+
fi
2749+
26902750
# Check if upgrades are available (unless they have specified -U to ignore Upgrade checks)
26912751
if [[ $_UPGRADE_CHECK -eq 1 ]]; then
26922752
check_getssl_upgrade

0 commit comments

Comments
 (0)