SagerNet / sing-box

The universal proxy platform
https://sing-box.sagernet.org/
Other
20.18k stars 2.4k forks source link

WireGuard outbounds with domain name in server field cause crashes when listed under a selector outbound #1825

Open Primate8423 opened 5 months ago

Primate8423 commented 5 months ago

Operating system

Windows

System version

Windows 11 Enterprise 23H2 (22631.3672)

Installation type

Original sing-box Command Line

If you are using a graphical client, please provide the version of the client.

No response

Version

sing-box version 1.9.0

Environment: go1.22.3 windows/amd64
Tags: with_gvisor,with_quic,with_dhcp,with_wireguard,with_ech,with_utls,with_reality_server,with_acme,with_clash_api
Revision: 5ff7006326e8a876d33d92b26ebd2671cdd48b9f
CGO: disabled

Description

If a WireGuard outbound with domain name in server field are listed in a selector outbound, sing-box will crash. If it is changed to IP address instead, sing-box won't crash. If the WireGuard outbound is put into final field directly, it won't crash, either.

I've tracked it down and the problem causing crash was introduced between 1.8.0-beta.4 and 1.8.0-beta.6. In 1.8.0-beta.4 the following configuration file won't crash sing-box (although sing-box will stuck retrying DNS lookup, say dns: lookup failed for reddit.com: exchange6: connect udp 1.1.1.1:53: no route to host | exchange4: connect udp 1.1.1.1:53: no route to host), and starting from 1.8.0-beta.6 sing-box will crash (invalid memory address or nil pointer dereference).

Reproduction

In elevated command prompt, run:

sing-box run -c .\config.json

The content of config.json:

{
    "log": {
        "disabled": false,
        "level": "trace",
        "timestamp": false
    },
    "dns": {
        "servers": [
            {
                "tag": "dns",
                "address": "udp://1.1.1.1"
            }
        ]
    },
    "inbounds": [
        {
            "type": "tun",
            "tag": "tun-in",
            "inet4_address": "172.19.0.1/30",
            "inet6_address": "fdfe:dcba:9876::1/126"
        }
    ],
    "outbounds": [
        {
            "type": "wireguard",
            "tag": "wg",
            "local_address": [
                "2001::1/128"
            ],
            "private_key": "kBYbjzUqq0dOxNxLT1wTO7oQ7rQuA6URX08hewaV2U8=",
            "peers": [
                {
                    "server": "reddit.com",
                    "server_port": 2333,
                    "public_key": "kTsgZURPG1dkirckXUTFVNcM/tW0iXiJJa+yLfO8qDQ=",
                    "allowed_ips": [
                        "::/0"
                    ]
                }
            ]
        },
        {
            "type": "direct",
            "tag": "direct"
        },
        {
            "type": "selector",
            "tag": "sel",
            "outbounds": [
                "wg"
            ],
            "default": "wg"
        }
    ],
    "route": {
        "final": "sel"
    }
}

Logs

INFO[0000] router: updated default interface Wi-Fi, index 28
DEBUG[0000] dns: lookup domain reddit.com
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x20 pc=0x111b825]

goroutine 52 [running]:
github.com/sagernet/sing-box/outbound.(*Selector).DialContext(0xc000249790, {0x176c620, 0xc000252320}, {0x155f7a6?, 0x0?}, {{{0x0, 0xffff01010101}, 0xc0000080d8}, 0x35, {0x0, ...}})
        github.com/sagernet/sing-box/outbound/selector.go:130 +0x45
github.com/sagernet/sing-box/common/dialer.(*RouterDialer).DialContext(0x10?, {0x176c620, 0xc000252320}, {0x155f7a6, 0x3}, {{{0x0, 0xffff01010101}, 0xc0000080d8}, 0x35, {0x0, ...}})
        github.com/sagernet/sing-box/common/dialer/router.go:25 +0x9d
github.com/sagernet/sing-dns.(*UDPTransport).DialContext(0x10?, {0x176c620?, 0xc000252320?})
        github.com/sagernet/sing-dns@v0.2.0-beta.18/transport_udp.go:68 +0x7a
github.com/sagernet/sing-dns.(*myTransportAdapter).open(0xc0002495f0, {0x176c620, 0xc000252320})
        github.com/sagernet/sing-dns@v0.2.0-beta.18/transport_base.go:72 +0x179
github.com/sagernet/sing-dns.(*myTransportAdapter).Exchange(0xc0002495f0, {0x176c5e8, 0xc000263350}, 0xc000264630)
        github.com/sagernet/sing-dns@v0.2.0-beta.18/transport_base.go:126 +0x7d
github.com/sagernet/sing-dns.(*UDPTransport).Exchange(0xc0002495f0, {0x176c5e8, 0xc000263350}, 0xc000264630)
        github.com/sagernet/sing-dns@v0.2.0-beta.18/transport_udp.go:56 +0x2d
github.com/sagernet/sing-dns.(*Client).ExchangeWithResponseCheck(0xc000232a80, {0x176c620, 0xc000252730}, {0x1773430, 0xc0002495f0}, 0xc000264630, 0x0, 0x0)
        github.com/sagernet/sing-dns@v0.2.0-beta.18/client.go:151 +0x92f
github.com/sagernet/sing-dns.(*Client).Exchange(...)
        github.com/sagernet/sing-dns@v0.2.0-beta.18/client.go:83
github.com/sagernet/sing-dns.(*Client).lookupToExchange(0xc000232a80, {0x176c620, 0xc000252730}, {0x1773430, 0xc0002495f0}, {0xc000268c64, 0xb}, 0x1c, 0x0, 0x0)
        github.com/sagernet/sing-dns@v0.2.0-beta.18/client.go:562 +0x2f9
github.com/sagernet/sing-dns.(*Client).LookupWithResponseCheck.func2({0x176c620?, 0xc000252730?})
        github.com/sagernet/sing-dns@v0.2.0-beta.18/client.go:212 +0x5a
github.com/sagernet/sing/common/task.(*Group).RunContextList.func1()
        github.com/sagernet/sing@v0.4.0-beta.20/common/task/task.go:91 +0x107
created by github.com/sagernet/sing/common/task.(*Group).RunContextList in goroutine 1
        github.com/sagernet/sing@v0.4.0-beta.20/common/task/task.go:75 +0x198

Supporter

Integrity requirements

Anderhar commented 3 months ago

Confirmed!

I noticed this when tried to use Hiddify and Husi on android to connect to Windscribe VPN in order to create multi-hop chain. Windscribe's WG configs contain domain names as an endpoint instead of a regular IPs (е.g. lux-149-wg.whiskergalaxy.com), and sing-box doesn't seem to know what to do with it.

If you resolve domain manually and put the resulting IP in the "server:" field, things immediately start working, but this is not envisioned by Windscribe, so leads to a different kind of issues.

Looks like a clear omission in the sing-box design.