Browse Source

Fix pebble and acmedns tests (#889)

* Use local copies of pebble certs as docker image contains outdated versions
* Update the preferred chain used in Staging
* Put test API keys in github secrets, add code to create/delete test domains to prevent misuse
* Simplify dns_add_acmedns
master
Tim Kimber 2 weeks ago
committed by GitHub
parent
commit
1d8f91bd0f
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
12 changed files with 168 additions and 60 deletions
  1. +4
    -2
      .github/workflows/run-tests-staging-acmedns.yml
  2. +1
    -1
      .github/workflows/run-tests-staging-dynu.yml
  3. +10
    -31
      dns_scripts/dns_add_acmedns
  4. +2
    -0
      docker-compose.yml
  5. +20
    -0
      pebble-certificates/cert.pem
  6. +27
    -0
      pebble-certificates/key.pem
  7. +0
    -19
      pebble.minica.pem
  8. +3
    -2
      test/36-full-chain-inc-root.bats
  9. +0
    -4
      test/Dockerfile-ubuntu-acmedns
  10. +5
    -0
      test/README-Testing.md
  11. +95
    -0
      test/run-test.sh
  12. +1
    -1
      test/test_helper.bash

+ 4
- 2
.github/workflows/run-tests-staging-acmedns.yml View File

@ -14,8 +14,10 @@ on:
env:
DYNU_API_KEY: ${{ secrets.DYNU_API_KEY == '' && '65cXefd35XbYf36546eg5dYcZT6X52Y2' || secrets.DYNU_API_KEY }}
DYNU_API_KEY: ${{ secrets.DYNU_API_KEY }}
ACMEDNS_API_KEY: ${{ secrets.ACMEDNS_API_KEY }}
ACMEDNS_API_USER: ${{ secrets.ACMEDNS_API_USER }}
ACMEDNS_SUBDOMAIN: ${{ secrets.ACMEDNS_SUBDOMAIN }}
jobs:
test-ubuntu-acmedns:
runs-on: ubuntu-latest


+ 1
- 1
.github/workflows/run-tests-staging-dynu.yml View File

@ -2,7 +2,7 @@ name: Run tests against Staging server using Dynu
on:
workflow_dispatch
env:
DYNU_API_KEY: ${{ secrets.DYNU_API_KEY == '' && '65cXefd35XbYf36546eg5dYcZT6X52Y2' || secrets.DYNU_API_KEY }}
DYNU_API_KEY: ${{ secrets.DYNU_API_KEY }}
jobs:
test-centos7-dynu:
runs-on: ubuntu-latest


+ 10
- 31
dns_scripts/dns_add_acmedns View File

@ -1,10 +1,5 @@
#!/usr/bin/env bash
. "$(dirname "${BASH_SOURCE}")/../common.shrc" || {
echo "Unable to load shared Bash code"
exit 1
} >&2
# ACMEDNS env variables can be set in a config file at domain level
acme_config="$DOMAIN_DIR/acme-dns.cfg"
[ -s "$acme_config" ] && . "$acme_config"
@ -37,29 +32,13 @@ if [[ -z "$token" ]]; then
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
}
curl.do \
"${curl_params[@]}" \
-X POST "${API}" \
--data "$(generate_post_data)" \
>/dev/null || {
echo 'Error: DNS challenge not added: unknown error'
exit 1
} >&2
exit 0
curl --fail --silent -X POST "${API}" \
-H "accept: application/json" \
-H "X-Api-Key: $apikey" \
-H "X-Api-User: $apiuser" \
-H 'Content-Type: application/json' \
-d '{
"subdomain": "'"${apisubdomain}"'",
"txt": "'"$token"'"
}'

+ 2
- 0
docker-compose.yml View File

@ -10,6 +10,8 @@ services:
ports:
- 14000:14000 # HTTPS ACME API
- 15000:15000 # HTTPS Management API
volumes:
- ./pebble-certificates:/test/certs/localhost
networks:
acmenet:
ipv4_address: 10.30.50.2


