MetaCubeX / mihomo

A simple Python Pydantic model for Honkai: Star Rail parsed data from the Mihomo API.
https://wiki.metacubex.one
MIT License
16.19k stars 2.61k forks source link

[Bug] tproxy模式不支持网桥流量入站 #1587

Open 020794 opened 1 week ago

020794 commented 1 week ago

Verify steps

Operating System

Linux

System Version

ubuntu 24.04

Mihomo Version

1.18.9

Configuration File

mode: rule
log-level: info
ipv6: false
interface-name: wlp3s0
allow-lan: true

listeners:
- name: tproxy-in
  type: tproxy
  listen: 0.0.0.0
  port: 7893
  udp: true

dns:
  enable: true
  listen: 0.0.0.0:5300
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 114.114.114.114
  default-nameserver:
    - 114.114.114.114
profile:
  store-fake-ip: true

hosts:
  time.windows.com: 203.107.6.88
  time.android.com: 203.107.6.88

proxies:
  - name: ld
    type: socks5
    server: localhost
    port: 7894

proxy-groups:
  - name: LD
    type: select
    disable-udp: true
    proxies:
      - ld

rule-providers:
  direct:
    type: http
    behavior: domain
    url: 'https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/direct.txt'
    path: ./ruleset/direct.yaml
    interval: 86400

  gfw:
    type: http
    behavior: domain
    url: 'https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/gfw.txt'
    path: ./ruleset/gfw.yaml
    interval: 86400

  proxy:
    type: http
    behavior: domain
    url: 'https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/proxy.txt'
    path: ./ruleset/proxy.yaml
    interval: 86400

rules:
  - RULE-SET,direct,DIRECT
  - RULE-SET,gfw,LD
  - RULE-SET,proxy,LD
  - MATCH,DIRECT

iptables的设置是:
iptables -t nat -N NAT_PRERT
iptables -t nat -N NAT_POSTRT
iptables -t filter -N FIL_INPT
iptables -t filter -N FIL_FWD
iptables -t mangle -N MAN_PRERT
iptables -t mangle -N MAN_OUT

iptables -t nat -A NAT_POSTRT -o wlp3s0 -j MASQUERADE

iptables -t filter -A FIL_INPT -i br0 -j ACCEPT
iptables -t filter -A FIL_INPT -i lo -j ACCEPT
iptables -t filter -A FIL_INPT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A FIL_INPT -j DROP

iptables -t filter -A FIL_FWD -i br0 -j ACCEPT
iptables -t filter -A FIL_FWD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A FIL_FWD -j DROP

ip -4 rule add fwmark 0x1 lookup 100
ip -4 route add local 0.0.0.0/0 dev lo table 100

iptables -t mangle -A MAN_PRERT ! -d 198.18.0.0/16 -j RETURN
iptables -t mangle -A MAN_PRERT -p udp -j TPROXY --on-port 7893 --tproxy-mark 0x1
iptables -t mangle -A MAN_PRERT -p tcp -j TPROXY --on-port 7893 --tproxy-mark 0x1

iptables -t mangle -A MAN_OUT ! -d 198.18.0.0/16 -j RETURN
iptables -t mangle -A MAN_OUT -p udp -j MARK --set-mark 0x1
iptables -t mangle -A MAN_OUT -p tcp -j MARK --set-mark 0x1

iptables -t filter -I FIL_INPT 2 -p tcp --dport 7892 -j ACCEPT
iptables -t filter -I FIL_INPT 2 -p tcp --dport 7894 -j ACCEPT
iptables -t filter -I FIL_INPT 2 -p tcp --dport 47892 -j ACCEPT

iptables -t nat -I PREROUTING -j NAT_PRERT
iptables -t nat -I POSTROUTING -j NAT_POSTRT
iptables -t filter -I INPUT -j FIL_INPT
iptables -t filter -I FORWARD -j FIL_FWD
iptables -t mangle -I PREROUTING -j MAN_PRERT
iptables -t mangle -I OUTPUT -j MAN_OUT

