Bookmark

RouterOS v7: Route Clients Through Multiple WANs with Routing Rules

This article uses a real RouterOS 7.21.5 configuration to demonstrate how individual clients can be routed through multiple WANs. The IP addresses and interface names are kept in the examples so they can be compared with WinBox.

Do not copy the complete configuration to another router. Check interface names, gateways, routing tables, and IP ranges first.

Configuration goal

The goal is to select a WAN for each LAN client:

  • Client 10.0.0.10 uses VNPT1.
  • Client 10.0.0.11 uses VT2.
  • Client 10.0.0.12 uses the main table.
  • Client 10.0.0.15 uses VNPT1.
  • Client 10.0.1.25 uses VNPT1.

This is commonly called policy routing or source-based routing: the router selects a path based on the source address instead of using only one shared default route.1

WAN and LAN interfaces in WinBox
WinBox: interfaces and PPPoE clients used in the example.

Interfaces in the real configuration

InterfaceRole
bridgeLANMain LAN
LAN2Physical port carrying PPPoE macvlan interfaces
LAN3Physical port carrying VLAN 597-VNPT-LAN3
597-VNPT-LAN3-MACVLAN1MACVLAN for PPPoE VNPT1
LAN2-MACVLAN1MACVLAN for PPPoE VT2
LAN2-MACVLAN2MACVLAN for PPPoE VT1
VNPT1VNPT PPPoE client
VT2Viettel/VT2 PPPoE client
VT1Other main PPPoE client

The PPPoE clients are:

1
2
3
4
5
6
7
8
/interface pppoe-client
add add-default-route=yes default-route-distance=3 \
    interface=597-VNPT-LAN3-MACVLAN1 name=VNPT1

add add-default-route=yes default-route-distance=2 \
    interface=LAN2-MACVLAN1 name=VT2

add add-default-route=yes interface=LAN2-MACVLAN2 name=VT1

The PPPoE username has been removed from this public tutorial. Never publish usernames, passwords, or secrets.

What is a routing table?

RouterOS v7 can create multiple routing tables. Each table can contain a different default route.1

1
2
3
/routing table
add disabled=no fib name=VNPT1
add disabled=no fib name=VT2

The fib parameter makes a table available for lookup and forwarding. A table is useful only when it contains suitable routes.

VNPT1 and VT2 routing tables in WinBox
WinBox: routing tables with FIB enabled.

Default routes for each WAN

The VNPT1 table uses the VNPT1 PPPoE interface:

1
2
3
/ip route
add disabled=no dst-address=0.0.0.0/0 \
    gateway=VNPT1 routing-table=VNPT1

The VT2 table uses the VT2 PPPoE interface:

1
2
3
/ip route
add disabled=no dst-address=0.0.0.0/0 \
    gateway=VT2 routing-table=VT2

Therefore:

  • Lookups in VNPT1 use WAN VNPT1.
  • Lookups in VT2 use WAN VT2.
  • Lookups in main use the router's primary routes.

Inspect the routes:

1
2
3
/ip route print detail where routing-table=VNPT1
/ip route print detail where routing-table=VT2
/ip route print detail where routing-table=main
VNPT1 and VT2 default routes in WinBox
WinBox: default routes pointing to the PPPoE interfaces.

Routing Rules

Internal-network rules are placed before client-specific rules:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
/routing rule
add action=lookup-only-in-table \
    comment="LAN IPv4 -> main" \
    dst-address=10.0.0.0/23 table=main

add action=lookup-only-in-table \
    comment="WG IPv4 -> main" \
    dst-address=10.0.2.0/24 table=main

add action=lookup-only-in-table \
    comment="VLAN10 IPv4 -> main" \
    dst-address=10.0.3.0/24 table=main

These rules keep internal traffic in main instead of sending it through a WAN. This is important for access to Proxmox, OpenHAB, AdGuard Home, and other LAN devices.

Client-specific WAN rules come after them:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
add action=lookup-only-in-table \
    comment="Socks5_1 -> VNPT1" \
    src-address=10.0.0.10/32 table=VNPT1

add action=lookup-only-in-table \
    comment="Socks5_2 -> VT2" \
    src-address=10.0.0.11/32 table=VT2

add action=lookup-only-in-table \
    comment="Socks5_3 -> main" \
    src-address=10.0.0.12/32 table=main

