I am trying to migrate our VPN-Server to v7 since wireguard is the best thing since sliced bread :-), but I am stuck with mangle/routing. The situation is this: The VPN-router has two interfaces with public IPs, one is exclusively for incoming VPN connections (“DFN” below, IP 1.2.3.4), the other is the default gateway to the Internet.
So, the router has to respond to incoming VPN connections via the same interface and forward other traffic via the default gateway. This did the trick in ROS 6:
It works as intended for all incoming VPN connections of SSTP, L2TP, but not for the wiregard tunnel: While SSTP and L2TP traffic goes via the “normal” default route for 0.0.0.0/0 (set by a dhcp-client), traffic from the wireguard tunnel goes out via 1.2.3.4.
/ip/route/print
Flags: D - DYNAMIC; A - ACTIVE; c - CONNECT, s - STATIC, d - DHCP, y - COPY; + - ECMP
Columns: DST-ADDRESS, GATEWAY, DISTANCE
# DST-ADDRESS GATEWAY D
DAd+ 0.0.0.0/0 4.5.6.1 1
0 As+ 0.0.0.0/0 1.2.3.1
DAc 10.43.231.0/24 wireguard1 0
DAc 4.5.6.7/24 bridge-local 0
DAc 1.2.3.4/24 DFN 0
Any ideas?
It seems like the packet coming from wireguard are also marked viaDFN. I tried to mark the packets at the wireguard interface and the private IP range of wiregard with routing mark “main”, but this does not seem to have an effect.
I missed it in original post, but even v6 config wasn’t correct. The mangle rule in prerouting is useless, all work is done by the one in output.
If you’d want to use “send it back to where it came from” approach, which would be useful if VPN server was accessible using both WANs, you’d use rule in prerouting to set connection mark (not routing mark) and then the rule in output would use this mark as condition, instead of src-address.
If VPN uses only the dedicated WAN, it’s possible to avoid mangle rules completely and use routing rule. In v6 it would be:
I missed it in original post, but even v6 config wasn’t correct. The mangle rule in prerouting is useless, all work is done by the one in output.
Thanks for the hint.
As for WG, I seem to be a little lost in description.
The situation is this: The router has two Ethernet interfaces with public IPs, 1.2.3.4/24 (fixed) and 4.5.6.7/24 (via dhcp, varying IP). 1.2.3.4 is supposed to serve only incoming VPN connections (L2TP, SSTP and wireguard). VPN interfaces in the router have private IP ranges, and all traffic coming out of the VPN tunnels should be NATed via 4.5.6.7.
I think I managed to achieve this in v7 for the traffic coming via L2TP and SSTP tunnels, but not for wireguard: It seems that the mangle rules did not only mark the wireguard UDP packets arriving at DFN, but also the traffic coming from the wireguard interface in the router (packets in the tunnel). However, I am not really sure: I recently tried to reboot the router, but it did not come back. I will go into the office tomorrow, reset it and start from scratch with the routing rule you suggest.
I don’t have any explanation why WG should differ from others. But if you suspect that marks may be inherited from tunnel traffic (outside) by tunneled traffic (inside), you can easily test it. Just add logging rule (action=log) in any chain, with any condition you need to check.
I am not able to ping in a specific routing table, using 7.1beta2 in a chateau. Example:
/int bri add name=prova1
/ip addr add address=169.254.1.1/24 interface=prova1
/routing/table/add name=prova1 fib
/ip/route/add dst-address=0.0.0.0/0 gateway=169.254.1.2@main routing-table=prova1
ping 8.8.8.8 routing-table=prova1
input does not match any value of routing-table
Looks like there’s something wrong with the ping command:
ping 8.8.8.8 routing-table=main
input does not match any value of routing-table
A workaround is to use an additional IP address as a source, adding a /routing/rule for that source, action=lookup-only-table and the intended table.
This problem still exists on 7.1beta6. routing-table doesn’t work properly in various places, especially with ping/traceroute but also when creating firewall mangle rules, if you print firewall rules it shows the routing-tables as some kind of pointer value for the table, not the string name, which also causes .rsc backups to fail on input.. Your workaround suggestion is helpful but doesn’t work for all scenarios, eg pinging a public WAN ip address from a LAN interface address behind another NAT router/gateway (eg, to test for connectivity via that other device, where that router’s dynamic WAN address is not known)
Incidentally, traceroute can be made to work using find, but ping refuses to open a socket:
[admin@fw] > /tool/traceroute address=8.8.8.8 routing-table=[/routing/table/find where name=“check_lte1”]
Columns: ADDRESS, LOSS, SENT, LAST, AVG, BEST, WORST, STD-DEV
ADDRESS LOSS S LAST AVG BEST WORS STD
1 192.168.8.1 0% 2 1.2ms 1 0.8 1.2 0.2
…
[admin@fw] > /tool/ping address=8.8.8.8 routing-table=[/routing/table/find where name=“check_lte1”]
SEQ HOST SIZE TTL TIME STATUS
0 could not make socket
sent=1 received=0 packet-loss=100%
But of course this doesn’t really help for scripting purposes…
Hopefully this issue can be addressed somewhat in the next update… even if they just succeed in letting ping work as traceroute does
Why do you need any mangling?
Not sure why you want to differentiate internet traffic from VPN traffic as the initial connection is very brief and then the tunnel is created.
I gather the issue is you then want the tunnel users to use the other WAN for normal internet access.
[note on my wireguard server I have two interfaces (each with one peer, aka external mt router client and pc behind it, and another for my iphone client)
So wouldnt it be a matter of an IP route direct traffic to the other WAN and then a route rule for returning WAN traffic to go back to the wireguard server?
Right now my wireguard server RBG is behind my CCR router and is on the CCR vlan31 subnet.
On the RBG I have the following which directs all traffic from the RBG through the gateway which hits the CCR and then on its way out.
The second rule is to ensure that return traffic from the internet intended for the client goes back into the tunnel.
/ip route
add disabled=no dst-address=0.0.0.0/0 gateway=192.168.31.1 routing-table=main
suppress-hw-offload=no
add disabled=no dst-address=192.168.40.0/24 gateway=WG-RM routing-table=main
suppress-hw-offload=no
I suppose I could then put a route on the CCR that stated
add disabled=no dst-address=0.0.0.0/0 gateway=preferred ISP routing-table=wgtraffic
suppress-hw-offload=no
where route rule is (source address 192.168.31.3) lookup only in table wgtraffic.
Then tunnel traffic would be diverted to the ISP of choice.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
If the RBG was internet facing then it would be these two rules then…
add disabled=no dst-address=0.0.0.0/0 gateway=preferredISP gateway routing-table=wg-traffic
suppress-hw-offload=no
add disabled=no dst-address=192.168.40.0/24 gateway=WG-INTERFACE routing-table=main
suppress-hw-offload=no
where wg traffic rule is source address=192.168.40.0/24 Action: lookup only in table wg-traffic
NOTE: This all done without assigning any IP address to any WG interface!!!