Linux 网关 - 用 mihomo 使用 Tproxy 模式 作为透明代理
侧边栏壁纸
  • 累计撰写 16 篇文章
  • 累计收到 11 条评论

Linux 网关 - 用 mihomo 使用 Tproxy 模式 作为透明代理

坑了个飞
2025-01-09 / 2 评论 / 90 阅读 / 正在检测是否收录...
注意: 我这个配置只能劫持局域网内的设备的请求流量, 无法劫持网关本身的请求流量

环境说明:

  • 机器: J643 6 口小主机
  • pve 8.0.4
  • lxc 容器里装个 debian 12

Tproxy 和 tun 模式有啥区别, 这是GPT给出的结果

特性TproxyTUN
工作层级四层(数据链路层)三层(IP 层)
是否保留源 IP
配置复杂度较高较低
性能较高可能较低
灵活性较低较高
适用场景流量转发、透明代理VPN、跨网络代理、用户态协议栈
我反正是没感觉出来, 我用 Tproxy 模式的最大原因是这个可以代理游戏加速, 打游戏不卡

一、开启 IP 转发

执行下面这行命令开启 ipv4 和 ipv6 转发

tee /etc/sysctl.conf <<-'EOF'
net.ipv4.ip_forward = 1
net.ipv4.conf.all.route_localnet=1
net.ipv6.conf.all.forwarding = 1
EOF

查看是否执行成功

sysctl -p

image.png

一、安装 mihomo

先自行安装 mihomo , 不会安装也可以参考我之前的一片文章:

pve lxc 环境下 安装配置 Clash Meta 作为透明网关 - 坑了个飞

二、配置 mihomo

tproxy 模式的配置跟 tun 的稍微有点不一样, 整体配置如下

重要部分我会在下面说明, 请根据自身情况酌情修改
#---------------------------------------------------#
## 配置文件需要放置在 $HOME/.config/clash.meta/*.yaml

## 这份文件是clashX的基础配置文件,请尽量新建配置文件进行修改。

## 如果您不知道如何操作,请参阅
## Clash Meta wiki  https://docs.metacubex.one
## Clash Meta wiki  https://clash-meta.wiki
## Clash Meta Github文档  https://github.com/MetaCubeX/Clash.Meta/blob/Alpha/README.md
## 规则地址 https://github.com/v2fly/domain-list-community/tree/master/data

#---------------------------------------------------#
log-level: warning
mode: rule
find-process-mode: off
ipv6: true
unified-delay: true
tcp-concurrent: true
keep-alive-idle: 600
keep-alive-interval: 15
external-ui: ui
external-ui-name: MetaCubeXD
external-ui-url: https://ghfast.top/https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip
external-controller: 0.0.0.0:9090
secret: "112233"
profile:
  store-selected: true
  store-fake-ip: true
allow-lan: true
port: 8080
socks-port: 1080
mixed-port: 7890
redir-port: 7891
tproxy-port: 7892
tun:
  enable: false
  stack: system
  device: mihomo
  mtu: 9000
  gso: true
  gso-max-size: 65536
  endpoint-independent-nat: false
dns:
  enable: true
  listen: 0.0.0.0:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  respect-rules: false
  prefer-h3: false
  ipv6: true
  use-system-hosts: false
  use-hosts: false
  fake-ip-filter-mode: blacklist
  fake-ip-filter:
    - +.lan
    - +.local
    - geosite:cn
    - rule-set:custom-direct-domain
    - +.20240215.xyz
  default-nameserver:
    - 10.0.0.5
  proxy-server-nameserver:
    - tcp://10.0.0.5
  direct-nameserver:
    - tcp://10.0.0.5
  nameserver:
    - tcp://10.0.0.5
  nameserver-policy:
    geosite:cn:
      - tcp://10.0.0.4
      - 223.5.5.5
    +.20240215.xyz:
      - 1.0.0.1
sniffer:
  enable: true
  force-dns-mapping: true
  parse-pure-ip: true
  override-destination: false
  skip-domain:
    - Mijia Cloud
    - dlg.io.mi.com
    - +.push.apple.com
    - +.apple.com
  sniff:
    HTTP:
      override-destination: true
      ports:
        - 80
        - 8080
    TLS:
      override-destination: true
      ports:
        - 443
        - 8443
    QUIC:
      override-destination: true
      ports:
        - 443
        - 8443
