Apply auto-delegation across all of a users' domains (so far only LPS) - #1253
Draft
peterthomassen wants to merge 11 commits into
Draft
peterthomassen wants to merge 11 commits into
peterthomassen wants to merge 11 commits into
Conversation
DomainManager.parent_zone(name, exclude=()) returns the closest ancestor domain that exists in the database, based on filter_qname(); the Domain.parent_zone property applies it to a domain instance and does not cache the result. (cherry picked from commit dbb0360fbad9e8e6875180a1c693fd57402705b5)
…ic suffix Domain.is_registrable() now returns False if the closest ancestor domain lies below the domain's public suffix and that public suffix is local, so that no subdomain of a domain such as example.dedyn.io can be registered by anyone. This prevents circumventing the restrictions that apply to domains delegated from a local public suffix. (cherry picked from commit f78fcd928ad7c29f28077e4c2584461488e4a1c4)
Domain.is_locally_registrable is now based on the closest ancestor domain instead of the literal parent name, so that domains like a.b.dedyn.io (with no b.dedyn.io registered) are covered by the REGISTER_LPS suspension, by the blocked subnet check for A records, and by the FRESH renewal state. Domain.update_delegation() accepts such domains as children, the domain views look up the delegating domain via Domain.parent_zone, and the now unused Domain.parent_domain_name is removed.
Domain.update_delegation() is replaced by add_delegation()/remove_delegation() on the delegating domain, which add and subtract our NS records and the child's DS records (Domain.ds_contents) instead of rebuilding both RRsets, and drop the DS RRset when no NS records remain. Domain.delegation_parent, Domain.auto_delegate(), Domain.delegation_state() and Domain.auto_undelegate() are the entry points used by the domain views, the account activation view and the scavenge-unused command; a domain's DS records are read before it is deleted, and Domain._partitioned_name goes away with update_delegation().
Domain.delegation_parent now also accepts the closest ancestor domain when it belongs to the same account, so that creating a domain adds NS and DS records to it and deleting the domain removes them again. Domain.delegation_error() reports a CNAME RRset at the delegation point or an overlong delegation point name, which DomainSerializer.validate_name() turns into a 400 response with code delegation_impossible.
…pears Domain.delegated_children() lists the domains a domain delegates, i.e. its descendants with no other domain in between, whoever owns that one. Domain.auto_delegate() now takes their delegations over from the domain that delegated them before, and Domain.delegation_state()/auto_undelegate() hand them to the next domain up when the domain delegating them is deleted. A zonefile with a CNAME record at the delegation point of a domain that would be taken over is rejected by DomainSerializer, as it would otherwise leave the new domain created but undelegated.
manage.py fix-auto-delegations reports delegations that are missing at a domain's delegating domain, and NS/DS records that carry our nameservers but no longer belong to a domain delegated there. It considers all domains unless domain names are given, in which case each name is taken both as a delegating and as a delegated domain, and performs the changes only with --apply.
The domain management docs gain an "Automatic Delegation" section covering which domains we delegate, how the records follow when a domain in between is created or deleted, and what having foreign NS/DS records at the delegation point means; the NS record notes in the RRset docs link to it. DomainSetup.vue now asks the domains endpoint for the parent name via owns_qname instead of matching the domain name against the local public suffixes only.
…me alone Domain.is_under_local_public_suffix tests the domain name against settings.LOCAL_PUBLIC_SUFFIXES without consulting the database, and now decides the blocked subnet check for A records, the lock on NS record modification and the FRESH renewal state instead of is_locally_registrable, which registering a domain in between can turn off.
RRset.clean_records() rejects NS RRsets whose subname starts with an asterisk, as the behavior of wildcard NS records in conjunction with DNSSEC is undefined (RFC 4592, Sec. 4.2), and fix-auto-delegations skips them, as a wildcard can never be a delegation point; the RRset docs say so instead of discouraging them.
peterthomassen
force-pushed
the
20260820_auto_delegation
branch
from
September 1, 2026 10:44
7ab951c to
2f851e5
Compare
Describes how auto-delegation grows from direct children of a local public suffix to any domain whose closest existing ancestor is owned by the same account: the ancestor lookup, the restrictions that follow a name below an LPS, record-level maintenance of NS and DS at the delegation point, re-parenting when a domain in between appears or disappears, the fix-auto-delegations command, and the tests and rollout checks per step.
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.
No description provided.