WireGuard and pbr - could not stop DNS Leak so far

My actual scenario is:

The WireGuard client is not used as default routing and I have created policies to selectively use the WireGuard client, as instructed in stangri’s Policy-Based Routing documentation.

But I'm facing DNS leaks, checked on devices selectively connected to WG;

Tried the solution proposed in this post, but with no success so far.

I really would appreciate any help.

Config files info:

/etc/config/network

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

config globals 'globals'
        option ula_prefix '...::/48'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'lan1'
        list ports 'lan2'
        list ports 'lan3'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'
        option ip6assign '60'

config device
        option name 'wan'
        option macaddr '...'

config interface 'wan'
        option device 'wan'
        option proto 'dhcp'

config interface 'wan6'
        option device 'wan'
        option proto 'dhcpv6'
        option reqaddress 'try'
        option reqprefix 'auto'
        option delegate '0'

config interface 'wg0'
 option proto 'wireguard'
        option private_key '...'
        list addresses '.../16'
        option peerdns '0'
        list dns '162...57'
        list dns '149...92'
        option defaultroute '0'

config wireguard_wg0
        list allowed_ips '0.0.0.0/0'
        list allowed_ips '::/0'
        option route_allowed_ips '1'
        option endpoint_host '...'
        option endpoint_port '51820'
        option description '...'
        option public_key '...'
/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 authoritative '1'
        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'

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 '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'

config host
        option name 'iPhone1'
        option dns '1'
        option mac 'mac_address_iPhone1'
        option ip '192.168.1.21'

config mac 'wg0'
        option mac 'mac_address_iPhone1'
        option network 'wg0'
        list dhcp_option '6,162...57 149...92'

/etc/config/firewall


config defaults
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option synflood_protect '1'

config zone
        option name 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        option mtu_fix '1'
        list network 'lan'

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

config forwarding
        option src 'lan'
        option dest 'wan'

config rule
        option name 'Allow-DHCP-Renew'
        option src 'wan'
        option proto 'udp'
        option dest_port '68'
        option target 'ACCEPT'
        option family 'ipv4'

config rule
        option name 'Allow-Ping'
        option src 'wan'
        option proto 'icmp'
        option icmp_type 'echo-request'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-IGMP'
        option src 'wan'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-DHCPv6'
        option src 'wan'
        option proto 'udp'
        option dest_port '546'
        option family 'ipv6'
        option target 'ACCEPT'
config rule
        option name 'Allow-MLD'
        option src 'wan'
        option proto 'icmp'
        option src_ip 'fe80::/10'
        list icmp_type '130/0'
        list icmp_type '131/0'
        list icmp_type '132/0'
        list icmp_type '143/0'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Input'
        option src 'wan'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        list icmp_type 'router-solicitation'
        list icmp_type 'neighbour-solicitation'
        list icmp_type 'router-advertisement'
        list icmp_type 'neighbour-advertisement'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Forward'
        option src 'wan'
        option dest '*'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
 list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-IPSec-ESP'
        option src 'wan'
        option dest 'lan'
        option proto 'esp'
        option target 'ACCEPT'

config rule
        option name 'Allow-ISAKMP'
        option src 'wan'
        option dest 'lan'
        option dest_port '500'
        option proto 'udp'
option target 'ACCEPT'

config include 'pbr'
        option fw4_compatible '1'
        option type 'script'
        option path '/usr/share/pbr/pbr.firewall.include'

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

config forwarding
        option src 'lan'
        option dest 'vpn'
/etc/config/pbr

config pbr 'config'
        option verbosity '2'
        option strict_enforcement '1'
        option ipv6_enabled '0'
        option boot_timeout '30'
        option rule_create_option 'add'
        option procd_reload_delay '1'
        list webui_supported_protocol 'all'
        list webui_supported_protocol 'tcp'
        list webui_supported_protocol 'udp'
        list webui_supported_protocol 'tcp udp'
        list webui_supported_protocol 'icmp'
        option enabled '1'
        list ignored_interface 'vpnserver'
        list ignored_interface 'wgserver'
        option webui_show_ignore_target '0'
        option resolver_set 'dnsmasq.ipset'

config include
 option path '/usr/share/pbr/pbr.user.aws'

config include
        option path '/usr/share/pbr/pbr.user.netflix'

config policy
        option name 'Ignore Local Traffic'
        option interface 'ignore'
        option dest_addr '192.168.200.0/24'

config policy
        option name 'Plex/Emby Local Server'
        option interface 'wan'
        option src_port '8096 8920 32400'
        option enabled '0'

config policy
        option name 'Plex/Emby Remote Servers'
        option interface 'wan'
       option dest_addr 'plex.tv my.plexapp.com emby.media app.emby.media tv.e>
        option enabled '0'

config policy
        option name 'WireGuard Server'
        option interface 'wan'
        option src_port '51820'
        option chain 'output'
        option proto 'udp'
        option enabled '0'