+ 20
- 0
pebble-certificates/cert.pem View File

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDMDCCAhigAwIBAgIILDt8c2fMw2IwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE
AxMVbWluaWNhIHJvb3QgY2EgNTM0NWU2MB4XDTI1MDkwMzIzNDAwNVoXDTI3MTAw
MzIzNDAwNVowFDESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAmxTFtw113RK70H9pQmdKs9AxhFmnQ6BdDtp3jOZlWlUO
0BltMXOUML5905etgtCbcC6RdKRtgSAiDfgx3VWiFMJH++4gUtnaB9SN8GhNSPBp
FfSa2JhWPo9HQNUsAZqlGTV4SzcGRqtWvdZxUiOfQ2TcvyXIqsaD19ivvqI1NhT6
bl3tredTZlzLLM6Wvkw6hfyHrJAPQP8LOlCIeDM4YIce6Gstv6qo9iCD4wJiY4u9
5HVL7RK8t8JpZAb7VR+dPhbHEvVpjwuYd5Q05OZ280gFyrhbrKLbqst104GOQT4k
QMJGWxGONyTX6np0Dx6O5jU7dvYvjVVawbJwGuaL6wIDAQABo3oweDAOBgNVHQ8B
Af8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAfBgNV
HSMEGDAWgBSu8RGpErgYUoYnQuwCq+/ggTiEjDAiBgNVHREEGzAZgglsb2NhbGhv
c3SCBnBlYmJsZYcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAAB0gkekXCNOwqWmY
vQ2lLJ8Zk2WzQ9B+VOC27IgxEEuskZyCpyXAbJB9sCGQWZhAARyaI4SPRGGagcug
d1SwDWdPGeSJzF3aDnXDYoP9Zw2KqiqVZTngeoiw8Yn0F8PNriANwRLybouX7mMc
4V7T5+2k4SUs7pFH4KO0a0XBCcjXDjdKuBljftRTXCHzJzfRtmieCCuZlpnp5sHx
hKa/uxKGyyZB+4Y3MrzsiQSCBOr9G4TH9RofmNcawl+tsVe08zLV/XVhrbakKEs7
Y7MGHSj3BkPFF32NObc0znqWzTaUD9hU+rXWGANM4sXd4dagdnxfrb7i0WYhcUFj
9Try8Q==
-----END CERTIFICATE-----

