From d7ce37c102710e49c7a333a7734551521c5d15ac Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Mon, 30 Mar 2026 13:29:15 +0200 Subject: [PATCH 1/2] Test loading of a signed zone with a CNAME at the apex. (resolves #427) The old zone loader / apex zone code couldn't handle this. --- integration-tests/system-tests.yml | 10 ++ .../tests/load-signed-apex-cname/action.yml | 102 ++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 integration-tests/tests/load-signed-apex-cname/action.yml diff --git a/integration-tests/system-tests.yml b/integration-tests/system-tests.yml index 6cf0a4a0..ee33f031 100644 --- a/integration-tests/system-tests.yml +++ b/integration-tests/system-tests.yml @@ -216,3 +216,13 @@ jobs: - uses: ./integration-tests/tests/remove-zone with: log-level: ${{ inputs.log-level }} + + load-signed-apex-cname: + name: + runs-on: ubuntu-latest + strategy: + matrix: + rust: [stable] + steps: + - uses: actions/checkout@v4 + - uses: ./integration-tests/tests/load-signed-apex-cname diff --git a/integration-tests/tests/load-signed-apex-cname/action.yml b/integration-tests/tests/load-signed-apex-cname/action.yml new file mode 100644 index 00000000..43069a2c --- /dev/null +++ b/integration-tests/tests/load-signed-apex-cname/action.yml @@ -0,0 +1,102 @@ +# Making reusable composite actions documented at +# https://docs.github.com/en/actions/tutorials/create-actions/create-a-composite-action#creating-a-composite-action-within-the-same-repository +name: 'Load a zonefile containing a signed apex CNAME' +description: 'Load a zonefile containing a signed apex CNAME' +defaults: + # see: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#defaultsrunshell + run: + shell: bash --noprofile --norc -eo pipefail -x {0} +inputs: + log-level: + description: The level of logging that Cascade should output. + required: false + default: debug + type: choice + options: + - error + - warning + - info + - debug + - trace +runs: + using: "composite" + steps: + #- uses: ./.github/actions/prepare-systest-env + - uses: ./.github/actions/setup-and-start-cascade + with: + log-level: ${{ inputs.log-level }} + + - name: Add a 'counter' policy + run: | + POLICY_DIR=$(integration-tests/scripts/get-default-path.sh policy-dir) + cascade template policy > "${POLICY_DIR}/counter.toml" + # Change the policy to use the 'counter' serial policy. + sed -i -e 's|^serial-policy = .\+|serial-policy = "counter"|' ${POLICY_DIR}/counter.toml + # Tell Cascade to load our new counter olicy. + cascade policy reload + + - name: Make an unsigned zonefile + run: | + tee example.test.zone <<'EOF' + $TTL 5 + example.test. IN SOA ns1.example.test. mail.example.test. ( + 1 ; serial + 60 ; refresh (60 seconds) + 60 ; retry (60 seconds) + 3600 ; expire (1 hour) + 5 ; minimum (5 seconds) + ) + @ NS example.test. + @ NS ns1.example.test. + @ A 127.0.0.1 + ns1 A 127.0.0.1 + + www A 169.254.1.1 + mail MX 10 example.test. + text TXT "Hello World!" + + ; For https://github.com/NLnetLabs/cascade/issues/427 + cname CNAME nlnetlabs.nl. + EOF + + - name: Add the new unsigned zonefile using our 'counter' policy + run: | + cascade zone add --policy counter --source $PWD/example.test.zone example.test + + - name: Wait for zone serial 1 to be published + run: | + timeout=10 # seconds + start=$(date +%s) + until cascade zone status example.test | grep -q "Published version 1"; do + if (($(date +%s) > (start + timeout))); then + cascade zone status example.test + echo "timeout: zone status did not report published serial 1 available" >&2 + exit 1 + fi + sleep 1 + done + + - name: Overwrite the input zone with the signed zone + run: | + dig +noall +answer +onesoa @127.0.0.1 -p 4543 example.test AXFR > $PWD/example.test.zone + + - name: Reload the now signed zone + run: | + cascade zone reload example.test + + - name: Wait for zone serial 2 to be published + run: | + timeout=10 # seconds + start=$(date +%s) + until cascade zone status example.test | grep -q "Published version 2"; do + if (($(date +%s) > (start + timeout))); then + cascade zone status example.test + echo "timeout: zone status did not report published serial 2 available" >&2 + exit 1 + fi + sleep 1 + done + + - name: Print log files on any failure in this job + uses: ./.github/actions/print-logfiles + if: failure() From fad8e9bc83bbb99c9d7ee941b82ae39b621c1b07 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Mon, 30 Mar 2026 13:51:50 +0200 Subject: [PATCH 2/2] Simplify the test. By using a pre-signed zone as input. --- .../load-signed-apex-cname/example.test.zone | 14 ++++ .../tests/load-signed-apex-cname/action.yml | 66 ++----------------- 2 files changed, 21 insertions(+), 59 deletions(-) create mode 100644 integration-tests/load-signed-apex-cname/example.test.zone diff --git a/integration-tests/load-signed-apex-cname/example.test.zone b/integration-tests/load-signed-apex-cname/example.test.zone new file mode 100644 index 00000000..c89d9040 --- /dev/null +++ b/integration-tests/load-signed-apex-cname/example.test.zone @@ -0,0 +1,14 @@ +example.test. 5 IN SOA ns1.example.test. mail.example.test. 2026033000 60 60 3600 5 +example.test. 5 IN NS example.test. +example.test. 5 IN NS ns1.example.test. +example.test. 3600 IN RRSIG DNSKEY 13 2 3600 20260413114923 20260329114923 45183 example.test. V7x/78Nnl5CE638nclvTbEpZkHXG10YQ/8ZeM6rQPbboQ8qKkw6hiB61 gG/qK3DPcDVSgAQoy/Q+jCzdA26+/A== +example.test. 5 IN RRSIG NSEC 13 2 5 20260413114923 20260329114923 58227 example.test. ijvwb5F9cTLQGyRn+qMaAhaumYolU47CZOsLLmL0BZpRWtj3ACG7zfmQ yEY9ZqzbLw5TkzR0DxvnNbEugR93mg== +example.test. 5 IN RRSIG SOA 13 2 5 20260413114923 20260329114923 58227 example.test. zKi74SYUJ9wppn5NAllR3iIUwBuMFEYucyX5RQp0ym+CUdm39b6l8zeW 47EdX6ObU1HGVdMGqlN2+8Gv9Rks4g== +example.test. 5 IN RRSIG NS 13 2 5 20260413114923 20260329114923 58227 example.test. DsiNh0onbIOYxxt7Ue3ypgV5RR5JQ05WC/r+bd2aImQz7iRgb/dIUXgv VTXOzMNasO2iSFKi6e8q82uS8PqlCQ== +example.test. 3600 IN DNSKEY 257 3 13 iKHfcKwR2R+o+qtzK06SvmD8nWuJwvS3dJQHD7I/r3R6dj+0lrB889V0 0X0m6s74g0g1je2gBB9jc6W5ETgi2Q== +example.test. 3600 IN DNSKEY 256 3 13 z//8PEhbP9uJMaWIGqLcjfv5V+67VUFBZpTTVnQAmBn+V8Ln9ADzAhLk 6oBTfIZLpLOXMuP9Sfv+hXZqGjFWEw== +example.test. 5 IN NSEC cname.example.test. NS SOA RRSIG NSEC DNSKEY +cname.example.test. 5 IN RRSIG NSEC 13 3 5 20260413114923 20260329114923 58227 example.test. N6K4dyRAig3Pmm4vublYQbs6uIYcBl9iQ6TKlyH8C5Z0viEwcQ9nwe7m 1oN+ki2ESE0UrJQL5RIXeftAH8ylMA== +cname.example.test. 5 IN RRSIG CNAME 13 3 5 20260413114923 20260329114923 58227 example.test. moIDfx3j1INEaIeaBYXY5TMJ+x9h7fVh3vgA3Y7vXhxKFwTLeQwP6PK5 cRJHMU3qyP6sRABPYMLxjCefFccYDw== +cname.example.test. 5 IN CNAME nlnetlabs.nl. +cname.example.test. 5 IN NSEC example.test. CNAME RRSIG NSEC diff --git a/integration-tests/tests/load-signed-apex-cname/action.yml b/integration-tests/tests/load-signed-apex-cname/action.yml index 43069a2c..e55a1eb9 100644 --- a/integration-tests/tests/load-signed-apex-cname/action.yml +++ b/integration-tests/tests/load-signed-apex-cname/action.yml @@ -26,72 +26,20 @@ runs: with: log-level: ${{ inputs.log-level }} - - name: Add a 'counter' policy + - name: Add the zone run: | - POLICY_DIR=$(integration-tests/scripts/get-default-path.sh policy-dir) - cascade template policy > "${POLICY_DIR}/counter.toml" - # Change the policy to use the 'counter' serial policy. - sed -i -e 's|^serial-policy = .\+|serial-policy = "counter"|' ${POLICY_DIR}/counter.toml - # Tell Cascade to load our new counter olicy. - cascade policy reload + INTEGRATION_TEST_DIR="${PWD}/integration-tests/load-signed-apex-cname" + cp "${INTEGRATION_TEST_DIR}/example.test.zone" /tmp/ + cascade zone add --policy default --source /tmp/example.test.zone example.test - - name: Make an unsigned zonefile - run: | - tee example.test.zone <<'EOF' - $TTL 5 - example.test. IN SOA ns1.example.test. mail.example.test. ( - 1 ; serial - 60 ; refresh (60 seconds) - 60 ; retry (60 seconds) - 3600 ; expire (1 hour) - 5 ; minimum (5 seconds) - ) - @ NS example.test. - @ NS ns1.example.test. - @ A 127.0.0.1 - ns1 A 127.0.0.1 - - www A 169.254.1.1 - mail MX 10 example.test. - text TXT "Hello World!" - - ; For https://github.com/NLnetLabs/cascade/issues/427 - cname CNAME nlnetlabs.nl. - EOF - - - name: Add the new unsigned zonefile using our 'counter' policy - run: | - cascade zone add --policy counter --source $PWD/example.test.zone example.test - - - name: Wait for zone serial 1 to be published - run: | - timeout=10 # seconds - start=$(date +%s) - until cascade zone status example.test | grep -q "Published version 1"; do - if (($(date +%s) > (start + timeout))); then - cascade zone status example.test - echo "timeout: zone status did not report published serial 1 available" >&2 - exit 1 - fi - sleep 1 - done - - - name: Overwrite the input zone with the signed zone - run: | - dig +noall +answer +onesoa @127.0.0.1 -p 4543 example.test AXFR > $PWD/example.test.zone - - - name: Reload the now signed zone - run: | - cascade zone reload example.test - - - name: Wait for zone serial 2 to be published + - name: Wait for zone to be published run: | timeout=10 # seconds start=$(date +%s) - until cascade zone status example.test | grep -q "Published version 2"; do + until cascade zone status example.test | grep -q "Published version"; do if (($(date +%s) > (start + timeout))); then cascade zone status example.test - echo "timeout: zone status did not report published serial 2 available" >&2 + echo "timeout: zone status did not report published zone available" >&2 exit 1 fi sleep 1