[SOLVED] How can I redirect DNS queries to 127.0.0.53:53 with iptables?

Question

This Content is from Stack Overflow. Question asked by Woods Chen

The problem is that I need to forward the incoming DNS query (from other computers) packets to 127.0.0.53 (not 127.0.0.1), the IP address of the incoming interface is 10.66.66.1, which is an virtual interface of the wireguard VPN service.

I tried to redirect the DNS request to 127.0.0.1, that worked fine, however it’s not able to redirect them to 127.0.0.53.

The commands I used for forwarding to 127.0.0.1 was:

sudo iptables -t nat -A PREROUTING -i wg0 -p tcp -d 10.66.66.1 --dport 53 -j DNAT --to-destination 127.0.0.1:53
sudo iptables -t nat -A PREROUTING -i wg0 -p udp -d 10.66.66.1 --dport 53 -j DNAT --to-destination 127.0.0.1:53
sudo iptables -I INPUT -i wg0 -p tcp -m tcp -d 10.66.66.1 --dport 53 -j ACCEPT
sudo iptables -I INPUT -i wg0 -p udp -m udp -d 10.66.66.1 --dport 53 -j ACCEPT
sudo iptables -A FORWARD -p tcp --dport 53 -j ACCEPT
sudo iptables -A FORWARD -p udp --dport 53 -j ACCEPT

in which wg0 was the interface of the wireguard VPN.

and the commands I used for forwarding to 127.0.0.1 was (the only difference is that I changed 127.0.0.1 to 127.0.0.53):

sudo iptables -t nat -A PREROUTING -i wg0 -p tcp -d 10.66.66.1 --dport 53 -j DNAT --to-destination 127.0.0.53:53
sudo iptables -t nat -A PREROUTING -i wg0 -p udp -d 10.66.66.1 --dport 53 -j DNAT --to-destination 127.0.0.53:53
sudo iptables -I INPUT -i wg0 -p tcp -m tcp -d 10.66.66.1 --dport 53 -j ACCEPT
sudo iptables -I INPUT -i wg0 -p udp -m udp -d 10.66.66.1 --dport 53 -j ACCEPT
sudo iptables -A FORWARD -p tcp --dport 53 -j ACCEPT
sudo iptables -A FORWARD -p udp --dport 53 -j ACCEPT

Besides, I enabled the port forwarding:

sudo sysctl net.ipv4.ip_forward=1
sudo sysctl -w net.ipv4.conf.eth0.route_localnet=1 # physical interface
sudo sysctl -w net.ipv4.conf.lo.route_localnet=1 # loopback interface
sudo sysctl -w net.ipv4.conf.wg0.route_localnet=1 # wireguard interface
sudo sysctl -w net.ipv4.conf.all.route_localnet=1

and the default policy of INPUT/OUTPUT/FORWARD chains is ACCEPT.

I have 2 questions:

  1. how can I redirect the DNS queries to 127.0.0.53?
  2. I checked the filtered bytes of iptables (iptables -L -v and iptables -t nat -L -v), and why can’t I see any packets filtered by the forward chain? even when the packets were redirected to 127.0.0.1 correctly?

The real problem I was trying to solve was that, the stubby service (encrypted DNS service) is listening at port 127.0.0.1:53, and I can also set it to listen to 10.66.66.1:53(the VPN interface), however, the stubby service ignored the static DNS bindings in /etc/hosts, which can be solved by sending DNS requests to 127.0.0.53 (dns-resolved serrvice), and I need to provide some static DNS bindings for all the VPN clients.

Solution

I wouldn’t try to use systemd resolved as DNS server for your network.

Simply run dnsmasq, which loads the contents of /etc/hosts so that local hostnames which do not appear in the global DNS can be resolved and also answers other DNS queries by forwarding them to the DNS server(s) of your choice (i.e. stubby).

Then push the IP-address where dnsmasq is listening as the resolver to your VPN users (or configure whatever forwarding you want to do for DNS traffic).

Edited by Rob


This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 4.0.

people found this article helpful. What about you?