+ 27
- 0
pebble-certificates/key.pem View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAmxTFtw113RK70H9pQmdKs9AxhFmnQ6BdDtp3jOZlWlUO0Blt
MXOUML5905etgtCbcC6RdKRtgSAiDfgx3VWiFMJH++4gUtnaB9SN8GhNSPBpFfSa
2JhWPo9HQNUsAZqlGTV4SzcGRqtWvdZxUiOfQ2TcvyXIqsaD19ivvqI1NhT6bl3t
redTZlzLLM6Wvkw6hfyHrJAPQP8LOlCIeDM4YIce6Gstv6qo9iCD4wJiY4u95HVL
7RK8t8JpZAb7VR+dPhbHEvVpjwuYd5Q05OZ280gFyrhbrKLbqst104GOQT4kQMJG
WxGONyTX6np0Dx6O5jU7dvYvjVVawbJwGuaL6wIDAQABAoIBAGW9W/S6lO+DIcoo
PHL+9sg+tq2gb5ZzN3nOI45BfI6lrMEjXTqLG9ZasovFP2TJ3J/dPTnrwZdr8Et/
357YViwORVFnKLeSCnMGpFPq6YEHj7mCrq+YSURjlRhYgbVPsi52oMOfhrOIJrEG
ZXPAwPRi0Ftqu1omQEqz8qA7JHOkjB2p0i2Xc/uOSJccCmUDMlksRYz8zFe8wHuD
XvUL2k23n2pBZ6wiez6Xjr0wUQ4ESI02x7PmYgA3aqF2Q6ECDwHhjVeQmAuypMF6
IaTjIJkWdZCW96pPaK1t+5nTNZ+Mg7tpJ/PRE4BkJvqcfHEOOl6wAE8gSk5uVApY
ZRKGmGkCgYEAzF9iRXYo7A/UphL11bR0gqxB6qnQl54iLhqS/E6CVNcmwJ2d9pF8
5HTfSo1/lOXT3hGV8gizN2S5RmWBrc9HBZ+dNrVo7FYeeBiHu+opbX1X/C1HC0m1
wJNsyoXeqD1OFc1WbDpHz5iv4IOXzYdOdKiYEcTv5JkqE7jomqBLQk8CgYEAwkG/
rnwr4ThUo/DG5oH+l0LVnHkrJY+BUSI33g3eQ3eM0MSbfJXGT7snh5puJW0oXP7Z
Gw88nK3Vnz2nTPesiwtO2OkUVgrIgWryIvKHaqrYnapZHuM+io30jbZOVaVTMR9c
X/7/d5/evwXuP7p2DIdZKQKKFgROm1XnhNqVgaUCgYBD/ogHbCR5RVsOVciMbRlG
UGEt3YmUp/vfMuAsKUKbT2mJM+dWHVlb+LZBa4pC06QFgfxNJi/aAhzSGvtmBEww
xsXbaceauZwxgJfIIUPfNZCMSdQVIVTi2Smcx6UofBz6i/Jw14MEwlvhamaa7qVf
kqflYYwelga1wRNCPopLaQKBgQCWsZqZKQqBNMm0Q9yIhN+TR+2d7QFjqeePoRPl
1qxNejhq25ojE607vNv1ff9kWUGuoqSZMUC76r6FQba/JoNbefI4otd7x/GzM9uS
8MHMJazU4okwROkHYwgLxxkNp6rZuJJYheB4VDTfyyH/ng5lubmY7rdgTQcNyZ5I
majRYQKBgAMKJ3RlII0qvAfNFZr4Y2bNIq+60Z+Qu2W5xokIHCFNly3W1XDDKGFe
CCPHSvQljinke3P9gPt2HVdXxcnku9VkTti+JygxuLkVg7E0/SWwrWfGsaMJs+84
fK+mTZay2d3v24r9WKEKwLykngYPyZw5+BdWU0E+xx5lGUd3U4gG
-----END RSA PRIVATE KEY-----

+ 0
- 19
pebble.minica.pem View File

@ -1,19 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDCTCCAfGgAwIBAgIIJOLbes8sTr4wDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE
AxMVbWluaWNhIHJvb3QgY2EgMjRlMmRiMCAXDTE3MTIwNjE5NDIxMFoYDzIxMTcx
MjA2MTk0MjEwWjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAyNGUyZGIwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5WgZNoVJandj43kkLyU50vzCZ
alozvdRo3OFiKoDtmqKPNWRNO2hC9AUNxTDJco51Yc42u/WV3fPbbhSznTiOOVtn
Ajm6iq4I5nZYltGGZetGDOQWr78y2gWY+SG078MuOO2hyDIiKtVc3xiXYA+8Hluu
9F8KbqSS1h55yxZ9b87eKR+B0zu2ahzBCIHKmKWgc6N13l7aDxxY3D6uq8gtJRU0
toumyLbdzGcupVvjbjDP11nl07RESDWBLG1/g3ktJvqIa4BWgU2HMh4rND6y8OD3
Hy3H8MY6CElL+MOCbFJjWqhtOxeFyZZV9q3kYnk9CAuQJKMEGuN4GU6tzhW1AgMB
AAGjRTBDMA4GA1UdDwEB/wQEAwIChDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB
BQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsFAAOCAQEAF85v
d40HK1ouDAtWeO1PbnWfGEmC5Xa478s9ddOd9Clvp2McYzNlAFfM7kdcj6xeiNhF
WPIfaGAi/QdURSL/6C1KsVDqlFBlTs9zYfh2g0UXGvJtj1maeih7zxFLvet+fqll
xseM4P9EVJaQxwuK/F78YBt0tCNfivC6JNZMgxKF59h0FBpH70ytUSHXdz7FKwix
Mfn3qEb9BXSk0Q3prNV5sOV3vgjEtB4THfDxSz9z3+DepVnW3vbbqwEbkXdk3j82
2muVldgOUgTwK8eT+XdofVdntzU/kzygSAtAQwLJfn51fS1GvEcYGBc1bDryIqmF
p9BI7gVKtWSZYegicA==
-----END CERTIFICATE-----

