Wireguard: work on specific interface

Hello!

I have HAP AC2 with ROS 7.2.1 connected to two ISPs, so I have two WANs.
There are static public IPs on each of those WANs. I have 2 default gateways in routing table with different distances.
There is a Wireguard “server” set up on this router. It’s used both for site-to-site connections and for road warriors (devices with access to the Internet via mobile networks).
Another complication is that one of the WG servers works on UDP/53 to let some of clients to bypass some ISPs’ blocks. Needless to say I also have DNS server that serves DNS zone :slight_smile:

What I want is to dedicate one WAN for all Wireguard traffic and another one for all other traffic.

I’ve tried to set up routing marking and dedicated routing tables together with routing rules but found that WG originated reply packet is always sourced with IP of WAN with lower distance.
Then I’ve realized that Wireguard works as a kernel driver, not user space application, and now I’m trying to understand if it possible at all to reach what I want without second router?

Thank you!

Check this thread for solution that worked for me. And if you’d be able to find out why exactly it works, I’d like you very much. :slight_smile:

How do you identify which users or subnets is for wireguard internet traffic ??
Do you mean all internet traffic (all users should go out wireguard or only for the users or subnets from question 1?

Ok, probably need to describe in more details.

I have one WG interface for outgoing internet traffic (for blocking override). I use huge routing table to forward users’ traffic via this interface.
Second WG interface listens on UDP/53, it’s for experiments now, but I plan to use it in the future as a main gate for road warriors.
WG-spider is used for site-to-site tunnels, several locations are connecting to this interface, I use it to have access to remote sites.
The traffic is forwarded to WG interfaces using pure routing table.

Regarding ISP. I have one 300Mbps WAN with strict and unpredictable blocking rules, I want to use it for state internet resources, in-country streaming services, etc
Second ISP is 100Mbps and I want to dedicate it to WG traffic.
Let’s assume first ISP has IP_A and second IP_B.
In routing table I have two default route records, route via WAN_A has less distance than via WAN_B.
What I see in packet sniffer - my router receives packet from remote to WAN_B, but the reply is sent with source IP = WAN_B.
So my question is - how to force wireguard to answer from the same address it’s received request to?

Well, I kind of solved it.
Only one client is now using “wrong” WAN, all other work fine, reply from WG on MT is sent via same interface as the request.

/interface wireguard add listen-port=15353 mtu=700 name=wg-53
/interface wireguard add listen-port=31626 mtu=1420 name=wg-spider

/interface ethernet set [ find default-name=ether1 ] loop-protect=off name=WAN-eth1
/interface ethernet set [ find default-name=ether5 ] loop-protect=off name=WAN-eth5

/interface wireguard peers add allowed-address=10.11.12.2/24 interface=wg-53 public-key="xxx"
/interface wireguard peers add allowed-address=10.1.1.1/32,172.28.0.0/24 comment=Remote1 interface=wg-spider public-key="x"
/interface wireguard peers add allowed-address=10.1.1.3/32,172.23.0.0/24 comment=Remote2 interface=wg-spider public-key="x"
/interface wireguard peers add allowed-address=10.1.1.5/32 comment=Warrior interface=wg-spider public-key="x"

/ip address add address=172.20.2.254/24 interface=LAN
/ip address add address=10.1.1.10/24 interface=wg-spider
/ip address add address=10.11.12.254/24 interface=wg-53
/ip address add address=1.1.1.1/24  interface=WAN-eth1
/ip address add address=1.1.2.1/24  interface=WAN-eth5 

/ip route add distance=1 dst-address=0.0.0.0/0 gateway=1.1.1.254%WAN-eth1 routing-table=out-wan1
/ip route add distance=1 dst-address=0.0.0.0/0 gateway=1.1.2.254%WAN-eth5 routing-table=out-wan5
/ip route add distance=1 dst-address=0.0.0.0/0 gateway=1.1.1.254%WAN-eth1 routing-table=main
/ip route add distance=1 dst-address=0.0.0.0/0 gateway=1.1.2.254%WAN-eth5 routing-table=main

/routing table add fib name=out-wan1
/routing table add fib name=out-wan5

/routing rule add action=lookup-only-in-table src-address=1.1.1.1/32 table=out-wan1
/routing rule add action=lookup-only-in-table src-address=1.1.2.1/32 table=out-wan5
/routing rule add action=lookup-only-in-table routing-mark=out-wan1 table=out-wan1
/routing rule add action=lookup-only-in-table routing-mark=out-wan5 table=out-wan5
/routing rule add action=lookup table=main

/ip firewall mangle add action=mark-routing chain=output new-routing-mark=out-wan1 passthrough=yes protocol=udp src-port=15353
/ip firewall mangle add action=mark-routing chain=output new-routing-mark=out-wan1 passthrough=yes protocol=udp src-port=31626
/ip firewall mangle add action=mark-connection chain=prerouting connection-mark=no-mark connection-state=new,untracked in-interface=WAN-eth1 new-connection-mark=wan1-conn passthrough=yes
/ip firewall mangle add action=mark-connection chain=prerouting connection-mark=no-mark connection-state=new,untracked in-interface=WAN-eth5 new-connection-mark=wan5-conn passthrough=yes
/ip firewall mangle add action=mark-routing chain=prerouting connection-mark=wan1-conn new-routing-mark=out-wan1 passthrough=yes
/ip firewall mangle add action=mark-routing chain=prerouting connection-mark=wan1-conn new-routing-mark=out-wan5 passthrough=yes

/ip firewall nat add action=masquerade chain=srcnat out-interface=WAN-eth1
/ip firewall nat add action=masquerade chain=srcnat out-interface=WAN--eth5
/ip firewall nat add action=dst-nat chain=dstnat dst-port=53 in-interface=WAN-eth1 protocol=udp to-ports=15353
/ip firewall nat add action=dst-nat chain=dstnat dst-port=1626 in-interface=WAN-eth1 protocol=udp to-ports=31626

/ip firewall filter add action=accept chain=input dst-port=15353 in-interface=WAN-eth1 protocol=udp
/ip firewall filter add action=accept chain=input dst-port=31626 in-interface-list=wan protocol=udp

“Kind of” is because Remote1 still get answered from wrong IP - 1.1.2.1 instead of 1.1.1.1, that’s why there is “in-interface-list=wan” instead of “in-interface=WAN-eth1” in firewall filter rule.

Glitch here is that all this marking stuff is not working if packets are not dst-nat’ed, i.e. if packets go to wireguard directly, without passing destination port rewrite.

Hope this may help someone.

The overall explanation is poor and convoluted.
No network diagram.
No clear set of user requirements…
No config on MT device
/export file=anynameyouwish


Two WAN, clear,
Static public IPs on WANs clear, (so good candidates to be servers for any wirguard tunnels).

You use the wireguard tunnel for several purposes,
a. mobile remote clients access the server to go out your internet???
b. mobile remote clients access the server to reach subnets behind your router??

c. You have one or both ISPs that blocks at your end or prevent incoming or outgoing use of MOST ports??
d. Your mobile clients use ISPs that block or prevent use of most ports??

e. What are the site to site connetions for wireguard that you speak of?? Is it to other work sites, or homes etc… and are they always acting as client for initial connection?
f. For site to site connections, do the remote sites need access to your local subnets
g. For site to site connections, do the remote siteds need access to your internet
h. For site to site connections do you need access to remote sites subnets
I. For site to site connections do you need access to remote sites internet.

J. If one of your ISPs is a bitch, then is not useful at all, for either Wireguard tunnels or regular internet access ???

In terms of wireguard setup, I would have you read this… https://forum.mikrotik.com/viewtopic.php?t=182340
Note: In terms of forcing users to use internet - read 3b.

In terms of handling multiple WANS, have a look here … https://forum.mikrotik.com/viewtopic.php?t=182373
Note: See Section I. and J.

The goal hopefully is to achieve what you need without any mangling!

Dear sir or madam,
I’m very sorry for upsetting you by poor and convoluted explanation of what I need, but I’ve already achieved my goal, thanks to Cisco courses finished in 1997 and packet flow diagram, of course.
Thank you very much for your time.

Awesome glad its sorted. Cisco, Crisco, its all the same to me. :slight_smile:

I would write the mangle part like this:

/ip firewall mangle add action=mark-connection chain=output connection-mark=no-mark new-connection-mark=wan5-conn passthrough=yes
/ip firewall mangle add action=mark-connection chain=output connection-mark=no-mark src-port=15353 new-connection-mark=wan1-conn passthrough=yes
/ip firewall mangle add action=mark-connection chain=output connection-mark=no-mark src-port=31626 new-connection-mark=wan1-conn passthrough=yes

/ip firewall mangle add action=mark-routing chain=output connection-mark=wan1-conn new-routing-mark=out-wan1 passthrough=no protocol=udp 
/ip firewall mangle add action=mark-routing chain=output connection-mark=wan5-conn new-routing-mark=out-wan5 passthrough=no

/ip firewall mangle add action=mark-routing chain=prerouting connection-mark=wan1-conn new-routing-mark=out-wan1 passthrough=no
/ip firewall mangle add action=mark-routing chain=prerouting connection-mark=wan5-conn new-routing-mark=out-wan5 passthrough=no

All non-WG uses wan5 and WG uses wan1

We need better routing rules. It looks like Linux can use also protocol and ports as conditions, so I suppose RouterOS could do it to, but it’s not exposed to users. Then it would be possible to just use one routing rule for each WG instance and avoid mangle rules and srcnat.