WireGuard - dynamic routes

Hello,

I need some guidance on what I am doing wrong. WireGuard connection is set up and working, but I have problem with dynamic routes.

Idea: Have list of domains that are using WireGuard connection, rest of traffic goes through normal ISP connection.

Working solution (but not dynamic):

ip route add disabled=no distance=1 dst-address=142.44.215.161/32 gateway=wireguard3 routing-table=main scope=30 suppress-hw-offload=no target-scope=10

Wish solution, but not working one:

ip firewall address-list add address=wtfismyip.com list=vpn
routing table add disabled=no fib name=vpn
ip firewall mangle add action=mark-routing chain=prerouting dst-address-list=vpn new-routing-mark=vpn
ip route add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=wireguard3 routing-table=vpn scope=30 suppress-hw-offload=no target-scope=10
ip firewall nat add action=masquerade chain=srcnat out-interface=wireguard3

Thank you.

Would need to see the complete config,
but it sounds like you want the users on your subnets to use wireguard for specific WANIPs that exist, and where they are not static but dynamic WANIPs.

First, please do not use the same name for different RoS funcitonalites, aka the name of the list being the same as a special table entry “vpn”. Bad move.
examples…
list=vpn-external-IPs
table name=useWG

Approach. if it was some number less than 5 WANIPs I would be tempted to forgo any mangling and just use routing rules with the special table and route for the table.

/routing rule
add dst-address=X>X>X>X action=lookup-in-table table=useWG
etc…

If the list was to onerous, then I would go the mangle route.
/ip firewall mangle.
add action=mark-routing dst-address-list=vpn-external-IPs
new-routing-mark=useWG

The firewall address list would look like
add address=domainnameA list=vpn-external-IPs
add address=domainnameB list=vpn-external-IPs
etc…

Hi Anav,

You made some very good points and hit exactly what I was trying to achieve.

I have renamed the “vpn” stuff to the appropriate ones.

Idea is to get a dynamic list because some of the domains have multiple A records and DNS resolution in address list would be super easy.

Problem is:

  • IP record in main routing table = works
  • IP record in route rule for new table = works
  • mangle for address list = doesn’t work at all (traffic stops on wireguard3 gateway)

I just think I’m missing a small step and can’t find it.

My super easy config:

# 2025-04-10 10:52:00 by RouterOS 7.18.2
# software id = NNB9-6TRS
#
# model = RBD52G-5HacD2HnD
# serial number = XXXX
/interface bridge
add name=bridge-lan port-cost-mode=short
/interface ethernet
set [ find default-name=ether1 ]
set [ find default-name=ether2 ]
set [ find default-name=ether3 ]
set [ find default-name=ether5 ]
/interface wireguard
add listen-port=13531 mtu=1420 name=wireguard3
/ip pool
add name=dhcp_pool0 ranges=10.0.10.20-10.0.10.199
/ip dhcp-server
add address-pool=dhcp_pool0 interface=bridge-lan lease-time=2d name=dhcp1
/ip smb users
set [ find default=yes ] disabled=yes
/routing table
add disabled=no fib name=vpn-route
/interface bridge port
add bridge=bridge-lan interface=ether2 internal-path-cost=10 path-cost=10
add bridge=bridge-lan interface=ether3 internal-path-cost=10 path-cost=10
add bridge=bridge-lan interface=ether4 internal-path-cost=10 path-cost=10
add bridge=bridge-lan interface=ether5 internal-path-cost=10 path-cost=10
add bridge=bridge-lan interface=wlan1 internal-path-cost=10 path-cost=10
add bridge=bridge-lan interface=wlan2 internal-path-cost=10 path-cost=10
/ip firewall connection tracking
set udp-timeout=10s
/ip settings
set rp-filter=strict
/ipv6 settings
set disable-ipv6=yes max-neighbor-entries=8192
/interface wireguard peers
add allowed-address=0.0.0.0/0 comment=ProtonVPN endpoint-address=XXXX endpoint-port=51820 interface=wireguard3 name=ProtonVPN persistent-keepalive=1m public-key="XXXXX"
/ip address
add address=10.0.10.254/24 interface=bridge-lan network=10.0.10.0
add address=10.2.0.2/24 interface=wireguard3 network=10.2.0.0
/ip cloud
set ddns-enabled=yes ddns-update-interval=1h
/ip dhcp-client
add interface=ether1
/ip dhcp-server lease
add address=10.0.10.230 client-id=1:18:fd:74:7f:8:e mac-address=18:FD:74:7F:08:0E server=dhcp1
/ip dhcp-server network
add address=10.0.10.0/24 dns-server=8.8.8.8,1.1.1.1 gateway=10.0.10.254 ntp-server=10.0.10.254
/ip dns
set allow-remote-requests=yes servers=8.8.8.8,1.1.1.1
/ip firewall address-list
add address=wtfismyip.com list=vpn-traffic
add address=hunterra.com list=vpn-traffic
/ip firewall filter
add action=accept chain=forward comment="ERU allow flow" connection-state=established,related,untracked
add action=drop chain=forward comment="DROP invalid - forward" connection-state=invalid
add action=accept chain=input comment="ERU allow flow" connection-state=established,related,untracked
add action=drop chain=input comment="DROP invalid - input" connection-state=invalid
add action=drop chain=forward comment="DROP ALL" in-interface=ether1
add action=accept chain=input comment="MikroTik (lan)" connection-state=new dst-port=22,8292 in-interface=bridge-lan protocol=tcp
add action=drop chain=input comment="DROP ALL" in-interface=ether1
/ip firewall mangle
add action=mark-routing chain=prerouting dst-address-list=vpn-traffic new-routing-mark=vpn-route
/ip firewall nat
add action=masquerade chain=srcnat out-interface=wireguard3 to-addresses=10.2.0.2
add action=masquerade chain=srcnat out-interface=ether1
/ip ipsec profile
set [ find default=yes ] dpd-interval=2m dpd-maximum-failures=5
/ip route
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=wireguard3 routing-table=vpn-route scope=30 suppress-hw-offload=no target-scope=10
add disabled=no distance=1 dst-address=10.2.0.0/24 gateway=wireguard3 routing-table=vpn-route scope=30 suppress-hw-offload=no target-scope=10
/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
set ssh port=22
set api disabled=yes
set api-ssl disabled=yes
/ip smb shares
set [ find default=yes ] directory=/flash/pub
/ip ssh
set always-allow-password-login=yes forwarding-enabled=both host-key-size=4096 host-key-type=ed25519 strong-crypto=yes
/ip upnp
set enabled=yes
/ip upnp interfaces
add interface=ether1 type=external
add interface=bridge-lan type=internal
/system clock
set time-zone-name=Europe/Prague
/system identity
set name=XXX
/system note
set show-at-login=no
/system ntp client
set enabled=yes
/system ntp server
set enabled=yes manycast=yes
/system ntp client servers
add address=0.cz.pool.ntp.org
add address=1.cz.pool.ntp.org
/tool bandwidth-server
set enabled=no
/tool graphing
set store-every=24hours
/tool graphing interface
add store-on-disk=no
/tool graphing resource
add store-on-disk=no
/tool romon
set enabled=yes
  1. Typically the recommendation here is loose, not strict!
    /ip settings
    set rp-filter=strict

  2. Lack of decent set of firewall rules, plus should be organized together in chains and in a coherent order.
    PLUS security infraction, one does not access winbox from external as you are attempting. Only arrive at the router via VPN and then use winbox.
    SSH22 is a type of encrypted connection service on the router so that can remain. But if using the service on the router (input chain), then it has nothing to with any bridge lan entity.
    I would never use default port by the way… for any config settings…