geodata-mode: true
geodata-loader: standard
geox-url:
  geosite: https://ghfast.top/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat
  mmdb: https://ghfast.top/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.metadb
  geoip: https://ghfast.top/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat
  asn: https://ghfast.top/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb
geo-auto-update: true
geo-update-interval: 24
authentication:
  - kenfei:654321


pr: &pr {type: select, proxies: [♻️ 自动选择, "\U0001F680 节点选择", "\U0001F310 全部节点", "\U0001F7E2 直连"]}
# url 里填写自己的订阅,名称不能重复
proxy-providers:
  provider1:
    url: "订阅地址"
    type: http
    interval: 86400
    health-check: {enable: true, url: "https://www.gstatic.com/generate_204", interval: 300}
    proxy: "\U0001F7E2 直连"
    override:
      additional-prefix: "[me]"
# 统一延迟, 更换延迟计算方式,去除握手等额外延迟
# unified-delay: true
# TCP 并发连接所有 IP, 将使用最快握手的 TCP
# tcp-concurrent: true
# 全局 TLS 指纹,优先低于 proxy 内的 client-fingerprint
# 可选: "chrome","firefox","safari","ios","random","none" options.
# Utls is currently support TLS transport in TCP/grpc/WS/HTTP for VLESS/Vmess and trojan.
global-client-fingerprint: chrome
proxies:
  - name: "\U0001F7E2 直连"
    type: direct
    udp: true
proxy-groups:
  - {name: "\U0001F680 节点选择", type: select, use: [provider1]}
  - {name: "\U0001F4F9 YouTube", !!merge <<: *pr}
  - {name: "\U0001F340 Google", !!merge <<: *pr}
  - {name: "\U0001F916 ChatGPT", !!merge <<: *pr}
  - {name: "\U0001F468\U0001F3FF‍\U0001F4BB GitHub", !!merge <<: *pr}
  - {name: "\U0001F42C OneDrive", !!merge <<: *pr}
  - {name: "\U0001FA9F Microsoft", !!merge <<: *pr}
  - {name: "\U0001F3B5 TikTok", !!merge <<: *pr}
  - {name: "\U0001F4F2 Telegram", !!merge <<: *pr}
  - {name: "\U0001F3A5 NETFLIX", !!merge <<: *pr}
  - {name: ✈️ Speedtest, !!merge <<: *pr}
  - {name: "\U0001F4B6 PayPal", !!merge <<: *pr}
  - {name: "\U0001F3AE xbox", use: [provider1], !!merge <<: *pr}
  - {name: "\U0001F34E Apple", type: select, proxies: ["\U0001F7E2 直连", "\U0001F680 节点选择"]}
  - {name: "\U0001F3AF 全球直连", type: select, proxies: ["\U0001F7E2 直连", "\U0001F680 节点选择"]}
  - {name: "\U0001F41F 漏网之鱼", use: [provider1], !!merge <<: *pr}
  - {name: ♻️ 自动选择, type: url-test, include-all: true, tolerance: 20, interval: 300, filter: "^((?!(直连)).)*$"}
  - {name: "\U0001F310 全部节点", type: select, include-all: true}
rule-anchor:
  ip: &ip {type: http, interval: 86400, behavior: ipcidr, format: mrs}
  domain: &domain {type: http, interval: 86400, behavior: domain, format: mrs}
  custom_ip: &custom_ip {type: http, interval: 86400, behavior: ipcidr, format: text}
  custom_domain: &custom_domain {type: http, interval: 86400, behavior: domain, format: yaml}
rule-providers:
  # 自定义直连规则
  custom-direct-domain: {!!merge <<: *custom_domain, url: "https://ghfast.top/https://raw.githubusercontent.com/fillpit/script/main/clash/rules/custom-direct-domain.yaml"}
  # 自定义直连规则
  custom-direct-ip: {!!merge <<: *custom_ip, url: "https://ghfast.top/https://raw.githubusercontent.com/fillpit/script/main/clash/rules/custom-direct-ip.txt"}
  # 自定义代理规则
  custom-proxy-domain: {!!merge <<: *custom_domain, url: "https://ghfast.top/https://raw.githubusercontent.com/fillpit/script/main/clash/rules/custom-proxy-domain.yaml"}
  # 自定义代理规则
  custom-proxy-ip: {!!merge <<: *custom_ip, url: "https://ghfast.top/https://raw.githubusercontent.com/fillpit/script/main/clash/rules/custom-proxy-ip.txt"}
