114 lines
2.9 KiB
Django/Jinja
114 lines
2.9 KiB
Django/Jinja
# Managed by Ansible (roles/resolvers/templates/nixos-unbound.nix.j2)
|
|
# Settings derived from unbound.conf.j2 — same configuration as resolver1.
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
let
|
|
accessControl = [
|
|
"0.0.0.0/0 refuse"
|
|
"::0/0 refuse"
|
|
{%- for netblock in resolver_allowed_netblocks %}
|
|
"{{ netblock }} allow"
|
|
{%- endfor %}
|
|
];
|
|
|
|
blocklistZone = pkgs.writeText "blocklist.rpz" ''
|
|
$TTL 3600
|
|
$ORIGIN blocklist.rpz.
|
|
@ IN SOA localhost. root.localhost. 1 3600 600 86400 3600
|
|
@ IN NS localhost.
|
|
{%- for domain in resolver_blocked_domains | default([]) %}
|
|
{{ domain }} CNAME .
|
|
*.{{ domain }} CNAME .
|
|
{%- endfor %}
|
|
'';
|
|
in
|
|
{
|
|
services.unbound = {
|
|
enable = true;
|
|
|
|
settings = {
|
|
server = {
|
|
interface = [ "0.0.0.0" "::0" ];
|
|
port = 53;
|
|
|
|
# DoH endpoint via loopback (Caddy terminates TLS upstream)
|
|
interface-auto = false;
|
|
https-port = 8080;
|
|
http-endpoint = "/dns-query";
|
|
http-notls-downstream = true;
|
|
|
|
access-control = accessControl;
|
|
|
|
# Performance tuning
|
|
num-threads = 4;
|
|
msg-cache-size = "512m";
|
|
rrset-cache-size = "512m";
|
|
key-cache-size = "512m";
|
|
msg-cache-slabs = 8;
|
|
rrset-cache-slabs = 8;
|
|
infra-cache-slabs = 8;
|
|
key-cache-slabs = 8;
|
|
num-queries-per-thread = 1024;
|
|
|
|
outgoing-port-permit = "32768-60999";
|
|
outgoing-num-tcp = 100;
|
|
incoming-num-tcp = 600;
|
|
|
|
# Prefetch and serve-expired
|
|
prefetch = true;
|
|
prefetch-key = true;
|
|
serve-expired = true;
|
|
serve-expired-ttl = 86400;
|
|
serve-expired-client-timeout = 1800;
|
|
|
|
# Socket tuning
|
|
so-reuseport = true;
|
|
so-rcvbuf = "4m";
|
|
ip-transparent = true;
|
|
edns-buffer-size = 1232;
|
|
edns-tcp-keepalive = true;
|
|
|
|
# Hardening
|
|
harden-short-bufsize = true;
|
|
harden-large-queries = true;
|
|
harden-glue = true;
|
|
harden-dnssec-stripped = true;
|
|
harden-below-nxdomain = true;
|
|
aggressive-nsec = true;
|
|
qname-minimisation = true;
|
|
|
|
# Logging
|
|
log-time-ascii = true;
|
|
|
|
# Statistics
|
|
extended-statistics = true;
|
|
shm-enable = false;
|
|
};
|
|
|
|
remote-control = {
|
|
control-enable = true;
|
|
control-interface = "127.0.0.1";
|
|
control-port = 8953;
|
|
control-use-cert = false;
|
|
};
|
|
|
|
rpz = {
|
|
name = "blocklist.rpz";
|
|
zonefile = "${blocklistZone}";
|
|
rpz-action-override = "nxdomain";
|
|
rpz-log = true;
|
|
rpz-log-name = "blocklist";
|
|
};
|
|
};
|
|
|
|
# DNSSEC root trust anchor
|
|
enableRootTrustAnchor = true;
|
|
};
|
|
|
|
# Python for Ansible management (appended, doesn't clobber other packages)
|
|
environment.systemPackages = lib.mkAfter [ pkgs.python3 ];
|
|
|
|
# Open DNS ports
|
|
networking.firewall.allowedTCPPorts = [ 53 ];
|
|
networking.firewall.allowedUDPPorts = [ 53 ];
|
|
}
|