WireGuard and PBR with VPN (DNS leaks)

Hello,

I'm using OpenWrt 23.05 with a commercial VPN service configured via WireGuard package. I've installed the PBR package (version 1.1.6) to route specific traffic through the VPN based on URLs. This setup is working as intended for routing traffic. However, I've encountered a problem with DNS resolution.

When the VPN is active, the DNS requests still go through the ISP's DNS servers instead of the VPN's DNS servers.

This is an issue because I want all DNS traffic to go through the VPN for privacy reasons and others:

Some websites can detect my location based on the DNS server used. If my traffic is routed through the VPN but the DNS requests go through my ISP's servers, it can cause issues where the website sees the VPN IP address but detects my true location via the ISP's DNS, leading to inconsistencies and potential content restrictions.

I have configured the VPN with its own DNS servers on the WireGuard interface (on network tab of OpenWRT), but they don't seem to be used.

I want to use my ISP's IP address for all internet traffic except for specific URLs that I've defined in the PBR configuration. For those specific URLs, the traffic should be routed through one of the VPNs, using the VPN's own DNS servers.

How can I ensure that all DNS requests, particularly those to specific domains like google.com (for example), are routed through the VPN using the VPN's DNS servers? This is crucial for maintaining both privacy and consistency in location detection. Is there a configuration step I'm missing in OpenWrt or PBR to achieve this? Additionally, how can I prevent DNS leaks in this setup?

Any insights or guidance would be greatly appreciated!

If I understood your question correctly, OpenWrt (well, built-in dnsmasq) allows you to specify which resolvers to use for which domains, like this:

uci add_list dhcp.@dnsmasq[0].server='/time.cloudflare.com/1.1.1.1'

Replace time.cloudflare.com with the domain you want to resolve thru your VPN provider servers and 1.1.1.1 with your VPN provider's DNS.

PS. You'll need to run uci commit dhcp and restart dnsmasq after you add those entries.

1 Like

To elaborate a bit more on @stangri's post see my notes:

My notes contain some more information about PBR and DNS leaks if you are interested

2 Likes

Thank you for your suggestion!

The solution you've provided works well for routing specific domains through specific DNS resolvers.
However, I have a more complex use case where I need to route different domains through different VPNs, each in different countries.

For example:

  • Domain A should use VPN 1 with DNS servers X.X.X.X and Y.Y.Y.Y.
  • Domain B should use VPN 2 with DNS servers Z.Z.Z.Z and W.W.W.W.
  • This could involve up to twenty or more domains and subdomains.

Like the picture below (PBR)

This setup is crucial for ensuring that the traffic appears to come from different regions based on the domain or subdomain, and to prevent DNS leaks by using the VPN's DNS servers. The challenge is maintaining and managing a large list of domains and subdomains, each associated with a specific VPN and DNS configuration.

Is there a way to configure dnsmasq (or another solution in OpenWrt) to handle this level of complexity, allowing multiple sets of domains and subdomains to be routed through different VPNs with their corresponding DNS servers? If not, are there any recommended approaches or tools for managing such a setup?

That's is interesting!

Let me know if I understood correctly, for example:

list server '/bbc.com/google.com/openwrt.org/10.20.0.126/DNS_VPN'

So, dnsmasq takes the following domains:

and resolves them via the VPN's DNS?

Is this how it works?

This uses DNS server 10.20.0.126 for the domains given.

The next step is that you make sure 10.20.0.126 is routed via the VPN (or via whatever route you want), if it is in the subnet of the VPN client then that will already be the case but otherwise you make a PBR policy to route destination 10.20.0.126 via the VPN.

