# bind popular [DNS](DNS) server read mailing list for security announcements: bind-announce@lists.isc.org @todo should run bind in two instances for recursive and authoritative see https://serverfault.com/questions/204159/multiple-instances-of-bind-on-debian#comment181124_204159 # Configuration Open DNSSEC-enabled recursive resolver with rate-limiting that listens on 53 UDP/TCP and 443 with DoH. Also open port 80 for certbot HTTP challenge. Get certificates with `certbot certonly --standalone --preferred-challenges http --agree-tos --email changeme@example.com -d ns.example.com` `/etc/named.conf.options` ```conf // RNDC key key "rndc-key" { algorithm hmac-sha256; secret "secretkey="; }; // TLS certs for DoH and DoT // requires open ports 80 and 443 for auto renewal with certbot tls letsencryptctq { cert-file "/etc/letsencrypt/live/orion.ctq.ro/fullchain.pem"; key-file "/etc/letsencrypt/live/orion.ctq.ro/privkey.pem"; }; options { directory "/var/cache/bind"; // hide version version "1337.69.420"; // serve DNS over UDP/TCP standard port 53 listen-on { any; }; listen-on-v6 { any; }; // serve DNS over HTTPS listen-on port 443 tls letsencryptctq http default { any; }; listen-on-v6 port 443 tls letsencryptctq http default { any; }; // serve DNS over TLS // DoH is used instead to avoid opening up yet another port // listen-on tls mycert { any; }; // listen-on-v6 tls mycert { any; }; // allow authoritative, recursive and cached lookups from anyone allow-query { any; }; allow-recursion { any; }; allow-query-cache { any; }; // DNSSEC for all zones dnssec-policy default; // various rate limiting rate-limit { // valid response rate limit responses-per-second 1; all-per-second 1; // answer(small) every 3rd request w/o valid cookie slip 3; // reduce limits in case of high number of queries qps-scale 200; // exempt localhost exempt-clients { 127.0.0.1; }; }; }; // rndc from localhost only controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; }; ``` `/etc/bind/named.conf.local` ```conf // loopback address zone zone "0.0.127.in-addr.arpa" { type primary; file "/etc/bind/localhost.rev"; notify no; }; // ctq.ro zone zone "ctq.ro" IN { type primary; file "/etc/bind/ctq.ro.zone"; allow-update { none; }; }; ``` ## Apparmor Under debian, some apparmor rules have to be modified for bind to access `/etc/bind/` and `/etc/letsencrypt/` for DNSSEC TLS certificates... Edit `/etc/apparmor.d/local/usr.sbin.named` and add the following rules: ```sh /etc/bind/** rw, /etc/letsencrypt/** r, ``` Afterwards reparse the rules with `apparmor_parser -r /etc/apparmor.d/usr.sbin.named` See also ISC's article on setting up DoH in bind at https://www.isc.org/blogs/doh-talkdns/ ## RNDC `/etc/bind/rndc.conf` ```conf key "rndc-key" { algorithm hmac-sha256; secret "secretkey="; }; options { default-key "rndc-key"; default-server 127.0.0.1; default-port 953; }; ``` `/etc/bind/rndc.key` ```conf key "rndc-key" { algorithm hmac-sha256; secret "secretkey="; }; ``` `/etc/bind/localhost.rev` ```rev $TTL 1D @ IN SOA localhost. root.localhost. ( 2007091701 ; serial 30800 ; refresh 7200 ; retry 604800 ; expire 300 ) ; minimum IN NS localhost. 1 IN PTR localhost. ``` # Authoritative zone `/etc/bind/ctq.ro.zone` ```rev $ORIGIN ctq.ro. $TTL 3600 @ SOA orion postmaster ( 2026041002 ; Serial 8h ; Refresh 30m ; Retry 1w ; Expire 1h ) ; Negative Cache TTL ; name servers for this domain @ NS orion ; sundown hosting root ctq.ro @ A 140.238.223.96 AAAA 2603:c022:5:faba:0:458e:65d:5dd0 ; mail handled by irix @ MX 10 irix ; mailtrap relay @ TXT "v=spf1 include:_spf.smtp.mailtrap.live -all" _dmarc TXT "v=DMARC1; p=reject; rua=mailto:dmarc@smtp-staging.mailtrap.net; ruf=mailto:dmarc@smtp-staging.mailtrap.net; rf=afrf; pct=100" rwmt2._domainkey CNAME rwmt2.dkim.smtp.mailtrap.live. rwmt1._domainkey CNAME rwmt1.dkim.smtp.mailtrap.live. mt96 CNAME smtp.mailtrap.live. ; orion (this machine) orion A 144.24.233.192 orion AAAA 2603:c022:5:f3cc:46ff:176e:6697:869c ; irix irix A 140.238.170.217 irix AAAA 2603:c022:5:f3cc:ae9:78e1:78a5:5c3d ; sundown sundown A 140.238.223.96 sundown AAAA 2603:c022:5:faba:0:458e:65d:5dd0 ; carddav caldav on irix dav CNAME irix ; wildcards * CNAME sundown *.irix CNAME irix ``` # Open resolver Running a recursive open resolver means anyone can ask you for anything. In general this comes with some risks: cache poisoning and amplification attacks. See Google's articles on how to mitigate these risks at https://developers.google.com/speed/public-dns/docs/security See the ISC's best practices for recursive resolvers using BIND at https://kb.isc.org/docs/bind-best-practices-recursive?highlight=best%20practice ## Cache poisoning Attacker requests (hopefully) uncached domain, flood with forged responses with attacker IPs, etc DNSSEC can solve these problems IF it is widely implemented. Other stopgap measures exist to help prevent cache poisoning. Most of these are to increase the entropy of a resolver's DNS requests: query port randomization, name server choice randomization, DNS cookies, query name case randomization... Test if query port randomization is enabled with DNS OARC's tool at https://www.dns-oarc.net/oarc/services/porttest ### DNSSEC @todo how does DNSSEC work? Most recent versions of bind9 ship with DNSSEC validation (for other domains) enabled by default. Check if DNSSEC is working with https://internet.nl/connection Or use dig: `dig @your.dns.server.here ftp.isc.org. A +dnssec +multiline` To enable DNSSEC for your own domains, include `dnssec-policy default` in the options clause to enable it for all zones. ## Amplification attacks Attackers send small requests with forged source IPs, you send much larger requests back, chaos ensues. bind9 can ratelimit source IPs with the following config: ```bind options { ... rate-limit { responses-per-second 10; }; }; ``` See also -------- https://bind9.readthedocs.io/en/latest/reference.html Official documentation https://wiki.archlinux.org/title/BIND Arch wiki article with examples