+ 3
- 2
test/36-full-chain-inc-root.bats View File

@ -32,7 +32,8 @@ EOF
check_output_for_errors
if [ -n "$STAGING" ]; then
PREFERRED_CHAIN="(STAGING) Doctored Durian Root CA X3"
# https://letsencrypt.org/docs/staging-environment/
PREFERRED_CHAIN="(STAGING) Pretend Pear X1"
else
# pebble doesn't support CA Issuers so the fullchain.crt will just contain the certificate (code path means it won't contain the intermediate cert in this case)
# This is testing that requesting FULL_CHAIN_INCLUDE_ROOT doesn't fail if there is no CA Issuers in the certificate
@ -76,7 +77,7 @@ EOF
assert [ -e "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.ec.crt" ]
if [ -n "$STAGING" ]; then
PREFERRED_CHAIN="(STAGING) Doctored Durian Root CA X3"
PREFERRED_CHAIN="(STAGING) Pretend Pear X1"
else
# pebble doesn't support CA Issuers so the fullchain.crt will just contain the certificate (code path means it won't contain the intermediate cert in this case)
# This is testing that requesting FULL_CHAIN_INCLUDE_ROOT doesn't fail if there is no CA Issuers in the certificate


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

@ -7,10 +7,6 @@ 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


+ 5
- 0
test/README-Testing.md View File

