Wireguard use peer dns server

I'm trying to use a dns server that belongs to a wireguard peer on Boxpn, and not having much luck. I'm working with openwrt v19.07.2 on a GoFlexNet device. I'm using rule-based routing as described at
https://www.wireguard.com/netns/

This is essentially the same technique that's used by wg-quick that works on my Debian 10 laptop. On the laptop, I use the endpoint address as the DNS server, which works without leaks. I've read that the tunnel IP (startpoint?) address can also be used as a DNS server:
https://wiki.archlinux.org/index.php/WireGuard#DNS
However, that doesn't work when I try it.

I use the /etc/config/network file for the setup, then a hotplug event to add the additional routing and write the nameserver to /tmp/resolv.conf.auto. I also suspend udhcpc processes to avoid overwiting the configuration.

It's curious that when I change the DNS server to point to my lan router, it works fine, 8.8.8.8 also works, but not the peer endpoint. I can't seem to see what the problem is in my setup, also none of the forum questions I can find deal directly with this issue, so I'm at a loss.

By the way, does anyone know how to properly find the peer DNS servers? Is there some way of discovering them? or should the endpoint function as one?

Thanks in advance.

#wg
interface: wg0
  public key: =
  private key: (hidden)
  listening port: 58244
  fwmark: 0xca6c

peer: =
  endpoint: 31.184.197.6:48020
  allowed ips: 0.0.0.0/0
  latest handshake: 1 minute, 37 seconds ago
  transfer: 34.13 MiB received, 499.68 MiB sent
  persistent keepalive: every 25 seconds

#ip route
default dev wg0 proto static scope link 
10.0.1.0/24 dev br-lan proto kernel scope link src 10.0.1.9 
31.184.197.6 via 10.0.1.1 dev br-lan proto static 
#ip rule
0:	from all lookup local 
32764:	from all lookup main suppress_prefixlength 0 
32765:	not from all fwmark 0xca6c lookup 10 
32766:	from all lookup main 
32767:	from all lookup default 
#ip route show table 10
default dev wg0 scope link 

#/etc/config/network

config interface 'loopback'
	option ifname 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config interface 'lan'
	option type 'bridge'
	option ifname 'eth0'
	option proto 'dhcp'

config interface 'wg0'
	option proto 'wireguard'
	option private_key '='
	list addresses '10.120.0.15/32'

config wireguard_wg0 'wgserver'
	option public_key '='
	option endpoint_host ''
	option endpoint_port '48020'
	option route_allowed_ips '1'
	option persistent_keepalive '25'
	list allowed_ips '0.0.0.0/0'

#/etc/config/firewall

config zone 'wan'
	option name 'wan'
	list network 'wan'
	list network 'wan6'
	list network 'wg0'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'

/etc/hotplug.d/iface/50-vpn

#!/bin/sh

#https://www.wireguard.com/netns/

interface=wg0
fwmark=51820
iptable=10

serv_resolv=/tmp/resolv.conf.auto

if [ "$INTERFACE" = "$interface" ] ; then case "$ACTION" in
ifup)

    # rule-based routing
    wg set wg0 fwmark "$fwmark"
    ip -4 route add default dev wg0 table "$iptable"
    ip -4 rule add not fwmark "$fwmark" table "$iptable"
    ip -4 rule add table main suppress_prefixlength 0
    sysctl -q net.ipv4.conf.all.src_valid_mark=1

    for PID in /var/run/udhcpc-*.pid ; do
        [ -e $PID ] || continue
        PID=$(cat $PID)

        # stop dhcp
        kill -SIGSTOP $PID
    done

    # use tunnel ip as DNS server
    tunip="$(ip address show dev $interface | sed -n -E -e 's/^ *inet +([0-9.]*).*$/\1/p')"

    echo "# wgvpn" > "$serv_resolv"
    echo "# nameserver" "$tunip" >> "$serv_resolv"
    echo nameserver 8.8.8.8 >> "$serv_resolv"

;;
ifdown)

    ip -4 rule delete table "$iptable"
    ip -4 rule delete table main suppress_prefixlength 0

    for PID in /var/run/udhcpc-*.pid ; do
        [ -e $PID ] || continue
        PID=$(cat $PID)

        # restart dhcp and renew
        kill -SIGCONT $PID
        kill -SIGUSR1 $PID
    done
;;
esac ; fi

You should ask the peer.

Try with nslookup www.example.com 8.8.4.4 and see if you'll get a response.

Not necessarily.

But why are you creating another routing table to route via wg, when the main table already has the same?

Yes, I would like to ask the peer, but how? In openvpn, there are callbacks of the type up and route-up that are passed the DNS server ips from the peer (among other information). Is there anything equivalent in wireguard? I think there is because wg-quick on my laptop is able to discover them, I'm just not able to see how it gets them. I know it's in the resolvconf script, but what it does is beyond me.

I don't have the url of the DNS servers, so I can't loop up the addresses. I only have the url of the endpoint.

Ok, but what does?

