Implementing DNS over TLS (DoT) on a Budget with CoreDNS
Few months back I just started to finds a new SBC-based computer to replace my super trusty beast Raspberry Pi 2 and yeah eventually settled with OrangePi zero 2. The main reason for quick replacing it because I use DoH/DoT for my daily internet connectivity needs.
While searching for another option SBC-based computer, I got the plan that want to no longer using Pi-Hole as my main DNS server and having idea that Coredns its support for running DoH/DoT based DNS.
(and the package has arrived…)
Just kickoff start the initial setup. At this moment I was choose Armbian as base OS flavor instead of using vanilla ubuntu or debian. Alternatively you can browse directly to OrangePi OS forum/docs support here .
Setup CoreDNS
Okay before setup it up, I had plan to using some automation things like Ansible (as part of new homelab plan that i want fully automate the tasks) but for now we can proceed it manually first.
Grab the CoreDNS binary using whatever download tools.
COREDNS_VERSION=1.11.1
# OrangePi Zero 2 using arm64/aarch64/armv8
wget https://github.com/coredns/coredns/releases/download/v${COREDNS_VERSION}/coredns_${COREDNS_VERSION}_linux_arm64.tgz -O /tmp/coredns_${COREDNS_VERSION}_linux_arm64.tgz
Unpack/untar that downloaded file.
tar xzvf /tmp/coredns_${COREDNS_VERSION}_linux_arm64.tgz -C .
Then move the output file into common executable path in Linux, such as placing it under /usr/local/bin
. Afterward, create CoreDNS user.
sudo useradd -M -s /bin/false coredns
Create file Corefile
under /etc/coredns/
then fill it up like below.
# make sure it run on port 53 and 853 (DoT)
.:53 tls://.:853 {
# bind to ip host and local
bind 10.10.0.2 127.0.0.1
# hosts block if you want make it as local DNS server serve from
# /etc/hosts
hosts /etc/coredns/home.hosts {
fallthrough
}
# important part; this case using blahdns with SG based server
# dont forget add healtcheck :)
forward . tls://2406:ef80:2:5ee4::1 tls://103.167.150.45 {
tls_servername dot-sg.blahdns.com
health_check 60s
}
# log the query :)
# carefully it will spamming write actions
log
errors
# No idea, but it's good to add caching mechanism
cache {
success 4096
denial 1024
prefetch 512
}
}
After the Corefile
setup, proceed to setup systemd to ensure that CoreDNS runs automatically at all times.
[Unit]
Description=CoreDNS Server
Wants=network-online.target
After=network.target network-online.target
[Service]
Type=simple
Restart=on-failure
User=coredns
Group=coredns
# i've added this to ensure restart looping 🤔
ExecStartPre=/bin/sleep 30
ExecStart=/usr/local/bin/coredns -conf /etc/coredns/Corefile
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target
Usually, NetworkManager
is enabled for DNS on Debian-based distributions. Therefore, before starting the CoreDNS service, it’s important to disable the default DNS settings in NetworkManager
and systemd-resolved
to free up UDP port 53 for CoreDNS.
# install resolvconf
sudo apt install resolvconf -y
# set dns=default
sudo sed -i 's/^dns=.*/dns=default/' /etc/NetworkManager/NetworkManager.conf
# add this to able resolve dns from localhost
echo "nameserver 127.0.0.1" | sudo tee -a /etc/resolvconf/resolv.conf.d/head
# stop and disable it
sudo systemctl stop systemd-resolved && sudo systemctl disable systemd-resolved
Here we go for the last setup
sudo systemctl daemon-reload
sudo systemctl enable coredns
sudo systemctl start coredns
P.S. If having issue with unprivileged port, can enable this to allow <1024
port. Be carefull security risk issue.
sudo bash -c "echo 'net.ipv4.ip_unprivileged_port_start=0' > /etc/sysctl.d/99-unprivileged-ports.conf"
sudo sysctl -p /etc/sysctl.d/99-unprivileged-ports.conf
Closing Thought
So far this approach make my small machine run more efficiently less cpu/memory usage, because with this setup, the DNS server communicates directly without going through Pi-Hole first and then continuing upstream to dnscrypt-proxy
while this approach also eliminate the need to maintain two different apps/services and still dont have any idea about which one best between DoT and DoH 😂😂 (need to investigate deep about that)
As my previous article , that talk about Pi-Hole with DoH before, you can directly test this configuration using tools like dns leak test or by run the command like,
dig @<your_coredns_server> <google.com>
…
Thank You!