aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorKaran Jayachandra <mail@karanjayachandra.com>2026-07-31 21:12:16 +0200
committerKaran Jayachandra <mail@karanjayachandra.com>2026-07-31 21:12:16 +0200
commit2144d31a0455ba32a7a0b655afdef33632a8724d (patch)
treea5bb01f93649511360dabdfb13524082d3e4edfc /modules
parentabfbee7c9b2632dcbd07e7940f8805942a93d14c (diff)
Hardened the server by blocking port 53 and added a deploy script
Diffstat (limited to 'modules')
-rw-r--r--modules/adguard.nix27
-rw-r--r--modules/common.nix13
2 files changed, 25 insertions, 15 deletions
diff --git a/modules/adguard.nix b/modules/adguard.nix
index e66d072..35cafc3 100644
--- a/modules/adguard.nix
+++ b/modules/adguard.nix
@@ -2,12 +2,17 @@
# AdGuard Home - DNS resolver + optional network-wide ad blocker.
#
-# Plain DNS listens on port 53 (udp/tcp) directly on the public IP.
-# DNS-over-TLS (853/tcp) and DNS-over-HTTPS (8443/tcp, path /dns-query) are
-# also served directly by AdGuard itself, terminating TLS with their own
-# independent Let's Encrypt cert (modules/acme.nix) - NOT via Caddy, since
-# Caddy already owns port 443 for its own reverse-proxied vhosts and
-# AdGuard's HTTPS/DoH listener needs its own port.
+# Plain DNS (port 53, udp/tcp) is disabled (dns.port = 0 below): CERT-Bund/BSI
+# flagged this host as an open DNS resolver, abusable for UDP reflection/
+# amplification DDoS since a spoofed source IP gets an amplified response with
+# no handshake required. DNS-over-TLS (853/tcp) and DNS-over-HTTPS (8443/tcp,
+# path /dns-query) are unaffected by this - both require a real TLS handshake
+# with the real client IP, so they aren't spoofable the same way - and remain
+# the only supported way to use this resolver. They're served directly by
+# AdGuard itself, terminating TLS with their own independent Let's Encrypt
+# cert (modules/acme.nix) - NOT via Caddy, since Caddy already owns port 443
+# for its own reverse-proxied vhosts and AdGuard's HTTPS/DoH listener needs
+# its own port.
#
# AdGuard's HTTPS/DoH listener binds to the same host as the plain `http`
# listener below (confirmed in AdGuardHome's source: both come from
@@ -45,11 +50,11 @@
dns = {
bind_hosts = [ "0.0.0.0" ];
- port = 53;
- # Clients configure this server's public IPv4 address (not
- # dns.karanj.com - that hostname only resolves to the HTTPS web UI
- # via Caddy) as their plain DNS resolver, e.g. <server-ipv4>:53.
- # For encrypted DNS, see the client setup notes in README.md.
+ # port = 0 disables the plain UDP/TCP:53 listener entirely; it does
+ # not affect the DoT/DoH listeners below, which are configured
+ # separately under `tls` and stay on. Clients use DoT/DoH exclusively
+ # - see the client setup notes in README.md.
+ port = 0;
# Upstream DNS resolvers (privacy-respecting)
upstream_dns = [
"https://dns.quad9.net/dns-query"
diff --git a/modules/common.nix b/modules/common.nix
index e27d276..7f46af8 100644
--- a/modules/common.nix
+++ b/modules/common.nix
@@ -15,14 +15,19 @@
};
};
- # Firewall: SSH, HTTP/HTTPS (Caddy), plain DNS, and AdGuard's own
- # DNS-over-TLS (853) + DNS-over-HTTPS (8443) listeners.
+ # Firewall: SSH, HTTP/HTTPS (Caddy), and AdGuard's own DNS-over-TLS (853) +
+ # DNS-over-HTTPS (8443) listeners.
+ # Plain DNS (port 53) is deliberately NOT opened: CERT-Bund/BSI flagged this
+ # host as an open DNS resolver abusable for UDP reflection/amplification
+ # DDoS (spoofed source IP, no handshake). AdGuard's plain listener is
+ # disabled entirely in modules/adguard.nix (dns.port = 0) - all clients use
+ # DoT/DoH instead, which require a real TLS handshake with the real client
+ # IP and so aren't spoofable the same way.
# Port 3000 (AdGuard's plain-HTTP web UI) is deliberately NOT opened here -
# see modules/adguard.nix for why it still binds 0.0.0.0 anyway.
networking.firewall = {
enable = true;
- allowedTCPPorts = [ 22 80 443 53 853 8443 ];
- allowedUDPPorts = [ 53 ];
+ allowedTCPPorts = [ 22 80 443 853 8443 ];
};
# Nix settings: flakes, auto-gc, auto-optimise