From 9b5c2e1994a1075e6ea421181f1b11179d062d2c Mon Sep 17 00:00:00 2001 From: Dmitrii Iurco Date: Sun, 7 Jun 2026 03:41:19 -0400 Subject: [PATCH] fix: ensure DNS zone changes take effect immediately on startup Three related issues prevented CoreDNS from serving updated zone records: 1. The `file` plugin blocks in generate_corefile() lacked a `reload` option, so CoreDNS never re-read zone files after they were written. Added `reload 30s` so zone file changes are picked up within 30s. 2. _reload_dns_service() sent SIGHUP via `docker exec ... kill -HUP 1`, which doesn't trigger zone reloads. Changed to SIGUSR1 via `docker kill --signal=SIGUSR1` (same as firewall_manager.reload_coredns). 3. _bootstrap_dns() wrote the zone file but never regenerated the Corefile. CoreDNS's reload plugin only fires when the Corefile changes, so zone records from startup were invisible until the next peer modification triggered apply_all_dns_rules(). Now _bootstrap_dns() always calls apply_all_dns_rules() after the zone write. Co-Authored-By: Claude Sonnet 4.6 --- api/app.py | 5 +++++ api/firewall_manager.py | 4 ++-- api/network_manager.py | 6 +++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/api/app.py b/api/app.py index 0c49e38..6f59d75 100644 --- a/api/app.py +++ b/api/app.py @@ -416,6 +416,11 @@ def _bootstrap_dns(): 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) + # Regenerate the Corefile so any new zone blocks or reload options take + # effect immediately without waiting for the next peer modification. + firewall_manager.apply_all_dns_rules( + peer_registry.list_peers(), COREFILE_PATH, domain, + cell_links=cell_link_manager.list_connections()) except Exception as e: logger.warning(f"DNS bootstrap failed (non-fatal): {e}") diff --git a/api/firewall_manager.py b/api/firewall_manager.py index f315402..c4aa9ad 100644 --- a/api/firewall_manager.py +++ b/api/firewall_manager.py @@ -739,7 +739,7 @@ def generate_corefile(peers: List[Dict[str, Any]], corefile_path: str = COREFILE acl_block = _build_acl_block(blocked, domain) - primary_zone_block = f'{domain} {{\n file /data/{domain}.zone\n log\n' + primary_zone_block = f'{domain} {{\n file /data/{domain}.zone reload 30s\n log\n' if acl_block: primary_zone_block += acl_block + '\n' primary_zone_block += '}\n' @@ -760,7 +760,7 @@ def generate_corefile(peers: List[Dict[str, Any]], corefile_path: str = COREFILE for sz in split_horizon_zones: corefile += ( f'\n{sz} {{\n' - f' file /data/{sz}.zone\n' + f' file /data/{sz}.zone reload 30s\n' f' log\n' f'}}\n' ) diff --git a/api/network_manager.py b/api/network_manager.py index 8a6d7df..d9324a5 100644 --- a/api/network_manager.py +++ b/api/network_manager.py @@ -453,10 +453,10 @@ class NetworkManager(BaseServiceManager): return {'running': False, 'stats': {}} def _reload_dns_service(self): - """Reload DNS service""" + """Send SIGUSR1 to CoreDNS so the reload plugin picks up zone file changes.""" try: - subprocess.run(['docker', 'exec', 'cell-dns', 'kill', '-HUP', '1'], - capture_output=True, timeout=10) + subprocess.run(['docker', 'kill', '--signal=SIGUSR1', 'cell-dns'], + capture_output=True, timeout=10) except Exception as e: logger.error(f"Failed to reload DNS service: {e}")