config policy
        option name 'iPhone1'
        option src_addr 'mac_address_iPhone1'
        option interface 'wg0'

config policy
        option interface 'wan'
        option dest_addr 'flxvpn.net netflix.ca netflix.com netflix.com.au netf...>
        option name 'Netflix Domains'
        option enabled '0'

The syntax doesn't seem quite right.
Also make sure there is a comma between the two DNS servers listed.

config mac 'iPhone1'
        option mac 'mac_address_iPhone1'
        option networkid 'wg0'
        list dhcp_option '6,162...57,149...92'

https://openwrt.org/docs/guide-user/base-system/dhcp_configuration#client_classifying_and_individual_options

2 Likes

Wireguard is a Layer 2 interface, there is no DHCP (which works on Layer 2 to provide a Layer 3 address).

Hi @pavelgl , thanks for syntax obs. I've forgot to mention that i have observed that the syntax proposed in the post was different from the guideline, and I already tried like posted.

Just did again:

config mac 'wg0'
        option Mac 'mac_address_iPhone1'
        option networkid 'wg0'
        list dhcp_option '6,162...57,149....92'

Still getting DNS leaks...

Is the typo only in the post?
I tested the classifier and it works as expected.

config mac 'ASRock'
        option mac '00:25:D3:7D:38:C0'
        option networkid 'wg0'
        list dhcp_option '6,192.168.1.1,192.168.92.200'

image

You're not using DNS hijacking, are you?

Sorry for the typo in the previous post @pavelgl , but is not, in the config file the syntax is correct:
config_mac_wg0_edited

I'm not using DNS hijacking also:


Also my firewall config file was posted early.

And the DNS still leaks:

Thanks in advance

Hi @lleachii , i think it's layer 3 indeed: https://notes.superlogical.ch/pages/note_wg/nolayer2/#paper

But anyway, what can i do to stop DNS leaking from the WG interface when the WG client is not used as default routing, but selectively routed by pbr?

If it concerned me, I would simply route the IP of the DNS I'm using in question over WG.

E.g.

  • assign 1.1.1.1 to clients
  • route 1.1.1.1./32 over the tunnel

(I do this for wcfg and a WG-based WARP tunnel to send DNS to Cloudflare.)

:spiral_notepad: Be sure WG can resolve the peer endpoint address, or use the IP.

But this way, all the dns are resolved only by Cloudflare, despite of wg0 or wan routes, right?

My goal is:

Devices connected through WG has dns resolved by address informed in WG interface:

Devices connected directly through WAN has dns advertised by peers:
image

Based on this post apparently it can be done (without dns leaks). i'm trying to achieve it.

