Skip to content

fix(rfc2136): add GSS-TSIG authentication to AXFR zone transfers#6528

Open
carterpewpew wants to merge 1 commit into
kubernetes-sigs:masterfrom
carterpewpew:fix/rfc2136-gss-tsig-axfr
Open

fix(rfc2136): add GSS-TSIG authentication to AXFR zone transfers#6528
carterpewpew wants to merge 1 commit into
kubernetes-sigs:masterfrom
carterpewpew:fix/rfc2136-gss-tsig-axfr

Conversation

@carterpewpew

Copy link
Copy Markdown
Contributor

What does it do ?

Adds GSS-TSIG (Kerberos) authentication to AXFR zone transfers in the rfc2136 provider.

IncomeTransfer() previously skipped all TSIG authentication when gssTsig was enabled, causing AXFR requests to be sent unauthenticated. Servers requiring GSS-TSIG (e.g. Active Directory DNS) rejected these transfers, so Records() returned empty and the controller re-created all records every interval. This mirrors the GSS-TSIG setup already present in SendMessage() into IncomeTransfer(): negotiate Kerberos credentials via KeyData(), set TsigProvider on the dns.Transfer, and sign the AXFR message. The GSS context is cleaned up after the transfer channel is fully drained.

Motivation

Users running --rfc2136-gss-tsig with --rfc2136-tsig-axfr against Active Directory DNS see the controller continuously re-applying all records every interval because AXFR zone transfers fail silently (unauthenticated). This makes --rfc2136-tsig-axfr unusable for GSS-TSIG deployments.

Fixes: #6450

More

  • Yes, this PR title follows Conventional Commits
  • Yes, I added unit tests
  • Yes, I updated end user documentation accordingly

IncomeTransfer() skipped all TSIG authentication when gssTsig was
enabled, causing AXFR requests to be sent unauthenticated. Servers
requiring GSS-TSIG (e.g. Active Directory DNS) rejected these
transfers, so Records() returned empty and the controller re-created
all records every interval.

Mirror the GSS-TSIG setup from SendMessage() into IncomeTransfer():
negotiate Kerberos credentials via KeyData(), set TsigProvider on
the dns.Transfer, and sign the AXFR message. The GSS context is
cleaned up after the transfer channel is fully drained.

Add a spy stub so the GSS-TSIG test verifies List() defers TSIG
setup to IncomeTransfer, and a direct IncomeTransfer test that
exercises the production GSS-TSIG code path.

Signed-off-by: Jathavedhan M <jathavedhan.m@ibm.com>
@kubernetes-prow

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign szuecs for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubernetes-prow
kubernetes-prow Bot requested review from szuecs and vflaux June 29, 2026 03:47
@kubernetes-prow kubernetes-prow Bot added provider Issues or PRs related to a provider needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Jun 29, 2026
@kubernetes-prow

Copy link
Copy Markdown

Hi @carterpewpew. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Tip

We noticed you've done this a few times! Consider joining the org to skip this step and gain /lgtm and other bot rights. We recommend asking approvers on your previous PRs to sponsor you.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@kubernetes-prow kubernetes-prow Bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Jun 29, 2026

@vflaux vflaux left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/ok-to-test

@kubernetes-prow kubernetes-prow Bot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Jun 30, 2026
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 28347292912

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Coverage increased (+0.4%) to 83.218%

Details

  • Coverage increased (+0.4%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 21761
Covered Lines: 18109
Line Coverage: 83.22%
Coverage Strength: 1431.25 hits per line

💛 - Coveralls

@vflaux vflaux left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add tests to fully cover IncomeTransfer()?
Also, could you add a test in List() to cover the case where the first nameserver fails and the next one succeeds?

Comment on lines +271 to +272
t.TsigProvider = handle
m.SetTsig(keyName, tsig.GSS, clockSkew, time.Now().Unix())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
t.TsigProvider = handle
m.SetTsig(keyName, tsig.GSS, clockSkew, time.Now().Unix())
t.TsigProvider = handle
m = m.Copy()
m.SetTsig(keyName, tsig.GSS, clockSkew, time.Now().Unix())

To avoid modifiying the provided dns.Msg.

Comment on lines +265 to 280
if !r.insecure {
if r.gssTsig {
keyName, handle, err := r.KeyData(nameserver)
if err != nil {
return nil, fmt.Errorf("failed to negotiate GSS-TSIG: %w", err)
}
t.TsigProvider = handle
m.SetTsig(keyName, tsig.GSS, clockSkew, time.Now().Unix())
gssCleanup = func() {
handle.DeleteContext(keyName)
handle.Close()
}
} else {
t.TsigSecret = map[string]string{r.tsigKeyName: r.tsigSecret}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we move this right before t.In(m, nameserver) so we don’t need all the gssCleanup() calls in the error paths?

handle.Close() should already be enough, since it cleans up all keys associated with its context

@stelucz

stelucz commented Jul 22, 2026

Copy link
Copy Markdown

when updates are secure and axfr is insecure at AD DNS, external-dns/rfc2136 fails:

level=error msg="AXFR error: dns: no signature found"

there should be an option for this case too, probably #6519 . Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. provider Issues or PRs related to a provider size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rfc2136: External-DNS continuously sends updates to AD DNS despite no changes (GSS-TSIG)

4 participants