I read about the fwmark and rule-based routing technique on the page
https://www.wireguard.com/netns/
it is an alternate way to do the routing, and I tried it because the main table wasn't working for my DNS queries, and I thought I would try another way.

I thought the rule-based technique would work for the case where the DNS server is the same as the endpoint since it would send DNS queries through the tunnel, the main table would send traffic to the endpoint outside of the tunnel which can't work due to the peer's firewall.

However, I can't get either way to work.

I meant you should contact the administrator of the other endpoint :stuck_out_tongue:
OpenVPN has an option to advertise the nameserver. As far as I am aware there isn't such a thing in WG.

DNS doesn't have URL, has IP. And I meant for you to try with nslookup to query some address, e.g openwrt.org with IP of the peer in order to verify if the peer can also serve names,

I don't know how the administrator of your peer has configured it and if the peer is also listening to dns port. But as I explained above it is very easy to test it yourself.

In OpenWrt to do Policy Based Routing you have 3 options:

  1. mwan3 package
  2. pbr package
  3. a set of rules/routes for each internet connection.

PBR is the easiest one.

Ah!:smile: Well, I'll try that, but they don't list any DNS servers in their wireguard configuration instructions, also they don't directly support openwrt. They do support Debian via the wireguard package. When I follow the Linux instructions, the connection is able to use DNS on the peer. I know because I can verify it via whoami.akamai.net and whoami.ds.akahelp.net, etc. I can't figure out how it finds the peer DNS servers, though. It uses wg-quick script from the wireguard package and resolvconf script from the openresolv package. I think my best bet is to digest the resolvconf script to figure out how it's getting them from the peer. But, yes, I'll try opening a support ticket to see if they can explain it.

On openwrt, I have verified that 8.8.8.8 works when the DNS requests go through the tunnel, as well as outside the tunnel. Requests to the peer endpoint don't work, but I'm not sure if that's because the peer endpoint is not a DNS server, or if it's just not getting the requests due to a routing problem. I just know that the requests don't get resolved:

#dig @31.184.197.6 openwrt.org

; <<>> DiG 9.14.12 <<>> @31.184.197.6 openwrt.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 65484
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: dc87ea3886ae32ebd2d3ae6b5ee281e16c7319dba4231737 (good)
;; QUESTION SECTION:
;openwrt.org.			IN	A

;; Query time: 52 msec
;; SERVER: 31.184.197.6#53(31.184.197.6)
;; WHEN: Thu Jun 11 21:11:29 CEST 2020
;; MSG SIZE  rcvd: 68

I used rules/routes because I was copying the way the scripts on Debian were doing it, and since it makes intuitive sense to me since I've used that before for openvpn on openwrt (where it does work). Also, I haven't used the web ui very much, but I have no problem trying other stuff, though.

The endpoint won't respond to any dns query. You'll have to query the tunnel IP. It is not obvious from the configuration which one is that. Maybe they don't use it at all. Hence you'll have to ask the vpn provider.

I've tried that as well. The tunnel IP is given out by the VPN provider, and it shows up in the interface configuration for wg0:

#/etc/config/network
config interface 'wg0'
	option proto 'wireguard'
	option private_key '='
	list addresses '10.120.0.15/32'

Also, it can be seen here:

#ip address show dev wg0
4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 10.120.0.15/32 brd 255.255.255.255 scope global wg0
       valid_lft forever preferred_lft forever

But, it doesn't work as a DNS server:

#dig @10.120.0.15 forum.openwrt.org

; <<>> DiG 9.14.12 <<>> @10.120.0.15 forum.openwrt.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 24402
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;forum.openwrt.org.		IN	A

;; Query time: 0 msec
;; SERVER: 10.120.0.15#53(10.120.0.15)
;; WHEN: Fri Jun 12 14:28:14 CEST 2020
;; MSG SIZE  rcvd: 46

A number of factors make it confusing to debug this behaviour, though.

The first issue is that DNS lookups are cached, so that each test with dig or nslookup must try to lookup a new domain, or it may be satisfied from the cache, giving a false positive.

Another point of confusion is that both dig and nslookup fallback to the default DNS provider when the one given in the command line is a valid ip address, but fails to do a DNS lookup. This can be seen when /tmp/resolv.conf.auto points to a working DNS server:

#cat /tmp/resolv.conf.auto 
nameserver 8.8.8.8
#dig @10.120.0.15 forum.openwrt.org

; <<>> DiG 9.14.12 <<>> @10.120.0.15 forum.openwrt.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16699
;; flags: qr rd ra;74.115.214.154 QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;forum.openwrt.org.		IN	A

;; ANSWER SECTION:
forum.openwrt.org.	469	IN	A	139.59.210.197

;; Query time: 56 msec
;; SERVER: 10.120.0.15#53(10.120.0.15)
;; WHEN: Fri Jun 12 14:35:36 CEST 2020
;; MSG SIZE  rcvd: 62

One final point is that cache or no cache, default or no default, a DNS lookup using a non-existent IP address does give an error after a time out:

# There is no 10.12.0.15 !
#dig @10.12.0.15 forum.openwrt.org