rules:
  # 自己的规则放前面
  - "RULE-SET,custom-direct-domain,\U0001F7E2 直连"
  - "RULE-SET,custom-direct-ip,\U0001F7E2 直连"
  - RULE-SET,custom-proxy-domain,♻️ 自动选择
  - "RULE-SET,custom-proxy-ip,\U0001F3AE xbox"
  # ******** 自定义 规则区域 start ********
  # ****** 默认 非国内的域名和ip都走代理 ******
  # ****** 也就是说分流规则这里主要关注 需要直连的地址 和需要屏蔽的地址 (没匹配上的都走代理) ******

  # 私有网络专用域名 
  - "GEOIP,lan,\U0001F7E2 直连,no-resolve"
  - "GEOSITE,private,\U0001F7E2 直连"
  - "GEOSITE,youtube,\U0001F4F9 YouTube"
  - "GEOSITE,google,\U0001F340 Google"
  - "GEOIP,google,\U0001F340 Google"
  - "GEOSITE,openai,\U0001F916 ChatGPT"
  - "GEOSITE,github,\U0001F468\U0001F3FF‍\U0001F4BB GitHub"
  - "GEOSITE,onedrive,\U0001F42C OneDrive"
  - "GEOSITE,microsoft,\U0001FA9F Microsoft"
  - "GEOSITE,tiktok,\U0001F3B5 TikTok"
  - "GEOSITE,telegram,\U0001F4F2 Telegram"
  - "GEOIP,telegram,\U0001F4F2 Telegram"
  - "GEOSITE,netflix,\U0001F3A5 NETFLIX"
  - "GEOIP,netflix,\U0001F3A5 NETFLIX"
  - GEOSITE,speedtest,✈️ Speedtest
  - "GEOSITE,paypal,\U0001F4B6 PayPal"
  - "GEOSITE,apple,\U0001F34E Apple"
  # 国内域名 直连
  - "GEOSITE,CN,\U0001F7E2 直连"
  # 国内 ip 直连
  - "GEOIP,CN,\U0001F7E2 直连"
  - "MATCH,\U0001F41F 漏网之鱼"
  • proxy-providers.provider1.url: 这里改成你自己的订阅链接
  • 10.0.0.5 ,10.0.0.4 : 这是我 Adguard DNS 的IP, 请改成你自己

配置防火墙规则

在大多数 Linux 系统上,/etc/nftables.confnftables 服务启动时加载的默认配置文件, 编辑该文件, 加入下面的内容

注意下面配置最上面的 TPROXY_PORT 、DNS_PORT、FAKE_IP 这三个变量要与 mihomo的配置里的一致
#!/usr/sbin/nft -f

flush ruleset

define TPROXY_PORT = 7892
define DNS_PORT = 1053
define FAKE_IP = 198.18.0.0/16

