๐ฏ WFH VPNs PBR
This guide explains how to configure Policy-Based Routing (PBR) to intelligently route home call center traffic (RDP, VPN protocols, MS Teams) through a dedicated VPN gateway while keeping other traffic on your main ISP. This prevents VPN congestion, ensures low-latency calls, and isolates business traffic from residential usage.
Key Takeaway: PBR lets you route specific traffic types to specific gateways based on source IP, destination IP, port, or protocolโrather than just using the default routing table for everything.
Prerequisitesโ
โ
MikroTik RouterOS v6.45+
โ
Two internet connections: Primary ISP + VPN gateway (or dedicated VPN tunnel)
โ
LAN subnet configured (e.g., 192.168.88.0/24)
โ
Call center server/endpoint IPs or address-list already defined
โ
Understanding of routing tables and firewall mangle rules
โ
SSH or Winbox access to router
Why PBR for Call Center VPNs?โ
Problem Without PBRโ
All LAN Traffic
โ
โโ Web browsing โ ISP (fast)
โโ Video streaming โ ISP (fast, bandwidth consumed)
โโ RDP/VoIP โ ISP (OK, but competes with streaming)
โโ VPN tunnels โ ISP (all through one connection)
RESULT:
โ Video = bandwidth starvation for VoIP
โ Buffering calls during downloads
โ No traffic prioritization
Solution With PBRโ
LAN Traffic with PBR Rules
โ
โโ Call Center traffic (RDP, specific VPN ports) โ VPN Gateway (dedicated)
โ โโ Low latency, guaranteed bandwidth
โโ MS Teams (port 3478-3481) โ VPN Gateway (dedicated)
โ โโ Crystal clear voice/video
โโ Everything else (web, video, general traffic) โ ISP (main connection)
โโ Separate path, no VoIP interference
RESULT:
โ
Calls isolated from general traffic
โ
VPN tunnel only carries business traffic
โ
ISP connection remains available for bulk transfers
โ
Call quality stable and predictable
Architecture Overviewโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LAN Client (192.168.88.100) โ
โ Initiating RDP connection to call center (10.0.0.50:3389) โ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโ
โ Firewall Mangle โ
โ (Mark Matching) โ
โโโโโโฌโโโโโโโโโโโฌโโโ
โ Step 1 โ
โ Prerouting
โ Analyze packet:
โ โข Source: 192.168.88.100 โ (in LAN)
โ โข Destination: 10.0.0.50 โ (in pbr_cc_vpn list)
โ โข Port: 3389 โ (in CC ports)
โ โข State: NEW connection โ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโ
โ Mark Connection โ
โ cc_conn โ
โโโโโโโโโโฌโโโโโโโโโโโโโโ
Step 2
Create connection-mark
(All future packets in this
connection use same mark)
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Mark Routing โ
โ to-pbr_cc_vpn โ
โโโโโโโโโโฌโโโโโโโโโโโโโโโโโโ
Step 3
Assign routing-mark
(Use alternate routing table)
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Routing Table Lookup โ
โ Table: to-pbr_cc_vpn โ
โ (Not main table) โ
โโโโโโโโโโฌโโโโโโโโโโโโโโโโโโ
Step 4
Query dedicated routing table
Default route: VPN Gateway
(e.g., 10.2.2.1 via tunnel)
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Send via VPN Gateway โ
โ Isolation from ISP trafficโ
โ Low-latency VoIP channel โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Configuration: Step-by-Stepโ
Step 1: Create Custom Routing Tableโ
Option A: Terminal
/routing table
add disabled=no fib name=to-pbr_cc_vpn
Option B: Winbox
- Go to: IP โ Routing โ Routing Tables
- Click +:
- Name: to-pbr_cc_vpn
- Disabled: unchecked
- FIB: checked โ Enables forwarding information base
Why? Creating a custom routing table isolates VPN traffic from the main routing table. All routes in this table can be different from the default route.
Step 2: Create Address Lists (Traffic Classification)โ
Before writing mangle rules, define which traffic is "call center":
Option A: Terminal
# Define call center VPN servers
/ip firewall address-list
add address=10.0.0.50 list=pbr_cc_vpn comment="Call Center Server 1"
add address=10.0.0.51 list=pbr_cc_vpn comment="Call Center Server 2"
add address=203.0.113.100/30 list=pbr_cc_vpn comment="VPN Gateway subnet"
# Define local LAN addresses (sources)
add address=192.168.88.0/24 list=local comment="LAN subnet"
# Define non-local addresses (internet)
add address=0.0.0.0/0 list=!local comment="Not local (internet)"
Option B: Winbox
- Go to: IP โ Firewall โ Address Lists
- Click + for each:
- Address: 10.0.0.50 | List: pbr_cc_vpn | Comment: Call Center Server 1
- Address: 192.168.88.0/24 | List: local | Comment: LAN subnet
Step 3: Create Firewall Mangle Rules (Connection Marking)โ
Option A: Terminal
/ip firewall mangle
# Rule 1: Mark RDP + VPN protocol traffic destined to CC servers
add action=mark-connection chain=prerouting \
comment="PBR Call Center VPNs" \
connection-mark=no-mark connection-state=new \
dst-address-list=pbr_cc_vpn \
in-interface-list=LAN \
new-connection-mark=cc_conn \
src-address-list=local
# Rule 2: Mark specific VPN/RDP ports to non-CC servers (backup route)
add action=mark-connection chain=prerouting \
connection-mark=no-mark connection-state=new \
dst-address-list=!local \
dst-port=3389,4433,10000,500,4500,60004,1701 \
in-interface-list=LAN \
new-connection-mark=cc_conn \
protocol=udp \
src-address-list=local
# Rule 3: Mark TCP versions of same ports
add action=mark-connection chain=prerouting \
connection-mark=no-mark connection-state=new \
dst-address-list=!local \
dst-port=3389,4433,10000,60004 \
in-interface-list=LAN \
new-connection-mark=cc_conn \
protocol=tcp \
src-address-list=local
# Rule 4: Mark MS Teams ports (UDP)
add action=mark-connection chain=prerouting \
comment="MS TEAMS PORTS" \
connection-mark=no-mark connection-state=new \
dst-address-list=!local \
dst-port=3478,3479,3480,3481 \
in-interface-list=LAN \
new-connection-mark=cc_conn \
protocol=udp \
src-address-list=local
# Rule 5: Apply routing mark to marked connections
add action=mark-routing chain=prerouting \
connection-mark=cc_conn \
in-interface-list=LAN \
new-routing-mark=to-pbr_cc_vpn
Option B: Winbox
- Go to: IP โ Firewall โ Mangle
- Click + for each rule above:
- Chain: prerouting
- Protocol: tcp/udp (as specified)
- Src. Address List: local
- Dst. Address List: pbr_cc_vpn (or !local for Rule 2-4)
- Dst. Port: (see each rule)
- In. Interface List: LAN
- Connection State: new
- Connection Mark: no-mark
- Action: mark-connection
- New Connection Mark: cc_conn (then cc_routing in Rule 5)
Step 4: Create Routing Rules (Route Marked Traffic)โ
Option A: Terminal
/ip route rule
add action=lookup routing-mark=to-pbr_cc_vpn table=to-pbr_cc_vpn \
comment="Route CC VPN traffic to custom table"
Option B: Winbox
- Go to: IP โ Route Rules
- Click +:
- Routing Mark: to-pbr_cc_vpn
- Action: lookup
- Table: to-pbr_cc_vpn
- Comment: Route CC VPN traffic to custom table
Step 5: Create Routes in Custom Tableโ
Option A: Terminal
/ip route
# Add default route in custom table pointing to VPN gateway
add dst-address="0.0.0.0/0" gateway="10.2.2.1" \
routing-table=to-pbr_cc_vpn \
comment="VPN default route for CC traffic" distance=1
# Optional: Add specific routes in custom table
add dst-address="10.0.0.0/8" gateway="10.2.2.1" \
routing-table=to-pbr_cc_vpn \
comment="Private network via VPN" distance=1
Option B: Winbox
- Go to: IP โ Routes
- Click +:
- Dst. Address: 0.0.0.0/0
- Gateway: 10.2.2.1 (VPN tunnel interface or gateway)
- Routing Table: to-pbr_cc_vpn
- Comment: VPN default route for CC traffic
Port Reference Tableโ
| Port(s) | Protocol | Service | Purpose |
|---|---|---|---|
| 3389 | TCP | Remote Desktop Protocol (RDP) | Windows remote desktop access |
| 4433 | TCP | HTTPS-ALT | Secure web/VPN management |
| 10000 | TCP | Webmin/VNC | Remote management panel |
| 500 | UDP | IPSec IKE | VPN key exchange |
| 4500 | UDP | IPSec NAT-T | IPSec over NAT traversal |
| 60004 | UDP | Custom VPN | Proprietary VPN protocol |
| 1701 | UDP | L2TP | Layer 2 Tunneling Protocol |
| 3478-3481 | UDP | MS Teams Media | Teams voice/video streams |
Complete Configuration Exampleโ
For a home call center with:
- LAN: 192.168.88.0/24
- Call Center Server: 10.0.0.50
- VPN Gateway: 10.2.2.1
- Main ISP route: 0.0.0.0/0 via 192.168.1.1 (distance=1)
Option A: Terminal (Paste All)
# Create routing table
/routing table
add disabled=no fib name=to-pbr_cc_vpn
# Define address lists
/ip firewall address-list
add address=192.168.88.0/24 list=local comment="LAN"
add address=10.0.0.50 list=pbr_cc_vpn comment="Call Center"
add address=203.0.113.0/24 list=pbr_cc_vpn comment="VPN Gateway"
# Mangle rules
/ip firewall mangle
add chain=prerouting comment="PBR Call Center VPNs" \
connection-mark=no-mark connection-state=new \
dst-address-list=pbr_cc_vpn in-interface-list=LAN \
new-connection-mark=cc_conn src-address-list=local \
action=mark-connection
add chain=prerouting connection-mark=no-mark connection-state=new \
dst-address-list=!local dst-port=3389,4433,10000,500,4500,60004,1701 \
in-interface-list=LAN new-connection-mark=cc_conn protocol=udp \
src-address-list=local action=mark-connection
add chain=prerouting connection-mark=no-mark connection-state=new \
dst-address-list=!local dst-port=3389,4433,10000,60004 \
in-interface-list=LAN new-connection-mark=cc_conn protocol=tcp \
src-address-list=local action=mark-connection
add chain=prerouting comment="MS TEAMS PORTS" \
connection-mark=no-mark connection-state=new \
dst-address-list=!local dst-port=3478,3479,3480,3481 \
in-interface-list=LAN new-connection-mark=cc_conn protocol=udp \
src-address-list=local action=mark-connection
add chain=prerouting connection-mark=cc_conn in-interface-list=LAN \
new-routing-mark=to-pbr_cc_vpn action=mark-routing
# Route rules
/ip route rule
add action=lookup routing-mark=to-pbr_cc_vpn table=to-pbr_cc_vpn
# Routes in custom table
/ip route
add dst-address="0.0.0.0/0" gateway="10.2.2.1" \
routing-table=to-pbr_cc_vpn comment="VPN for CC" distance=1
# Main ISP route (in default table)
add dst-address="0.0.0.0/0" gateway="192.168.1.1" \
routing-table=main comment="ISP default" distance=1
Verification Stepsโ
1. Check Routing Table Existsโ
/routing table print
# Should show: to-pbr_cc_vpn (flags: F for FIB)
2. Verify Mangle Rules Appliedโ
/ip firewall mangle print
# Should show 5 rules with:
# - connection-mark=cc_conn
# - routing-mark=to-pbr_cc_vpn
3. Verify Address Listsโ
/ip firewall address-list print
# Should show local, pbr_cc_vpn lists with addresses
4. Check Route Rulesโ
/ip route rule print
# Should show rule with routing-mark=to-pbr_cc_vpn table=to-pbr_cc_vpn
5. Verify Routes in Custom Tableโ
/ip route print where routing-table=to-pbr_cc_vpn
# Should show: 0.0.0.0/0 via 10.2.2.1
6. Test Live Traffic (From LAN Client)โ
Test 1: RDP to Call Center
# On LAN client, RDP to call center server
mstsc /v:10.0.0.50
# Check path on MikroTik:
/tool traceroute 10.0.0.50
# Should route via 10.2.2.1 (VPN gateway), not ISP
Test 2: Regular Internet
# On LAN client, browse web
ping 8.8.8.8
# Check path on MikroTik:
/tool traceroute 8.8.8.8
# Should route via 192.168.1.1 (ISP), not VPN
7. Monitor Connection Marksโ
/ip firewall connection tracking print
# Should show connections with mark=cc_conn (call center traffic)
Troubleshootingโ
| Issue | Cause | Solution |
|---|---|---|
| RDP traffic still uses ISP instead of VPN | Mangle rule doesn't match, or routing-mark not applied | Run /ip firewall mangle print stats to see rule hit count. Verify dst-port 3389 is in rule. Check /ip firewall connection tracking print for mark=cc_conn. |
| VPN traffic fails completely (timeout) | Custom routing table missing, or route points to wrong gateway | Verify table exists: /routing table print. Verify route: /ip route print where routing-table=to-pbr_cc_vpn. Test gateway: /ping 10.2.2.1. |
| Some connections still use ISP | Rule condition not specific enough, or connection state != new | Verify rule matches exact ports/protocols. Check if traffic uses different port. Ensure connection-state=new in rule. |
| Address list not working | List syntax error, or addresses not added correctly | Verify address lists: /ip firewall address-list print. Check address format (single IP or CIDR). |
| Teams calls drop on failover | No secondary VPN route in custom table | Add backup route: /ip route add dst-address=0.0.0.0/0 gateway=10.2.2.2 routing-table=to-pbr_cc_vpn distance=2 |
| Routing rule not evaluating | Rule disabled, or lower-priority rule matching first | Check rule order: /ip route rule print. Move CC rule before default rules. Verify action=lookup. |
| Performance: Latency to VPN high | VPN gateway overloaded, or QoS not configured | Check VPN tunnel stats: /interface print stats. Enable QoS on custom table routes. Monitor gateway CPU usage. |
Advanced Optionsโ
1. Add Secondary/Backup VPN Routeโ
/ip route
add dst-address="0.0.0.0/0" gateway="10.2.2.2" \
routing-table=to-pbr_cc_vpn comment="Backup VPN" distance=2
Failover to second VPN gateway if primary goes down.
2. Add Specific Subnet Routes (Not Just Default)โ
/ip route
# Route internal company network via VPN
add dst-address="10.0.0.0/8" gateway="10.2.2.1" \
routing-table=to-pbr_cc_vpn comment="Company private network"
# Route data center network via VPN
add dst-address="203.0.113.0/24" gateway="10.2.2.1" \
routing-table=to-pbr_cc_vpn comment="Company data center"
More efficient than default 0.0.0.0/0 when routes are specific.
3. Per-User VPN Routingโ
Route different users to different VPN gateways:
/ip firewall address-list
add address=192.168.88.100 list=user_alice comment="Alice"
add address=192.168.88.101 list=user_bob comment="Bob"
/ip firewall mangle
# Alice โ VPN Gateway 1
add chain=prerouting src-address-list=user_alice \
dst-port=3389,4433,10000 protocol=tcp \
action=mark-routing new-routing-mark=vpn-alice
# Bob โ VPN Gateway 2
add chain=prerouting src-address-list=user_bob \
dst-port=3389,4433,10000 protocol=tcp \
action=mark-routing new-routing-mark=vpn-bob
/ip route rule
add routing-mark=vpn-alice table=table-alice
add routing-mark=vpn-bob table=table-bob
/ip route
add dst-address=0.0.0.0/0 gateway=10.2.2.1 routing-table=table-alice
add dst-address=0.0.0.0/0 gateway=10.2.2.2 routing-table=table-bob
4. QoS on VPN Table Routesโ
Prevent VPN from saturating by limiting bandwidth:
/queue simple
add name="cc-vpn-limit" target=10.2.2.1 max-limit=20M/20M \
comment="Limit CC VPN to 20Mbps"
5. Exclude Certain Traffic from PBRโ
Route only VPN, but NOT Teams to avoid double-tunneling:
/ip firewall mangle
add chain=prerouting dst-port=3478-3481 protocol=udp \
action=mark-routing new-routing-mark=main
This bypasses PBR for Teams (uses main table instead).
6. Log Matched Connectionsโ
Debug PBR by logging marked connections:
/ip firewall mangle
add chain=prerouting connection-mark=cc_conn \
action=log log-prefix="CC_VPN_ROUTED:"
View logs: /log print where message~"CC_VPN_ROUTED"
Performance Optimizationโ
Fasttrack for Non-VPN Trafficโ
Skip mangle processing for non-VPN traffic:
/ip firewall filter
add chain=forward action=fasttrack-connection \
connection-state=established,related \
comment="FastTrack non-VPN"
add chain=forward connection-mark=!cc_conn \
action=fasttrack-connection \
comment="FastTrack LANโISP"
Reduce Mangle Rule Overheadโ
Before (5 rules to evaluate every packet):
Rule 1: dst-address-list=pbr_cc_vpn
Rule 2: dst-port=3389,4433,... protocol=udp
Rule 3: dst-port=3389,4433,... protocol=tcp
Rule 4: dst-port=3478-3481 protocol=udp
Rule 5: mark-routing (apply)
After (use single combined rule):
/ip firewall mangle
add chain=prerouting connection-mark=no-mark connection-state=new \
in-interface-list=LAN src-address-list=local \
action=mark-connection new-connection-mark=cc_conn \
((dst-address-list=pbr_cc_vpn) || \
(dst-address-list=!local dst-port=3389,4433,10000,500,4500,60004,1701 protocol=udp) || \
(dst-address-list=!local dst-port=3389,4433,10000,60004 protocol=tcp) || \
(dst-address-list=!local dst-port=3478-3481 protocol=udp))
Fewer rules = less CPU per packet.
Real-World Example: Multi-VPN Setupโ
Scenario:
- VPN-1: Call Center (10.2.2.1) โ low-latency, dedicated
- VPN-2: Company General VPN (10.3.3.1) โ shared
- ISP: Primary internet (192.168.1.1)
# Create separate tables
/routing table
add name=to-vpn-cc
add name=to-vpn-company
# Create address lists
/ip firewall address-list
add address=192.168.88.0/24 list=local
add address=10.0.0.50 list=pbr_cc_vpn comment="Call center"
add address=10.0.0.100-10.0.0.200 list=pbr_company comment="Company IPs"
# Mangle: CC โ VPN-1
/ip firewall mangle
add chain=prerouting dst-address-list=pbr_cc_vpn src-address-list=local \
action=mark-routing new-routing-mark=cc-mark
# Mangle: Company โ VPN-2
add chain=prerouting dst-address-list=pbr_company src-address-list=local \
action=mark-routing new-routing-mark=company-mark
# Route rules
/ip route rule
add routing-mark=cc-mark table=to-vpn-cc
add routing-mark=company-mark table=to-vpn-company
# Routes
/ip route
add dst-address=0.0.0.0/0 gateway=10.2.2.1 routing-table=to-vpn-cc
add dst-address=0.0.0.0/0 gateway=10.3.3.1 routing-table=to-vpn-company
add dst-address=0.0.0.0/0 gateway=192.168.1.1 routing-table=main
Related Guidesโ
- MikroTik Failover Methods
- Policy-Based Routing (PBR) for GCash
- Quality of Service (QoS) Setup
- MikroTik Security Hardening
โ PBR Configuration Complete! Your call center traffic now routes through the dedicated VPN tunnel, isolated from ISP traffic. Monitor connection marks and verify latency improvements on VoIP quality.