From 125d9e25e857727c9fde890cdf90349be21d0374 Mon Sep 17 00:00:00 2001 From: Tim Kimber Date: Tue, 24 Mar 2020 21:58:53 +0000 Subject: [PATCH 1/5] Add test for IGNORE_DIRECTORY_DOMAIN --- test/9-multiple-domains-dns01.bats | 19 +++++++++ .../getssl-ignore-directory-domain.cfg | 39 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 test/test-config/getssl-ignore-directory-domain.cfg diff --git a/test/9-multiple-domains-dns01.bats b/test/9-multiple-domains-dns01.bats index 1b2cd9e..2a9344f 100644 --- a/test/9-multiple-domains-dns01.bats +++ b/test/9-multiple-domains-dns01.bats @@ -45,3 +45,22 @@ setup() { cleanup_environment curl --silent -X POST -d '{"host":"getssl.tst"}' http://10.30.50.3:8055/clear-a } + +@test "Test IGNORE_DIRECTORY_DOMAIN using DNS-01 verification" { + # This tests we can create a certificate for getssl.test and .getssl.test (*both* in SANS) + if [ -n "$STAGING" ]; then + skip "Using staging server, skipping internal test" + fi + CONFIG_FILE="getssl-ignore-directory-domain.cfg" + setup_environment + + # Add top level domain from SANS to DNS + curl --silent -X POST -d '{"host":"getssl.test", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a + + init_getssl + create_certificate + assert_success + refute_output --regexp '[Ff][Aa][Ii][Ll][Ee][Dd]' + refute_output --regexp '[Ee][Rr][Rr][Oo][Rr]' + refute_output --regexp '[Ww][Aa][Rr][Nn][Ii][Nn][Gg]' +} diff --git a/test/test-config/getssl-ignore-directory-domain.cfg b/test/test-config/getssl-ignore-directory-domain.cfg new file mode 100644 index 0000000..9777891 --- /dev/null +++ b/test/test-config/getssl-ignore-directory-domain.cfg @@ -0,0 +1,39 @@ +# Uncomment and modify any variables you need +# see https://github.com/srvrco/getssl/wiki/Config-variables for details +# see https://github.com/srvrco/getssl/wiki/Example-config-files for example configs +# +CA="https://pebble:14000/dir" + +VALIDATE_VIA_DNS=true +DNS_ADD_COMMAND="/getssl/dns_scripts/dns_add_challtestsrv" +DNS_DEL_COMMAND="/getssl/dns_scripts/dns_del_challtestsrv" +PUBLIC_DNS_SERVER=10.30.50.3 +DNS_EXTRA_WAIT="" + +# Ignore directory domain (i.e. the domain passed on the command line), and just use the domains in the SANS list +IGNORE_DIRECTORY_DOMAIN="true" +SANS="getssl.test,$GETSSL_HOST" + +# Acme Challenge Location. The first line for the domain, the following ones for each additional domain. +ACL=( + '/var/www/html/.well-known/acme-challenge' + '/var/www/html/.well-known/acme-challenge' +) + +#Set USE_SINGLE_ACL="true" to use a single ACL for all checks +USE_SINGLE_ACL="false" + +# Location for all your certs, these can either be on the server (full path name) +# or using ssh /sftp as for the ACL +DOMAIN_CERT_LOCATION="/etc/nginx/pki/server.crt" +DOMAIN_KEY_LOCATION="/etc/nginx/pki/private/server.key" +CA_CERT_LOCATION="/etc/nginx/pki/chain.crt" +DOMAIN_CHAIN_LOCATION="" # this is the domain cert and CA cert +DOMAIN_PEM_LOCATION="" # this is the domain_key, domain cert and CA cert + +# The command needed to reload apache / nginx or whatever you use +RELOAD_CMD="cp /getssl/test/test-config/nginx-ubuntu-ssl ${NGINX_CONFIG} && /getssl/test/restart-nginx" + +# Define the server type and confirm correct certificate is installed +SERVER_TYPE="https" +CHECK_REMOTE="true" From e7a67f39e609940a9169efc2f46743630ee05114 Mon Sep 17 00:00:00 2001 From: Tim Kimber Date: Mon, 30 Mar 2020 22:01:59 +0100 Subject: [PATCH 2/5] Fix problem with domain in mixed case --- getssl | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/getssl b/getssl index 010b755..72d3f36 100755 --- a/getssl +++ b/getssl @@ -773,6 +773,9 @@ create_order() { # find array position (This is O(n2) but that doubt we'll see performance issues) dn=0 for d in $alldomains; do + # Convert domain to lowercase as response from server will be in lowercase + # shellcheck disable=SC2018,SC2019 + d=$(echo "$d" | tr A-Z a-z) if [ "$d" == "$authdomain" ]; then debug "Saving authorization response for $authdomain for domain alldomains[$dn]" AuthLinkResponse[$dn]=$response @@ -913,8 +916,10 @@ for d in $alldomains; do | sed -e 's:=*$::g' -e 'y:+/:-_:') debug auth_key "$auth_key" - debug "adding dns via command: $DNS_ADD_COMMAND $d $auth_key" - if ! eval "$DNS_ADD_COMMAND" "$d" "$auth_key" ; then + # shellcheck disable=SC2018,SC2019 + lower_d=$(echo "$d" | tr A-Z a-z) + debug "adding dns via command: $DNS_ADD_COMMAND $lower_d $auth_key" + if ! eval "$DNS_ADD_COMMAND" "$lower_d" "$auth_key" ; then error_exit "DNS_ADD_COMMAND failed for domain $d" fi @@ -1091,7 +1096,9 @@ if [[ $VALIDATE_VIA_DNS == "true" ]]; then check_challenge_completion "$uri" "$d" "$keyauthorization" debug "remove DNS entry" - eval "$DNS_DEL_COMMAND" "$d" "$auth_key" + # shellcheck disable=SC2018,SC2019 + lower_d=$(echo "$d" | tr A-Z a-z) + eval "$DNS_DEL_COMMAND" "$lower_d" "$auth_key" # remove $dnsfile after each loop. rm -f "$dnsfile" fi From 0dfda4f64dd262c5dd5c2af10b00b7c1b518f903 Mon Sep 17 00:00:00 2001 From: Tim Kimber Date: Mon, 30 Mar 2020 22:02:57 +0100 Subject: [PATCH 3/5] Make "check domain exists" case insensitive --- getssl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/getssl b/getssl index 72d3f36..41663da 100755 --- a/getssl +++ b/getssl @@ -438,29 +438,29 @@ check_config() { # check the config files for all obvious errors fi # check domain exists if [[ "$DNS_CHECK_FUNC" == "drill" ]]; then - if [[ "$($DNS_CHECK_FUNC "${d}" |grep -c "${d}")" -ge 1 ]]; then + if [[ "$($DNS_CHECK_FUNC "${d}" |grep -c -i "${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" == "dig" ]]; then - if [[ "$($DNS_CHECK_FUNC "${d}" -t SOA|grep -c "^${d}")" -ge 1 ]]; then + if [[ "$($DNS_CHECK_FUNC "${d}" -t SOA|grep -c -i "^${d}")" -ge 1 ]]; then debug "found SOA IP for ${d}" - elif [[ "$($DNS_CHECK_FUNC "${d}" -t A|grep -c "^${d}")" -ge 1 ]]; then + elif [[ "$($DNS_CHECK_FUNC "${d}" -t A|grep -c -i "^${d}")" -ge 1 ]]; then debug "found A IP for ${d}" else info "${DOMAIN}: DNS lookup failed for ${d}" config_errors=true fi elif [[ "$DNS_CHECK_FUNC" == "host" ]]; then - if [[ "$($DNS_CHECK_FUNC "${d}" |grep -c "^${d}")" -ge 1 ]]; then + if [[ "$($DNS_CHECK_FUNC "${d}" |grep -c -i "^${d}")" -ge 1 ]]; then debug "found IP for ${d}" else info "${DOMAIN}: DNS lookup failed for ${d}" config_errors=true fi - elif [[ "$(nslookup -query=AAAA "${d}"|grep -c "^${d}.*has AAAA address")" -ge 1 ]]; then + elif [[ "$(nslookup -query=AAAA "${d}"|grep -c -i "^${d}.*has AAAA address")" -ge 1 ]]; then debug "found IPv6 record for ${d}" elif [[ "$(nslookup "${d}"| grep -c ^Name)" -ge 1 ]]; then debug "found IPv4 record for ${d}" From ad28d693716d0e707b146912c509c53c20ea4431 Mon Sep 17 00:00:00 2001 From: Tim Kimber Date: Mon, 30 Mar 2020 22:04:29 +0100 Subject: [PATCH 4/5] Fix error messages in find_dns_utils from older versions of "command" --- getssl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/getssl b/getssl index 41663da..73ca097 100755 --- a/getssl +++ b/getssl @@ -833,20 +833,20 @@ find_dns_utils() { HAS_NSLOOKUP=false HAS_DIG_OR_DRILL="" HAS_HOST=false - if [[ -n "$(command -v nslookup)" ]]; then + if [[ -n "$(command -v nslookup 2>/dev/null)" ]]; then debug "HAS NSLOOKUP=true" HAS_NSLOOKUP=true fi - if [[ -n "$(command -v drill)" ]]; then + if [[ -n "$(command -v drill 2>/dev/null)" ]]; then debug "HAS DIG_OR_DRILL=drill" HAS_DIG_OR_DRILL="drill" - elif [[ -n "$(command -v dig)" ]]; then + elif [[ -n "$(command -v dig 2>/dev/null)" ]]; then debug "HAS DIG_OR_DRILL=dig" HAS_DIG_OR_DRILL="dig" fi - if [[ -n "$(command -v host)" ]]; then + if [[ -n "$(command -v host 2>/dev/null)" ]]; then debug "HAS HOST=true" HAS_HOST=true fi From 125fabdc33708eaf31aade340ab4e6ddd5bb5552 Mon Sep 17 00:00:00 2001 From: Tim Kimber Date: Mon, 30 Mar 2020 22:31:33 +0100 Subject: [PATCH 5/5] Add mixed case tests, rename duckdns tests --- .github/workflows/run-all-tests.yml | 8 ++-- test/10-mixed-case-staging.bats | 24 ++++++++++ test/10-mixed-case.bats | 45 +++++++++++++++++++ ...ns01-dig.bats => 7-staging-dns01-dig.bats} | 2 +- ...kup.bats => 7-staging-dns01-nslookup.bats} | 2 +- ...uckdns-ecdsa.bats => 8-staging-ecdsa.bats} | 4 +- test/9-test--all.bats | 34 ++++++++++++++ ...os7-duckdns => Dockerfile-centos7-staging} | 0 ...untu-duckdns => Dockerfile-ubuntu-staging} | 0 test/run-test.cmd | 10 ++--- test/run-test.sh | 6 +-- ...duckdns01.cfg => getssl-staging-dns01.cfg} | 0 test/test_helper.bash | 9 ++-- 13 files changed, 125 insertions(+), 19 deletions(-) create mode 100644 test/10-mixed-case-staging.bats create mode 100644 test/10-mixed-case.bats rename test/{7-duckdns-dns01-dig.bats => 7-staging-dns01-dig.bats} (95%) rename test/{7-duckdns-dns01-nslookup.bats => 7-staging-dns01-nslookup.bats} (96%) rename test/{8-duckdns-ecdsa.bats => 8-staging-ecdsa.bats} (96%) create mode 100644 test/9-test--all.bats rename test/{Dockerfile-centos7-duckdns => Dockerfile-centos7-staging} (100%) rename test/{Dockerfile-ubuntu-duckdns => Dockerfile-ubuntu-staging} (100%) rename test/test-config/{getssl-duckdns01.cfg => getssl-staging-dns01.cfg} (100%) diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index 1ff795d..ff0e121 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -31,14 +31,14 @@ jobs: run: docker-compose up -d --build - name: Run test suite on CentOS7 run: test/run-test.sh centos7 - test-centos7-duckdns: + test-centos7-staging: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Build the docker-compose stack run: docker-compose up -d --build - name: Run test suite on CentOS7 against Staging using DuckDNS - run: test/run-test.sh centos7-duckdns + run: test/run-test.sh centos7-staging test-debian: runs-on: ubuntu-latest steps: @@ -71,11 +71,11 @@ jobs: run: docker-compose up -d --build - name: Run test suite on Ubuntu18 run: test/run-test.sh ubuntu18 - test-ubuntu-duckdns: + test-ubuntu-staging: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Build the docker-compose stack run: docker-compose up -d --build - name: Run test suite on Ubuntu against Staging using DuckDNS - run: test/run-test.sh ubuntu-duckdns + run: test/run-test.sh ubuntu-staging diff --git a/test/10-mixed-case-staging.bats b/test/10-mixed-case-staging.bats new file mode 100644 index 0000000..c1bac0d --- /dev/null +++ b/test/10-mixed-case-staging.bats @@ -0,0 +1,24 @@ +#! /usr/bin/env bats + +load '/bats-support/load.bash' +load '/bats-assert/load.bash' +load '/getssl/test/test_helper.bash' + + +@test "Check can create certificate if domain is not lowercase using staging server and DuckDNS" { + if [ -z "$STAGING" ]; then + skip "Running internal tests, skipping external test" + fi + + CONFIG_FILE="getssl-staging-dns01.cfg" + GETSSL_CMD_HOST=$(echo $GETSSL_HOST | tr a-z A-Z) + + setup_environment + init_getssl + create_certificate + + assert_success + refute_output --regexp '[Ff][Aa][Ii][Ll][Ee][Dd]' + refute_output --regexp '[Ee][Rr][Rr][Oo][Rr]' + refute_output --regexp '[Ww][Aa][Rr][Nn][Ii][Nn][Gg]' +} diff --git a/test/10-mixed-case.bats b/test/10-mixed-case.bats new file mode 100644 index 0000000..2a4d6f3 --- /dev/null +++ b/test/10-mixed-case.bats @@ -0,0 +1,45 @@ +#! /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() { + export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt +} + +@test "Check that HTTP-01 verification works if the domain is not lowercase" { + if [ -n "$STAGING" ]; then + skip "Using staging server, skipping internal test" + fi + + CONFIG_FILE="getssl-http01.cfg" + GETSSL_CMD_HOST=$(echo $GETSSL_HOST | tr a-z A-Z) + + setup_environment + init_getssl + create_certificate + + assert_success + refute_output --regexp '[Ff][Aa][Ii][Ll][Ee][Dd]' + refute_output --regexp '[Ee][Rr][Rr][Oo][Rr]' + refute_output --regexp '[Ww][Aa][Rr][Nn][Ii][Nn][Gg]' +} + +@test "Check that DNS-01 verification works if the domain is not lowercase" { + if [ -n "$STAGING" ]; then + skip "Using staging server, skipping internal test" + fi + CONFIG_FILE="getssl-dns01.cfg" + GETSSL_CMD_HOST=$(echo $GETSSL_HOST | tr a-z A-Z) + setup_environment + + init_getssl + create_certificate + assert_success + refute_output --regexp '[Ff][Aa][Ii][Ll][Ee][Dd]' + refute_output --regexp '[Ee][Rr][Rr][Oo][Rr]' + refute_output --regexp '[Ww][Aa][Rr][Nn][Ii][Nn][Gg]' +} diff --git a/test/7-duckdns-dns01-dig.bats b/test/7-staging-dns01-dig.bats similarity index 95% rename from test/7-duckdns-dns01-dig.bats rename to test/7-staging-dns01-dig.bats index c6d8f56..8c0d7f1 100644 --- a/test/7-duckdns-dns01-dig.bats +++ b/test/7-staging-dns01-dig.bats @@ -10,7 +10,7 @@ load '/getssl/test/test_helper.bash' if [ -z "$STAGING" ]; then skip "Running internal tests, skipping external test" fi - CONFIG_FILE="getssl-duckdns01.cfg" + CONFIG_FILE="getssl-staging-dns01.cfg" setup_environment init_getssl diff --git a/test/7-duckdns-dns01-nslookup.bats b/test/7-staging-dns01-nslookup.bats similarity index 96% rename from test/7-duckdns-dns01-nslookup.bats rename to test/7-staging-dns01-nslookup.bats index 81c921e..027a210 100644 --- a/test/7-duckdns-dns01-nslookup.bats +++ b/test/7-staging-dns01-nslookup.bats @@ -24,7 +24,7 @@ teardown() { if [ -z "$STAGING" ]; then skip "Running internal tests, skipping external test" fi - CONFIG_FILE="getssl-duckdns01.cfg" + CONFIG_FILE="getssl-staging-dns01.cfg" setup_environment init_getssl diff --git a/test/8-duckdns-ecdsa.bats b/test/8-staging-ecdsa.bats similarity index 96% rename from test/8-duckdns-ecdsa.bats rename to test/8-staging-ecdsa.bats index 2e10512..92c694a 100644 --- a/test/8-duckdns-ecdsa.bats +++ b/test/8-staging-ecdsa.bats @@ -11,7 +11,7 @@ load '/getssl/test/test_helper.bash' if [ -z "$STAGING" ]; then skip "Running internal tests, skipping external test" fi - CONFIG_FILE="getssl-duckdns01.cfg" + CONFIG_FILE="getssl-staging-dns01.cfg" setup_environment init_getssl @@ -41,7 +41,7 @@ load '/getssl/test/test_helper.bash' if [ -z "$STAGING" ]; then skip "Running internal tests, skipping external test" fi - CONFIG_FILE="getssl-duckdns01.cfg" + CONFIG_FILE="getssl-staging-dns01.cfg" setup_environment init_getssl diff --git a/test/9-test--all.bats b/test/9-test--all.bats new file mode 100644 index 0000000..94a2c28 --- /dev/null +++ b/test/9-test--all.bats @@ -0,0 +1,34 @@ +#! /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() { + export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt + export PATH=$PATH:/getssl +} + + +@test "Create new certificate using --all" { + if [ -n "$STAGING" ]; then + skip "Using staging server, skipping internal test" + fi + + # Setup + CONFIG_FILE="getssl-http01.cfg" + setup_environment + init_getssl + cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/${GETSSL_HOST}/getssl.cfg" + + # Run test + run ${CODE_DIR}/getssl --all + + # Check success conditions + assert_success + refute_output --regexp '[Ff][Aa][Ii][Ll][Ee][Dd]' + refute_output --regexp '[Ee][Rr][Rr][Oo][Rr]' + refute_output --regexp '[Ww][Aa][Rr][Nn][Ii][Nn][Gg]' +} diff --git a/test/Dockerfile-centos7-duckdns b/test/Dockerfile-centos7-staging similarity index 100% rename from test/Dockerfile-centos7-duckdns rename to test/Dockerfile-centos7-staging diff --git a/test/Dockerfile-ubuntu-duckdns b/test/Dockerfile-ubuntu-staging similarity index 100% rename from test/Dockerfile-ubuntu-duckdns rename to test/Dockerfile-ubuntu-staging diff --git a/test/run-test.cmd b/test/run-test.cmd index d1cf263..43c4e40 100644 --- a/test/run-test.cmd +++ b/test/run-test.cmd @@ -7,8 +7,8 @@ IF %2.==. GOTO NoCmd set COMMAND=%2 %3 :CheckAlias -REM check if OS *contains* duckdns -IF NOT x%OS:duckdns=%==x%OS% GOTO duckdns +REM check if OS *contains* staging +IF NOT x%OS:staging=%==x%OS% GOTO staging set ALIAS=%OS%.getssl.test set STAGING= GOTO Run @@ -22,8 +22,8 @@ REM set COMMAND=/getssl/test/run-bats.sh set COMMAND=bats /getssl/test GOTO CheckAlias -:duckdns -set ALIAS=%OS:-duckdns=%-getssl.duckdns.org +:staging +set ALIAS=%OS:-staging=%-getssl.duckdns.org set STAGING=--env STAGING=true :Run @@ -33,7 +33,7 @@ docker build --rm -f "test\Dockerfile-%OS%" -t getssl-%OS% . @echo on docker run -it ^ --env GETSSL_HOST=%ALIAS% %STAGING% ^ - --env GETSSL_OS=%OS:-duckdns=% ^ + --env GETSSL_OS=%OS:-staging=% ^ -v %cd%:/getssl ^ --rm ^ --network %CurrDirName%_acmenet ^ diff --git a/test/run-test.sh b/test/run-test.sh index 97842a5..d99d5a3 100755 --- a/test/run-test.sh +++ b/test/run-test.sh @@ -14,8 +14,8 @@ else COMMAND="bats /getssl/test" fi -if [[ "$OS" == *"duckdns"* ]]; then - ALIAS="${OS%-duckdns}-getssl.duckdns.org" +if [[ "$OS" == *"staging"* ]]; then + ALIAS="${OS%-staging}-getssl.duckdns.org" STAGING="--env STAGING=true" else ALIAS="$OS.getssl.test" @@ -26,7 +26,7 @@ docker build --rm -f "test/Dockerfile-$OS" -t "getssl-$OS" . # shellcheck disable=SC2086 docker run \ --env GETSSL_HOST=$ALIAS $STAGING \ - --env GETSSL_OS=${OS%-duckdns} \ + --env GETSSL_OS=${OS%-staging} \ -v "$(pwd)":/getssl \ --rm \ --network ${PWD##*/}_acmenet \ diff --git a/test/test-config/getssl-duckdns01.cfg b/test/test-config/getssl-staging-dns01.cfg similarity index 100% rename from test/test-config/getssl-duckdns01.cfg rename to test/test-config/getssl-staging-dns01.cfg diff --git a/test/test_helper.bash b/test/test_helper.bash index f311b18..f4c62af 100644 --- a/test/test_helper.bash +++ b/test/test_helper.bash @@ -21,7 +21,7 @@ cleanup_environment() { init_getssl() { # Run initialisation (create account key, etc) - run ${CODE_DIR}/getssl -c "$GETSSL_HOST" + run ${CODE_DIR}/getssl -c "$GETSSL_CMD_HOST" assert_success [ -d "$INSTALL_DIR/.getssl" ] } @@ -29,9 +29,9 @@ init_getssl() { create_certificate() { # Create certificate - cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/${GETSSL_HOST}/getssl.cfg" + cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl.cfg" # shellcheck disable=SC2086 - run ${CODE_DIR}/getssl $1 "$GETSSL_HOST" + run ${CODE_DIR}/getssl $1 "$GETSSL_CMD_HOST" } # start nginx in background on alpine via supervisord @@ -68,6 +68,9 @@ fi export GETSSL_IP +GETSSL_CMD_HOST=$GETSSL_HOST +export GETSSL_CMD_HOST + if [ ! -f ${INSTALL_DIR}/pebble.minica.pem ]; then wget --quiet --no-clobber https://raw.githubusercontent.com/letsencrypt/pebble/master/test/certs/pebble.minica.pem 2>&1 CERT_FILE=/etc/ssl/certs/ca-certificates.crt