; <<>> DiG 9.14.12 <<>> @10.12.0.15 forum.openwrt.org
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached

This makes it look like the tunnel ip is refusing to do the lookup since the dig command fails immediately without waiting for a timeout. So, something is blocking the lookup. I suspect that the VPN provider is not blocking it since I can do DNS lookups via the VPN provider when I connect to it from my Linux box, but not from my openwrt box. This makes me think that something in my openwrt setup is blocking DNS lookups using the peer's DNS servers.

At any rate, I do have a ticket open at Boxpn now. I included a link to this discussion in it.

This is your side of the tunnel IP. What I meant is to use the vpn provider side of the tunnel IP. Since it is not used anywhere in the configuration, you'll have to wait until they reply to you.

1 Like

No idea if this help but normally in the client peerdns, you can put the DNS like so;

[Interface]
PrivateKey = XXXXXXXXX
Address = 10.20.23.22/19
DNS = 1.0.0.1, 1.1.1.1

[Peer]
PublicKey = XXXXXXXXXXXX
AllowedIPs = 0.0.0.0/0
Endpoint = XXXXXXXX:51820

1 Like

The answer is that the provider side IP is 10.120.0.1. Which does work as a DNS server! It makes for a great improvement over not working at all!

Unfortunately, there are still some drawbacks to this. One is that it relies on "special" information. The provider side IP is not in any of their faqs or installation guides, and perhaps subject to change without notice. Being able to detect it would be better.

There is perhaps a more serious problem, though. I studied my Linux setup enough to see that it is successfully using the endpoint ip as a DNS server and not the tunnel ip. By this I mean 31.184.197.6, the same IP wireguard lists as the endpoint. It's certainly possible that I have a mistake in my setup, but I don't see it despite going over it many times. I'm beginning to suspect a bug in openwrt, although I have no idea about what else to check.

Thanks for the idea, but this is a line that is handled by the wg-quick utility which is not present in openwrt packages, and not likely to work properly if it was there.

1 Like

I've used this method in my WireGuard config also:

config interface 'WireGuard'
	option proto 'wireguard'
	list dns '209.222.18.222'
	list dns '209.222.18.218'
...

and it pick's the DNS up looking in the logs...

Sat Jun 13 10:52:00 2020 daemon.info dnsmasq[32729]: using local addresses only for domain lan
Sat Jun 13 10:52:00 2020 daemon.info dnsmasq[32729]: using nameserver 209.222.18.222#53
Sat Jun 13 10:52:00 2020 daemon.info dnsmasq[32729]: using nameserver 209.222.18.218#53
Sat Jun 13 10:52:00 2020 daemon.info dnsmasq[32729]: using nameserver 209.222.18.222#53
Sat Jun 13 10:52:00 2020 daemon.info dnsmasq[32729]: using nameserver 209.222.18.218#53
Sat Jun 13 10:52:00 2020 user.notice firewall: Reloading firewall due to ifup of WireGuard (WireGuard)
2 Likes

I'm not so experienced with wireguard. But for me it makes no sense using a commercial wireguard provider and trying to use either endpoint or wg peer address as DNS. There is simply no such service setup. For that they would (if they do) provide other services like a VPS where you can do anything with your (shared) IP address.

Usually they provide their own DNS from their Network already. Their job is to route traffic. Not to add additional services like you can setup on a VPS. They will just pass your DNS traffic to your prefered DNS provider.

Maybe I'm wrong. Then sorry for this thought. :slight_smile:

Nope, they do offer log-less dns too.
Mullvad for example.

O. K. But then how you would interpret this statement on their page?

We also have a DNS server running on each VPN server that can only be accessed
via the tunnel on this address: 10.8.0.1 (or any other address matching 10.x.0.1).

It sounds for me you can choose any of the possible numbers as DNS. So I would go for one of this numbers in DNS entry and not for tunnel ip itself. Maybe I'm wrong again. :smiley: But I'm interested in a solution also. :slight_smile:

The public DNS can be used to resolve the name of the vpn server and after it connects you can use the private dns.
It helps to prevent dns leaks, the private one can only be used after you are connected.

2 Likes

The answer from Boxpn is

We don't plan to change an endpoint, so you can use 10.120.0.1 as DNS for all configs. Even if will be forced to change it - you will get and email about that. Why 31.184.197.6 doesn't work on openwrt - well, maybe openwrt sends dns requests not through a tunnel but from home ip and therefore our DNS rejects it.

So, the point is that the public endpoint IP should work as DNS as long as it goes through the tunnel (and it does work on my debian install). But, somehow the rule based routing doesn't work correctly on openwrt, and I can't find the problem.

One idea I'd like to try is to use the rule
to 31.184.197.6 dport 53 table 10
instead of
not from all fwmark 0xca6c lookup 10
which has the advantage of not needing fwmark. Unfortunately that requires a kernel version >= 4.17.

So, for now, I'll stick with 10.120.0.1 which has no problem going through the tunnel. I just don't like using this IP since it requires a special request to find it out.