Route certain traffic through ProtonVPN

Hello Community, I hope you are doing great.

On my RB I have an up and running WG connection. I did follow this guide and it works perfectlyhttps://protonvpn.com/support/wireguard-mikrotik-routers/

But I do not want to route ALL the traffic through the VPN.

I want to route certain traffic based on URLs to the VPN. For example, if I want to visit youtube.com I want it to use the VPN

I have tried using with address list or layer 7 filter but probably I did something wrong so I started over, here is my conf

/interface ethernet
set [ find default-name=ether2 ] disabled=yes
/interface wireguard
add listen-port=13231 mtu=1420 name=wireguard1
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/ip pool
add name=default-dhcp ranges=192.168.88.10-192.168.88.254
/ip dhcp-server
add address-pool=default-dhcp interface=bridge lease-time=10m name=defconf
/ip smb users
set [ find default=yes ] disabled=yes


/ip neighbor discovery-settings
set discover-interface-list=LAN
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
add interface=ether2 list=WAN
add interface=wireguard1 list=WAN
/interface wireguard peers
add allowed-address=0.0.0.0/0 endpoint-address=37.19.221.198 endpoint-port=\
    51820 interface=wireguard1 name=wireguardpeer persistent-keepalive=25s \
    public-key="xxxx"
/ip address
add address=192.168.88.1/24 comment=defconf interface=bridge network=\
    192.168.88.0
add address=10.2.0.2/30 interface=wireguard1 network=10.2.0.0

/ip dhcp-client
add add-default-route=no comment=defconf interface=ether1 use-peer-dns=no
/ip dhcp-server lease
add address=192.168.88.2 client-id=1:d8:32:14:e4:1c:88 mac-address=\
    D8:32:14:E4:1C:88 server=defconf
add address=192.168.88.10 client-id=1:0:1d:92:ee:6d:38 mac-address=\
    00:1D:92:EE:6D:38 server=defconf
add address=192.168.88.254 client-id=1:5e:b:17:99:8b:55 mac-address=\
    5E:0B:17:99:8B:55 server=defconf
/ip dhcp-server network
add address=192.168.88.0/24 comment=defconf dns-server=192.168.88.1 gateway=\
    192.168.88.1
/ip dns
set allow-remote-requests=yes cache-size=32768KiB servers=\
    208.67.222.222,10.2.0.1
/ip dns adlist
add file=sblack-adlist ssl-verify=no
add file=wblock ssl-verify=no

/ip firewall filter
add action=accept chain=input comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
    invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment=\
    "defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=drop chain=input comment="defconf: drop all not coming from LAN" \
    in-interface-list=!LAN
add action=accept chain=forward comment="defconf: accept in ipsec policy" \
    ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" \
    ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
    connection-state=established,related disabled=yes hw-offload=yes
add action=accept chain=forward comment=\
    "defconf: accept established,related, untracked" connection-state=\
    established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
    connection-state=invalid
add action=drop chain=forward comment=\
    "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \
    connection-state=new in-interface-list=WAN

/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" \
    ipsec-policy=out,none out-interface-list=WAN

/ip route
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=192.168.1.1 \
    pref-src="" routing-table=main suppress-hw-offload=no
add disabled=yes distance=1 dst-address=0.0.0.0/1 gateway=10.2.0.1 pref-src=\
    "" routing-table=main scope=30 suppress-hw-offload=no target-scope=10
add disabled=yes distance=1 dst-address=128.0.0.0/1 gateway=10.2.0.1 \
    pref-src="" routing-table=main scope=30 suppress-hw-offload=no \
    target-scope=10
add disabled=yes distance=1 dst-address=37.19.221.198/32 gateway=192.168.1.1 \
    routing-table=main scope=30 suppress-hw-offload=no target-scope=10

Multiple issues here.

First, you cannot use layer7 rules to look for the fqdn in TCP packets because the first packet of a TCP session does not carry that bit of information, and you have to decide which route to use already when handling that packet. Leaving aside that from TLS 1.3 onwards, the fqdn is not present in the TCP payload in plaintext any more (which might be useful if you wanted to use it to block some traffic rather than to route it).

So the address-list approach where you define the address as an fqdn looks better at first glance, as the fqdn gets resolved to a list of IP addresses and you can refer to the list in the mangle rules. However, there are two moments that break that idea as well:

  • multiple fqdns are often hosted by the same IP address, so you cannot handle e.g. youtube.com and google.com separately (which might not be a problem for your use case)
  • a single web page consists of many components and the top level html document loaded from the url you have specificed in the browser may contain many links to other urls with totally different fqdns, so you’ll load the youtube page layout from youtube.com via the tunnel but the video itself may download via the regular WAN, which would probably ruin the purpose of the whole exercise.

In other words, the requirements are not possible to meet based on what has been stated.
You can elect to
a. use a single port to send all traffic to wireguard
b. use an SSID and wlan to send all traffic to wireguard
c. use a vlan to send all traffic to wireguard
d. use an IP address or a few them to wireguard

the above can all be solved by using routing rules.
++++++++++++++++++++++++++++++++++++++

If you need any other grouping that can only be described by a firewall address list, then you will need to get into mangling.

Definitely, you are the Gurus here…!

I thought that the if we are threating the VPN as an interface (the same way we do a PCC with a secondary WAN connection) we could decide where to route certain traffic.

I understand the example about the web page and the video loading from different sources but I really thought you can mark the connection and route it inside the interfaces.

Thank you so much for the help

You indeed can mark a “connection” and you can route packets belonging to a given connection in a specific way, and you can indeed treat a VPN tunnel as yet another WAN.

The thing is the precise meaning of “connection” - in the firewall vernacular, it means a single TCP, UDP or similar session between two IP addresses and ports, and the match criteria you can use to mark the connection. The task becomes different if, instead of saying “I want to access web site XYZ via VPN”, you say “I want all devices connected to SSID blue-strawberry to access the internet via VPN” or something similar.

Another feasible way: some people managed more or less successfully to use a list of IP addresses assigned to ISPs in their country to use direct connection for “local” traffic and VPN for all the rest, but whether one can do this using a Mikrotik device depends on the size of that device’s RAM and the size of the country in terms of IP prefixes.