January 22, 2025

Caching DNS server

This is a caching DNS proxy/resolver so you can point all your local boxes at it instead of 1.1.1.1 or 8.8.8.8 or something.

It will hold a bunch of content so you don’t have to keep requesting it upstream, which will speed up your network quite a lot.

Unbound DNS cache proxy

apt update
apt install unbound curl
vi /etc/unbound/unbound.conf.d/default.conf
  server:
    verbosity: 1
    interface: 0.0.0.0         # Listen on all interfaces
    interface: ::0             # For IPv6
    access-control: 127.0.0.0/8 allow
    access-control: 192.168.1.0/24 allow
    access-control: ::1 allow
    access-control: 0.0.0.0/0 refuse
    access-control: ::/0 refuse
 
    # Specify the cache size (adjust based on system memory)
    msg-cache-size: 50m
    rrset-cache-size: 100m
 
    # Default root hints
    root-hints: "/etc/unbound/root.hints"
 
    prefetch: yes              # Prefetch popular queries
    prefetch-key: yes
 
    hide-identity: yes         # Improve privacy
    hide-version: yes
    use-caps-for-id: yes       # Enhanced security
    qname-minimisation: yes    # Minimize query names
 
  forward-zone:
    name: "."
    forward-addr: 1.1.1.1      # Cloudflare DNS
    forward-addr: 8.8.8.8      # Google DNS
curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
 100  3314  100  3314    0     0   7995      0 --:--:-- --:--:-- --:--:--  8024
unbound-checkconf
  unbound-checkconf: no errors in /etc/unbound/unbound.conf

Now start and test your server

systemctl enable unbound
systemctl start unbound
  Synchronizing state of unbound.service with SysV service script with /lib/systemd/systemd-sysv-install.
  Executing: /lib/systemd/systemd-sysv-install enable unbound
systemctl status unbound
● unbound.service - Unbound DNS server
     Loaded: loaded (/lib/systemd/system/unbound.service; enabled; preset: enabled)
     Active: active (running) since Tue 2024-12-03 11:25:04 PST; 7min ago
       Docs: man:unbound(8)
   Main PID: 68555 (unbound)
      Tasks: 1 (limit: 1107)
     Memory: 12.1M
        CPU: 97ms
     CGroup: /system.slice/unbound.service
             └─68555 /usr/sbin/unbound -d -p
 
 Dec 03 11:25:04 cache systemd[1]: Starting unbound.service - Unbound DNS server...
 Dec 03 11:25:04 cache unbound-helper[68550]: Updating /var/lib/unbound/root.key from /usr/share/dns/root.key
 Dec 03 11:25:04 cache unbound[68555]: [68555:0] notice: init module 0: subnetcache
 Dec 03 11:25:04 cache unbound[68555]: [68555:0] notice: init module 1: validator
 Dec 03 11:25:04 cache unbound[68555]: [68555:0] notice: init module 2: iterator
 Dec 03 11:25:04 cache unbound[68555]: [68555:0] info: start of service (unbound 1.17.1).
 Dec 03 11:25:04 cache systemd[1]: Started unbound.service - Unbound DNS server.
 Dec 03 11:25:04 cache unbound[68555]: [68555:0] info: generate keytag query _ta-4f66. NULL IN
dig @127.0.0.1 ford.com
 ; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> @127.0.0.1 ford.com
 ; (1 server found) 
 ;; global options: +cmd
 ;; Got answer:
 ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18733
 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
 
 ;; OPT PSEUDOSECTION:
 ; EDNS: version: 0, flags:; udp: 1232
 ;; QUESTION SECTION:
 ;ford.com.			IN	A
 
 ;; ANSWER SECTION:
 ford.com.		1800	IN	A	19.12.97.37
 ford.com.		1800	IN	A	19.12.113.37
 
 ;; Query time: 395 msec
 ;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
 ;; WHEN: Tue Dec 03 11:34:40 PST 2024
 ;; MSG SIZE  rcvd: 69
vi /etc/resolv.conf
  nameserver 127.0.0.1

Now if you want to add your own local zones, like ftp.whatever.com or fileshare.whatever.com, add these lines AFTER the line that starts with qname-….

vi /etc/unbound/unbound.conf.d/default.conf
    qname-minimisation: yes    # Minimize query names
 
	##
	# Add some local hosts if you want to use them
	# first set your local domain
	local-zone: "youractualdomain.com." static
 
	# now add the actual zone you want to use like ftp.blah.com
	local-data: "helpdesk.youractualdomain.com IN A 192.168.1.50"
	local-data: "fileshare.youractualdomain.com IN A 192.168.1.25"
unbound-checkconf
unbound-checkconf: no errors in /etc/unbound/unbound.conf
systemctl restart unbound
dig @127.0.0.1 helpdesk.youractualdomain.com 
 
; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> @127.0.0.1 helpdesk.ivdatacenter.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60371
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
 
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;helpdesk.youractualdomain.com.	IN	A
 
;; ANSWER SECTION:
helpdesk.youractualdomain.com. 3600	IN	A	192.168.1.50
 
;; Query time: 3 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Tue Dec 03 11:46:18 PST 2024
;; MSG SIZE  rcvd: 70