Perhaps it is easier to just use option 6 for your clients or if you use the updated PBR package a DNS Policy` your LAN clients will resolve the DNS always through the same route as their other traffic, so if your LAN client is set to use the VPN, with option 6 or a DNS policy it will always send DNS queries through the VPN

1 Like

I'll give you an example with the screenshot I posted earlier:

As you see there are the domains and its IPs of the site, all these are routed to the VPN that I have selected in the PBR policy.
Obviously this site not only sees the IP of the VPN but also DNS which is from the ISP and is not good beacuse there's DNS leak.

As you saw the domains and IPs in the screenshot above, I would like them to route to VPN + DNS of the same VPN as if it were a VPN's app.

A VPN (NordVPN WireGuard) has two DNS: 103.86.96.100 and 103.86.99.100 and the IP is 10.5.0.2/32
If so, what could you configure compared to the screenshot above?

I don't have just one VPN but 4, because each one works better for each different site.

For example:

  • Domains A, B, C and their subdomains should use VPN 1 with specific DNS servers.
  • Domains X, Y, Z and their subdomains should use VPN 2 with different DNS servers.

I understand the suggestion to use a "DNS Policy" with the updated PBR package, which could route DNS queries based on the client’s IP. However, this solution might not suit my needs because it requires setting a local device's private IP address to route the DNS queries. In my case, I'm aiming for more granular control at the domain/subdomain level rather than just at the client level.
This approach could potentially lead to a mismatch where the client might resolve DNS via the VPN but not have the necessary traffic routing, or vice versa, especially when dealing with multiple VPNs.

I hope I was clear in my explanation and I know it is quite complicated :sweat_smile: but I am sure it is possible to do it.

PS: I like your initiative what you are doing the post on GitHub.

That is exactly the problem, not only the origin of your IP is tracked but also the origin of the DNS, so DNS has to be resolved through the VPN tunnel, it does not matter by which DNS server so does not necessary has to be the DNS server of your VPN provider but that does not hurt.

Of course there are more ways to track your origin, WebRTC is also often used, a good check is to use ipleak.net

So the best bet is if your client uses the tunnel e.g. with option 6.
But I can understand your search for more granular control but that is not guaranteed to work.

But you can certainly give it a try.

For all the domains you want to route via wg_surf_it you add as DNSMasq options e.g (fill in all your domains).
`list server '/mediapolis.vod.it/auth.raiplay.it/ipleak.net/103.86.96.100'

Note I also added ipleak.net to test

Choose in the PBR GUI as Resolver: dnsmasq nft set this will dynamically resolve all IP addresses, it helps if you do an nslookup of the domains you entered to prefill the set, I had some trouble getting the set populated otherwise disable this

The next step is that you make sure that 103.86.96.100 is routed via the vpn.
But as it is DNSMasq which does the resolving you need the OUTPUT chain
So make a policy with remote address: 103.86.96.100, chain OUTPUT, interface wg_surf_it

Using the Resolver dnsmasq nft set is mandatory? I'm getting some trouble too.

I tried it as you say but it doesn't work, i.e. it's like nothing configured. ipleak.net tells me I'm still using the ISP's IP and DNS.

I share my config of dnsmasq on /etc/config/dhcp:

config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/lan/'
        option domain 'lan'
        option expandhosts '1'
        option cachesize '1000'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option localservice '1'
        option ednspacket_max '1232'
        option confdir '/tmp/dnsmasq.d'
        list server '/mediapolis.vod.it/auth.raiplay.it/ipleak.net/103.86.96.100'

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option dhcpv6 'server'
        option ra 'server'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'

config odhcpd 'odhcpd'
        option maindhcp '0'
        option leasefile '/tmp/hosts/odhcpd'
        option leasetrigger '/usr/sbin/odhcpd-update'
        option loglevel '4'

My config policy of PBR on /etc/config/pbr:

config policy
        option name 'Resolver DNS'
        option dest_addr '103.86.96.100'
        option chain 'output'
        option interface 'wg_surf_it'

If I do the PBR policy:

  • Remote address: ipleak.net
  • Chain: Prerouting
  • Interface: wg_surf_en

ipleak.net tells me I am staying under VPN IP (which is fine) and of course DNS is being used by ISP's one.

So, something I got wrong?

Start by checking if the DNS servers you set are indeed used.

disable PBR for now and see what DNS server is used.

