Skip to content

fix(ingress): check CAA before issuing when SET_CAA is off - #166

Closed
kvinwang wants to merge 1 commit into
mainfrom
fix/ingress-caa-precheck
Closed

kvinwang wants to merge 1 commit into
mainfrom
fix/ingress-caa-precheck

Conversation

@kvinwang

@kvinwang kvinwang commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Why

With SET_CAA=false, plain dns-01 never checked CAA before asking the CA. A CAA that refuses this account — left pinned to a previous account by an earlier SET_CAA=true run (the account changes when /etc/letsencrypt is lost or ACME_STAGING/ACME_DIRECTORY_URL switches), or the operator's own record naming another CA — refused every attempt. Each one spent one of Let's Encrypt's 5 failed validations per hostname per hour, and the container never fixes the record itself.

What

  • dnsguide.py --caa-only: one-shot run of the existing check_caa (walks up to the governing CAA set, checks issuer, validationmethods and accounturi). Exits 3 only when CAA forbids issuance; anything else (unreadable DNS, a crash) leaves the decision to the CA.
  • dns01.sh: with SET_CAA off (non-delegation), check before certman.py and fail the pass with a clear message. SET_CAA=true and delegation are unchanged: there the container replaces the record itself.
  • A fresh account has no URI yet, so an accounturi pin is caught from its second pass on.
  • README rows for SET_CAA and DOH_RESOLVERS; a TESTING.md negative-path row.

Tests

  • New TestCaaOnly (pinned to another account → 3, inherited other CA for a wildcard → 3, no CAA → 0, resolver failure → 0); 78 unit tests pass.
  • Against public DNS: www.google.com → 3 ("issue allows 'pki.goog'"), *.github.com and example.com → 0.
  • process_domain stubbed with SET_CAA=false: check exit 0 or 1 → issues; 3 → fails the pass without calling certman.

With SET_CAA=false plain dns-01 never looked at CAA before asking the
CA. A CAA record that refuses this account -- one an earlier
SET_CAA=true run pinned to a previous account, after the account
changed, or the operator's own record naming another CA -- then refused
every attempt, each spending one of Let's Encrypt's five failed
validations per hostname per hour, and nothing in the container would
ever fix it.

Check the CAA in force first with dnsguide's existing check_caa (new
--caa-only) and fail the pass with a clear message instead. DNS that
cannot be read does not block. A fresh account has no URI yet, so an
accounturi pin can only be caught from its second pass on. With
SET_CAA=true the stale record is the container's own to replace, so
that path is unchanged.

Signed-off-by: Kevin Wang <wy721@qq.com>
@kvinwang
kvinwang force-pushed the fix/ingress-caa-precheck branch from ed407d4 to cb516ab Compare October 16, 2026 02:34
@kvinwang

Copy link
Copy Markdown
Collaborator Author

Superseded: CAA handling is being made uniform across modes (register first, publish, check, issue once) in a follow-up PR.

@kvinwang kvinwang closed this Oct 16, 2026
@kvinwang
kvinwang deleted the fix/ingress-caa-precheck branch October 16, 2026 02:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant