Tailscale and mihomo linkage configuration

Image: Jiayuguan Cantilever Great Wall

Previously, I wrote about the configuration of mihomo transparent proxy. This time, let’s talk about how to link Tailscale with mihomo.
The effect is to connect Tailscale with a mobile phone outside, select Raspberry Pi as the export node, and all traffic will go through mihomo
proxy before going out of the network. Tested very useful, you can also enjoy the agency rules at home outside!
1. Install Tailscale on Raspberry Pi and enable IP forwarding

First, install Tailscale:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

Then enable IP forwarding, which is crucial, otherwise other devices cannot access the Raspberry Dispatch Network:

echo ‘ net.ipv4.ip_forward = 1’ | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo ‘ net.ipv6.conf.all.forwarding = 1’ | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

Please confirm that forwarding has been enabled:

sysctl net.ipv4.ip_forward

The output should be net.ipv4. ip_forward=1. If there is no problem, continue.
2. Configure Raspberry Pi as Tailscale exit node

Execute the following command to make the Raspberry Pi broadcast itself as an exit node:

sudo tailscale up – advertise-exit-node

Then go to Tailscale’s management backend ( https://login.tailscale.com/admin/machines )
Find the Raspberry Pi and click on “# 8220;” in the menu.
; Use as exit node” Approve this setting.

Open the Tailscale client on your phone, Settings -> Exit Node, Choose Raspberry Pi.
At this point, all the data on the phone will go through the Raspberry Pi network! But it hasn’t gone through mihomo yet, keep reading.
III. Analysis of Traffic Trends

It is important to clarify the traffic path:

Phone ->Tailscale Tunnel ->Raspberry Pi (tailscale0 interface) ->Forwarding ->eth0 Outbound

Our goal is to; Forwarding&# 8221; This step hijacks TCP traffic to mihomo, allowing mihomo to perform diversion and proxy.
UDP traffic is forwarded directly without any processing.
4. Iptables Rule Configuration (Core!)

This is the most critical part, and the final configuration that can be used is:

Create MIHOMO Chain

sudo iptables -t nat -N MIHOMO

Exclude direct traffic between Tailscale devices (very important!)

sudo iptables -t nat -A MIHOMO -d 100.64.0.0/10 -j RETURN

Exclude LAN addresses

sudo iptables -t nat -A MIHOMO -d 10.0.0.0/8 -j RETURN
sudo iptables -t nat -A MIHOMO -d 172.16.0.0/12 -j RETURN
sudo iptables -t nat -A MIHOMO -d 192.168.0.0/16 -j RETURN

Exclude mihomo’s own traffic (prevent loopback)

sudo iptables -t nat -A MIHOMO -m owner – uid-owner mihomo -j RETURN

TCP traffic is redirected to mihomo’s port (assuming it is 7777)

sudo iptables -t nat -A MIHOMO -p tcp -j REDIRECT – to-ports 7777

Introduce PREROUTING traffic from Tailscale subnet into mihomo chain

sudo iptables -t nat -A PREROUTING -i tailscale0 -p tcp -j MIHOMO

Here is a key point among the key points! The rule {{PROTECT_0-CODE}} (I achieved the same effect using – d 100.64.0.0/10
in conjunction with RETURN). 100.64.0.0/10 is the CGNAT address segment of Tailscale, where all direct traffic between Tailscale devices is located. If this network segment is not excluded, direct communication between devices will also be sent to mihomo, resulting in Tailscale’s point-to-point connection being disconnected, and even devices cannot ping each other! I have been stepping on this pit for a long time, everyone must pay attention!
Why only handle TCP and what about UDP?

Why not use TProxy to handle both TCP and UDP simultaneously? Because Tailscale’s kernel routing and TProxy will fight! I have found through practical testing that when using TProxy to mark packets with fwmark, the ts forward chain registered by Tailscale will interfere with the kernel’s routing decisions, resulting in packets marked with
being directly discarded. The specific manifestation is that in TProxy mode, both TCP and UDP timeout and are completely disconnected.

So the final solution is:

  • TCP: Using REDIRECT (NAT mode) to hijack mihomo, simple and reliable
  • UDP: No hijacking at all, direct forwarding

The good news is that UDP not using proxies has little impact. The QUIC protocol used by services such as YouTube, although based on UDP, can still function properly during TCP fallback. In actual experience, YouTube videos still open in seconds, and there is no significant difference in speed.
VI. Mihomo Configuration Points

Mihomo needs to enable Redis port on this side:

config.yaml

redir-port: 7777
tcp-concurrent: true

Just make sure that mihomo is listening to the TCP redirect traffic on port 7777.
7. Testing and Verification

On the phone:

  1. Confirm that Tailscale is connected and select Raspberry Pi as the Exit Node
  2. Open a browser to access https://ipinfo.io
  3. If the displayed IP is the IP of your proxy server, it means that the traffic has successfully passed through mihomo!
  4. Visit https://www.youtube.com See if the video can be played normally

You can use the following command on Raspberry Pi to observe traffic in real-time:

sudo iptables -t nat -L MIHOMO -v -n

If you see the pkts count increasing, it means the rule is working properly.

8. Summary of pitfalls: a core principle

Each traffic source only uses one interception method!
Specifically:

  • Transparent proxy for local LAN devices: using TProxy (UDP+TCP can handle both)
  • Traffic coming from Tailscale tunnel: only REDIRECT (processing TCP only)

Never use both TProxy and REDIRECT on the same traffic source, and do not tamper with Tailscale’s ts forward chain. I have tried various combinations, but in the end, the only one is the one above; TCP REDIRECT+UDP Direct Connection;
The plan can operate stably.
9. Complete Command Summary

Convenient for everyone to copy and paste

Enable forwarding

sudo sysctl -w net.ipv4.ip_forward=1

Start Tailscale exit node

sudo tailscale up – advertise-exit-node

Iptables rule

sudo iptables -t nat -N MIHOMO
sudo iptables -t nat -A MIHOMO -d 100.64.0.0/10 -j RETURN
sudo iptables -t nat -A MIHOMO -d 10.0.0.0/8 -j RETURN
sudo iptables -t nat -A MIHOMO -d 172.16.0.0/12 -j RETURN
sudo iptables -t nat -A MIHOMO -d 192.168.0.0/16 -j RETURN
sudo iptables -t nat -A MIHOMO -m owner – uid-owner mihomo -j RETURN
sudo iptables -t nat -A MIHOMO -p tcp -j REDIRECT – to-ports 7892
sudo iptables -t nat -A PREROUTING -i tailscale0 -p tcp -j MIHOMO

Remember to write these rules into the startup script and they will automatically take effect after restarting.

Reference materials:

  1. Tailscale Official Document; Exit Nodes: https://tailscale.com/kb/1103/exit-nodes
  2. Tailscale Official Document; Subnet Routes: https://tailscale.com/kb/1019/subnets
  3. Mihomo official document: https://wiki.metacubex.one/
  4. Linux iptables REDIRECT vs TProxy: https://www.kernel.org/doc/Documentation/networking/tproxy.txt
  5. Tailscale CGNAT Address Segment Description: https://tailscale.com/kb/1015/100.x-addresses

Published on October 7, 2026.

Leave a Reply

Your email address will not be published. Required fields are marked *