Route only specific devices through Wireguard VPN

I want to use a wireguard VPN depending on the device (for privacy reasons), but I have trouble setting it up.

I cannot get the traffic to go through the VPN without setting route_allowed_ips to 1 on the VPN peer. When I do set route_allowed_ips, all traffic from ALL devices goes through the VPN.

I thought, if I set up the firewall forwarding like this:
vpn -> lan
lan -> wan

that route_allowed_ips would only apply for devices that are routed through lan. But that doesn't seem to be the case. Honestly, I don't even understand where exactly the routes are set once you change route_allowed_ips?

I setup a firewall rule:

config rule
	option name 'Allow iPhone to VPN'
	option src 'lan'
	list src_ip '192.168.1.158'
	option dest 'vpn'
	option target 'ACCEPT'
	list proto 'all'

With the above setup, the iPhones traffic goes through the VPN correctly. However, other devices don't have internet access any longer.

Happy about any hints, cheers :slight_smile:

https://openwrt.org/docs/guide-user/network/routing/pbr

1 Like

Yeah, I've tried pbr, but I don't really comprehend what the setup would look like.

In pbr, I setup a rule for the iPhone device to use the VPN interface.

But what about the other settings? I didn't manage to route only the iPhone traffic through the VPN and still allow other devices to connect without the VPN.

You already gave the answer yourself :slight_smile:
The PBR guide should also tell you this:

Sorry, I don't get it. What exactly do I need to change in order to apply the VPN only to certain devices and still let other devices through without the VPN?

So do not Enable Route Allowed IPs

Reboot after changing settings!

Yeah, but when I don't enable that, no traffic goes through the VPN at all. Nomatter what I do. I tried to route devices through the VPN interface using pbr or the firewall.

The firewall is not doing the routing, the firewall can prevent traffic via the LAN if you have setup a Kill switch e.g removing Forwarding from LAN to WAN

Actually, it does work now :smiley: I disabled route_allowed_ips and enabled pbr.

One more thing, though: On my iPhone, which is the device set in pbr to go through the VPN interface, the IP is from my VPN, but DNS is not. How can I stop DNS leaking?

And is there a way to set a kill-switch for specific devices? For example, when I reboot the router and pbr is not starting fast enough, there might be leaks :thinking:

PBR has settings specifically for DNS.
See the manual
If you also have implemented IPv6 use the MAC address as that will take care of both IPv6 and IPv4

There are other ways to do it as well see:

Sure make a firewall traffic rule for your specific device to block WAN access

1 Like

Thank you! WAN access block is working fine now.

I have setup DNS through pbr:

config policy
	option name 'iPhoneVpn'
	option src_addr '192.168.1.158'
	option interface 'wg0'

config dns_policy
	option name 'iPhoneVpnDns'
	option src_addr '192.168.1.158'
	option dest_dns 'wg0'

But it still leaks my DNS. Why could that be? Is iptables a safer bet?

I tried with port forwarding, too:

config redirect
    option name 'Force-DNS-WG'
    option target 'DNAT'
    option src 'vpn'
    option src_dport '53'
    option dest_ip 'my.vpn.dns'

config redirect
    option name 'Force-DNS-WG-IPv6'
    option target 'DNAT'
    option src 'vpn'
    option src_dport '53'
    option dest_ip 'my.vpn.dns.ipv6'

Nothing changed. DNS still leaks.

# /etc/config/pbr

config dns_policy
	    option name 'iPhoneVpnDns'
	    option src_addr '192.168.1.158'
	    option dest_dns 'my.vpn.dns'

or

# /etc/config/firewall

config redirect
        option target 'DNAT'
        option name 'Force-DNS-WG'
        option src 'lan'
        option src_dport '53'
        option src_ip '192.168.1.158'
        option dest_ip 'my.vpn.dns'
3 Likes

iptables are not used any more current, builds use fw4 with nftables.

The DNS policy actually uses nftables to redirect DNS.

To rule out that you did not set a valid DNS server on the interface use the following DNS Policy , I use 1.1.1.1 but use a well known DNS server which is not otherwise in use.

config dns_policy
	option name 'iPhoneVpnDns'
	option src_addr '192.168.1.158'
	option dest_dns '1.1.1.1'

This assumes that you have not implemented IPv6 on the router.

Reboot and wait two minutes before testing.

Check with your phone using ipleak.net your IP address should be the VPN's IP address and the DNS server should be Cloudfare

If that is not the case make sure your Phone and browser are using DNS53 and not Private DNS nowadays using private DNS is standard.

If your phone and browser are using DNS53 then lets see the output of:

nft list ruleset

See my notes about it: https://github.com/egc112/OpenWRT-egc-add-on/tree/main/stop-dns-leak#pbr-dns-policies

1 Like

Oh, it's due to Ipv6. I disabled Ipv6 on the phone and it works. No dns leaks.