netplan的配置为:
network:
    version: 2
    wifis:
        wlp3s0:
            optional: true
            access-points:
                y50:
                    password: 'password'
            dhcp4: false
            addresses:
                - 192.168.1.2/24
            routes:
                - to: default
                  via: 192.168.1.1
            nameservers:
                addresses: [127.0.0.1]
    ethernets:
        enp1s0:
            optional: true
            dhcp4: false
        eno1:
            optional: true
            dhcp4: false
    bridges:
        br0:
            optional: true
            interfaces:
                - enp1s0
                - eno1
            dhcp4: false
            addresses:
                - 192.168.0.2/24

检查tproxy端口流量的python脚本:
!/usr/bin/env python3

import socket
import struct

def start_tproxy_raw_socket():
    # 创建原始套接字,SOCK_RAW 捕获所有传入的数据包
    sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)

    # 开启 IP_TRANSPARENT 选项
    sock.setsockopt(socket.SOL_IP, 19, 1)  # 19 是 IP_TRANSPARENT 的值

    print("Listening for TPROXY traffic using raw socket...")

    while True:
        packet, addr = sock.recvfrom(65535)

        # 提取源 IP 和目标 IP
        src_ip, dst_ip = parse_ip_header(packet)

        print(f"Source IP: {src_ip}, Destination IP: {dst_ip}")

def parse_ip_header(packet):
    # IP 头部结构解析
    ip_header = packet[:20]
    iph = struct.unpack('!BBHHHBBH4s4s', ip_header)

    # 源 IP 和目标 IP
    src_ip = socket.inet_ntoa(iph[8])
    dst_ip = socket.inet_ntoa(iph[9])

    return src_ip, dst_ip

if __name__ == "__main__":
    start_tproxy_raw_socket()

Description

我的linux软路由有3个网口,其中1个无线网口wlp3s0作为WAN口,地址是192.168.1.2,另外两个有线接口eno1和enp1s0作为LAN口,并加入了网桥br0,地址是192.168.0.2。

mihomo始终工作在tproxy模式,端口是7893。在不开启网桥的情况下,LAN口eno1和enp1s0的流量可以被mihomo正确处理,日志中可以看到大量LAN网段192.168.0.0的流量。

把eno1和enp1s0加入网桥br0后,mihomo就拿不到LAN流量了,日志里看不到LAN网段192.168.0.0的流量,只有WAN口192.168.1.2的本机流量。

我写了python脚本来检查tproxy端口的流量,发现tproxy端口上是有LAN网段192.168.0.0流量的,说明防火墙和路由配置应该是没问题的。但mihomo日志里就是看不到LAN的流量,有没有可能被mihomo丢掉了?

望大家不吝赐教。

Reproduction Steps

可以通过配置文件重现问题

Logs

