MetaCubeX / mihomo

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

[Bug] ipv6 tproxy udp 报错 panic: runtime error: index out of range [0] with length 0 #977

Open YaxAu opened 7 months ago

YaxAu commented 7 months ago

Verify steps

Mihomo version

Mihomo Meta v1.18.0 linux arm64 with go1.21.5 Tue Jan 2 07:30:47 UTC 2024

What OS are you seeing the problem on?

Linux

Mihomo config

ipv6: true

log-level: debug

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

proxies:
- name: "direct-connect"
  type: direct
  udp: true

rules:
  - MATCH,direct-connect

Mihomo log

root@raspberrypi:~/hysteria-client# sudo -u tproxy ./mihomo-linux-arm64 -d mihomo
INFO[2024-01-13T00:02:37.115046775-09:00] Start initial configuration in progress      
INFO[2024-01-13T00:02:37.115937812-09:00] Geodata Loader mode: memconservative         
INFO[2024-01-13T00:02:37.116096957-09:00] Geosite Matcher implementation: succinct     
INFO[2024-01-13T00:02:37.117704073-09:00] Initial configuration complete, total time: 2ms 
INFO[2024-01-13T00:02:37.18607361-09:00] Sniffer is closed                            
INFO[2024-01-13T00:02:37.187480924-09:00] TProxy[tproxy-in] proxy listening at: [::]:2500 
INFO[2024-01-13T00:02:37.1913793-09:00] Start initial Compatible provider default    
DEBU[2024-01-13T00:02:37.917806025-09:00] [Rule] use default rules                     
INFO[2024-01-13T00:02:37.936915964-09:00] [TCP] [240e:...someIP...]:57062 --> [240e:...some_other_IP....]:443 match Match using direct-connect 
DEBU[2024-01-13T00:02:46.433612383-09:00] [Rule] use default rules                     
INFO[2024-01-13T00:02:46.435795037-09:00] [TCP] 192.168.6.146:53644 --> 39.156.66.10:80 match Match using direct-connect # <--- curl baidu.com
panic: runtime error: index out of range [0] with length 0 # <--- curl ipv6.baidu.com

goroutine 39 [running]:
github.com/metacubex/mihomo/listener/tproxy.getOrigDst({0x400064a000?, 0x4000656000?, 0x0?})
    github.com/metacubex/mihomo/listener/tproxy/udp_linux.go:107 +0x1d8
github.com/metacubex/mihomo/listener/tproxy.NewUDP.func1()
    github.com/metacubex/mihomo/listener/tproxy/udp.go:77 +0xec
created by github.com/metacubex/mihomo/listener/tproxy.NewUDP in goroutine 1
    github.com/metacubex/mihomo/listener/tproxy/udp.go:64 +0x2f0

Description

系统

root@raspberrypi:~/hysteria-client# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 12 (bookworm)
Release:    12
Codename:   bookworm

刚重装的树莓派官方镜像,仅运行了预装的服务和 docker 及 docker-compose 相关服务 仅 ipv6 & udp & tproxy 协议会出现此问题,不论是 ipv4 & udp & tproxy 还是 ipv6 & udp & http 或是 ipv6 & tcp & tproxy 都不会出现此问题 使用 arm64, armv7 版本,以及测试过 Openwrt,Arch Linux(amd64 版本),Docker 镜像,均会报出同样的错误

工作目录

.
├── compose.yaml
├── config.yaml
├── iprules
│   ├── auto.sh
│   ├── auto_v6.sh
│   ├── i4.rules
│   ├── i6.rules
│   ├── o4.rules
│   └── o6.rules
├── mihomo
│   ├── cache.db
│   ├── config.yaml
│   ├── GeoIP.dat
│   ├── GeoSite.dat
│   ├── proxies
│   │   ├── *somthing1
│   │   ├── *somthing2
│   │   ├── *somthing3
│   │   └── *somthing4
│   └── ui
└── mihomo-linux-arm64

运行方式

使用 sudo -u tproxy ./mihomo-linux-arm64 -d ./mihomo 运行

其中 tproxy uid:gid 为 0:23333

代码报错位置

github.com/metacubex/mihomo/listener/tproxy/udp_linux.go

