Browse Source

Support acme-dns and fix CNAME issues

pull/731/head
Tim Kimber 4 years ago
parent
commit
e5cb7fedfd
No known key found for this signature in database GPG Key ID: 3E1804964E76BD18
18 changed files with 655 additions and 117 deletions
  1. +25
    -0
      .github/workflows/run-tests-staging-acmedns.yml
  2. +1
    -0
      .gitignore
  3. +55
    -0
      dns_scripts/dns_add_acmedns
  4. +55
    -0
      dns_scripts/dns_del_acmedns
  5. +60
    -20
      getssl
  6. +1
    -0
      test/2-simple-dns01-dig.bats
  7. +6
    -0
      test/2-simple-dns01-nslookup.bats
  8. +4
    -0
      test/32-test-upgrade.bats
  9. +60
    -0
      test/40-cname-dns01-dig.bats
  10. +111
    -0
      test/40-cname-dns01-nslookup.bats
  11. +39
    -0
      test/Dockerfile-ubuntu-acmedns
  12. +7
    -0
      test/run-test.cmd
  13. +5
    -1
      test/run-test.sh
  14. +16
    -12
      test/test-config/getssl-dns01.cfg
  15. +0
    -38
      test/u1-test-get_auth_dns-dig.bats
  16. +0
    -46
      test/u2-test-get_auth_dns-drill.bats
  17. +148
    -0
      test/u7-test-get_auth_dns-nslookup.bats
  18. +62
    -0
      test/u8-test-get_auth_dns-cname-nslookup.bats

+ 25
- 0
.github/workflows/run-tests-staging-acmedns.yml View File

@ -0,0 +1,25 @@
name: Run all tests using Dynu and acmedns
on:
push:
paths-ignore:
- '.github/workflows/*'
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
branches:
- master
env:
DYNU_API_KEY: ${{ secrets.DYNU_API_KEY == '' && '65cXefd35XbYf36546eg5dYcZT6X52Y2' || secrets.DYNU_API_KEY }}
jobs:
test-ubuntu-acmedns:
runs-on: ubuntu-latest
if: always()
steps:
- uses: actions/checkout@v2
- name: Build the docker-compose stack
run: docker-compose up -d --build
- name: Run test suite on Ubuntu against Staging using acmedns
run: test/run-test.sh ubuntu-acmedns

+ 1
- 0
.gitignore View File

@ -7,3 +7,4 @@
*.tar.gz
*.orig
JSON.sh
.vscode/settings.json

+ 55
- 0
dns_scripts/dns_add_acmedns View File

@ -0,0 +1,55 @@
#!/usr/bin/env bash
# Need to add your API user and key below or set as env variable
apiuser=${ACMEDNS_API_USER:-''}
apikey=${ACMEDNS_API_KEY:-''}
apisubdomain=${ACMEDNS_SUBDOMAIN:-''}
# This script adds a token to acme-dns.io DNS for the ACME challenge
# usage dns_add_acme-dns "domain name" "token"
# return codes are;
# 0 - success
# 1 - error returned from server
fulldomain="${1}"
token="${2}"
API='https://auth.acme-dns.io/update'
# Check initial parameters
if [[ -z "$fulldomain" ]]; then
echo "DNS script requires full domain name as first parameter"
exit 1
fi
if [[ -z "$token" ]]; then
echo "DNS script requires challenge token as second parameter"
exit 1
fi
curl_params=(
-H "accept: application/json"
-H "X-Api-Key: $apikey"
-H "X-Api-User: $apiuser"
-H 'Content-Type: application/json'
)
generate_post_data()
{
cat <<EOF
{
"subdomain": "$apisubdomain",
"txt": "$token"
}
EOF
}
resp=$(curl --silent \
"${curl_params[@]}" \
-X POST "${API}" \
--data "$(generate_post_data)")
echo $resp
# If adding record failed (returned json includes "error" then print error message
if [[ "$resp" = *"\"error\""* ]]; then
echo "Error: DNS challenge not added: unknown error - ${resp}"
exit 1
fi

+ 55
- 0
dns_scripts/dns_del_acmedns View File

@ -0,0 +1,55 @@
#!/usr/bin/env bash
# Need to add your API user and key below or set as env variable
apiuser=${ACMEDNS_API_USER:-''}
apikey=${ACMEDNS_API_KEY:-''}
apisubdomain=${ACMEDNS_SUBDOMAIN:-''}
# This script adds a token to acme-dns.io DNS for the ACME challenge
# usage dns_add_acme-dns "domain name" "token"
# return codes are;
# 0 - success
# 1 - error returned from server
fulldomain="${1}"
token="${2}"
API='https://auth.acme-dns.io/update'
# Check initial parameters
if [[ -z "$fulldomain" ]]; then
echo "DNS script requires full domain name as first parameter"
exit 1
fi
if [[ -z "$token" ]]; then
echo "DNS script requires challenge token as second parameter"
exit 1
fi
curl_params=(
-H "accept: application/json"
-H "X-Api-Key: $apikey"
-H "X-Api-User: $apiuser"
-H 'Content-Type: application/json'
)
generate_post_data()
{
cat <<EOF
{
"subdomain": "$apisubdomain",
"txt": "$token"
}
EOF
}
resp=$(curl --silent \
"${curl_params[@]}" \
-X POST "${API}" \
--data "$(generate_post_data)")
echo $resp
# If adding record failed (returned json includes "error" then print error message
if [[ "$resp" = *"\"error\""* ]]; then
echo "Error: DNS challenge not added: unknown error - ${resp}"
exit 1
fi

