This post goes over configuring Tailscale DNS to support DNS resolution from other AppVMs using the Tailscale VM.
This guide assumes you already have Tailscale configured in a TemplateVM and a sys-tailscale AppVM is running Tailscaled for other AppVMs to use. If you don’t have Tailscale already configured, then please head over to taradiddles’ excellent guide over on the Qubes forum.
We need to do the following on the TemplateVM to get it all configured:
- Create a systemd service that runs a script.
- Create the script that gets executed by the systemd service.
- Shutdown the TemplateVM and restart the AppVMs based on it.
Create /etc/systemd/system/qubes-tailscaled-dns.service
with the following contents:
[Unit]
Description=Forward all DNS traffic to Tailscale
Requires=tailscaled.service
After=qubes-network.service
[Service]
Type=oneshot
ExecStart=/usr/bin/qubes-tailscaled-dns.sh start
ExecStop=/usr/bin/qubes-tailscaled-dns.sh stop
RemainAfterExit=yes
Restart=on-failure
[Install]
WantedBy=multi-user.target
Create the script that’s used by the service /usr/bin/qubes-tailscaled-dns.sh
with the following contents:
#!/usr/bin/env bash
set -euo pipefail
tailscale_dns=100.100.100.100
readonly tailscale_dns
primary_dns=$(/usr/bin/qubesdb-read /qubes-primary-dns 2>/dev/null) || primary_dns=
secondary_dns=$(/usr/bin/qubesdb-read /qubes-secondary-dns 2>/dev/null) || secondary_dns=
readonly primary_dns secondary_dns
# Protect against empty DNS server list
if [[ -z "$primary_dns" ]] && [[ -z "$secondary_dns" ]]; then
>&2 echo "No primary or secondary DNS servers configured, cannot continue"
exit 1
fi
# Flush the current dnat-dns chain
nft flush chain ip qubes dnat-dns # nft is used to interact with the firewall
for dns in $primary_dns $secondary_dns; do
if [[ "$1" == "start" ]]; then
nft add rule ip qubes dnat-dns ip daddr $dns udp dport 53 dnat to $tailscale_dns
nft add rule ip qubes dnat-dns ip daddr $dns tcp dport 53 dnat to $tailscale_dns
else
nft add rule ip qubes dnat-dns ip daddr $dns udp dport 53 dnat to $dns
nft add rule ip qubes dnat-dns ip daddr $dns tcp dport 53 dnat to $dns
fi
done
Once all this is done, simply shutdown the TemplateVM and restart your sys-tailscale AppVM. You should be up and running with DNS working on any AppVM that’s using sys-tailscale for networking.