table inet mihomo {
  # 同时劫持的IPV4 和 IPV6 的 DNS
  set dns_hijack_nfproto {
    type nf_proto
    flags interval
    elements = { ipv4, ipv6 }
  }
  # 代理 IPV4 和 IPV6
  set proxy_nfproto {
    type nf_proto
    flags interval
    elements = { ipv4, ipv6 }
  }
  # 预留的 IPV4 地址
  set reserved_ip {
    type ipv4_addr
    flags interval
    auto-merge
    elements = {
      0.0.0.0/8,
      10.0.0.0/8,
      100.64.0.0/10,
      127.0.0.0/8,
      169.254.0.0/16,
      172.16.0.0/12,
      192.168.0.0/16,
      224.0.0.0/4,
      240.0.0.0/4
    }
  }

  # 预留的 IPV6 地址
  set reserved_ip6 {
    type ipv6_addr
    flags interval
    auto-merge
    elements = {
      ::,
      ::1,
      ::ffff:0.0.0.0/96,
      64:ff9b::/96,
      100::/64,
      2001::/32,
      2001:10::/28,
      2001:20::/28,
      2001:db8::/32,
      2002::/16,
      fc00::/7,
      fe80::/10,
      ff00::/8
    }
  }

  # 要代理端口范围
  set proxy_dport {
    type inet_proto . inet_service
    flags interval
    auto-merge
    elements = {
      tcp . 0-65535,
      udp . 0-65535
    }
  }

  # 走直连的局域网 IPV4 地址
  set acl_ip {
    type ipv4_addr
    flags interval
    auto-merge
    elements = {
      10.0.10.33,
      10.0.10.34
    }
  }

  # 走直连的局域网 IPV6 地址
  set acl_ip6 {
    type ipv6_addr
    flags interval
    auto-merge
  }

  # 代理局域网设备的DNS 查询
  chain block_dns_hijack {
    meta nfproto @dns_hijack_nfproto udp dport 53 ip saddr @acl_ip counter return
    meta nfproto @dns_hijack_nfproto udp dport 53 ip6 saddr @acl_ip6 counter return
    meta nfproto @dns_hijack_nfproto udp dport 53 counter redirect to :$DNS_PORT
  }

  # 走代理的局域网设备
  chain block_tproxy {
    meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip counter return
    meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter return
    meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set 1 tproxy to :$TPROXY_PORT counter accept
  }

  # 代理网关本机 DNS 查询(未启用-有问题)
  chain nat_output {
    type nat hook output priority -101; policy accept;
    #ip daddr != 127.0.0.1 meta nfproto @dns_hijack_nfproto udp dport 53 counter redirect to :$DNS_PORT
  }

  # 代理网关本机
  chain router_reroute {
    ip daddr != 127.0.0.1 meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set 1 counter accept 
  }


  # 代理网关本机(未启用-有问题)
  chain mangle_output {
    type route hook output priority 100; policy accept;
    meta l4proto { tcp, udp } iifname "mihomo" counter accept
    fib daddr type { local, broadcast, anycast, multicast } counter return
    ip daddr @reserved_ip counter return
    ip6 daddr @reserved_ip6 counter return

    meta l4proto . th dport != @proxy_dport ip daddr != $FAKE_IP counter return
    meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return

    udp dport 53 counter return

    #meta l4proto tcp jump router_reroute
    #meta l4proto udp jump router_reroute
  }



  chain dstnat {
    type nat hook prerouting priority dstnat + 1; policy accept;
    jump block_dns_hijack
  }

  chain mangle_prerouting {
    type filter hook prerouting priority mangle; policy accept;
    meta l4proto { tcp, udp } iifname "mihomo" counter accept
    fib daddr type { local, broadcast, anycast, multicast } counter return
    ct direction reply counter return
    ip daddr @reserved_ip counter return
    ip6 daddr @reserved_ip6 counter return
    meta l4proto . th dport != @proxy_dport ip daddr != $FAKE_IP counter return
    meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return
    udp dport 53 counter return
    meta l4proto tcp jump block_tproxy
    meta l4proto udp jump block_tproxy
  }
}

编辑该文件后重启服务:

systemctl restart nftables

配置路由表

添加路由规则

ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100

持久化路由配置

编辑 /etc/network/interfaces

nano /etc/network/interfaces

在对应的 iface 配置下添加:

auto lo
iface lo inet loopback
    post-up ip rule add fwmark 1 lookup 100
    post-up ip route add local 0.0.0.0/0 dev lo table 100
    pre-down ip rule del fwmark 1 lookup 100
    pre-down ip route del local 0.0.0.0/0 dev lo table 100
  • post-up:开机时执行
  • pre-down:关机或网络重启前清理规则

应用更改:

systemctl restart networking

这个脚本会在网络接口启动时自动运行。

现在重启机器试试效果吧

0

评论 (2)

取消
  1. 头像
    dnvcupid
    MacOS · Google Chrome
    @

    大佬能说说前面套个mosdns分流后再到mihomo要怎么修改不

    回复
    1. 头像
      dnvcupid
      MacOS · Google Chrome
      @ dnvcupid

      主要是nftables

      回复