openwrt通过tailscale出口节点转发路由

前言 在当今高度互联的世界中,出于隐私保护、安全审计、或是访问特定区域网络服务的需求,许多技术爱好者和企业网络管理员都需要构建跨越不同地理位置的加密网络隧道。一个非常经典的场景是:将位于 A 地的家用或办公路由器,通过加密隧道将所有物理局域网流量,强制经过 B 地的出口节点(Exit Node)访问

前言

在当今高度互联的世界中,出于隐私保护、安全审计、或是访问特定区域网络服务的需求,许多技术爱好者和企业网络管理员都需要构建跨越不同地理位置的加密网络隧道。一个非常经典的场景是:将位于 A 地的家用或办公路由器,通过加密隧道将所有物理局域网流量,强制经过 B 地的出口节点(Exit Node)访问互联网。

这样的配置可以让我们看起来就像完全置身于 B 地一样。

基本情况

  • A 地(客户端):运行 QWRT的高原型路由器。局域网网段为 10.168.166.0/24,路由器管理 IP 为 10.168.166.253

  • B 地(服务端/出口节点):一台运行 Tailscale 并被配置为 Exit Node 的服务器。

路由设置

# !!!请修改相关IP地址
# !!!请修改相关IP地址
# !!!请修改相关IP地址

# 删除旧的策略路由规则,防止防火墙重启导致规则无限叠加报错
ip rule del priority 40 2>/dev/null
ip rule del priority 50 2>/dev/null
ip rule del priority 60 2>/dev/null
# 局域网互通,如果数据包的目的地是局域网内部 (10.168.166.0/24),查主路由表
ip rule add to 10.168.166.0/24 table main priority 40
# 强制流量走隧道,如果数据包是从局域网发出的 (来自于10.168.166.0/24),强制让它去查编号为52的路由表(tailscale路由表)
ip rule add from 10.168.166.0/24 table 52 priority 50
# 如果tailscale断开,路由表52就会失效,数据包就会继续往下走到优先级60。实现断网效果
ip rule add from 10.168.166.0/24 type unreachable priority 60
# tailscale有时会在它路由表里生成一条throw规则,导致本地流量被踢回主路由表形成黑洞
ip route del throw 10.168.166.0/24 table 52 2>/dev/null
# 显式添加去往局域网的流量,请直接走物理局域网口 到tailscale路由表
ip route add 10.168.166.0/24 dev br-lan table 52 2>/dev/null

防火墙转发设置

# !!!请修改相关IP地址
# !!!请修改相关IP地址
# !!!请修改相关IP地址

nft add rule inet fw4 srcnat oifname "tailscale0" masquerade

nft insert rule inet fw4 forward iifname "br-lan" oifname "tailscale0" accept
nft insert rule inet fw4 forward iifname "tailscale0" oifname "br-lan" accept
nft insert rule inet fw4 input iifname "br-lan" ip daddr 10.168.166.253 accept

nft insert rule inet fw4 forward iifname "br-lan" ip daddr != 10.168.166.0/24 oifname != "tailscale0" drop

nft insert rule inet fw4 mangle_forward oifname "tailscale0" tcp flags syn tcp option maxseg size set rt mtu

开机脚本

# !!!请修改相关IP地址
# !!!请修改相关IP地址
# !!!请修改相关IP地址

cat << 'EOF' > /etc/hotplug.d/iface/99-tailscale-route
#!/bin/sh

[ "$ACTION" = "ifup" ] || [ "$ACTION" = "ifupdate" ] || exit 0

if [ "$DEVICE" = "tailscale0" ] || [ "$INTERFACE" = "lan" ]; then
    logger -t tailscale-route "Applying Tailscale Kill Switch routing rules..."
    
    ip rule del priority 40 2>/dev/null
    ip rule del priority 50 2>/dev/null
    ip rule del priority 60 2>/dev/null
    ip route del throw 10.168.166.0/24 table 52 2>/dev/null

    ip rule add to 10.168.166.0/24 table main priority 40
    ip rule add from 10.168.166.0/24 table 52 priority 50
    ip rule add from 10.168.166.0/24 type unreachable priority 60
    
    ip route add 10.168.166.0/24 dev br-lan table 52 2>/dev/null
fi
EOF

LICENSED UNDER CC BY-NC-SA 4.0
Comment