83 lines
2.3 KiB
Nix
83 lines
2.3 KiB
Nix
# LAN DHCP (Kea) and DNS (Blocky). Fully declarative: one Kea subnet per VLAN
|
|
# with dhcp.enable, Blocky as the blocklist resolver every DHCP lease points
|
|
# at. Blocky's HTTP listener (:4000) serves Prometheus metrics, scraped by
|
|
# control over the mesh (firewall.nix scopes it to the mesh subnet).
|
|
{ settings }:
|
|
{ lib, ... }:
|
|
let
|
|
cfg = settings;
|
|
dhcpVlans = lib.filterAttrs (_: vlan: vlan.dhcp.enable) cfg.vlans;
|
|
in
|
|
{
|
|
services.kea.dhcp4 = {
|
|
enable = true;
|
|
settings = {
|
|
interfaces-config.interfaces = lib.mapAttrsToList (name: _: "vlan-${name}") dhcpVlans;
|
|
lease-database = {
|
|
type = "memfile";
|
|
persist = true;
|
|
name = "/var/lib/kea/dhcp4.leases";
|
|
};
|
|
valid-lifetime = 86400;
|
|
subnet4 = lib.mapAttrsToList (name: vlan: {
|
|
id = vlan.id;
|
|
subnet = vlan.subnet;
|
|
interface = "vlan-${name}";
|
|
valid-lifetime = vlan.dhcp.leaseTime;
|
|
pools = [ { pool = "${vlan.dhcp.pool.from} - ${vlan.dhcp.pool.to}"; } ];
|
|
reservations = lib.mapAttrsToList (host: res: {
|
|
hostname = host;
|
|
hw-address = res.hwAddress;
|
|
ip-address = res.ipAddress;
|
|
}) vlan.dhcp.reservations;
|
|
option-data = [
|
|
{
|
|
name = "routers";
|
|
data = vlan.address;
|
|
}
|
|
{
|
|
name = "domain-name-servers";
|
|
data = vlan.address;
|
|
}
|
|
];
|
|
}) dhcpVlans;
|
|
};
|
|
};
|
|
|
|
services.blocky = {
|
|
enable = true;
|
|
settings = {
|
|
ports = {
|
|
dns = 53;
|
|
http = 4000;
|
|
};
|
|
upstreams.groups.default = [
|
|
"9.9.9.9"
|
|
"149.112.112.112"
|
|
"2620:fe::fe"
|
|
];
|
|
blocking = {
|
|
denylists.ads = [
|
|
"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
|
|
];
|
|
clientGroupsBlock.default = [ "ads" ];
|
|
};
|
|
caching = {
|
|
minTime = "5m";
|
|
prefetching = true;
|
|
};
|
|
prometheus.enable = true;
|
|
};
|
|
};
|
|
|
|
# The router itself resolves via public resolvers, not via Blocky, so DNS
|
|
# for deploys/updates survives a broken local resolver. networkd would
|
|
# enable systemd-resolved by default, whose stub listener on 127.0.0.53:53
|
|
# makes Blocky's wildcard :53 bind fail — plain resolv.conf instead.
|
|
services.resolved.enable = false;
|
|
networking.nameservers = [
|
|
"9.9.9.9"
|
|
"1.1.1.1"
|
|
];
|
|
}
|