Yes - because the WG tunnel is CloudFlare (that's what WARP is).

Just FYI - I used a CloudFlare/WARP WG tunnel as an example. You'd use your own DNS server IP's and your current WG tunnel. Sorry if it caused confusion.

Hey, chiming in just because I got tagged:

I've spent some time just comparing our configs and don't see anything so far off as to explain your experience. And unfortunately I'm a total novice with OpenWRT and routing.

For what it's worth, biggest things I was helped with in that thread:

  1. option src_addr '192.168.1.225/32' for the device's policy src_addr (the /32 was something I was missing)
  2. Using the single DNS provided to the WG interface (I see you're using two)

Hope someone else can help out, though.

2 Likes

@trendy ,

You solved @inadeqtfuturs pbr dns leak issue.

could you please help me too?

Thanks in advance

  • What's stopping you from doing this?
  • Perhaps you can explain what issues you're having?

You configure your WG clients with the IP that's routed thru Wireguard - just as I noted.

Well, i thought you have understood what i already did and the issue that i'm facing, because you posted early some advices.

But for the sake of understanding, i will summarize this post:

  • I already have a WireGuard interface fully functional in my router. It's not the default routing, so i have created policies to selectively use the WireGuard client, as instructed in stangri’s Policy-Based Routing documentation.;

  • Issues: there are DNS leaks, checked on devices selectively connected to WG;

  • What i already tried: the solution proposed in this post , but with no success so far;

  • I have provided my config files on the first post;

  • @pavelgl observed some syntax erros on mac classifier options. I answered that " i have observed that the syntax proposed in the post was different from the guideline , and I already tried like posted.". He observed that the classifier is working as expected in his machine;

  • @lleachii posted that "Wireguard is a Layer 2 interface, there is no DHCP (which works on Layer 2 to provide a Layer 3 address).". I said that "i think it's layer 3 indeed: https://notes.superlogical.ch/pages/note_wg/nolayer2/#paper";

  • @lleachii proposed a solution: "I would simply route the IP of the DNS I'm using in question over WG." i ansewered that it implies that all the dns are resolved only by dns advertised by WG, despite of wg0 or wan routes. I reiterated that what i need is "devices connected through WG with dns resolved by address informed in WG interface", and "devices connected directly through WAN with dns advertised by peers" (excluding the dns used by the WG interface);

  • @inadeqtfuturs has compared our configs and didn't saw anything so far off as to explain my experience (dns persisting leaks);

  • @trendy has solved @inadeqtfuturs wireguard over pbr dns leaks issues in this post. So by now i really would appreciate a helping hand from @trendy , if it's possible;

Thanks again for all the help so far;

That is incorrect. It would use whatever IP you assign them. There is no "advertised by WG". Wireguard peers are statically configured. In fact, I never suggested editing the WG config.

So did you try?

Eg, use 9.9.9.9:

  1. Assign all clients the DNS server 9.9.9.9
  2. Then:
config route
        option target '9.9.9.9'
        option netmask '255.255.255.255'
        option interface 'wg0'

or

config route
        option target '9.9.9.9/32'
        option interface 'wg0'

You can choose any IP, so you can exclusively assign it to clients using WG via Step 1, hence no leak. As long as you assign the peers the correct IP, they'll use the correct server, it seems optional for Step 2- that you wish/need to tunnel to the desired DNS over WG too.

It's kinda odd to say it won't work, when I (and others) are noting to you that they have setups with no DNS leaks.

I see one as well, and corrected, based on the information I've provided:

config mac 'iPhone1'
        option mac 'mac_address_iPhone1'
        option networkid 'lan' #<---I assume this needs to be LAN, not wg0
        list dhcp_option '6,9.9.9.9'

WG is Layer 3, so you cannot make assignments via DHCP in that manner. You have to configure the iPhone if it's connected via Wireguard, see e.g. setting:

  • Phone will use 9.9.9.9 when connected to peer (OpenWrt) - i.e. Step 1
  • 9.9.9.9 will be routed thru WG - i.e. Step 2

If you want to set the route more specifically, see: https://openwrt.org/docs/guide-user/network/routing/routes_configuration

The route statement can be customized to specify: SRC IP/range, etc. so only your WG IP SRC range will use WG for reaching the e.g. IP of 9.9.9.9.

Have you checked what DNS servers the devices in question are getting via DHCP?
Are you sure they don't have some additional hardcoded DNS settings or are not using DoH/DoT?

Try intercepting the (normal) DNS traffic and then redirect it to one of the servers to see if it makes a difference.

uci add firewall redirect
uci set firewall.@redirect[-1].target='DNAT'
uci set firewall.@redirect[-1].name='DNS-Test'
uci set firewall.@redirect[-1].src='lan'
uci add_list firewall.@redirect[-1].src_mac='mac_address_iPhone1'
uci add_list firewall.@redirect[-1].proto='udp'
uci add_list firewall.@redirect[-1].proto='tcp'
uci set firewall.@redirect[-1].src_dport='53'
uci set firewall.@redirect[-1].dest_ip='162...57'
uci set firewall.@redirect[-1].dest_port='53'
uci commit firewall
/etc/init.d/firewall restart
1 Like

I tried the solutions proposed:

@lleachii

Solution 1:

  1. Assign all clients the DNS server 9.9.9.9 : done
  2. Then
config route
        option target '9.9.9.9'
        option netmask '255.255.255.255'
        option interface 'wg0

Done.

I got an error on pbr:

Also tried alternative way:

config route
        option target '9.9.9.9/32'
        option interface 'wg0'

Got the same error on pbr.

@pavelgl :

Tried the redirect firewall rule as proposed (via uci commands), as shown in luci interface:

Still getting dns leaks.

Then I checked what you observed:

Have you checked what DNS servers the devices in question are getting via DHCP?
Are you sure they don't have some additional hardcoded DNS settings or are not using DoH/DoT?

I figured out that Safari was using a private relay iCloud option enabled, messing up the dns leaking test. Checking again with private relay disabled it works without leaks.

So, the solution proposed by @trendy in this post worked for me, with syntax corrected (on my settings) by @pavelgl:

config mac 'wg0'
         option mac 'mac_address_iPhone1'
         option networkid 'wg0'
         list dhcp_option '6,162...57,149...92'

The same solution as proposed by @lleachii with 'lan' instead of 'wg0' also worked. In my tests, both networkid`s worked. I didn't understood yet why using networkid 'wg0' option the dns (162...57,149...92) keeps even when connected outside wg0...

Finally, I also tried tagging group option and it worked the same way as mac classifier:

config tag 'tag1'
         option dhcp_option '6,162...57,149...92'

config host
         option name 'iPhone1'
         option mac 'mac_address_iPhone1'
         option tag 'tag1'

This way I could assign the tag option to other hosts I want to route through 'wg0', and all those clients got no dns leaks in my tests.

But, the disadvantage of those methods is that when I route devices outside 'wg0' the dns remains the same used in 'wg0'...

Anyway, I finally got my devices selectively routed by pbr through wireguard interface without dns leaks!

Thanks again @lleachii , @pavelgl and @inadeqtfuturs for the attention and support.

Just to clarify, the job of the networkid option is only to set a tag, so you can use whatever you want.

1 Like