/ip firewall filter
{ default rules to keep }
add action=accept chain=input connection-state=established,related,untracked
add action=drop chain=input connection-state=invalid
add action=accept chain=input protocol=icmp
add action=accept chain=input dst-address=127.0.0.1

(admin rules)
add action=accept chain=input comment=“SSH handshake” dst-port=20022 protocol=tcp
add action=accept chain=input comment=“LAN access to config and services” in-interface=bridge-lan
add action=drop chain=input comment=“drop all else”
{ insert this rule here last of all rules so you dont lock yourself out }
+++++++++++++++++++++
{ default rules to keep }
add action=fasttrack-connection chain=forward connection-state=established,related
add action=accept chain=forward connection-state=established,related,untracked
add action=drop chain=forward connection-state=invalid
add action=accept chain=forward comment=“internet traffic” in-interface=bridge-lan out-interface=ether1
add action=accept chain=forward comment=“lan to wg” in-interface=bridge-lan dst-address=vpn-traffic out-interface=wireguard3
add action=accept chain=forward comment=“port forwarding” connection-nat-state=dstnat disabled=yes { enable if required or remove }
add action=drop chain=forward comment=“drop all else”

set ssh port=20022

  1. Masquerade rule is incorrect, remove the to-address part, that is only when you use action=src-nat.
    In this case we are correctly using masquerade so should look like…
    add action=masquerade chain=srcnat out-interface=wireguard3

  2. You have two routes for Wireguard, you only need one.
    A route on the main table is automatically created due to the IP address for wireguard.
    Also assumes for ether1 a default route was selected in ip dhcp client as I see none on the config for that.

Thus should only have
/ip route
add dst-address=0.0.0.0/0 gateway=wireguard3 routing-table=vpn-route

  1. Any reason why you need upnp enabled???

  2. The mangle rule with above fixes should work.

You are AMAZING!!!

Thank you very much.

That did the magic I needed and now everything is working. To be honest, I will never find this.

/ip settings set rp-filter=loose
  1. Fixed my issue

  2. I will take look on it, I was living in piece only bridge-lan devices can access this MikroTik, so I keep default ports there. Ether1 (internet) is not part of the bridge-lan.
    Rules are odered by traffic consumption - I was hoping is better for CPU usage.

This make sense - I don’t know how LAN devices was able to working without this rule.

add action=accept chain=forward comment="internet traffic" in-interface=bridge-lan out-interface=ether1
  1. Strange, in normal situation you can’t via WinBox add there IP, maybe some stuff from previous src-nat testing.

  2. Yes, maybe again leftover from playing with routing rules - thank you.

  3. No, should be there from default config - disabled now.

  4. You are right :slight_smile:

Thank you again very very much.

RoS is very for giving, many of the default settings are ALLOW by default, so unless you define what is allowed, everything is allowed.