feat(kerberos): honour DNS SRV port and fail over across multiple KDCs#698
Draft
Richard Markiewicz (thenextman) wants to merge 1 commit into
Draft
feat(kerberos): honour DNS SRV port and fail over across multiple KDCs#698Richard Markiewicz (thenextman) wants to merge 1 commit into
Richard Markiewicz (thenextman) wants to merge 1 commit into
Conversation
Copilot started reviewing on behalf of
Richard Markiewicz (thenextman)
June 24, 2026 14:41
View session
There was a problem hiding this comment.
Pull request overview
This PR enhances the Kerberos KDC discovery + transport path to (a) honor DNS SRV-provided ports, (b) return and iterate across multiple KDC candidates for failover, and (c) add per-realm KDC “stickiness” within an authentication exchange to reduce re-resolution churn and improve resilience.
Changes:
- Add
detect_kdc_urls()(multi-candidate) alongside existing single-candidate helpers, and thread multi-KDC selection into the send path. - Extend krb5.conf parsing to preserve multiple
kdc =entries for a realm (in order). - Update DNS SRV resolution to retain SRV ports (including Windows
DnsQuery_W), and introduce per-realm KDC caching during Kerberos exchanges.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lib.rs | Re-exports the new multi-candidate KDC resolver API. |
| src/krb.rs | Adds Krb5Conf::get_all_values and tests to support multi-kdc realms. |
| src/kerberos/tests.rs | Updates Kerberos struct construction for the new kdc_cache field. |
| src/kerberos/mod.rs | Implements per-realm KDC pinning + failover logic and adds select_kdc_urls tests. |
| src/kdc.rs | Adds detect_kdc_urls() and uses multi-kdc krb5.conf values on non-Windows. |
| src/dns.rs | Preserves SRV ports and adds srv_records_to_kdc_urls + tests; Windows now walks all SRV records. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+408
to
+412
| fn srv_records_to_kdc_urls(scheme: &str, records: &[(String, u16)]) -> Vec<String> { | ||
| records | ||
| .iter() | ||
| .map(|(target, port)| format!("{scheme}://{}:{port}", target.trim_end_matches('.'))) | ||
| .collect() |
Member
Author
There was a problem hiding this comment.
Documented as a known limitation, not for this PR.
696dadf to
7052bb1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ℹ️ 1. This doesn't come from any specific client issue or concern; it's more of a feature gap that I'd like to close before it becomes an issue and a personal itch to scratch.
ℹ️ 2. Primarily engineered with Claude and dev testing still to be completed.
So, at this point the PR is more to validate the correctness of the approach, underlying code, etc
Issues
detect_kdc_hosts_from_dns_windowshardcoded :88 and read only the first SRV recorddetect_kdc_host().first()), and the send path tried one KDC with no failover if it was down.Changes
DnsQuery_Wresults, filters to SRV records and uses the record'swPort.detect_kdc_urls()returns the full ordered candidate list (DNS SRV / Windows KdcNames / krb5.conf);send_for_realmtries each in order.detect_kdc_url()kept (first candidate) for backward compatibility.Krb5Conf::get_all_valuesreturns every kdc = entry; one-host-per-line.KRB-ERROR, is returned as-is.Decisions
KDC_CONNECT_TIMEOUT).&mut selfand plainHashMap, notRefCell: the generator's futures are +Send, so aRefCell(!Sync) would break the bound.&mutself threaded through all callers without borrow conflicts.self.realmstays the home realm; the per-realm cache is keyed independently, so the home-vs-child KDC decision is preserved.For pinning a KDC across requests, I was unsure what to do here. As I understand it, a message sequence is not tied to a specific KDC i.e. requests in a single exchange can round-robin between different KDCs. It seems an inherent part of the design. However I think we should avoid the lookup on every request if possible.
MIT does a staggered, parallel request (i.e. it tries all KDCs with a stagger and backoff). There's no pinning after successfully talking to a KDC, although the used KDC is passed back to the client in an
outparameter so the client can pin if they desire to. This seems an optimal solution but also has significant complexity.In Windows, as far as I can tell, this is handled in
netlogonrather than the Kerberos client. The documentation says:So it seems Windows supports the spirit of "pinning" to a DC, but it's the OS doing that across the whole machine, not a per-auth context cache on the Kerberos side.
I consider what we have here a reasonable middle-ground; not a faithful copy of MIT or Microsoft but its own thing. There's some complexity overhead, if we wanted to simply drop the pinning and re-resolve on every request it simplifies the code somewhat.