+ 60
- 20
getssl View File

@ -276,6 +276,9 @@
# 2021-10-01 Show help if no domain specified (#705)(2.44)
# 2021-10-08 Extract release tag from release api using awk (fix BSD issues)
# 2021-10-11 Fix broken upgrade url (#718)(2.45)
# 2021-10-22 Copy fullchain to DOMAIN_CHAIN_LOCATION (amartin-git)
# 2021-11-10 Detect Solaris and use gnu tools (#701)(miesi)
# 2021-11-12 Support acme-dns and fix CNAME issues (#722)(#308)
# ----------------------------------------------------------------------------------------
case :$SHELLOPTS: in
@ -536,12 +539,6 @@ check_challenge_completion() { # checks with the ACME server if our challenge is
debug "sleep 5 secs before testing verify again"
sleep 5
done
if [[ "$DEACTIVATE_AUTH" == "true" ]]; then
deactivate_url=$(echo "$responseHeaders" | grep "^Link" | awk -F"[<>]" '{print $2}')
deactivate_url_list="$deactivate_url_list $deactivate_url"
debug "adding url to deactivate list - $deactivate_url"
fi
}
check_challenge_completion_dns() { # perform validation via DNS challenge
@ -575,10 +572,19 @@ check_challenge_completion_dns() { # perform validation via DNS challenge
# shellcheck disable=SC2086
debug "$DNS_CHECK_FUNC" $DNS_CHECK_OPTIONS TXT "${rr}" "@${ns}"
# shellcheck disable=SC2086
check_result=$($DNS_CHECK_FUNC $DNS_CHECK_OPTIONS TXT "${rr}" "@${ns}" \
| grep -i "^${rr}" \
| grep 'IN\WTXT'|awk -F'"' '{ print $2}')
check_output=$($DNS_CHECK_FUNC $DNS_CHECK_OPTIONS TXT "${rr}" "@${ns}")
check_result=$(grep -i "^${rr}"<<<"${check_output}"|grep 'IN\WTXT'|awk -F'"' '{ print $2}')
debug "check_result=\"$check_result\""
# Check if rr is a CNAME
if [[ -z "$check_result" ]]; then
rr_cname=$(grep -i "^${rr}"<<<"${check_output}"|grep 'IN\WCNAME'|awk '{ print $5}')
debug "cname check=\"$rr_cname\""
if [[ -n "$rr_cname" ]]; then
check_result=$(grep -i "^${rr_cname}"<<<"${check_output}"|grep 'IN\WTXT'|awk -F'"' '{ print $2}' | uniq)
fi
fi
if [[ -z "$check_result" ]]; then
# shellcheck disable=SC2086
debug "$DNS_CHECK_FUNC" $DNS_CHECK_OPTIONS ANY "${rr}" "@${ns}"
@ -589,14 +595,20 @@ check_challenge_completion_dns() { # perform validation via DNS challenge
debug "check_result=\"$check_result\""
fi
elif [[ "$DNS_CHECK_FUNC" == "host" ]]; then
debug "$DNS_CHECK_FUNC" -t TXT "${rr}" "${ns}"
check_result=$($DNS_CHECK_FUNC -t TXT "${rr}" "${ns}" \
| grep 'descriptive text'|awk -F'"' '{ print $2}')
debug "check_result=\"$check_result\""
else
debug "$DNS_CHECK_FUNC" -type=txt "${rr}" "${ns}"
check_result=$(nslookup -type=txt "${rr}" "${ns}" \
| grep 'text ='|awk -F'"' '{ print $2}')
debug "check_result=\"$check_result\""
if [[ -z "$check_result" ]]; then
debug "$DNS_CHECK_FUNC" -type=any "${rr}" "${ns}"
check_result=$(nslookup -type=any "${rr}" "${ns}" \
| grep 'text ='|awk -F'"' '{ print $2}')
debug "check_result=\"$check_result\""
fi
fi
debug "expecting \"$auth_key\""
@ -1201,6 +1213,11 @@ create_order() {
fi
((dn++))
done
if [[ "$DEACTIVATE_AUTH" == "true" ]]; then
deactivate_url_list+=" $l "
debug "url added to deactivate list ${l}"
debug "deactivate list is now $deactivate_url_list"
fi
done
fi
}
@ -1352,12 +1369,6 @@ for d in "${alldomains[@]}"; do
if [[ $response_status == "valid" ]]; then
info "$d is already validated"
if [[ "$DEACTIVATE_AUTH" == "true" ]]; then
deactivate_url="$(echo "$responseHeaders" | awk ' $1 ~ "^Location" {print $2}' | tr -d "\r")"
deactivate_url_list+=" $deactivate_url "
debug "url added to deactivate list ${deactivate_url}"
debug "deactivate list is now $deactivate_url_list"
fi
# increment domain-counter
((dn++))
else
@ -1554,6 +1565,7 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n
# domain is a CNAME: resolve it and continue with that
debug Domain is a CNAME, actual domain is "$cname"
gad_d=${cname}
res=
fi
# Use SOA +trace to find the name server
@ -1629,6 +1641,7 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n
primary_ns="$primary_ns $PUBLIC_DNS_SERVER"
fi
debug set primary_ns="$primary_ns"
return
fi
fi
@ -1639,26 +1652,48 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n
# shellcheck disable=SC2086
res=$(nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns "$gad_d" ${gad_s})
# check for CNAME (assumes gad_d is _acme-challenge.{host})
if [[ "$(grep -c "NXDOMAIN"<<<"$res")" -gt 0 ]]; then
debug "Cannot find nameserver record for $gad_d, using parent domain ${gad_d#*.}"
gad_d="${gad_d#*.}"
debug "nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns $gad_d ${gad_s}"
# shellcheck disable=SC2086
res=$(nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns "$gad_d" ${gad_s})
fi
if [[ "$(echo "$res" | grep -c "Non-authoritative")" -gt 0 ]]; then
# this is a Non-authoritative server, need to check for an authoritative one.
debug "Response from non-authoritative server looking for authoritative server"
gad_s=$(echo "$res" | awk '$2 ~ "nameserver" {print $4; exit }' |sed 's/\.$//g')
if [[ "$(echo "$res" | grep -c "an't find")" -gt 0 ]]; then
# If the previous line fails to find the nameserver, use the original
if [[ -z "$gad_s" ]]; then
gad_s="$orig_gad_s"
fi
if [[ "$(echo "$res" | grep -c "canonical name")" -gt 0 ]]; then
debug "$gad_d" appears to be a CNAME
gad_d=$(echo "$res" | awk ' $2 ~ "canonical" {print $5; exit }' |sed 's/\.$//g')
debug "Using $gad_d instead"
elif [[ "$(echo "$res" | grep -c "an't find")" -gt 0 ]]; then
# if domain name doesn't exist, then find auth servers for next level up
debug "Couldn't find NS or SOA for domain name, using nslookup $DNS_CHECK_OPTIONS -debug ${gad_d#*.} ${orig_gad_s}"
# shellcheck disable=SC2086
res=$(nslookup $DNS_CHECK_OPTIONS -debug "${gad_d#*.}" ${orig_gad_s})
gad_s=$(echo "$res" | awk '$1 ~ "origin" {print $3; exit }')
gad_d=$(echo "$res" | awk '$1 ~ "->" {print $2; exit}')
# handle scenario where awk returns nothing
if [[ -z "$gad_d" ]]; then
gad_d="$orig_gad_d"
gad_d="${orig_gad_d}"
fi
fi
debug "Using nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns $gad_d ${gad_s}"
# shellcheck disable=SC2086
res=$(nslookup $DNS_CHECK_OPTIONS -debug -type=soa -type=ns "$gad_d" ${gad_s})
fi
if [[ "$(echo "$res" | grep -c "canonical name")" -gt 0 ]]; then
gad_d=$(echo "$res" | awk ' $2 ~ "canonical" {print $5; exit }' |sed 's/\.$//g')
elif [[ "$(echo "$res" | grep -c "an't find")" -gt 0 ]]; then
if [[ "$(echo "$res" | grep -c "an't find")" -gt 0 ]]; then
gad_s=$(echo "$res" | awk ' $1 ~ "origin" {print $3; exit }')
gad_d=$(echo "$res"| awk '$1 ~ "->" {print $2; exit}')
# handle scenario where awk returns nothing
@ -1680,6 +1715,11 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n
primary_ns=$(echo "$all_auth_dns_servers" | awk '{print $1}')
fi
if [[ "$CHECK_PUBLIC_DNS_SERVER" == "true" ]]; then
primary_ns="$primary_ns $PUBLIC_DNS_SERVER"
fi
debug set primary_ns="$primary_ns"
return
fi
fi


+ 1
- 0
test/2-simple-dns01-dig.bats View File

@ -6,6 +6,7 @@ load '/getssl/test/test_helper.bash'
setup_file() {
[ ! -f $BATS_RUN_TMPDIR/failed.skip ] || skip "skipping tests after first failure"
if [ -z "$STAGING" ]; then
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
fi


+ 6
- 0
test/2-simple-dns01-nslookup.bats View File

@ -14,6 +14,9 @@ setup() {
if [ -f /usr/bin/dig ]; then
mv /usr/bin/dig /usr/bin/dig.getssl.bak
fi
if [ -f /usr/bin/drill ]; then
mv /usr/bin/drill /usr/bin/drill.getssl.bak
fi
if [ -f /usr/bin/host ]; then
mv /usr/bin/host /usr/bin/host.getssl.bak
fi
@ -25,6 +28,9 @@ teardown() {
if [ -f /usr/bin/dig.getssl.bak ]; then
mv /usr/bin/dig.getssl.bak /usr/bin/dig
fi
if [ -f /usr/bin/drill.getssl.bak ]; then
mv /usr/bin/drill.getssl.bak /usr/bin/drill
fi
if [ -f /usr/bin/host.getssl.bak ]; then
mv /usr/bin/host.getssl.bak /usr/bin/host
fi


+ 4
- 0
test/32-test-upgrade.bats View File

@ -38,6 +38,10 @@ check_github_quota() {
setup_file() {
if [ -n "$STAGING" ]; then
echo "Using staging server, skipping internal test" >&3
return 0
fi
if [ -f $BATS_RUN_TMPDIR/failed.skip ]; then
echo "# Skipping setup due to previous test failure" >&3
return 0


+ 60
- 0
test/40-cname-dns01-dig.bats View File

@ -0,0 +1,60 @@
#! /usr/bin/env bats
load '/bats-support/load.bash'
load '/bats-assert/load.bash'
load '/getssl/test/test_helper.bash'
setup_file() {
if [ -z "$STAGING" ]; then
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
fi
if [ -f /usr/bin/host ]; then
mv /usr/bin/host /usr/bin/host.getssl.bak
fi
if [ -f /usr/bin/nslookup ]; then
mv /usr/bin/nslookup /usr/bin/nslookup.getssl.bak
fi
}
teardown_file() {
if [ -f /usr/bin/host.getssl.bak ]; then
mv /usr/bin/host.getssl.bak /usr/bin/host
fi
if [ -f /usr/bin/nslookup.getssl.bak ]; then
mv /usr/bin/nslookup.getssl.bak /usr/bin/nslookup
fi
}
setup() {
[ ! -f $BATS_RUN_TMPDIR/failed.skip ] || skip "skipping tests after first failure"
}
teardown() {
[ -n "$BATS_TEST_COMPLETED" ] || touch $BATS_RUN_TMPDIR/failed.skip
}
@test "Check CNAME _acme-challenge works if AUTH_DNS specified (dig)" {
if [ -z "$STAGING" ]; then
skip "Running local tests this is a staging server test"
fi
CONFIG_FILE="getssl-dns01.cfg"
setup_environment
init_getssl
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
PUBLIC_DNS_SERVER=
AUTH_DNS_SERVER="8.8.8.8"
CHECK_ALL_AUTH_DNS="false"
CHECK_PUBLIC_DNS_SERVER="false"
EOF
create_certificate
assert_success
assert_output --partial "dig"
check_output_for_errors
}

+ 111
- 0
test/40-cname-dns01-nslookup.bats View File

@ -0,0 +1,111 @@
#! /usr/bin/env bats
load '/bats-support/load.bash'
load '/bats-assert/load.bash'
load '/getssl/test/test_helper.bash'
setup_file() {
if [ -z "$STAGING" ]; then
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
fi
if [ -f /usr/bin/dig ]; then
mv /usr/bin/dig /usr/bin/dig.getssl.bak
fi
if [ -f /usr/bin/drill ]; then
mv /usr/bin/drill /usr/bin/drill.getssl.bak
fi
if [ -f /usr/bin/host ]; then
mv /usr/bin/host /usr/bin/host.getssl.bak
fi
}
teardown_file() {
if [ -f /usr/bin/dig.getssl.bak ]; then
mv /usr/bin/dig.getssl.bak /usr/bin/dig
fi
if [ -f /usr/bin/drill.getssl.bak ]; then
mv /usr/bin/drill.getssl.bak /usr/bin/drill
fi
if [ -f /usr/bin/host.getssl.bak ]; then
mv /usr/bin/host.getssl.bak /usr/bin/host
fi
}
setup() {
[ ! -f $BATS_RUN_TMPDIR/failed.skip ] || skip "skipping tests after first failure"
}
teardown() {
[ -n "$BATS_TEST_COMPLETED" ] || touch $BATS_RUN_TMPDIR/failed.skip
}
@test "Check CNAME _acme-challenge works with default DNS values (nslookup)" {
if [ -z "$STAGING" ]; then
skip "Running local tests this is a staging server test"
fi
CONFIG_FILE="getssl-dns01.cfg"
setup_environment
init_getssl
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
PUBLIC_DNS_SERVER=
AUTH_DNS_SERVER=
CHECK_ALL_AUTH_DNS="false"
CHECK_PUBLIC_DNS_SERVER="false"
EOF
create_certificate
assert_success
assert_output --partial "nslookup -type=txt"
check_output_for_errors
}
@test "Check CNAME _acme-challenge works if PUBLIC_DNS specified (nslookup)" {
if [ -z "$STAGING" ]; then
skip "Running local tests this is a staging server test"
fi
CONFIG_FILE="getssl-dns01.cfg"
setup_environment
init_getssl
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
PUBLIC_DNS_SERVER="8.8.8.8"
AUTH_DNS_SERVER=
CHECK_ALL_AUTH_DNS="false"
CHECK_PUBLIC_DNS_SERVER="false"
EOF
create_certificate
assert_success
assert_output --partial "nslookup -type=txt"
check_output_for_errors
}
@test "Check CNAME _acme-challenge works if AUTH_DNS specified (nslookup)" {
if [ -z "$STAGING" ]; then
skip "Running local tests this is a staging server test"
fi
CONFIG_FILE="getssl-dns01.cfg"
setup_environment
init_getssl
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
PUBLIC_DNS_SERVER=
AUTH_DNS_SERVER="8.8.8.8"
CHECK_ALL_AUTH_DNS="false"
CHECK_PUBLIC_DNS_SERVER="false"
EOF
create_certificate
assert_success
assert_output --partial "nslookup -type=txt"
check_output_for_errors
}

+ 39
- 0
test/Dockerfile-ubuntu-acmedns View File

@ -0,0 +1,39 @@
FROM ubuntu:latest
# Note this image uses mawk1.3
# Set noninteractive otherwise tzdata hangs
ENV DEBIAN_FRONTEND noninteractive
# Ensure tests in this image use the staging server
ENV staging "true"
# 2016ENV dynamic_dns "acme-dns"
ENV ACMEDNS_API_USER 49ac5f6d-74cd-4aca-acfe-f9457af7894c
ENV ACMEDNS_API_KEY 2NPGF8cH7PeTrHZWXImi1prhTsQGz2pdCC7Za5zE
ENV ACMEDNS_SUBDOMAIN 7268181b-7075-4dce-be51-9c20c205cf6e
# Update and install required software
RUN apt-get update --fix-missing
RUN apt-get install -y git curl dnsutils ldnsutils wget nginx-light
RUN apt-get install -y vim dos2unix # for debugging
RUN apt-get install -y locales # for idn testing
# Set locale
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
WORKDIR /root
# Prevent "Can't load /root/.rnd into RNG" error from openssl
RUN touch /root/.rnd
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local
# Run eternal loop - for testing
CMD tail -f /dev/null

+ 7
- 0
test/run-test.cmd View File

@ -11,6 +11,7 @@ REM check if OS *contains* staging
SET GETSSL_IDN_HOST=%OS%.xn--t-r1a81lydm69gz81r.test
IF NOT x%OS:duck=%==x%OS% GOTO duckdns
IF NOT x%OS:dynu=%==x%OS% GOTO dynu
IF NOT x%OS:acmedns=%==x%OS% GOTO acmedns
IF NOT x%OS:bash=%==x%OS% GOTO bash
SET ALIAS=%OS%.getssl.test
SET STAGING=
@ -38,6 +39,12 @@ SET STAGING=--env STAGING=true --env dynamic_dns=dynu --env DYNU_API_KEY=65cXefd
SET GETSSL_OS=%OS:-dynu=%
GOTO Run
:acmedns
SET ALIAS=%OS%-getssl.freeddns.org
SET STAGING=--env STAGING=true --env dynamic_dns=acmedns
SET GETSSL_OS=%OS:-acmedns=%
GOTO Run
:bash
SET ALIAS=%OS%.getssl.test
SET STAGING=


+ 5
- 1
test/run-test.sh View File

@ -37,13 +37,17 @@ elif [[ "$OS" == *"dynu"* ]]; then
ALIAS="${REPO}${OS%-dynu}-getssl.freeddns.org"
STAGING="--env STAGING=true --env dynamic_dns=dynu"
GETSSL_OS="${OS%-dynu}"
elif [[ "$OS" == *"acmedns"* ]]; then
ALIAS="${REPO}${OS}-getssl.freeddns.org"
STAGING="--env STAGING=true --env dynamic_dns=acmedns"
GETSSL_OS="${OS%-acmedns}"
elif [[ "$OS" == "bash"* ]]; then
GETSSL_OS="alpine"
fi
docker build --rm -f "test/Dockerfile-$OS" -t "getssl-$OS" .
# shellcheck disable=SC2086
docker run \
docker run -it \
--env GETSSL_HOST=$ALIAS $STAGING \
--env GETSSL_IDN_HOST=$GETSSL_IDN_HOST \
--env GETSSL_OS=$GETSSL_OS \


+ 16
- 12
test/test-config/getssl-dns01.cfg View File

@ -1,6 +1,11 @@
# Test that the script works with dns
VALIDATE_VIA_DNS=true
# Speed up the test by reducing the number or retries and the wait between retries.
DNS_WAIT=2
DNS_WAIT_COUNT=11
DNS_EXTRA_WAIT=0
if [ -z "$STAGING" ]; then
# Settings for challtestserv dns provider running in local docker
CA="https://pebble:14000/dir"
@ -8,30 +13,29 @@ if [ -z "$STAGING" ]; then
DNS_ADD_COMMAND="/getssl/dns_scripts/dns_add_challtestsrv"
DNS_DEL_COMMAND="/getssl/dns_scripts/dns_del_challtestsrv"
AUTH_DNS_SERVER=10.30.50.3
# Speed up the test by reducing the number or retries and the wait between retries.
DNS_WAIT=2
DNS_WAIT_COUNT=11
DNS_EXTRA_WAIT=0
else
# Settings for external dns provider and staging server
CA="https://acme-staging-v02.api.letsencrypt.org/directory"
# Re-use the account key when calling the staging server (otherwise hit limits)
ACCOUNT_KEY="${HOME}/account.key"
DEACTIVATE_AUTH="true"
DNS_ADD_COMMAND="/getssl/dns_scripts/dns_add_${dynamic_dns}"
DNS_DEL_COMMAND="/getssl/dns_scripts/dns_del_${dynamic_dns}"
PUBLIC_DNS_SERVER="8.8.8.8 resolver1.infoserve.de"
PUBLIC_DNS_SERVER="8.8.8.8" # resolver1.infoserve.de"
if [[ "${dynamic_dns}" == "dynu" ]]; then
AUTH_DNS_SERVER=ns1.dynu.com
else
elif [[ "${dynamic_dns}" != "acmedns" ]]; then
AUTH_DNS_SERVER=ns1.duckdns.org
fi
CHECK_ALL_AUTH_DNS="true"
CHECK_PUBLIC_DNS_SERVER="true"
DNS_EXTRA_WAIT=120
DNS_WAIT_COUNT=20
DNS_WAIT=30
DNS_WAIT_RETRY_ADD="true"
if [[ "${dynamic_dns}" != "acmedns" ]]; then
DNS_WAIT=30
DNS_WAIT_COUNT=20
DNS_EXTRA_WAIT=120
fi
fi
# Additional domains - this could be multiple domains / subdomains in a comma separated list
SANS=""


+ 0
- 38
test/u1-test-get_auth_dns-dig.bats View File

@ -139,41 +139,3 @@ teardown() {
run get_auth_dns www.duckdns.org
assert_output --regexp 'set primary_ns = ns.*\.awsdns.*\.net 1\.0\.0\.1'
}
@test "Check get_auth_dns using dig CNAME (duckdns)" {
# Test that get_auth_dns() handles scenario where CNAME query returns authority section containing NS records
#
# ************** EXAMPLE DIG OUTPUT **************
#
# ;; ANSWER SECTION:
# www.duckdns.org. 600 IN CNAME DuckDNSAppELB-570522007.us-west-2.elb.amazonaws.com.
#
# ;; AUTHORITY SECTION:
# duckdns.org. 600 IN NS ns1.duckdns.org.
# duckdns.org. 600 IN NS ns2.duckdns.org.
# duckdns.org. 600 IN NS ns3.duckdns.org.
#
# ;; ADDITIONAL SECTION:
# ns1.duckdns.org. 600 IN A 54.187.92.222
# ns2.duckdns.org. 600 IN A 54.191.117.119
# ns3.duckdns.org. 600 IN A 52.26.169.94
PUBLIC_DNS_SERVER=ns1.duckdns.org
CHECK_PUBLIC_DNS_SERVER=false
CHECK_ALL_AUTH_DNS=false
run get_auth_dns www.duckdns.org
# Assert that we've found the primary_ns server
assert_output --regexp 'set primary_ns = ns[1-9]+\.duckdns\.org'
# Assert that we found a CNAME but didn't use dig NS
assert_line --regexp 'Using dig.* CNAME'
refute_line --regexp 'Using dig.* NS'
# Check all Authoritive DNS servers are returned if requested
CHECK_ALL_AUTH_DNS=true
run get_auth_dns www.duckdns.org
assert_output --regexp 'set primary_ns = (ns[1-9]+\.duckdns\.org )+'
}

+ 0
- 46
test/u2-test-get_auth_dns-drill.bats View File

@ -155,49 +155,3 @@ teardown() {
run get_auth_dns www.duckdns.org
assert_output --regexp 'set primary_ns = ns.*\.awsdns.*\.net 1\.0\.0\.1'
}
@test "Check get_auth_dns using drill CNAME (duckdns)" {
if [ ! -f /usr/bin/drill ]; then
# Can't find drill package for centos8
skip "Drill not installed on this system"
fi
# Test that get_auth_dns() handles scenario where CNAME query returns authority section containing NS records
#
# ************** EXAMPLE drill OUTPUT **************
#
# ;; ANSWER SECTION:
# www.duckdns.org. 600 IN CNAME DuckDNSAppELB-570522007.us-west-2.elb.amazonaws.com.
#
# ;; AUTHORITY SECTION:
# duckdns.org. 600 IN NS ns1.duckdns.org.
# duckdns.org. 600 IN NS ns2.duckdns.org.
# duckdns.org. 600 IN NS ns3.duckdns.org.
#
# ;; ADDITIONAL SECTION:
# ns1.duckdns.org. 600 IN A 54.187.92.222
# ns2.duckdns.org. 600 IN A 54.191.117.119
# ns3.duckdns.org. 600 IN A 52.26.169.94
# Disable SOA check
_TEST_SKIP_SOA_CALL=1
PUBLIC_DNS_SERVER=ns1.duckdns.org
CHECK_PUBLIC_DNS_SERVER=false
CHECK_ALL_AUTH_DNS=false
run get_auth_dns www.duckdns.org
# Assert that we've found the primary_ns server
assert_output --regexp 'set primary_ns = ns[1-9]+\.duckdns\.org'
# Assert that we found a CNAME but didn't use drill NS
assert_line --regexp 'Using drill.* CNAME'
refute_line --regexp 'Using drill.* NS'
# Check all Authoritive DNS servers are returned if requested
CHECK_ALL_AUTH_DNS=true
run get_auth_dns www.duckdns.org
assert_output --regexp 'set primary_ns = (ns[1-9]+\.duckdns\.org )+'
}

+ 148
- 0
test/u7-test-get_auth_dns-nslookup.bats View File

@ -0,0 +1,148 @@
#! /usr/bin/env bats
load '/bats-support/load.bash'
load '/bats-assert/load.bash'
load '/getssl/test/test_helper.bash'
# This is run for every test
setup() {
[ ! -f $BATS_RUN_TMPDIR/failed.skip ] || skip "skipping tests after first failure"
for app in dig drill host
do
if [ -f /usr/bin/${app} ]; then
mv /usr/bin/${app} /usr/bin/${app}.getssl.bak
fi
done
. /getssl/getssl --source
_USE_DEBUG=1
find_dns_utils
NSLOOKUP_VERSION=$(echo "" | nslookup -version 2>/dev/null | awk -F"[ -]" '{ print $2 }')
# Version 9.11.3 on Ubuntu -debug doesn't work inside docker in my test env, version 9.16.1 does
if [[ "${NSLOOKUP_VERSION}" != "Invalid" ]] && check_version "${NSLOOKUP_VERSION}" "9.11.4" ; then
DNS_CHECK_OPTIONS="$DNS_CHECK_OPTIONS -debug"
else
skip "This version of nslookup either doesn't support -debug or it doesn't work in local docker"
fi
}
teardown() {
[ -n "$BATS_TEST_COMPLETED" ] || touch $BATS_RUN_TMPDIR/failed.skip
for app in dig drill host
do
if [ -f /usr/bin/${app}.getssl.bak ]; then
mv /usr/bin/${app}.getssl.bak /usr/bin/${app}
fi
done
}
@test "Check get_auth_dns using nslookup NS" {
# Test that get_auth_dns() handles scenario where NS query returns Authority section
#
# ************** EXAMPLE DIG OUTPUT **************
#
# ;; ANSWER SECTION:
# ubuntu-getssl.duckdns.org. 60 IN A 54.89.252.137
#
# ;; AUTHORITY SECTION:
# duckdns.org. 600 IN NS ns2.duckdns.org.
# duckdns.org. 600 IN NS ns3.duckdns.org.
# duckdns.org. 600 IN NS ns1.duckdns.org.
#
# ;; ADDITIONAL SECTION:
# ns2.duckdns.org. 600 IN A 54.191.117.119
# ns3.duckdns.org. 600 IN A 52.26.169.94
# ns1.duckdns.org. 600 IN A 54.187.92.222
# Disable CNAME check
_TEST_SKIP_CNAME_CALL=1
PUBLIC_DNS_SERVER=ns1.duckdns.org
CHECK_PUBLIC_DNS_SERVER=false
CHECK_ALL_AUTH_DNS=false
run get_auth_dns ubuntu-getssl.duckdns.org
# Assert that we've found the primary_ns server
#assert_output --regexp 'set primary_ns = ns[1-9]+\.duckdns\.org'
# Assert that we had to use dig NS
#assert_line --regexp 'Using nslookup.* NS'
# Check all Authoritive DNS servers are returned if requested
CHECK_ALL_AUTH_DNS=true
run get_auth_dns _acme-challenge.ubuntu-getssl.duckdns.org
assert_output --regexp 'set primary_ns=(ns[1-9]+\.duckdns\.org )+'
}
@test "Check get_auth_dns using nslookup SOA" {
# Test that get_auth_dns() handles scenario where SOA query returns Authority section
#
# ************** EXAMPLE DIG OUTPUT **************
#
# ;; AUTHORITY SECTION:
# duckdns.org. 600 IN SOA ns3.duckdns.org. hostmaster.duckdns.org. 2019170803 6000 120 2419200 600
# DuckDNS server returns nothing for SOA, so use public dns instead
PUBLIC_DNS_SERVER=1.0.0.1
CHECK_PUBLIC_DNS_SERVER=false
CHECK_ALL_AUTH_DNS=false
run get_auth_dns _acme-challenge.ubuntu-getssl.duckdns.org
# Assert that we've found the primary_ns server
assert_output --regexp 'set primary_ns=ns[1-9]+\.duckdns\.org'
# Assert that we had to use nslookup NS
assert_line --regexp 'Using nslookup.*-type=soa'
assert_line --regexp 'Using nslookup.*-type=ns'
# Check all Authoritive DNS servers are returned if requested
CHECK_ALL_AUTH_DNS=true
run get_auth_dns _acme-challenge.ubuntu-getssl.duckdns.org
assert_output --regexp 'set primary_ns=(ns[1-9]+\.duckdns\.org )+'
# Check that we also check the public DNS server if requested
CHECK_PUBLIC_DNS_SERVER=true
run get_auth_dns _acme-challenge.ubuntu-getssl.duckdns.org
assert_output --regexp 'set primary_ns=(ns[1-9]+\.duckdns\.org )+ 1\.0\.0\.1'
}
@test "Check get_auth_dns using nslookup CNAME (public dns)" {
# Test that get_auth_dns() handles scenario where CNAME query returns just a CNAME record
#
# ************** EXAMPLE DIG OUTPUT **************
#
# ;; ANSWER SECTION:
# www.duckdns.org. 600 IN CNAME DuckDNSAppELB-570522007.us-west-2.elb.amazonaws.com.
# Disable SOA check
_TEST_SKIP_SOA_CALL=1
PUBLIC_DNS_SERVER=1.0.0.1
CHECK_PUBLIC_DNS_SERVER=false
CHECK_ALL_AUTH_DNS=false
run get_auth_dns www.duckdns.org
# Assert that we've found the primary_ns server
assert_output --regexp 'set primary_ns=ns.*\.awsdns.*\.org'
# Assert that we found a CNAME
assert_line --partial 'appears to be a CNAME'
# Check all Authoritive DNS servers are returned if requested
CHECK_ALL_AUTH_DNS=true
run get_auth_dns www.duckdns.org
assert_output --regexp 'set primary_ns=(ns.*\.awsdns.*\.org )+'
# Check that we also check the public DNS server if requested
CHECK_PUBLIC_DNS_SERVER=true
run get_auth_dns www.duckdns.org
assert_output --regexp 'set primary_ns=(ns.*\.awsdns.* )+ 1\.0\.0\.1'
}

+ 62
- 0
test/u8-test-get_auth_dns-cname-nslookup.bats View File

@ -0,0 +1,62 @@
#! /usr/bin/env bats
load '/bats-support/load.bash'
load '/bats-assert/load.bash'
load '/getssl/test/test_helper.bash'
# This is run for every test
setup() {
[ ! -f $BATS_RUN_TMPDIR/failed.skip ] || skip "skipping tests after first failure"
for app in dig drill host
do
if [ -f /usr/bin/${app} ]; then
mv /usr/bin/${app} /usr/bin/${app}.getssl.bak
fi
done
. /getssl/getssl --source
find_dns_utils
_USE_DEBUG=1
NSLOOKUP_VERSION=$(echo "" | nslookup -version 2>/dev/null | awk -F"[ -]" '{ print $2 }')
# Version 9.11.3 on Ubuntu -debug doesn't work inside docker in my test env, version 9.16.1 does
if [[ "${NSLOOKUP_VERSION}" != "Invalid" ]] && check_version "${NSLOOKUP_VERSION}" "9.11.4" ; then
DNS_CHECK_OPTIONS="$DNS_CHECK_OPTIONS -debug"
else
skip "This version of nslookup either doesn't support -debug or it doesn't work in local docker"
fi
}
teardown() {
[ -n "$BATS_TEST_COMPLETED" ] || touch $BATS_RUN_TMPDIR/failed.skip
for app in dig drill host
do
if [ -f /usr/bin/${app}.getssl.bak ]; then
mv /usr/bin/${app}.getssl.bak /usr/bin/${app}
fi
done
}
@test "Check get_auth_dns for a CNAME using system DNS and nslookup" {
PUBLIC_DNS_SERVER=
AUTH_DNS_SERVER=
CHECK_ALL_AUTH_DNS="false"
CHECK_PUBLIC_DNS_SERVER="false"
# This is a CNAME, but the later `nslookup -type=txt <domain>` call will fail if set to the remote ns
run get_auth_dns _acme-challenge.ubuntu-acmedns-getssl.freeddns.org
assert_output --regexp 'set primary_ns=ns[0-9].dynu.com'
}
@test "Check get_auth_dns for a CNAME using public DNS and nslookup" {
PUBLIC_DNS_SERVER=1.0.0.1
AUTH_DNS_SERVER=
CHECK_ALL_AUTH_DNS="false"
CHECK_PUBLIC_DNS_SERVER="false"
run get_auth_dns _acme-challenge.ubuntu-acmedns-getssl.freeddns.org
assert_output --regexp 'set primary_ns=ns[0-9].dynu.com'
}

Loading…
Cancel
Save