func getOrigDst(oob []byte) (netip.AddrPort, error) {
    // oob contains socket control messages which we need to parse.
    scms, err := unix.ParseSocketControlMessage(oob)
    if err != nil {
        return netip.AddrPort{}, fmt.Errorf("parse control message: %w", err)
    }

    // retrieve the destination address from the SCM.
//----------------------------------------------------------------------
    sa, err := unix.ParseOrigDstAddr(&scms[0])  // <-  panic: runtime error: index out of range [0] with length 0
//----------------------------------------------------------------------
    if err != nil {
        return netip.AddrPort{}, fmt.Errorf("retrieve destination: %w", err)
    }

    // encode the destination address into a cmsg.
    var rAddr netip.AddrPort
    switch v := sa.(type) {
    case *unix.SockaddrInet4:
        rAddr = netip.AddrPortFrom(netip.AddrFrom4(v.Addr), uint16(v.Port))
    case *unix.SockaddrInet6:
        rAddr = netip.AddrPortFrom(netip.AddrFrom16(v.Addr), uint16(v.Port))
    default:
        return netip.AddrPort{}, fmt.Errorf("unsupported address type: %T", v)
    }

    return rAddr, nil
}

已开启 ipv6 转发

root@raspberrypi:~/hysteria-client# cat /proc/sys/net/ipv6/conf/all/forwarding
1

ipv6 相关规则、路由

auto_v6.sh

# --------------------------------- ipv6
ip -6 rule add fwmark 0x1 lookup 100
ip -6 route add local default dev lo table 100

ip6tables -t mangle -N HYSTERIA6
# 跳过已经由 TProxy 接管的流量
ip6tables -t mangle -A HYSTERIA6 -p tcp -m socket --transparent -j MARK --set-mark 0x1
ip6tables -t mangle -A HYSTERIA6 -p udp -m socket --transparent -j MARK --set-mark 0x1
ip6tables -t mangle -A HYSTERIA6 -m socket -j RETURN

# 绕过私有和特殊 IPv6 地址
ip6tables -t mangle -A HYSTERIA6 -d ::1/128 -j RETURN
ip6tables -t mangle -A HYSTERIA6 -d fe80::/10 -j RETURN
ip6tables -t mangle -A HYSTERIA6 -d fd00::/8 -j RETURN

# 给 TCP 打标记 1,转发至 2500 端口
ip6tables -t mangle -A HYSTERIA6 -p tcp -j TPROXY --on-port 2500 --on-ip ::1 --tproxy-mark 0x1
ip6tables -t mangle -A HYSTERIA6 -p udp -j TPROXY --on-port 2500 --on-ip ::1 --tproxy-mark 0x1

# 应用规则
ip6tables -t mangle -A PREROUTING -j HYSTERIA6

# === 代理本机流量 - 开始 ===

ip6tables -t mangle -N HYSTERIA6_MARK

# 通过匹配用户来避免环路
ip6tables -t mangle -A HYSTERIA6_MARK -m owner --gid-owner 23333 -j RETURN

# 绕过局域网和特殊 IPv6 地址
ip6tables -t mangle -A HYSTERIA6_MARK -d ::1/128 -j RETURN
ip6tables -t mangle -A HYSTERIA6_MARK -d fe80::/10 -j RETURN
ip6tables -t mangle -A HYSTERIA6_MARK -d fd00::/8 -j RETURN

# 重路由 OUTPUT 链流量到 PREROUTING 链
ip6tables -t mangle -A HYSTERIA6_MARK -p tcp -j MARK --set-mark 0x1
ip6tables -t mangle -A HYSTERIA6_MARK -p udp -j MARK --set-mark 0x1

# 启用上述规则
ip6tables -t mangle -A OUTPUT -j HYSTERIA6_MARK

# === 代理本机流量 - 结束 ===

若还需其他信息,我将尽快提供

感谢!

YaxAu commented 7 months ago

此外,测试过 v1.16.0 和 Alpha 版本,均有同样问题

Larvan2 commented 7 months ago

https://github.com/MetaCubeX/mihomo/commit/25d6ad220d15aaedf6a07720f59845b3d3c725da 这个commit之后有修复吗?