Fix three DNS corruption bugs in DDNS/non-LAN mode
Unit Tests / test (push) Successful in 11m30s

apply_cell_name() now skips multi-label zone files (split-horizon DDNS
zones like pic2.pic.ngo.zone) and excludes '*' and '@' from hostname
candidate detection, preventing the wildcard record from being renamed
to the old cell name during a cell rename.

update_split_horizon_zone() now deletes stale zone files from previous
cell names sharing the same TLD (e.g. pic3.pic.ngo.zone when renaming
to pic2.pic.ngo), eliminating orphaned DNS entries.

_bootstrap_dns() now detects non-LAN domain modes and calls
update_split_horizon_zone() instead of apply_ip_range(), preventing
service records (api, calendar, files…) from being re-injected into
the DDNS parent zone on every container restart.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-28 05:56:00 -04:00
parent 66500bb128
commit b16189d00f
3 changed files with 197 additions and 33 deletions
+14 -2
View File
@@ -390,8 +390,20 @@ def _bootstrap_dns():
cell_name = identity.get('cell_name', os.environ.get('CELL_NAME', 'mycell'))
domain = identity.get('domain', os.environ.get('CELL_DOMAIN', 'cell'))
ip_range = identity.get('ip_range', os.environ.get('CELL_IP_RANGE', '172.20.0.0/16'))
# Bootstrap on first start; then always regenerate to ensure A records use WG server IP.
network_manager.apply_ip_range(ip_range, cell_name, domain)
domain_mode = identity.get('domain_mode', 'lan')
if domain_mode == 'lan':
# LAN mode: write full service records into the primary local zone.
network_manager.apply_ip_range(ip_range, cell_name, domain)
else:
# Non-LAN mode (DDNS/ACME): ensure the split-horizon zone is present so
# LAN clients resolve service subdomains to the internal Caddy IP.
# Never call apply_ip_range here — it would pollute the DDNS parent zone.
effective_domain = config_manager.get_effective_domain()
if effective_domain and effective_domain != domain:
import ip_utils
caddy_ip = ip_utils.get_service_ips(ip_range).get('caddy', '172.20.0.2')
network_manager.update_split_horizon_zone(
effective_domain, caddy_ip, primary_domain=domain)
except Exception as e:
logger.warning(f"DNS bootstrap failed (non-fatal): {e}")