I tried to setup two policies:

config dns_policy
	option name 'iPhoneVpnDns'
	option src_addr '192.168.1.158'
	option dest_dns '1.1.1.1'
config dns_policy
	option name 'iPhoneVpnDns'
	option src_addr '192.168.1.158'
	option dest_dns '2606:4700:4700::1111'

And enabled ipv6 support in pbr settings, but it still leaks my private dns.

Already told you this :slight_smile:

My notes also describe this please have a look.

Use the MAC address and set an IPv4 and IPv6 DNS server on the wg0 interface then you can use the MAC address as source and the wg0 interface as destination for just one DNS policy rule.
Then actually two DNS redirect rules are automatically made.
One with your IPv4 address to an IPv4 DNS server and one with your IPv6 address to the IPv6 DNS server.

As outlined in my notes

3 Likes

Thanks so much, that did the trick.

One last question: So right now I have set up the VPN only for one device. But actually I want it the other way around: Route every to the router connected device through the VPN, but not the router itself. Is that possible to set up?

Great you solved it.

If you use the local physical device name (see ifconfig) prepended with @ then everything connected to this device can use the vpn

1 Like

@egc Perfect. I almost got everything working exactly the way I wanted it to now. To get completely rid of DNS leaks I had to set noresolv to 1. I then set the DNS of the wan/wan6 interfaces to Cloudflare DNS and added a pbr rule for the router itself there, too. The only problem now is that the router itself does not use the Cloudflare DNS for some reason? (I also tried @eth1 instead of the router ip in Router itself uses WAN DNS)

pbr:

config policy
	option name 'All LAN devices use VPN'
	option src_addr '@br-lan'
	option interface 'wg0'

config dns_policy
	option name 'Router itself uses WAN DNS'
	option src_addr '192.168.1.1'
	option dest_dns 'wan'

config dns_policy
	option name 'All LAN devices use VPN DNS'
	option src_addr '@br-lan'
	option dest_dns 'wg0'

/tmp/resolv.conf.d/resolv.conf.auto:

# Interface wan
nameserver 1.1.1.1
nameserver 1.0.0.1
nameserver 2606:4700:4700::1111
nameserver 2606:4700:4700::1001
# Interface wan6
nameserver 1.1.1.1
nameserver 1.0.0.1
nameserver 2606:4700:4700::1111
nameserver 2606:4700:4700::1001
# Interface wg0
nameserver **vpndnsipv4**
nameserver **vpndnsipv6**

Kill-switch on firewall (works!):

config rule
	option name 'No WAN/WAN6 for connected devices'
	list proto 'all'
	option src '*'
	option dest 'wan'
	option target 'REJECT'

config rule
	option name 'Router still allowed to access WAN/WAN6'
	list proto 'all'
	option src '*'
	list src_ip '192.168.1.1'
	option dest 'wan'
	option target 'ACCEPT'

I think the problem is that the pbr rules for some reason can't target the router itself? I added this rule for testing and it didn't work:

config policy
	option name 'Router itself uses VPN'
	option src_addr '192.168.1.1'
	option interface 'wg0'

Then, I wonder, why can the router use my private DNS, when I set noresolv to 1?

Also, this is weird - nslookup is using 1.1.1.1 cloudflare dns:

root@OpenWrt:~# nslookup openwrt.org
Server:		1.1.1.1
Address:	1.1.1.1:53

Non-authoritative answer:
Name:	openwrt.org
Address: 64.226.122.113

Non-authoritative answer:
Name:	openwrt.org
Address: 2a03:b0c0:3:d0::1a51:c001

But on curl https://ipleak.net/json/ I see my private DNS.

Some background how DNS works:

First you have to carefully plan what you want to do regarding DNS.

Your default route is via the WAN assuming you are using DNSMasq for DNS resolution then DNSMasq will just follow the default route so DNS resolution is via the WAN

For your VPN clients you want DNS resolution via the VPN and this DNS Policy will take care of that, provide you have set an IPv4 and IPv6 DNS server on the WG interface then those DNS servers are used by your VPN clients and it is routed via the VPN

Clients using the WAN will just use DNSMasq and DNS is routed via the WAN so effectively you have Split DNS.

The router itself by default is also using DNSMasq for DNS resolution (this is configurable with option localuse if this is set to 0 it disables the use of DNSMasq , the router will then use the DNS servers set on the interfaces)

noresolv is only instructing DNSMasq not to use the DNS server set on the interfaces, in which case you have to add a DNS server under DHCP and DNS > Forwards > DNS Forwards
So it is not related to any routing or DNS leak

If you want a PBR rule to have effect on a process on the router (DNSMasq, DNS resolution) you have to use a PBR Policy on the OUTPUT chain.

Bottom line, first carefully plan what you want, you can make it very complicated but not sure if you should want that