Oct 13 21:03:11 m7 clash[19124]: time="2024-10-13T21:03:11.947202101+08:00" level=info msg="Geosite Matcher implementation: succinct"
Oct 13 21:03:11 m7 clash[19124]: time="2024-10-13T21:03:11.947332823+08:00" level=info msg="Initial configuration complete, total time: 0ms"
Oct 13 21:03:11 m7 clash[19124]: time="2024-10-13T21:03:11.957121482+08:00" level=info msg="Sniffer is closed"
Oct 13 21:03:11 m7 clash[19124]: time="2024-10-13T21:03:11.957207608+08:00" level=info msg="DNS server listening at: [::]:5300"
Oct 13 21:03:11 m7 clash[19124]: time="2024-10-13T21:03:11.95729683+08:00" level=info msg="TProxy[tproxy-in] proxy listening at: [::]:7893"
Oct 13 21:03:11 m7 clash[19124]: time="2024-10-13T21:03:11.957372266+08:00" level=info msg="Start initial provider proxy"
Oct 13 21:03:11 m7 clash[19124]: time="2024-10-13T21:03:11.957382676+08:00" level=info msg="Start initial provider direct"
Oct 13 21:03:11 m7 clash[19124]: time="2024-10-13T21:03:11.957427352+08:00" level=info msg="Start initial provider gfw"
Oct 13 21:03:12 m7 clash[19124]: time="2024-10-13T21:03:12.738461321+08:00" level=info msg="Start initial Compatible provider LD"
Oct 13 21:03:12 m7 clash[19124]: time="2024-10-13T21:03:12.73848654+08:00" level=info msg="Start initial Compatible provider default"
Oct 13 21:03:19 m7 clash[19124]: time="2024-10-13T21:03:19.649765715+08:00" level=debug msg="[Rule] use default rules"
Oct 13 21:03:19 m7 clash[19124]: time="2024-10-13T21:03:19.649886879+08:00" level=debug msg="[DNS] resolve api.io.mi.com A from udp://202.96.209.5:53"
Oct 13 21:03:19 m7 clash[19124]: time="2024-10-13T21:03:19.653871195+08:00" level=debug msg="[DNS] api.io.mi.com --> [118.26.252.107 110.43.87.16 220.181.106.173] A from udp://202.96.209.5:53"
Oct 13 21:03:19 m7 clash[19124]: time="2024-10-13T21:03:19.684532371+08:00" level=info msg="[TCP] 192.168.1.2:40762 --> api.io.mi.com:443 match RuleSet(direct) using DIRECT"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.289524612+08:00" level=debug msg="[Rule] use default rules"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.289584107+08:00" level=debug msg="[DNS] cache hit api.io.mi.com --> [118.26.252.107 110.43.87.16 220.181.106.173] A, expire at 2024-10-13 21:13:19"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.289657639+08:00" level=debug msg="[Rule] use default rules"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.289686404+08:00" level=debug msg="[DNS] cache hit api.io.mi.com --> [118.26.252.107 110.43.87.16 220.181.106.173] A, expire at 2024-10-13 21:13:19"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.289726131+08:00" level=debug msg="[Rule] use default rules"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.289755027+08:00" level=debug msg="[DNS] cache hit api.io.mi.com --> [118.26.252.107 110.43.87.16 220.181.106.173] A, expire at 2024-10-13 21:13:19"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.289789844+08:00" level=debug msg="[Rule] use default rules"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.289811766+08:00" level=debug msg="[DNS] cache hit api.io.mi.com --> [118.26.252.107 110.43.87.16 220.181.106.173] A, expire at 2024-10-13 21:13:19"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.289868255+08:00" level=debug msg="[Rule] use default rules"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.28988659+08:00" level=debug msg="[DNS] cache hit api.io.mi.com --> [118.26.252.107 110.43.87.16 220.181.106.173] A, expire at 2024-10-13 21:13:19"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.31977552+08:00" level=info msg="[TCP] 192.168.1.2:41910 --> api.io.mi.com:443 match RuleSet(direct) using DIRECT"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.321173586+08:00" level=info msg="[TCP] 192.168.1.2:41922 --> api.io.mi.com:443 match RuleSet(direct) using DIRECT"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.322405461+08:00" level=info msg="[TCP] 192.168.1.2:41940 --> api.io.mi.com:443 match RuleSet(direct) using DIRECT"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.322436882+08:00" level=info msg="[TCP] 192.168.1.2:41932 --> api.io.mi.com:443 match RuleSet(direct) using DIRECT"
Oct 13 21:03:30 m7 clash[19124]: time="2024-10-13T21:03:30.322486838+08:00" level=info msg="[TCP] 192.168.1.2:41924 --> api.io.mi.com:443 match RuleSet(direct) using DIRECT"
020794 commented 1 week ago

求助!

xishang0128 commented 1 week ago

请确保其他tproxy程序正常工作,否则这是你iptables配置的问题

mihomo只负责监听