Add local DNS records, DHCP reservations and an installer ISO
DNS and DHCP (needed to replace a dnsmasq-based router): - router.dns.domain/hosts/overrides/forwardZones: authoritative local domain, split-horizon host records with reverse entries, wildcard overrides and per-zone forwarders (private zones skip DNSSEC). - lans.<n>.dhcp.reservations: Kea host reservations, published in DNS. - Tunnels with dns = true admit what their peers route, so a site-to-site peer without a transfer address can use the resolver. Installer: - router-install wipes a disk, creates an ESP and an ext4 root and installs a prebuilt system with its secrets; nothing is built on the box. installed-layout is the shared disk layout contract. - lib.mkInstaller builds an ISO for a given nixosSystem; packages.installer-example is the example's ISO. Covered by the dns and installer VM tests (the latter installs onto an empty disk and boots it under UEFI), wireguard DNS and assertion cases. PLAN.md records the remaining gaps for replacing the hand-written router. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -783,6 +783,163 @@ let
|
||||
};
|
||||
expect = [ "used by both the PPPoE uplink and a LAN" ];
|
||||
};
|
||||
dnsValid = {
|
||||
router = {
|
||||
lans.main = lan {
|
||||
dhcp.reservations = {
|
||||
nas = {
|
||||
mac = "a8:a1:59:0b:4b:97";
|
||||
address = "192.168.10.20";
|
||||
};
|
||||
};
|
||||
};
|
||||
dns = {
|
||||
domain = "home.example.org";
|
||||
hosts = {
|
||||
printer = [ "192.168.10.30" ];
|
||||
"git.example.org" = [
|
||||
"10.43.0.50"
|
||||
"fd00::50"
|
||||
];
|
||||
};
|
||||
overrides."k8s.example.org" = [ "10.43.0.50" ];
|
||||
forwardZones."branch.example.org" = [ "10.1.0.254" ];
|
||||
};
|
||||
};
|
||||
expect = [ ];
|
||||
};
|
||||
dnsShortNoDomain = {
|
||||
router = {
|
||||
lans.main = lan { dhcp.reservations = { }; };
|
||||
dns = {
|
||||
hosts.printer = [ "192.168.10.30" ];
|
||||
};
|
||||
};
|
||||
expect = [ "router.dns.domain must be set" ];
|
||||
};
|
||||
dnsBadName = {
|
||||
router = {
|
||||
lans.main = lan { dhcp.reservations = { }; };
|
||||
dns = {
|
||||
domain = "home.example.org";
|
||||
hosts."bad name" = [ "192.168.10.30" ];
|
||||
};
|
||||
};
|
||||
expect = [ "not a valid DNS name" ];
|
||||
};
|
||||
dnsBadAddress = {
|
||||
router = {
|
||||
lans.main = lan { dhcp.reservations = { }; };
|
||||
dns = {
|
||||
domain = "home.example.org";
|
||||
hosts.x = [ "192.168.10.300" ];
|
||||
};
|
||||
};
|
||||
expect = [ "valid IPv4 or IPv6 address" ];
|
||||
};
|
||||
dnsBadZone = {
|
||||
router = {
|
||||
lans.main = lan { dhcp.reservations = { }; };
|
||||
dns = {
|
||||
forwardZones."a.example.org" = [ ];
|
||||
};
|
||||
};
|
||||
expect = [ "valid resolver address" ];
|
||||
};
|
||||
dnsHostVsReservation = {
|
||||
router = {
|
||||
lans.main = lan {
|
||||
dhcp.reservations = {
|
||||
nas = {
|
||||
mac = "a8:a1:59:0b:4b:97";
|
||||
address = "192.168.10.20";
|
||||
};
|
||||
};
|
||||
};
|
||||
dns = {
|
||||
domain = "home.example.org";
|
||||
hosts.nas = [ "192.168.10.99" ];
|
||||
};
|
||||
};
|
||||
expect = [ "also a DHCP reservation" ];
|
||||
};
|
||||
resBadMac = {
|
||||
router = {
|
||||
lans.main = lan {
|
||||
dhcp.reservations = {
|
||||
nas = {
|
||||
mac = "nonsense";
|
||||
address = "192.168.10.20";
|
||||
};
|
||||
};
|
||||
};
|
||||
dns = { };
|
||||
};
|
||||
expect = [ "is not a MAC address" ];
|
||||
};
|
||||
resOutside = {
|
||||
router = {
|
||||
lans.main = lan {
|
||||
dhcp.reservations = {
|
||||
nas = {
|
||||
mac = "a8:a1:59:0b:4b:97";
|
||||
address = "192.168.99.20";
|
||||
};
|
||||
};
|
||||
};
|
||||
dns = { };
|
||||
};
|
||||
expect = [ "is not inside" ];
|
||||
};
|
||||
resRouterAddress = {
|
||||
router = {
|
||||
lans.main = lan {
|
||||
dhcp.reservations = {
|
||||
nas = {
|
||||
mac = "a8:a1:59:0b:4b:97";
|
||||
address = "192.168.10.1";
|
||||
};
|
||||
};
|
||||
};
|
||||
dns = { };
|
||||
};
|
||||
expect = [ "router's own address" ];
|
||||
};
|
||||
resDuplicates = {
|
||||
router = {
|
||||
lans.main = lan {
|
||||
dhcp.reservations = {
|
||||
a = {
|
||||
mac = "a8:a1:59:0b:4b:97";
|
||||
address = "192.168.10.20";
|
||||
};
|
||||
b = {
|
||||
mac = "A8:A1:59:0B:4B:97";
|
||||
address = "192.168.10.20";
|
||||
};
|
||||
};
|
||||
};
|
||||
dns = { };
|
||||
};
|
||||
expect = [
|
||||
"share a MAC address"
|
||||
"share an address"
|
||||
];
|
||||
};
|
||||
resBadHostname = {
|
||||
router = {
|
||||
lans.main = lan {
|
||||
dhcp.reservations = {
|
||||
"bad name" = {
|
||||
mac = "a8:a1:59:0b:4b:97";
|
||||
address = "192.168.10.20";
|
||||
};
|
||||
};
|
||||
};
|
||||
dns = { };
|
||||
};
|
||||
expect = [ "not a valid hostname" ];
|
||||
};
|
||||
nonOverlappingLans = {
|
||||
router.lans = {
|
||||
a = lan { };
|
||||
@@ -831,6 +988,7 @@ let
|
||||
"wgValid"
|
||||
"wanValid"
|
||||
"sharedLinkValid"
|
||||
"dnsValid"
|
||||
];
|
||||
|
||||
subnet =
|
||||
|
||||
Reference in New Issue
Block a user