add action=lookup-only-in-table \
    comment="HTTPS Proxy -> VNPT1" \
    src-address=10.0.0.15/32 table=VNPT1

add action=lookup-only-in-table \
    comment="PC LINUX -> VNPT1" \
    src-address=10.0.1.25/32 table=VNPT1

lookup-only-in-table restricts the lookup to the selected table. If no suitable route exists, the packet may be dropped instead of falling back to another table. This differs from lookup.2

Routing Rules in WinBox
WinBox: internal rules before client-specific routing rules.
Client rule routed through VNPT1
WinBox: src-address=10.0.0.10/32 with table VNPT1.
Client rule routed through VT2
WinBox: src-address=10.0.0.11/32 with table VT2.

Why must internal rules come first?

Suppose 10.0.0.10 is routed through VNPT1. When it accesses 10.0.0.4, the AdGuard Home server, the router must evaluate this rule first:

1
dst-address=10.0.0.0/23 table=main

Without the internal rule, the request may be looked up in VNPT1 and sent to the WAN instead of the LAN server.

The conceptual order is:

1
2
3
4
1. Internal networks → main
2. WireGuard/VLAN internal networks → main
3. Specific client → desired WAN table
4. Other routes → main/default route

Add a new client

Route 10.0.0.20 through VNPT1:

1
2
3
4
/routing rule
add action=lookup-only-in-table \
    comment="New client -> VNPT1" \
    src-address=10.0.0.20/32 table=VNPT1

Route it through VT2 instead:

1
2
3
4
/routing rule
add action=lookup-only-in-table \
    comment="New client -> VT2" \
    src-address=10.0.0.20/32 table=VT2

Use /32 for one host. For a subnet, use the appropriate CIDR such as 10.0.1.0/24.

Inspect rules and routes

Print all rules in order:

1
/routing rule print detail

Inspect policy-table routes:

1
2
/ip route print detail where routing-table=VNPT1
/ip route print detail where routing-table=VT2

From a client, check the public address:

1
curl -4 https://ifconfig.me

Expected routing in this example:

1
2
3
4
5
10.0.0.10 → public IP of VNPT1
10.0.0.11 → public IP of VT2
10.0.0.12 → public IP selected by main
10.0.0.15 → public IP of VNPT1
10.0.1.25 → public IP of VNPT1

The public address can change, so this is a relative routing test rather than a permanent value.

When a client cannot reach the LAN

If a client can access the Internet but cannot reach 10.0.0.4, 10.0.0.2, or OpenHAB, inspect:

1
2
3
4
/routing rule print detail
/ip route print detail where routing-table=main
/ip firewall filter print stats
/ip firewall nat print stats

The internal networks in the example are:

1
2
3
10.0.0.0/23  → bridgeLAN
10.0.2.0/24  → WireGuard1
10.0.3.0/24  → VLAN10_Guest

Ensure their dst-address rules appear before client src-address rules.

IPv6 considerations

The export also contains IPv6 rules, such as fd00:10::10/128 and fd00:10::25/128. Test IPv4 and IPv6 separately:

1
2
/routing rule print detail
/ipv6 route print detail

A client can use VNPT1 for IPv4 while IPv6 follows another route. If both protocols must use the same WAN, configure and test both rule sets.

The export contains this example:

1
2
comment="Socks5_2 v6 -> VT1" \
src-address=fd00:10::11/128 table=main

The comment says VT1, but the actual table is main. Verify such discrepancies on the device before publishing a configuration.

Roll back a rule

Export the rules before editing:

1
/routing rule export file=routing-rules-before-change

Disable a rule by number:

1
/routing rule disable <rule-number>

Or remove it after confirming the number:

1
/routing rule remove <rule-number>

Do not rely on an old number after adding or removing several rules. Use print detail to confirm the comment and src-address first.

Summary

The policy-routing flow is:

1
2
3
4
5
6
7
8
9
Client source address
/routing rule
VNPT1 or VT2 routing table
Default route through the matching PPPoE interface
Selected WAN

The difficult part is not adding one more rule; it is ensuring that traffic to internal networks is sent to main before the client-specific WAN rule is applied.

WinBox illustrations

The following images show the interfaces, routing tables, default routes, and routing rules used in this example.

Sources

0 Bình luận

Góp Ý / Bình Luận / Đánh giá