IPv6: router.wan.ipv6.enable mirrors the existing uplink config (DHCPv6 with WithoutRA=solicit, delegated prefix). The ISP delegates a single /64, so exactly one LAN may claim it via router.lans.<name>.ipv6.pd (asserted); other LANs stay IPv4-only. SLAAC only, no NAT66. PPPoE: router.wan.ipv4.type = "pppoe" runs pppd on an optional VLAN of the uplink, with the password read from a file at service start (never the Nix store). NAT, forwarding and MSS clamping (MTU 1492) use the derived PPP device; native IPv6 stays on the untagged link. Tests: basic.nix is parameterised by uplink type; the pppoe variant uses a fake ISP with pppoe-server (VLAN 7, CHAP). Both variants cover IPv6 PD, SLAAC, routing without NAT and WAN-deny. Assertion tests gain PD/PPPoE cases and a full-system evaluation step. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
32 lines
745 B
Nix
32 lines
745 B
Nix
{ config, lib, ... }:
|
|
let
|
|
cfg = config.router;
|
|
lans = lib.attrValues cfg.lans;
|
|
in
|
|
{
|
|
config = lib.mkIf cfg.enable {
|
|
services.unbound = {
|
|
enable = true;
|
|
settings = {
|
|
server = {
|
|
interface = [ "127.0.0.1" ] ++ map (l: l.ipv4.address) lans;
|
|
# LAN addresses are assigned by networkd, possibly after Unbound starts.
|
|
ip-freebind = true;
|
|
access-control = [
|
|
"127.0.0.0/8 allow"
|
|
]
|
|
++ map (l: "${l.ipv4.subnet} allow") lans;
|
|
};
|
|
}
|
|
// lib.optionalAttrs (cfg.dns.forwarders != [ ]) {
|
|
forward-zone = [
|
|
{
|
|
name = ".";
|
|
forward-addr = cfg.dns.forwarders;
|
|
}
|
|
];
|
|
};
|
|
};
|
|
};
|
|
}
|