Wireguard ProtonVPN config for a single IP

Hi,

I am trying to force a machine (192.168.20.9) traffic through a ProtonVPN wireguard interface configured on my RB5009.

I created a Wireguard interface on the router, added the router as peer, gave it an address.
Also added the WG interface to the WAN list (to use the masquerade NAT rule), created a routing table “proton” and a route for everything to go through the WG interface.
I added a routing rule to have the machine lookup-only-in-table proton.

The machine is configured to use Proton DNS (10.2.0.1) but DNS resolution fails.

I added some logs on a dummy rule in the firewall and even allowed all forward traffic for this ip but here is what I see when I try to curl google.com.

Log everything forward: in:vlan20-core out:wg-protonvpn, connection-state:new src-mac xx:xx:xx:xx:xx:xx, proto UDP, 192.168.20.9:37505->10.2.0.1:53, len 56
Accept everything forward forwa: in:vlan20-core out:wg-protonvpn, connection-state:new src-mac xx:xx:xx:xx:xx:xx8, proto UDP, 192.168.20.9:37505->10.2.0.1:53, len 56
Log everything forward: in:vlan20-core out:wg-protonvpn, connection-state:new,snat src-mac xx:xx:xx:xx:xx:xx, proto UDP, 192.168.20.9:37505->10.2.0.1:53, NAT (192.168.20.9:37505->10.2.0.2:37505)->10.2.0.1:53, len 56
Accept everything forward forwa: in:vlan20-core out:wg-protonvpn, connection-state:new,snat src-mac xx:xx:xx:xx:xx:xx, proto UDP, 192.168.20.9:37505->10.2.0.1:53, NAT (192.168.20.9:37505->10.2.0.2:37505)->10.2.0.1:53, len 56

Not sure if that matters but the machine is on a Proxmox host which has a single NIC (ether6) configured as a vlan aware bridge, then I can give guests a virtual NIC with different VLAN ids and it seems to be working fine so far.

The proxmox host network config :

iface eno1 inet manual
        post-up /usr/sbin/ethtool -s eno1 wol g
#NUC physical interface

auto vmbr0
iface vmbr0 inet manual
        bridge-ports eno1
        bridge-stp off
        bridge-fd 0
        bridge-vlan-aware yes
        bridge-vids 2-4094
#VLAN aware bridge

auto vmbr0.10
iface vmbr0.10 inet static
        address 192.168.10.10/24
        gateway 192.168.10.1
#Management VLAN

And the machine network config:

root@machine:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: eth0@if335: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.20.9/24 brd 192.168.20.255 scope global dynamic eth0
       valid_lft 38619sec preferred_lft 38619sec
    inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link 
       valid_lft forever preferred_lft forever
root@machine:~# ip route
default via 192.168.20.1 dev eth0 
192.168.20.0/24 dev eth0 proto kernel scope link src 192.168.20.9 
root@machine:~# cat /etc/resolv.conf 
nameserver 10.2.0.1

You can find my router config attached to this post.

Thanks for your help
conf-2024-06-22.rsc (23.2 KB)

Dont see anything on a quick review…
Yes one can either add proton interface to WAN interface list or separate srcnat rule, both work.

(1) Do you have a firewall rule allowing single device to enter proton tunnel?

(2) simplify the rule…
/routing rule
add action=lookup-only-in-table src-address=192.168.20.9/32 table=proton

  1. Recommend to go along with (1) Add a dst nat rule.

add chain=dstnat action=dst-nat src-address=192.168.20.9/32 dst-port=53 protocol=udp to-address=10.2.0.1
add chain=dstnat action=dst-nat src-address=192.168.20.9/32 dst-port=53 protocol=tcp to-address=10.2.0.1

Sometimes they may give an obscure not directly related DNS address to use like lets say 10.4.12.2
In this case you would also want to add a routing rule.
add dst-address=10.4.12.2 gateway=wg-protonvpn routing-table=main.

However in this case the DNS address is within the subnet of the address you have for wireguard.
I tend to use /24 on my wireguard address definition not /30 etc… What if the dns address they gave you was 10.2.0.200 …

  1. I have configured this temporary rule, it should be enough right ?
    /ip firewall filter add action=accept chain=forward src-address=192.168.20.9
    I enabled logs on this rule and tried to ping 8.8.8.8 :
    Accept everything forward forwa: in:vlan20-core out:wg-protonvpn, connection-state:new src-mac, proto ICMP (type 8, code 0), 192.168.20.9->8.8.8.8, len 84
    Accept everything forward forwa: in:vlan20-core out:wg-protonvpn, connection-state:new,snat src-mac, proto ICMP (type 8, code 0), 192.168.20.9->8.8.8.8, NAT (192.168.20.9->10.2.0.2)->8.8.8.8, len 84
    Accept everything forward forwa: in:vlan20-core out:wg-protonvpn, connection-state:new,snat src-mac, proto ICMP (type 8, code 0), 192.168.20.9->8.8.8.8, NAT (192.168.20.9->10.2.0.2)->8.8.8.8, len 84

    But I get Destination Host Unreachable on the machine.

  2. Done

  3. Done, but still not resolving .. Btw I don’t understand this rule, why are we using src-address=192.168.20.9/32 with no dst-address on the dstnat chain ?

I checked the routing table configured by the wireguard’s wg-quick on a test device, maybe I’m missing something I need to configure on the router ? I can’t really tell..

root@test:~# ip route show table all
default dev FR-77 table 51820 scope link 
default via 192.168.20.1 dev eth0 
192.168.20.0/24 dev eth0 proto kernel scope link src 192.168.20.11 
local 10.2.0.2 dev FR-77 table local proto kernel scope host src 10.2.0.2 
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1 
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1 
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1 
local 192.168.20.11 dev eth0 table local proto kernel scope host src 192.168.20.11 
broadcast 192.168.20.255 dev eth0 table local proto kernel scope link src 192.168.20.11 
fe80::/64 dev eth0 proto kernel metric 256 pref medium
local ::1 dev lo table local proto kernel metric 0 pref medium
local fe80::xxx dev eth0 table local proto kernel metric 0 pref medium
multicast ff00::/8 dev eth0 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev FR-77 table local proto kernel metric 256 pref medium

Also checked the DNS used when connected and ProtonVPN pushes 10.2.0.1.

First, details matter
(1) the request was to do this in firewall forward chain.
add chain=forward action=accept src-address=192.168.20.9/32 out-interface=wg-protonvpn log=yes log=prefix=“outbound proton”

(2) why did you try pinging anything untilt he rest of the rules were completed?
Also dont care about pinging try to reach the internet..

(3) The destination rule has a destination, the TO-ADDRESS.
The rule basically says anything from192.168.20.9/32 heading towards port53, send to 10.2.0.1

The router knows about the wg interface, routing exists so will send this traffic to wg-protonvpn etc…

+++++++++++++++++

Repost your config with the changes made and will take a second look.

Oh I guess I was confused about 3) because I only ever used dst-nat for inbound traffic on the WAN, I’ll read more about it.

Here is the updated config with your suggestions, thank you so much for your help.
updated-conf-2024-06-22.rsc (23.4 KB)

I finally found the problem, my wireguard peer was configured with allowed-address=::/0, I switched to 0.0.0.0/0 and it’s now working :slight_smile:

Yes that would do it, I assumed that was short form for 0.0.0.0/0 and didnt mention it. I will know better next time thanks for the feedback.
Glad its working for ya.