I use this for testing in DNSMasq:

	list server '/ipleak.net/bbc.com/103.86.96.100'
	list server '/dnsleaktest.com/8.8.8.8'

If open from my phone or laptop dnsleaktest.com I get google.com as DNS server and if I open ipleak.test I get 102.86.96.100 and a german IPv6 server, neither are my regular 9.9.9.9 DNS server so that works.

If it does not work perhaps you have implemented DNS Hijacking?

BTW if you do not want to use your ISP DNS server but only the DNS server you yourself set on the WAN interface then under Intefaces > WAN > Advanced settings :Disable Use DNS servers advertised by peer and set your own trusted DNS server

config interface 'wan'
	option device 'eth0.2'
	option proto 'dhcp'
	option peerdns '0'          <<<<<<<
	option norelease '1'
	list dns '9.9.9.9'             <<<<<<<

It works the same for me too!

Nope, I don't think so.

I did it, that works.

I noticed a weird (or interesting?) thing:
I re-enabled PBR and set two PBR policies

I have already configured inside dnsmasq:
list server '/ipleak.net/bbc.com/103.86.96.100'

The result of this is:

I got 16 servers, is it normal? It just seems very strange to me, this happens when you use the policy with:

  • remote address: 103.86.96.100
  • chain: OUTPUT
  • interface: wg_surf_it

And finally I get the ip of the vpn thanks to the PBR policy:

  • remote address: ipleak.net
  • chain: PREROUTING
  • interface: wg_surf_it

That is exactly what the doctor ordered.

You let the Domain name ( ipleak.net) be resolved by 103.86.96.100.
You make sure that the route to this resolver (103.86.96.100) is via the VPN, as the resolving is by DNSMasq which sits on the router you have to use an OUTPUT rule.

Next make sure that the query you are doing as lan client for said domain (ipleak.net) also goes via the tunnel by making a PBR route for that same domain as PREROUTING rule

And now as your screenshot shows no DNS leak, the origin of ip address and DNS query are both from the VPN :slight_smile:

The reason you are not seeing 103.86.96.100 is because the VPN provider either hijacks the DNS53 request and/or if you use their own DNS server as in this case send the DNS request to another upstream resolver.
But it only matters that the origin of the DNS server is from the VPN and that works.

1 Like

How can I do it?

I left ipleaks.net that routes to Italy (as you saw in the screenshots), and if I wanted to add dnsleaktest.com in the list server (DNSMasq) with the same DNS 103.86.96.100 and same VPN however in Switzerland, is it possible to do that?

No, simply choose another DNS server e.g. 9.9.9.9 or 1.0.0.1 as long as it is not in use elsewhere in your network.

I repeat it doesn't really matter what DNS server you are using as long as it is routed via the tunnel, that way the origin of the DNS and origin of your IP address is the same and that is what is tracked by e.g. netflix, amazon, bbc etc.

To get some more information about DNS you can use the dig command

opkg update
opkg install bind-dig

Usage: https://www.geeksforgeeks.org/dig-command-in-linux-with-examples/
e.g.: dig +trace

1 Like

If I have IPs (not domains) to route to DNS configured, for example IPs to be routed:

  • 10.0.1.2.3
  • 10.2.5.1.21
  • 54.10.5.3

And I want to route them to DNS, for example, 103.50.15.15

In DNSMasq would I configure the same thing?

list server '/10.0.1.2.3/10.2.5.1.21/54.10.5.3/103.50.15.15'

After that I create two PBR policies by putting it like this:
The first one:

  • remote address: 103.50.15.15
  • chain: OUTPUT
  • interface: wg_surf_it

The second one:

  • remote address: '10.0.1.2.3 10.2.5.1.21 54.10.5.3'
  • chain: PREROUTING
  • interface: wg_surf_it

Is the form correct?

This is nonsense, a DNS server is to translate a Domain name into an IP address.

So, what do I do for that?

It depends on what those IP addresses are and what you want to do with it.

Some site for some strange reason, it still sees my ISP IP so I had to take the remote IPs of some site and route them to VPN so that they use the VPN IP instead of the ISP IP.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.