MikroTik: Route LAN Traffic to XRAY TProxy (Transparent)
Step-by-step guide to route LAN traffic via MikroTik to an XRAY transparent proxy using TProxy, mangle rules, policy routing and iptables for correct routing.
How to route client traffic through a MikroTik router to a transparent XRAY proxy server on a separate PC in the same LAN (192.168.0.0/24)?
Setup Overview:
- Transparent proxy server running XRAY on port 12345 with tproxy, marking proxied traffic (mark: 255).
- iptables rules on proxy PC for tproxy redirection (PREROUTING and OUTPUT chains).
- Works when clients set proxy PC (e.g., 192.168.0.5) as gateway directly.
- Goal: Route via MikroTik (Client PCs → MikroTik → Proxy PC → Internet).
XRAY Config (partial): ```json
{
“log”: {
“loglevel”: “warning”
},
“inbounds”: [
{
“tag”: “all-in”,
“port”: 12345,
“protocol”: “dokodemo-door”,
“settings”: {
“network”: “tcp,udp”,
“followRedirect”: true
},
“sniffing”: {
“enabled”: true,
“destOverride”: [“http”, “tls”, “quic”]
},
“streamSettings”: {
“sockopt”: {
“tproxy”: “tproxy”
}
}
}
],
“outbounds”: [
{
// Proxy server settings
“streamSettings”: {
“sockopt”: {
“mark”: 255
}
}
},
{
“tag”: “dns-out”,
“protocol”: “dns”,
“streamSettings”: {
“sockopt”: {
“mark”: 255
}
}
}
],
“dns”: {
“servers”: [
“https://1.1.1.1/dns-query”,
“https://dns.google/dns-query”
]
},
“routing”: {
“domainMatcher”: “mph”,
“domainStrategy”: “IPIfNonMatch”,
“rules”: [
{
“type”: “field”,
“inboundTag”: [“all-in”],
“port”: 53,
“network”: “udp”,
“outboundTag”: “dns-out”
},
{
“type”: “field”,
“ip”: [“1.1.1.1”, “8.8.8.8”],
“outboundTag”: “proxy”
}
]
}
}
**iptables on Proxy PC (net.ipv4.ip_forward=1):** ```bash
iptables -t mangle -N XRAY
iptables -t mangle -A XRAY -d 127.0.0.1/32 -j RETURN
iptables -t mangle -A XRAY -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A XRAY -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A XRAY -d 192.168.0.0/24 -p tcp -j RETURN
iptables -t mangle -A XRAY -d 192.168.0.0/24 -p udp ! --dport 53 -j RETURN
iptables -t mangle -A XRAY -j RETURN -m mark --mark 0xff
iptables -t mangle -A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
iptables -t mangle -A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
iptables -t mangle -A PREROUTING -j XRAY
iptables -t mangle -N XRAY_MASK
iptables -t mangle -A XRAY_MASK -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A XRAY_MASK -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A XRAY_MASK -d 192.168.0.0/24 -p tcp -j RETURN
iptables -t mangle -A XRAY_MASK -d 192.168.0.0/24 -p udp ! --dport 53 -j RETURN
iptables -t mangle -A XRAY_MASK -j RETURN -m mark --mark 0xff
iptables -t mangle -A XRAY_MASK -p udp -j MARK --set-mark 1
iptables -t mangle -A XRAY_MASK -p tcp -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -j XRAY_MASK
iptables -t mangle -N DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT
Attempted MikroTik Config: ```
/ip firewall mangle
add action=mark-connection chain=prerouting connection-mark=no-mark connection-state=new dst-address-list=to-proxy new-connection-mark=to-proxy-conn
add action=mark-routing chain=prerouting connection-mark=to-proxy-conn new-routing-mark=proxy
/ip route
add distance=1 dst-address=0.0.0.0/0 gateway=192.168.0.5 routing-table=proxy scope=30 suppress-hw-offload=no target-scope=10
Individual setups work, but combining MikroTik routing with the proxy fails. What MikroTik mangle rules, routes, or additional configurations (e.g., NAT, marks) are needed to transparently redirect all client traffic to the proxy PC's tproxy port?To set up MikroTik proxy routing for transparent redirection to an XRAY proxy server on a separate PC (like 192.168.0.5) in your 192.168.0.0/24 LAN, focus on MikroTik mangle rules that mark non-local traffic with a routing mark, paired with a custom routing table sending everything via the proxy as gateway. This keeps the original destination IP intact—crucial for the proxy’s tproxy iptables to kick in and hand off to XRAY’s dokodemo-door on port 12345 without issues. Skip DNAT; it rewrites the dst IP/port, triggering your proxy’s LAN RETURN rules and killing transparency.
Contents
- Setup Overview and Why Direct Routing Fails
- Core MikroTik Mangle Rules for Traffic Marking
- Creating Routing Tables and Routes
- XRAY and iptables Compatibility Tweaks
- Additional MikroTik Configurations
- Testing and Troubleshooting
- Sources
- Conclusion
Setup Overview and Why Direct Routing Fails
Your XRAY proxy shines in direct mode—clients point straight to 192.168.0.5 as gateway, packets hit the proxy with original src=clientIP dst=remote-serverIP, tproxy snags them in PREROUTING, marks with 1, and loops to local port 12345. XRAY’s dokodemo-door grabs the original destination via kernel magic (IP_ORIGDSTADDR), dials the real server from the proxy IP, and pipes data back transparently. Replies spoof the server IP back to client directly over LAN ARP. Clean.
But chain it through MikroTik? Your attempted config almost nails it, but stumbles because the mark-connection rule relies on an undefined “to-proxy” address-list, and it doesn’t broadly catch all non-local traffic (dst-address-type=!local is key). Without proper marking, packets don’t hit the proxy routing table—they blast straight to WAN. Policy routing fixes this: MikroTik L3-forwards untouched packets (dst=remoteIP) to proxy MAC, mimicking the direct-gateway flow. Proxy tproxy sees identical traffic, XRAY processes, outbounds mark 255 and route via your fwmark rules (assuming you have ip rule fwmark 1/255 lookup table via MikroTik IP). Boom—MikroTik transparent proxy without loops.
Ever wonder why DNAT tempts but fails here? It flips dst to 192.168.0.5:12345 before proxy sees it. Your iptables RETURNs LAN-destined TCP/UDP(!53), so no tproxy. Original dst lost. Policy routing > NAT for this.
Core MikroTik Mangle Rules for Traffic Marking
MikroTik настройка starts in Winbox or terminal: /ip firewall mangle. We mark new outbound connections from LAN, then route-mark packets in that connection. Target non-local dst (Internet), exclude proxy IP to dodge loops. Passthrough=yes on connection mark keeps it flowing.
Here’s the money rules—add in this order:
/ip firewall mangle
add chain=prerouting action=mark-connection new-connection-mark=proxy_conn passthrough=yes connection-state=new in-interface-list=LAN dst-address-type=!local dst-address!=192.168.0.5 comment="Mark new non-local conns from LAN"
add chain=prerouting action=mark-routing new-routing-mark=proxy passthrough=yes connection-mark=proxy_conn in-interface-list=LAN comment="Route-mark proxy conns"
add chain=prerouting action=mark-connection new-connection-mark=proxy_conn passthrough=yes connection-state=new in-interface-list=LAN dst-address-type=!local dst-address=192.168.0.5 protocol=udp dst-port=53 comment="DNS UDP to proxy if needed"
Why these? First rule hits TCP/UDP new flows to !local (covers geo-outbound, RFC1918-excluded). dst-address-type=!local auto-catches public IPs—no clunky lists. Second applies routing-mark to all packets in that conn (replies too, though proxy handles most). Third sneaks DNS if XRAY’s port-53 rule needs it—your config routes it internally.
Pro tip: If clients are WiFi-heavy, swap in-interface-list=WLAN. Check /interface list member for your LAN/WLAN.
Disable fasttrack on these:
/ip firewall filter
add chain=forward action=fasttrack-connection connection-state=established,related hw-offload=no comment="No fasttrack"
add chain=forward action=fasttrack-connection connection-mark=proxy_conn hw-offload=no comment="Block fasttrack on proxy traffic"
Fasttrack skips mangle—kills your marks.
Creating Routing Tables and Routes
Now the brains: custom fib table for marked traffic.
/routing table
add fib name=proxy disabled=no comment=“Proxy routing table”
Then the blackhole-avoiding default route—gw=proxy IP, low distance, ping-check:
/ip route
add dst-address=0.0.0.0/0 gateway=192.168.0.5 routing-table=proxy distance=1 check-gateway=ping target-scope=10 scope=30 comment=“All proxy traffic via XRAY PC”
Target-scope=10 ensures recursive lookup doesn’t loop (proxy won’t route back). Scope=30 for connected. Suppress-hw-offload=yes if bridges glitch.
Test it: /ip route print where routing-table=proxy. Your main table stays untouched—local/LAN zips direct.
On proxy PC, confirm fwmark routing:
ip rule add fwmark 1 priority 10 lookup proxy_table
ip route add default via 192.168.0.1 dev eth0 table proxy_table # MikroTik IP
Mark 255 from XRAY outbounds uses similar. Your DIVERT and OUTPUT chains look solid—mark 1 propagates.
XRAY and iptables Compatibility Tweaks
Your vless xray mikrotik partial config rocks: dokodemo-door with followRedirect=true, tproxy sockopt, DNS rules. No changes needed—xray proxy already sniffs HTTP/TLS/QUIC, marks outbounds 255.
But iptables nitpicks for MikroTik flow:
Your PREROUTING XRAY chain RETURNs dst=192.168.0.0/24 tcp fully, udp !53—perfect, skips LAN loops. Add if missing:
iptables -t mangle -I XRAY 1 -s 192.168.0.0/24 -j RETURN # Early src LAN return? Nah, yours is dst-focused.
For UDP DNS: your routing rule inboundTag=all-in port=53 udp -> dns-out (marked 255). Good—avoids tproxy on it if excluded.
Restart XRAY post-tweaks: systemctl restart xray or whatever. Logs at warning: tail -f /var/log/xray/access.log for “accepted tcp/xx.xx.xx.xx:xxxxx->…”
MikroTik xray searches spike because this combo crushes censorship—xray reality mikrotik vibes.
Additional MikroTik Configurations
Polish it:
-
Proxy-ARP? Nah—policy routing handles ARP for proxy MAC.
-
Connection tracking: /ip settings set tcp-syncookies=yes netfilter-tefo=no if timeouts bug.
-
Firewall holes: Allow forward proxy<->WAN:
/ip firewall filter
add chain=forward src-address=192.168.0.5 action=accept place-before=0 comment="XRAY outbound"
add chain=forward dst-address=192.168.0.5 action=accept comment="XRAY inbound replies"
-
NAT unchanged: Keep MASQ on WAN for proxy outbounds. No srcnat/dstnat on LAN traffic.
-
IPv6? Duplicate for ip6 if enabled.
-
Load balance? Add dst-address-list=proxy exclude=192.168.0.5.
Reboot-proof: export compact to script.
Testing and Troubleshooting
-
CLI verify: /tool traceroute 8.8.8.8 routing-table=proxy —hits proxy first.
-
Traffic sniff: /tool sniffer quick interface=LAN ip-protocol=tcp dst-address=8.8.8.8 —marks show?
-
Proxy logs: tcpdump -i any port 12345 or XRAY logs for client IPs.
Fails? Common gotchas:
-
No marks: /ip firewall connection print where connection-mark=proxy_conn —empty? Fix interface-list.
-
Loops: Ping proxy from MikroTik routing-table=proxy —should reply direct.
-
UDP drops: Add mark-packet too: chain=prerouting packet-mark=no-mark connection-mark=proxy_conn action=mark-packet new-packet-mark=proxy_pkt
-
Conntrack flood: /ip firewall connection remove [find]
Works? Speedtest—should proxy all but LAN.
Sources
- MikroTik Wiki on Routing Marks and Policy Routing
- MikroTik Firewall Mangle Guide
- XRAY Docs Dokodemo-door with TProxy
- Linux TPROXY Man Page for mark handling
Conclusion
Nail MikroTik transparent proxy to XRAY proxy with targeted mangle marks on non-local LAN traffic, a proxy routing table, and zero NAT fiddling—your tproxy iptables and XRAY config handle the rest seamlessly. Clients stay oblivious, traffic proxies outbound via marks, replies fly direct over LAN. Tweak fasttrack and firewall, test marks/routes, and you’re golden. This scales for vless xray mikrotik or WireGuard hybrids; watch Yandex volumes climb on mikrotik настройка. Questions? Ping the forum.