Route selected domains via containers using DNS-populated address lists and policy routing. LAN keeps normal WAN; chosen domains go either to ByeDPI (DPI-bypass) or Mihomo (VPN).
Based on the article by @wiktorbgu at Habr.
- Router DNS resolves domains and fills address-lists (
to-dpi,to-mihomo). - Mangle marks connections by lists, then marks routing.
- Policy routes send marked traffic to container gateways.
- LAN DNS is intercepted, so clients use router DNS.
- containers bridge: 172.18.0.0/24
- veth1-byedpi: 172.18.0.2 (ByeDPI)
- veth2-mihomo: 172.18.0.3 (Mihomo)
- LAN uses router DNS; policy routing directs per-domain flows.
Explanation: Create interface lists.
/interface list add name=WAN
/interface list add name=LAN
/interface list add name=CONTAINERS
# TODO: this is your router-specific configuration, these settings might be already set
# /interface list member add interface="ether2" list=WAN
# /interface list member add interface=bridge list=LAN
# CONTAINERS will be added laterExplanation: RFC1918/CGNAT address-lists and bypass marking for local destinations.
/ip firewall address-list add address=10.0.0.0/8 list=rfc6890
/ip firewall address-list add address=172.16.0.0/12 list=rfc6890
/ip firewall address-list add address=192.168.0.0/16 list=rfc6890
/ip firewall address-list add address=100.64.0.0/10 list=rfc6890 comment=CGNAT
/ip firewall mangle add chain=prerouting in-interface-list=!WAN dst-address-list=rfc6890 action=accept comment="Bypass route-marking for local RFC addresses"Explanation: Bridge for containers, veth interfaces, IPs, add to CONTAINERS list.
/interface bridge add name=containers port-cost-mode=short
/ip address add address=172.18.0.1/24 interface=containers network=172.18.0.0
/interface veth add address=172.18.0.2/24 gateway=172.18.0.1 name=veth1-byedpi
/interface veth add address=172.18.0.3/24 gateway=172.18.0.1 name=veth2-mihomo
/interface bridge port add bridge=containers interface=veth1-byedpi
/interface bridge port add bridge=containers interface=veth2-mihomo
/interface list member add interface=containers list=CONTAINERSExplanation: Configure container runtime, mounts, envs; add ByeDPI and Mihomo.
Note: enabling containers requires a direct physical contact:
Enable Container mode and follow the instructions the command gives you (read more about Device-mode). You will need to confirm the device-mode with a press of the reset button, or a cold reboot (if using Containers on x86).
# Common setup
# Note: it uses tmpfs, you might prefer to mount a directory instead
/disk add slot=tmpfs tmpfs-max-size=200M type=tmpfs
/container config set layer-dir=tmpfs tmpdir=tmpfs memory-high=512.0MiB registry-url=https://registry-1.docker.io
# Mihomo (VLESS)
/container mounts add dst=/etc/mihomo name=mihomo-config src=/mihomo
# Follow the instructions from https://hub.docker.com/r/wiktorbgu/mihomo-mikrotik and fill SRV1 variable
/container envs add name=mihomo-envs key=SRV1 value="vless://..."
/container add check-certificate=no dns=1.1.1.1,8.8.8.8,9.9.9.9 envlists=mihomo-envs interface=veth2-mihomo mounts=mihomo-config name=mihomo remote-image=wiktorbgu/mihomo-mikrotik:1.19.14 root-dir=mihomo start-on-boot=yes workdir=/
# ByeDPI
# Note: it uses tmpfs, you might prefer to mount a directory instead
/container envs add name=byedpi-envs key=QUIC value=ACCEPT
/container add check-certificate=no cmd="-n google.com -Qr -f-204 -s1:5+sm -a1 -As -d1 -s3+s -s5+s -q7 -a1 -As -o2 -f-43 -a1 -As -r5 -Mh -s1:5+s -s3:7+sm -a1" envlists=byedpi-envs interface=veth1-byedpi name=byedpi remote-image=wiktorbgu/byedpi-hev-socks5-tunnel:redirect root-dir=/byedpi start-on-boot=yes workdir=/Explanation: Create FIB tables; default routes via container IPs.
/routing table add fib name=to-dpi
/routing table add fib name=to-mihomo
/ip route add dst-address=0.0.0.0/0 gateway=172.18.0.2 routing-table=to-dpi
/ip route add dst-address=0.0.0.0/0 gateway=172.18.0.3 routing-table=to-mihomoExplanation: DNS servers and domain → address-list population. Note: empty name= line will error; replace/skip when applying.
# don't forget to import certificates for DoH or use verify-doh-cert=no
#
# /tool fetch https://cacerts.digicert.com/DigiCertAssuredIDRootG2.crt.pem
# /certificate import file-name=DigiCertAssuredIDRootG2.crt.pem passphrase=””
/ip dns set allow-remote-requests=yes cache-max-ttl=1d cache-size=10000KiB use-doh-server=https://doh.opendns.com/dns-query
# ByeDPI (to-dpi)
/ip dns static
add address-list=to-dpi match-subdomain=yes name=youtube.com type=FWD
add address-list=to-dpi match-subdomain=yes name=youtu.be type=FWD
# ... add more if needed
# VPN (to-mihomo)
/ip dns static
add address-list=to-mihomo match-subdomain=yes name=rutracker.org type=FWD
add address-list=to-mihomo match-subdomain=yes name=rutracker.cc type=FWD
# ... add more if neededExplanation: Masquerade LAN and containers to WAN for outbound connectivity.
/ip firewall nat add chain=srcnat out-interface-list=WAN action=masquerade comment="Masquerade LAN -> WAN"
/ip firewall nat add chain=srcnat src-address=172.18.0.0/24 out-interface-list=WAN action=masquerade comment="Masquerade
containers -> WAN"Explanation: Configure firewall rules.
# Default filters (they should be present in defconf)
# /ip firewall filter add chain=input action=accept connection-state=established,related comment="Router input: established/related"
# /ip firewall filter add chain=input action=drop connection-state=invalid comment="Router input: drop invalid"
# /ip firewall filter add chain=input action=drop in-interface-list=!LAN comment="Drop input not from LAN"
# /ip firewall filter add chain=forward action=accept connection-state=established,related comment="Forward: established/related"
# /ip firewall filter add chain=forward action=drop connection-state=invalid comment="Forward: drop invalid"
# /ip firewall filter add chain=forward action=drop connection-state=new connection-nat-state=!dstnat in-interface-list=WAN comment="Drop new from WAN not dstnated"
# Mark fasttrack connection (disable default, create new)
# or you can edit the default rule by enabling `connection-mark=no-mark` and `packet-mark=no-mark`
/ip firewall filter set [find chain=forward action=fasttrack-connection] disabled=yes
/ip firewall filter add chain=forward action=fasttrack-connection connection-state=established,related
in-interface-list=LAN out-interface-list=WAN packet-mark=no-mark connection-mark=no-mark hw-offload=yes comment="FastTrack safe (exclude marked)"
# Allow LAN access to containers
/ip firewall filter add chain=forward in-interface-list=LAN dst-address=172.18.0.0/24 action=accept comment="Clients -> containers (UI, etc)"
# Local DNS interception
/ip firewall nat add action=redirect chain=dstnat dst-address-list=!rfc6890 dst-port=53 in-interface-list=LAN protocol=udp
/ip firewall nat add action=redirect chain=dstnat dst-address-list=!rfc6890 dst-port=53 in-interface-list=LAN protocol=tcpExplanation: Mark connections and route per-address-list; optionally mark router-originated traffic.
/ip firewall mangle add chain=prerouting in-interface-list=LAN dst-address-list=to-dpi action=mark-connection new-connection-mark=to-dpi-con passthrough=yes comment="Conn-Mark: LAN -> to-dpi"
/ip firewall mangle add chain=prerouting in-interface-list=LAN dst-address-list=to-mihomo action=mark-connection new-connection-mark=to-mihomo-con passthrough=yes comment="Conn-Mark: LAN -> to-mihomo"
/ip firewall mangle add chain=prerouting in-interface-list=LAN connection-mark=to-dpi-con action=mark-routing new-routing-mark=to-dpi passthrough=no comment="Route-Mark: to-dpi"
/ip firewall mangle add chain=prerouting in-interface-list=LAN connection-mark=to-mihomo-con action=mark-routing new-routing-mark=to-mihomo passthrough=no comment="Route-Mark: to-mihomo"
# Optional: mark router-originated traffic as well
/ip firewall mangle add chain=output dst-address-list=rfc6890 action=accept comment="Bypass local RFC from router"
/ip firewall mangle add chain=output dst-address=172.18.0.0/24 action=accept comment="Bypass router -> containers UI"
/ip firewall mangle add chain=output dst-address-list=to-dpi action=mark-routing new-routing-mark=to-dpi passthrough=no comment="Router-originated -> to-dpi"
/ip firewall mangle add chain=output dst-address-list=to-mihomo action=mark-routing new-routing-mark=to-mihomo passthrough=no comment="Router-originated -> to-mihomo"Explanation: An optional address list for container subnet.
/ip firewall address-list add address=172.18.0.0/24 list=containers comment="Containers subnet"- Debug containers:
/container/print/container/logs print
- Try access
172.18.0.2and172.18.0.3from router/LAN, e.g.http://172.18.0.3:9090/ui/ - Address-lists should not be empty:
/ip firewall address-list print where list=to-dpi or list=to-mihomo - Mangle counters must be non-zero:
/ip firewall mangle print stats - Browse target domains to confirm routing
In the end it also would be the best to reboot router, devices and also flush DNS cache.