feat(mercury): AdGuard Home DNS adblock + DHCP, forwards to unbound
- services/adguardhome.nix: upstream unbound, .sol local domain, DHCP 50-200 - nix-owned config (mutableSettings=false); adlists + dns declared - mercury imports adguard + unbound; drop the pick-one placeholder block - TODO: bcrypt admin password, jupiter static lease via UI (needs its MAC)
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
imports = [
|
imports = [
|
||||||
../../common.nix # shared base: user / ssh / nix / firewall
|
../../common.nix # shared base: user / ssh / nix / firewall
|
||||||
../../services/unbound.nix # local recursive resolver (127.0.0.1:5335)
|
../../services/unbound.nix # local recursive resolver (127.0.0.1:5335)
|
||||||
# ../../services/<dns>.nix # add once the adblock DNS engine is chosen (below)
|
../../services/adguardhome.nix # DNS adblock + DHCP, forwards to unbound
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.hostName = "mercury";
|
networking.hostName = "mercury";
|
||||||
@@ -22,29 +22,12 @@
|
|||||||
];
|
];
|
||||||
# VERIFY with `ip route` on the Pi — assuming the router is .1.
|
# VERIFY with `ip route` on the Pi — assuming the router is .1.
|
||||||
networking.defaultGateway = { address = "10.0.0.1"; interface = "eth0"; };
|
networking.defaultGateway = { address = "10.0.0.1"; interface = "eth0"; };
|
||||||
# Upstream resolvers for the box itself (the adblock DNS forwards to these).
|
# Resolvers for the Pi's OWN lookups (not the LAN service). Kept public so the
|
||||||
|
# host resolves during boot without depending on its own AdGuard/unbound.
|
||||||
networking.nameservers = [ "1.1.1.1" "9.9.9.9" ];
|
networking.nameservers = [ "1.1.1.1" "9.9.9.9" ];
|
||||||
|
|
||||||
# ---- DNS + adblock + DHCP — pick ONE, then open its ports below ----
|
# DNS adblock + DHCP (AdGuard) and the recursive resolver (unbound) come from
|
||||||
#
|
# the imported service modules. AdGuard forwards to unbound at 127.0.0.1:5335.
|
||||||
# Option A: pihole (native module)
|
|
||||||
# services.pihole-ftl = {
|
|
||||||
# enable = true;
|
|
||||||
# # dhcp, lists, upstreams, local records...
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# Option B: AdGuard Home (native module, fully declarative)
|
|
||||||
# services.adguardhome = {
|
|
||||||
# enable = true;
|
|
||||||
# settings = {
|
|
||||||
# dns.upstream_dns = [ "1.1.1.1" "9.9.9.9" ];
|
|
||||||
# # filters (adlists), rewrites (local DNS), dhcp static leases...
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# Then open the ports this service needs:
|
|
||||||
# networking.firewall.allowedTCPPorts = [ 53 80 ]; # DNS + web UI
|
|
||||||
# networking.firewall.allowedUDPPorts = [ 53 67 ]; # DNS + DHCP
|
|
||||||
|
|
||||||
# Do not modify after first flash.
|
# Do not modify after first flash.
|
||||||
system.stateVersion = "26.05";
|
system.stateVersion = "26.05";
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
{ ... }:
|
||||||
|
|
||||||
|
# AdGuard Home — network DNS (adblock) + DHCP.
|
||||||
|
# Forwards to the local unbound recursive resolver (services/unbound.nix).
|
||||||
|
# Config is nix-owned (mutableSettings = false): the web UI can view but not
|
||||||
|
# persist changes — edit here and redeploy. EXCEPTION: DHCP static leases live
|
||||||
|
# in AdGuard's separate leases.json, so add those in the UI (they persist).
|
||||||
|
{
|
||||||
|
services.adguardhome = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true; # opens the web + DNS ports
|
||||||
|
mutableSettings = false; # AdGuardHome.yaml is authoritative from nix
|
||||||
|
# allowDHCP is implied by settings.dhcp.enabled (grants NET_RAW/NET_BIND).
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
# Web UI on :3000. Admin login — replace with YOUR bcrypt hash:
|
||||||
|
# nix run nixpkgs#apacheHttpd -- htpasswd -B -n -b admin 'yourpassword'
|
||||||
|
# (take the part after "admin:"). For repo hygiene, move this to sops later.
|
||||||
|
http.address = "0.0.0.0:3000";
|
||||||
|
users = [
|
||||||
|
{ name = "admin"; password = "$2y$10$REPLACE-WITH-BCRYPT-HASH"; }
|
||||||
|
];
|
||||||
|
|
||||||
|
dns = {
|
||||||
|
bind_hosts = [ "0.0.0.0" ];
|
||||||
|
port = 53;
|
||||||
|
# Recursive resolution via local unbound — no public upstream.
|
||||||
|
upstream_dns = [ "127.0.0.1:5335" ];
|
||||||
|
bootstrap_dns = [ "1.1.1.1" "9.9.9.9" ];
|
||||||
|
upstream_mode = "load_balance";
|
||||||
|
};
|
||||||
|
|
||||||
|
filtering.filtering_enabled = true;
|
||||||
|
filters = [
|
||||||
|
{
|
||||||
|
enabled = true;
|
||||||
|
id = 1;
|
||||||
|
name = "AdGuard DNS filter";
|
||||||
|
url = "https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
enabled = true;
|
||||||
|
id = 2;
|
||||||
|
name = "AdAway Default Blocklist";
|
||||||
|
url = "https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
# ---- DHCP (replaces pihole's) ----
|
||||||
|
dhcp = {
|
||||||
|
enabled = true;
|
||||||
|
interface_name = "eth0";
|
||||||
|
local_domain_name = "sol"; # clients resolve as <host>.sol
|
||||||
|
dhcpv4 = {
|
||||||
|
gateway_ip = "10.0.0.1";
|
||||||
|
subnet_mask = "255.255.255.0";
|
||||||
|
range_start = "10.0.0.50";
|
||||||
|
range_end = "10.0.0.200";
|
||||||
|
lease_duration = 86400;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# Static lease: add jupiter (10.0.0.20) via the UI once — persists in
|
||||||
|
# leases.json. Needs jupiter's eth MAC (`ip link` on jupiter).
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedUDPPorts = [ 67 ]; # DHCP (DNS/web via openFirewall)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user