SagerNet / sing-box

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

Sniffing doesn't work on the server side - ShadowTLS #1699

Closed FPPweb3 closed 2 months ago

FPPweb3 commented 2 months ago

Operating system

Linux

System version

Debian 12

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.8.11

Environment: go1.22.2 linux/amd64
Tags: with_gvisor,with_quic,with_dhcp,with_wireguard,with_ech,with_utls,with_reality_server,with_acme,with_clash_api
Revision: 70381e93c824d385c931c5d6853dcf07f7d9e3ad
CGO: disabled

Description

Expected behavior:

  1. instagram.com with an IP address in the Iran range goes through Warp.
  2. instagram.com with an IP address outside Iran goes through Direct (user-out).
  3. Any other sites gets blocked.

Actual behavior:

  1. Any sites gets blocked.

Reproduction

Server:

{
  "log": {
    "level": "trace",
    "output": "boxes.log"
  },
  "dns": {
    "servers": [
      {
        "address": "tls://1.1.1.1"
      }
    ],
    "strategy": "prefer_ipv6"
  },
  "inbounds": [
    {
      "type": "shadowtls",
      "tag": "ss-tls-in",
      "listen": "SERVER_IPv4",
      "detour": "ss-in",
      "listen_port": 443,
      "version": 3,
      "strict_mode": true,
      "users": [
        {
          "name": "user",
          "password": "PASSWORD"
        }
      ],
      "handshake": {
        "server": "pinterest.com",
        "server_port": 443,
        "domain_strategy": "ipv4_only"
      }
    },
    {
      "type": "shadowsocks",
      "tag": "ss-in",
      "listen": "127.0.0.1",
      "network": "tcp",
      "sniff": true,
      "method": "2022-blake3-aes-128-gcm",
      "password": "PASSWORD"
    }
  ],
  "outbounds": [
    {
      "type": "direct"
    },
    {
      "type": "dns",
      "tag": "dns-out"
    },
    {
      "type": "block",
      "tag": "block"
    },
    {
      "type": "direct",
      "inet6_bind_address": "SERVER_IPv6",
      "tag": "user-out"
    },
    {
      "type": "socks",
      "tag": "warp",
      "server": "127.0.0.1",
      "server_port": 40000
    }
  ],
  "route": {
    "rules": [
      {
        "protocol": "dns",
        "outbound": "dns-out"
      },
      {
        "type": "logical",
        "mode": "and",
        "outbound": "warp",
        "rules": [
          {
            "ip_version": 4,
            "auth_user": "user",
            "rule_set": [
              "instagram",
              "twitter"
            ],
            "domain_suffix": [
              "bing.com",
              "canva.com"
            ]
          },
          {
            "rule_set": "geoip-ir"
          }
        ]
      },
      {
        "auth_user": "user",
        "outbound": "user-out",
        "rule_set": [
          "instagram",
          "twitter"
        ],
        "domain_suffix": [
          "bing.com",
          "canva.com"
        ]
      },
      {
        "auth_user": "user",
        "outbound": "block"
      }
    ],
    "rule_set": [
      {
        "tag": "geoip-ir",
        "type": "remote",
        "format": "binary",
        "url": "https://github.com/SagerNet/sing-geoip/raw/rule-set/geoip-ir.srs"
      },
      {
        "tag": "instagram",
        "type": "remote",
        "format": "binary",
        "url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-instagram.srs"
      },
      {
        "tag": "twitter",
        "type": "remote",
        "format": "binary",
        "url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-twitter.srs"
      }
    ]
  },
  "experimental": {
    "cache_file": {
      "enabled": true
    }
  }
}

User:

{
  "log": {
    "level": "trace"
  },
  "dns": {
    "servers": [
      {
        "tag": "dns-remote",
        "address": "https://cloudflare-dns.com/dns-query",
        "address_resolver": "dns-local"
      },
      {
        "tag": "dns-local",
        "address": "local",
        "detour": "direct"
      }
    ],
    "rules": [
      {
        "domain": "cloudflare-dns.com",
        "server": "dns-direct"
      },
      {
        "domain_suffix": [
          "bing.com",
          "canva.com"
        ],
        "rule_set": [
          "instagram",
          "twitter"
        ],
        "server": "dns-remote"
      }
    ],
    "final": "dns-local",
    "strategy": "prefer_ipv6",
    "independent_cache": true
  },
  "inbounds": [
    {
      "type": "mixed",
      "tag": "mixed-in",
      "listen": "127.0.0.1",
      "listen_port": 2080,
      "sniff": true,
      "domain_strategy": "prefer_ipv6"
    }
  ],
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct"
    },
    {
      "type": "block",
      "tag": "block"
    },
    {
      "type": "dns",
      "tag": "dns-out"
    },
    {
      "type": "shadowtls",
      "tag": "ss-tls-out",
      "server": "SERVER_IPv4",
      "server_port": 443,
      "version": 3,
      "password": "PASSWORD",
      "tls": {
        "enabled": true,
        "server_name": "pinterest.com",
        "utls": {
          "enabled": true,
          "fingerprint": "randomized"
        }
      }
    },
    {
      "type": "shadowsocks",
      "tag": "shadowsocks",
      "detour": "ss-tls-out",
      "method": "2022-blake3-aes-128-gcm",
      "password": "PASSWORD",
      "network": "tcp"
    }
  ],
  "route": {
    "rules": [
      {
        "protocol": "dns",
        "outbound": "dns-out"
      },
      {
        "protocol": "quic",
        "domain_suffix": [
          "bing.com",
          "canva.com"
        ],
        "rule_set": [
          "instagram",
          "twitter"
        ],
        "outbound": "block"
      },
      {
        "domain_suffix": [
          "bing.com",
          "canva.com"
        ],
        "rule_set": [
          "instagram",
          "twitter"
        ],
        "outbound": "shadowsocks"
      }
    ],
    "rule_set": [
      {
        "type": "remote",
        "tag": "instagram",
        "format": "binary",
        "url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-instagram.srs"
      },
      {
        "type": "remote",
        "tag": "twitter",
        "format": "binary",
        "url": "https://github.com/SagerNet/sing-geosite/raw/rule-set/geosite-twitter.srs"
      }
    ]
  },
  "experimental": {
    "cache_file": {
      "enabled": true
    }
  }
}

