| @ -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 | |||
| @ -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 | |||
| @ -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 | |||
| @ -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 | |||
| } | |||
| @ -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 | |||
| } | |||
| @ -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 | |||
| @ -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' | |||
| } | |||
| @ -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' | |||
| } | |||