nixos-vps/modules/adguard.nix
2026-03-18 21:33:42 +01:00

132 lines
No EOL
3.2 KiB
Nix

# AdGuard Home Module
# Provides: Private DNS-over-HTTPS with ClientID-based access control
#
# Usage:
# myModules.adguard = {
# enable = true;
# domain = "dns.example.com";
# clients = [
# { name = "phone"; idSecret = "adguard_client_phone"; }
# ];
# };
{
config,
lib,
pkgs,
...
}:
let
cfg = config.myModules.adguard;
in
{
options.myModules.adguard = {
enable = lib.mkEnableOption "AdGuard Home DNS server";
domain = lib.mkOption {
type = lib.types.str;
example = "dns.example.com";
description = "Public domain name for DoH endpoint";
};
port = lib.mkOption {
type = lib.types.port;
default = 3000;
description = "Internal port for AdGuard HTTP/DoH listener";
};
upstreamDoh = lib.mkOption {
type = lib.types.str;
default = "https://dns.mullvad.net/dns-query";
description = "Upstream DoH server URL";
};
bootstrapDns = lib.mkOption {
type = lib.types.listOf (lib.types.str);
default = [ "194.242.2.2" "2a07:e340::2" ];
description = "Bootstrap DNS servers for resolving DoH upstream";
};
};
config = lib.mkIf cfg.enable {
services.adguardhome = {
enable = true;
host = "127.0.0.1";
port = cfg.port;
settings = {
dns = {
bind_hosts = [ "0.0.0.0" ];
port = 5353;
upstream_dns = [ cfg.upstreamDoh ];
bootstrap_dns = cfg.bootstrapDns;
querylog_enabled = true;
querylog_file_enabled = true;
statistics_enabled = true;
};
tls = {
enabled = true;
server_name = cfg.domain;
certificate_path = "/var/lib/acme/${cfg.domain}/fullchain.pem";
private_key_path = "/var/lib/acme/${cfg.domain}/key.pem";
port_https = 3001; # Prevent conflict with Nginx on port 443
port_dns_over_tls = 853;
port_dns_over_quic = 0;
allow_unencrypted_doh = false;
};
filtering = {
protection_enabled = true;
filtering_enabled = true;
};
safebrowsing = {
enabled = false;
};
parental = {
enabled = false;
};
safesearch = {
enabled = false;
};
log = {
file = "";
max_backups = 0;
max_size = 100;
compress = false;
local_time = false;
verbose = false;
};
};
};
# Give AdGuardHome access to ACME certificates
systemd.services.adguardhome = {
requires = [ "acme-${cfg.domain}.service" ];
after = [ "acme-${cfg.domain}.service" ];
serviceConfig.SupplementaryGroups = [ "acme" "nginx" ];
};
# Open firewall for DoT
networking.firewall.allowedTCPPorts = [ 853 ];
networking.firewall.allowedUDPPorts = [ 853 ];
# Nginx configuration (kept to satisfy ACME challenges for DoT certificates)
services.nginx.virtualHosts."${cfg.domain}" = {
enableACME = true;
forceSSL = true;
# Block all paths (no DoH or UI exposed via Nginx)
locations."/" = {
return = "404";
};
};
# Ensure nginx user can access ACME certs
users.users.nginx.extraGroups = [ "acme" ];
};
}