@ -24,6 +24,11 @@ For dynu.com:
- Add DYNU_API_KEY to your repository's environment secrets. The value is your account's API Key.
- Add domains \<reponame>-centos7-getssl.freedns.org, wild-\<reponame>-centos7.freedns.org, \<reponame>-ubuntu-getssl.freedns.org, and wild-\<reponame>-ubuntu-getssl.freedns.org
For ACME DNS (also needs Dynu)
- Register to get a user, key and subdomain from acme-dns.io (see https://github.com/joohoi/acme-dns?tab=readme-ov-file)
- Create a CNAME _acme-challenge.ubuntu-acmedns-getssl.freeddns.org. to ${ACMEDNS_SUBDOMAIN}.auth.acme-dns.io (this is done automatically in run-test.sh)
To run dynamic DNS tests outside the CI environment, you need accounts without \<reponame> in the domain names. Export the environment variable corresponding to the secrets (with the same values).
For individual accounts, \<reponame> is your github account name.


+ 95
- 0
test/run-test.sh View File

@ -1,5 +1,80 @@
#! /usr/bin/env bash
set -e
function add-dynu-domain() {
domain=$1
curl --silent --fail-with-body -X POST "https://api.dynu.com/v2/dns" \
-H "accept: application/json" \
-H "API-Key: $DYNU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "'"${domain}"'",
"ipv4Address": "1.2.3.4",
"ttl": 60,
"ipv4": true,
"ipv6": false
}'
}
function get-dynu-domain-id() {
domain=$1
curl --silent --fail-with-body -X GET "https://api.dynu.com/v2/dns" \
-H "accept: application/json" \
-H "API-Key: $DYNU_API_KEY" | \
jq -r ".domains[] | select(.name == \"${domain}\") | .id"
}
function remove-dynu-domain() {
domain=$1
echo "Removing dynu domain: $domain"
domain_id=$(get-dynu-domain-id "$domain")
echo "Found id for dynu domain: $domain = $domain_id"
if [ -n "$domain_id" ] && [ "$domain_id" != "null" ]; then
curl --silent --fail-with-body -X DELETE "https://api.dynu.com/v2/dns/${domain_id}" \
-H "accept: application/json" \
-H "API-Key: $DYNU_API_KEY"
echo "Domain $domain removed successfully"
else
echo "Domain $domain not found or already removed"
fi
}
function add-dynu-cname() {
subdomain=$1
domain=$2
target=$3
echo "Creating CNAME record: ${subdomain}.${domain} -> ${target}"
domain_id=$(get-dynu-domain-id "$domain")
if [ -n "$domain_id" ] && [ "$domain_id" != "null" ]; then
curl --silent --fail-with-body -X POST "https://api.dynu.com/v2/dns/${domain_id}/record" \
-H "accept: application/json" \
-H "API-Key: $DYNU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"nodeName": "'"${subdomain}"'",
"recordType": "CNAME",
"state": true,
"host": "'"${target}"'"
}'
else
echo "Error: Domain $domain not found"
return 1
fi
}
# Cleanup function to remove dynu domains on exit
cleanup() {
if [[ ("$OS" == *"dynu"* || "$OS" == *"acmedns"*)]] && [ -n "$DYNU_API_KEY" ]; then
echo "Cleaning up domains..."
remove-dynu-domain "$ALIAS"
remove-dynu-domain "wild-$ALIAS"
fi
}
# Set up trap to run cleanup on exit
trap cleanup EXIT
if [ $# -eq 0 ]; then
echo "Usage: $(basename "$0") <os> [<command>]"
echo "e.g. $(basename "$0") alpine bats /getssl/test"
@ -54,10 +129,26 @@ elif [[ "$OS" == *"dynu"* ]]; then
ALIAS="${REPO}${OS%-dynu}-getssl.freeddns.org"
STAGING="--env STAGING=true --env dynamic_dns=dynu"
GETSSL_OS="${OS%-dynu}"
if [ -n "$DYNU_API_KEY" ]; then
echo "Creating Dynu domains for $OS..."
add-dynu-domain "$ALIAS"
add-dynu-domain "wild-$ALIAS"
else
echo "Warning: DYNU_API_KEY not set, skipping domain creation"
fi
elif [[ "$OS" == *"acmedns"* ]]; then
ALIAS="${REPO}${OS}-getssl.freeddns.org"
STAGING="--env STAGING=true --env dynamic_dns=acmedns"
GETSSL_OS="${OS%-acmedns}"
if [ -n "$DYNU_API_KEY" ]; then
echo "Creating Dynu domains for $OS..."
add-dynu-domain "$ALIAS"
add-dynu-domain "wild-$ALIAS"
add-dynu-cname "_acme-challenge" "$ALIAS" "${ACMEDNS_SUBDOMAIN}.auth.acme-dns.io"
add-dynu-cname "_acme-challenge" "wild-$ALIAS" "${ACMEDNS_SUBDOMAIN}.auth.acme-dns.io"
else
echo "Warning: DYNU_API_KEY not set, skipping domain creation"
fi
elif [[ "$OS" == "bash"* ]]; then
GETSSL_OS="alpine"
fi
@ -77,6 +168,9 @@ docker run $INT\
--env GITHUB_REPOSITORY="${GITHUB_REPOSITORY}" \
--env DUCKDNS_TOKEN="${DUCKDNS_TOKEN}" \
--env DYNU_API_KEY="${DYNU_API_KEY}" \
--env ACMEDNS_API_KEY="${ACMEDNS_API_KEY}" \
--env ACMEDNS_API_USER="${ACMEDNS_API_USER}" \
--env ACMEDNS_SUBDOMAIN="${ACMEDNS_SUBDOMAIN}" \
-v "$(pwd)":/getssl \
--rm \
--network ${PWD##*/}_acmenet \
@ -97,3 +191,4 @@ docker run $INT\
--name "getssl-$OS" \
"getssl-$OS" \
$COMMAND

+ 1
- 1
test/test_helper.bash View File

@ -166,7 +166,7 @@ GETSSL_CMD_HOST=$GETSSL_HOST
export GETSSL_CMD_HOST
if [ -z "$STAGING" ] && [ ! -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
wget --quiet --no-clobber https://raw.githubusercontent.com/letsencrypt/pebble/main/test/certs/pebble.minica.pem 2>&1
CERT_FILE=/etc/ssl/certs/ca-certificates.crt
if [ ! -f $CERT_FILE ]; then
CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt


Loading…
Cancel
Save