Logs

Server:

INFO router: updated default interface ens3, index 2
INFO inbound/shadowtls[ss-tls-in]: tcp server started at SERVER_IPv4:443
INFO inbound/shadowsocks[ss-in]: tcp server started at 127.0.0.1:33421
INFO sing-box started (0.11s)
INFO [930242761 0ms] inbound/shadowtls[ss-tls-in]: inbound connection from USER_IPv4:26907
DEBUG [1545744731 6ms] dns: lookup domain pinterest.com
INFO outbound/direct[0]: outbound connection to 1.1.1.1:853
DEBUG [1545744731 23ms] dns: exchanged pinterest.com NOERROR 429
DEBUG [1545744731 23ms] dns: exchanged pinterest.com A pinterest.com. 429 IN A 151.101.0.84
DEBUG [1545744731 23ms] dns: exchanged pinterest.com A pinterest.com. 429 IN A 151.101.192.84
DEBUG [1545744731 24ms] dns: exchanged pinterest.com A pinterest.com. 429 IN A 151.101.64.84
DEBUG [1545744731 24ms] dns: exchanged pinterest.com A pinterest.com. 429 IN A 151.101.128.84
DEBUG [1545744731 24ms] dns: lookup succeed for pinterest.com: 151.101.0.84 151.101.192.84 151.101.64.84 151.101.128.84
TRACE [1545744731 25ms] inbound/shadowtls[ss-tls-in]: client hello verify success
TRACE [1545744731 115ms] inbound/shadowtls[ss-tls-in]: handshake relay finished
INFO [1545744731 115ms] inbound/shadowtls[ss-tls-in]: [user] inbound connection to SERVER_IPv4:443
INFO [473222794 0ms] inbound/shadowsocks[ss-in]: inbound connection to [::1]:443
DEBUG [473222794 0ms] router: match[3] auth_user=user => block
INFO [473222794 0ms] outbound/block[block]: blocked connection to [::1]:443

User:

INFO[0000] router: updated default interface rmnet_data4, index 21
INFO[0000] inbound/mixed[mixed-in]: tcp server started at 127.0.0.1:2080
INFO[0000] sing-box started (0.66s)
INFO[0003] [2927019820 0ms] inbound/mixed[mixed-in]: inbound connection from 127.0.0.1:37518
INFO[0003] [2927049820 4ms] inbound/mixed[mixed-in]: inbound connection to [::1]:443
DEBUG [0003] [2927049820-14ms] router: sniffed protocol: tls, domain: instagram.com
DEBUG [0003] [2927049820 15ms] router: match[2] domain_suffix=[bing.com canva.com] rule_set=[instagram twitter] => shadowsocks
INFO[0003] [2927049820 15ms] outbound/ shadowsocks[shadowsocks]: outbound connection to [::1]:443
TRACE[0048] [3308796261 203ms] outbound/shadowtls[ss-tis-out]: handshake success


### Supporter

- [ ] I am a [sponsor](https://github.com/sponsors/nekohasekai/)

### Integrity requirements

- [X] I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
- [X] I confirm that I have provided the server and client configuration files and process that can be reproduced locally, instead of a complicated client configuration file that has been stripped of sensitive data.
- [X] I confirm that I have provided the simplest configuration that can be used to reproduce the error I reported, instead of depending on remote servers, TUN, graphical interface clients, or other closed-source software.
- [X] I confirm that I have provided the complete configuration files and logs, rather than just providing parts I think are useful out of confidence in my own intelligence.
dyhkwong commented 2 months ago

https://github.com/SagerNet/sing-box/issues/694#issuecomment-1624780771 Rule ip_version only applies to IP requests.

FPPweb3 commented 2 months ago

#694 (comment) Rule ip_version only applies to IP requests.

However, if it were indeed the case, there would be a DEBUG entry in the server logs reflecting successful sniffing, and this configuration rule would have triggered:

      {
        "auth_user": "user",
        "outbound": "user-out",
        "rule_set": [
          "instagram",
          "twitter"
        ],
        "domain_suffix": [
          "bing.com",
          "canva.com"
        ]
      }
dyhkwong commented 2 months ago

You should sniff at shadow-tls inbound not shadowsocks inbound.