Compare commits

..

38 Commits

Author SHA1 Message Date
世界
a6b1f1b2b1 documentation: Bump version 2024-05-20 22:22:19 +08:00
世界
5fa834db7d documentation: Add manuel for mitigating tunnelvision attacks 2024-05-20 22:20:55 +08:00
世界
d4c2d5bfce documentation: Update DNS manual 2024-05-20 22:20:55 +08:00
世界
b19513bda7 dialer: Allow nil router 2024-05-20 22:20:54 +08:00
世界
777ee2f57a Add rule-set match command 2024-05-20 22:20:54 +08:00
世界
0b1eb52987 Add bypass_domain and search_domain platform HTTP proxy options 2024-05-20 22:20:54 +08:00
世界
fd75d66b73 Handle includeAllNetworks 2024-05-20 22:20:54 +08:00
世界
028da31021 Update gVisor to 20240422.0 2024-05-20 22:20:51 +08:00
世界
d2e2345bd5 Update quic-go to v0.43.1 2024-05-18 17:24:46 +08:00
世界
dcf68feec8 Fixed order for Clash modes 2024-05-18 17:23:55 +08:00
世界
3f6f879780 Add custom prefix support in EDNS0 client subnet options 2024-05-18 17:23:55 +08:00
气息
1fa7de078b Fix DNS exchange index
Signed-off-by: 气息 <qdshizh@gmail.com>
2024-05-18 17:23:55 +08:00
dyhkwong
3efaf834db Always disable cache for fake-ip servers 2024-05-18 17:23:55 +08:00
PuerNya
041a4992cf Always disable cache for fake-ip DNS transport if independent_cache disabled 2024-05-18 17:23:55 +08:00
世界
926e436347 Fix missing rule_set_ipcidr_match_source item in DNS rules 2024-05-18 17:23:55 +08:00
世界
8fc13e41d0 Improve DNS truncate behavior 2024-05-18 17:23:55 +08:00
世界
38eaf15360 Fix DNS fallthrough incorrectly 2024-05-18 17:23:54 +08:00
世界
f287856162 Add rejected DNS response cache support 2024-05-18 17:23:54 +08:00
世界
7763c7847e Add support for client-subnet DNS options 2024-05-18 17:23:54 +08:00
世界
53c3445291 Add address filter support for DNS rules 2024-05-18 17:23:54 +08:00
世界
6ebec97500 Fix timezone for Android and iOS 2024-05-18 17:23:15 +08:00
世界
fd38020bf4 Improve loopback detector 2024-05-18 17:23:15 +08:00
世界
e596213646 Remove unused fakeip packet conn 2024-05-18 17:23:15 +08:00
世界
fd36b07feb Set the default TCP keep alive period 2024-05-18 17:23:15 +08:00
世界
5ce43842d0 Migrate ntp service to library 2024-05-18 17:23:15 +08:00
世界
a8e480a35a Handle Windows power events 2024-05-18 17:23:15 +08:00
世界
8eee98f74e Improve domain suffix match behavior
For historical reasons, sing-box's `domain_suffix` rule matches literal prefixes instead of the same as other projects.

This change modifies the behavior of `domain_suffix`: If the rule value is prefixed with `.`,
the behavior is unchanged, otherwise it matches `(domain|.+\.domain)` instead.
2024-05-18 17:22:54 +08:00
世界
cbcf005f37 Remove PROCESS_NAME_NATIVE dwFlag in process query output
The `process_path` rule of sing-box is inherited from Clash,
the original code uses the local system's path format (e.g. `\Device\HarddiskVolume1\folder\program.exe`),
but when the device has multiple disks, the HarddiskVolume serial number is not stable.

This change make QueryFullProcessImageNameW output a Win32 path (such as `C:\folder\program.exe`),
which will disrupt the existing `process_path` use cases in Windows.
2024-05-18 17:22:14 +08:00
世界
daee0b154e badtls: Support uTLS and TLS ECH for read waiter 2024-05-18 17:22:14 +08:00
世界
d530c724c0 Bump version 2024-05-18 16:53:05 +08:00
世界
7f698c1104 Fix hysteria2 panic 2024-05-18 16:20:32 +08:00
renovate[bot]
7a4a44c6d2 [dependencies] Update golangci/golangci-lint-action action to v6 2024-05-10 19:49:20 +08:00
世界
44277e5dd2 Fix urltest logic 2024-05-10 17:41:20 +08:00
世界
1f470c69c4 Update docker workflow 2024-05-03 19:33:20 +08:00
世界
742adacce7 Bump version 2024-05-03 17:38:26 +08:00
世界
32e1d5a5e2 documentation: Update package status 2024-05-03 17:38:26 +08:00
世界
cb9f4ce597 Minor fixes 2024-05-03 15:34:47 +08:00
世界
4b1a6185ba Fix DNF repo 2024-04-29 23:13:04 +08:00
37 changed files with 338 additions and 358 deletions

View File

@@ -4,13 +4,35 @@ on:
release:
types:
- released
workflow_dispatch:
inputs:
tag:
description: "The tag version you want to build"
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get commit to build
id: ref
run: |-
if [[ -z "${{ github.event.inputs.tag }}" ]]; then
ref="${{ github.ref_name }}"
else
ref="${{ github.event.inputs.tag }}"
fi
echo "ref=$ref"
echo "ref=$ref" >> $GITHUB_OUTPUT
if [[ $ref == *"-"* ]]; then
latest=latest-beta
else
latest=latest
fi
echo "latest=$latest"
echo "latest=$latest" >> $GITHUB_OUTPUT
- name: Checkout
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4
with:
ref: ${{ steps.ref.outputs.ref }}
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Setup QEMU for Docker Buildx
@@ -30,10 +52,11 @@ jobs:
uses: docker/build-push-action@v5
with:
platforms: linux/386,linux/amd64,linux/arm64,linux/s390x
context: .
target: dist
build-args: |
BUILDKIT_CONTEXT_KEEP_GIT_DIR=1
tags: |
ghcr.io/sagernet/sing-box:latest
ghcr.io/sagernet/sing-box:${{ github.ref_name }}
ghcr.io/sagernet/sing-box:${{ steps.ref.outputs.latest }}
ghcr.io/sagernet/sing-box:${{ steps.ref.outputs.ref }}
push: true

View File

@@ -30,7 +30,7 @@ jobs:
with:
go-version: ^1.22
- name: golangci-lint
uses: golangci/golangci-lint-action@v5
uses: golangci/golangci-lint-action@v6
with:
version: latest
args: --timeout=30m

View File

@@ -86,7 +86,7 @@ type DNSRule interface {
Rule
DisableCache() bool
RewriteTTL() *uint32
ClientSubnet() *netip.Addr
ClientSubnet() *netip.Prefix
WithAddressLimit() bool
MatchAddressLimit(metadata *InboundContext) bool
}

View File

@@ -2,6 +2,42 @@
icon: material/alert-decagram
---
#### 1.9.0-rc.20
* Prioritize `*_route_address` in linux auto-route
* Fix `*_route_address` in darwin auto-route
#### 1.8.14
* Fix hysteria2 panic
* Fixes and improvements
#### 1.9.0-rc.18
* Add custom prefix support in EDNS0 client subnet options
* Fix hysteria2 crash
* Fix `store_rdrc` corrupted
* Update quic-go to v0.43.1
* Fixes and improvements
#### 1.9.0-rc.16
* Mitigating TunnelVision attacks **1**
* Fixes and improvements
**1**:
See [TunnelVision](/manual/misc/tunnelvision).
#### 1.9.0-rc.15
* Fixes and improvements
#### 1.8.13
* Fix fake-ip mapping
* Fixes and improvements
#### 1.9.0-rc.14
* Fixes and improvements

View File

@@ -73,6 +73,8 @@ problematic in environments such as macOS, where DNS is proxied and cached by th
!!! question "Since sing-box 1.9.0"
Append a `edns0-subnet` OPT extra record with the specified IP address to every query by default.
Append a `edns0-subnet` OPT extra record with the specified IP prefix to every query by default.
If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
Can be overrides by `servers.[].client_subnet` or `rules.[].client_subnet`.

View File

@@ -71,8 +71,10 @@ icon: material/new-box
!!! question "自 sing-box 1.9.0 起"
默认情况下,将带有指定 IP 地址`edns0-subnet` OPT 附加记录附加到每个查询。
默认情况下,将带有指定 IP 前缀`edns0-subnet` OPT 附加记录附加到每个查询。
如果值是 IP 地址而不是前缀,则会自动附加 `/32``/128`
可以被 `servers.[].client_subnet``rules.[].client_subnet` 覆盖。
#### fakeip

View File

@@ -125,7 +125,7 @@ icon: material/new-box
"server": "local",
"disable_cache": false,
"rewrite_ttl": 100,
"client_subnet": "127.0.0.1"
"client_subnet": "127.0.0.1/24"
},
{
"type": "logical",
@@ -134,7 +134,7 @@ icon: material/new-box
"server": "local",
"disable_cache": false,
"rewrite_ttl": 100,
"client_subnet": "127.0.0.1"
"client_subnet": "127.0.0.1/24"
}
]
}
@@ -339,7 +339,9 @@ Rewrite TTL in DNS responses.
!!! question "Since sing-box 1.9.0"
Append a `edns0-subnet` OPT extra record with the specified IP address to every query by default.
Append a `edns0-subnet` OPT extra record with the specified IP prefix to every query by default.
If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
Will overrides `dns.client_subnet` and `servers.[].client_subnet`.

View File

@@ -124,7 +124,7 @@ icon: material/new-box
],
"server": "local",
"disable_cache": false,
"client_subnet": "127.0.0.1"
"client_subnet": "127.0.0.1/24"
},
{
"type": "logical",
@@ -132,7 +132,7 @@ icon: material/new-box
"rules": [],
"server": "local",
"disable_cache": false,
"client_subnet": "127.0.0.1"
"client_subnet": "127.0.0.1/24"
}
]
}
@@ -337,7 +337,9 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
!!! question "自 sing-box 1.9.0 起"
默认情况下,将带有指定 IP 地址`edns0-subnet` OPT 附加记录附加到每个查询。
默认情况下,将带有指定 IP 前缀`edns0-subnet` OPT 附加记录附加到每个查询。
如果值是 IP 地址而不是前缀,则会自动附加 `/32``/128`
将覆盖 `dns.client_subnet``servers.[].client_subnet`

View File

@@ -100,7 +100,9 @@ Default outbound will be used if empty.
!!! question "Since sing-box 1.9.0"
Append a `edns0-subnet` OPT extra record with the specified IP address to every query by default.
Append a `edns0-subnet` OPT extra record with the specified IP prefix to every query by default.
If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
Can be overrides by `rules.[].client_subnet`.

View File

@@ -100,7 +100,9 @@ DNS 服务器的地址。
!!! question "自 sing-box 1.9.0 起"
默认情况下,将带有指定 IP 地址`edns0-subnet` OPT 附加记录附加到每个查询。
默认情况下,将带有指定 IP 前缀`edns0-subnet` OPT 附加记录附加到每个查询。
如果值是 IP 地址而不是前缀,则会自动附加 `/32``/128`
可以被 `rules.[].client_subnet` 覆盖。

View File

@@ -57,16 +57,16 @@ go build -tags "tag_a tag_b" ./cmd/sing-box
| Build Tag | Enabled by default | Description |
|------------------------------------|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `with_quic` | :material-check: | Build with QUIC support, see [QUIC and HTTP3 DNS transports](/configuration/dns/server/), [Naive inbound](/configuration/inbound/naive/), [Hysteria Inbound](/configuration/inbound/hysteria/), [Hysteria Outbound](/configuration/outbound/hysteria/) and [V2Ray Transport#QUIC](/configuration/shared/v2ray-transport#quic). |
| `with_grpc` | :material-close: | Build with standard gRPC support, see [V2Ray Transport#gRPC](/configuration/shared/v2ray-transport#grpc). |
| `with_grpc` | :material-close: | Build with standard gRPC support, see [V2Ray Transport#gRPC](/configuration/shared/v2ray-transport#grpc). |
| `with_dhcp` | :material-check: | Build with DHCP support, see [DHCP DNS transport](/configuration/dns/server/). |
| `with_wireguard` | :material-check: | Build with WireGuard support, see [WireGuard outbound](/configuration/outbound/wireguard/). |
| `with_ech` | :material-check: | Build with TLS ECH extension support for TLS outbound, see [TLS](/configuration/shared/tls#ech). |
| `with_utls` | :material-check: | Build with [uTLS](https://github.com/refraction-networking/utls) support for TLS outbound, see [TLS](/configuration/shared/tls#utls). |
| `with_ech` | :material-check: | Build with TLS ECH extension support for TLS outbound, see [TLS](/configuration/shared/tls#ech). |
| `with_utls` | :material-check: | Build with [uTLS](https://github.com/refraction-networking/utls) support for TLS outbound, see [TLS](/configuration/shared/tls#utls). |
| `with_reality_server` | :material-check: | Build with reality TLS server support, see [TLS](/configuration/shared/tls/). |
| `with_acme` | :material-check: | Build with ACME TLS certificate issuer support, see [TLS](/configuration/shared/tls/). |
| `with_clash_api` | :material-check: | Build with Clash API support, see [Experimental](/configuration/experimental#clash-api-fields). |
| `with_v2ray_api` | :material-close: | Build with V2Ray API support, see [Experimental](/configuration/experimental#v2ray-api-fields). |
| `with_gvisor` | :material-check: | Build with gVisor support, see [Tun inbound](/configuration/inbound/tun#stack) and [WireGuard outbound](/configuration/outbound/wireguard#system_interface). |
| `with_clash_api` | :material-check: | Build with Clash API support, see [Experimental](/configuration/experimental#clash-api-fields). |
| `with_v2ray_api` | :material-close: | Build with V2Ray API support, see [Experimental](/configuration/experimental#v2ray-api-fields). |
| `with_gvisor` | :material-check: | Build with gVisor support, see [Tun inbound](/configuration/inbound/tun#stack) and [WireGuard outbound](/configuration/outbound/wireguard#system_interface). |
| `with_embedded_tor` (CGO required) | :material-close: | Build with embedded Tor support, see [Tor outbound](/configuration/outbound/tor/). |
It is not recommended to change the default build tag list unless you really know what you are adding.

View File

@@ -54,19 +54,19 @@ go build -tags "tag_a tag_b" ./cmd/sing-box
## :material-folder-settings: 构建标记
| 构建标记 | 默认启动 | 说明 |
|------------------------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 构建标记 | 默认启动 | 说明 |
|------------------------------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `with_quic` | :material-check: | Build with QUIC support, see [QUIC and HTTP3 DNS transports](/configuration/dns/server/), [Naive inbound](/configuration/inbound/naive/), [Hysteria Inbound](/configuration/inbound/hysteria/), [Hysteria Outbound](/configuration/outbound/hysteria/) and [V2Ray Transport#QUIC](/configuration/shared/v2ray-transport#quic). |
| `with_grpc` | :material-close: | Build with standard gRPC support, see [V2Ray Transport#gRPC](/configuration/shared/v2ray-transport#grpc). |
| `with_dhcp` | :material-check: | Build with DHCP support, see [DHCP DNS transport](/configuration/dns/server/). |
| `with_wireguard` | :material-check: | Build with WireGuard support, see [WireGuard outbound](/configuration/outbound/wireguard/). |
| `with_ech` | :material-check: | Build with TLS ECH extension support for TLS outbound, see [TLS](/configuration/shared/tls#ech). |
| `with_utls` | :material-check: | Build with [uTLS](https://github.com/refraction-networking/utls) support for TLS outbound, see [TLS](/configuration/shared/tls#utls). |
| `with_reality_server` | :material-check: | Build with reality TLS server support, see [TLS](/configuration/shared/tls/). |
| `with_acme` | :material-check: | Build with ACME TLS certificate issuer support, see [TLS](/configuration/shared/tls/). |
| `with_clash_api` | :material-check: | Build with Clash API support, see [Experimental](/configuration/experimental#clash-api-fields). |
| `with_v2ray_api` | :material-close: | Build with V2Ray API support, see [Experimental](/configuration/experimental#v2ray-api-fields). |
| `with_gvisor` | :material-check: | Build with gVisor support, see [Tun inbound](/configuration/inbound/tun#stack) and [WireGuard outbound](/configuration/outbound/wireguard#system_interface). |
| `with_embedded_tor` (CGO required) | :material-close: | Build with embedded Tor support, see [Tor outbound](/configuration/outbound/tor/). |
| `with_grpc` | :material-close: | Build with standard gRPC support, see [V2Ray Transport#gRPC](/configuration/shared/v2ray-transport#grpc). |
| `with_dhcp` | :material-check: | Build with DHCP support, see [DHCP DNS transport](/configuration/dns/server/). |
| `with_wireguard` | :material-check: | Build with WireGuard support, see [WireGuard outbound](/configuration/outbound/wireguard/). |
| `with_ech` | :material-check: | Build with TLS ECH extension support for TLS outbound, see [TLS](/configuration/shared/tls#ech). |
| `with_utls` | :material-check: | Build with [uTLS](https://github.com/refraction-networking/utls) support for TLS outbound, see [TLS](/configuration/shared/tls#utls). |
| `with_reality_server` | :material-check: | Build with reality TLS server support, see [TLS](/configuration/shared/tls/). |
| `with_acme` | :material-check: | Build with ACME TLS certificate issuer support, see [TLS](/configuration/shared/tls/). |
| `with_clash_api` | :material-check: | Build with Clash API support, see [Experimental](/configuration/experimental#clash-api-fields). |
| `with_v2ray_api` | :material-close: | Build with V2Ray API support, see [Experimental](/configuration/experimental#v2ray-api-fields). |
| `with_gvisor` | :material-check: | Build with gVisor support, see [Tun inbound](/configuration/inbound/tun#stack) and [WireGuard outbound](/configuration/outbound/wireguard#system_interface). |
| `with_embedded_tor` (CGO required) | :material-close: | Build with embedded Tor support, see [Tor outbound](/configuration/outbound/tor/). |
除非您确实知道您正在启用什么,否则不建议更改默认构建标签列表。

View File

@@ -57,38 +57,38 @@ icon: material/package
=== ":material-linux: Linux"
| Type | Platform | Link | Command | Actively maintained |
|----------|---------------|-------------------------|------------------------------|---------------------|
| APK | Alpine | [sing-box][alpine] | `apk add sing-box` | :material-check: |
| AUR | Arch Linux | [sing-box][aur] ᴬᵁᴿ | `? -S sing-box` | :material-check: |
| nixpkgs | NixOS | [sing-box][nixpkgs] | `nix-env -iA nixos.sing-box` | :material-check: |
| Homebrew | macOS / Linux | [sing-box][brew] | `brew install sing-box` | :material-check: |
| Type | Platform | Command | Link |
|----------|---------------|------------------------------|---------------------------------------------------------------------------------------------------------------|
| AUR | Arch Linux | `? -S sing-box` | [![AUR package](https://repology.org/badge/version-for-repo/aur/sing-box.svg)][aur] |
| nixpkgs | NixOS | `nix-env -iA nixos.sing-box` | [![nixpkgs unstable package](https://repology.org/badge/version-for-repo/nix_unstable/sing-box.svg)][nixpkgs] |
| Homebrew | macOS / Linux | `brew install sing-box` | [![Homebrew package](https://repology.org/badge/version-for-repo/homebrew/sing-box.svg)][brew] |
| APK | Alpine | `apk add sing-box` | [![Alpine Linux Edge package](https://repology.org/badge/version-for-repo/alpine_edge/sing-box.svg)][alpine] |
=== ":material-apple: macOS"
| Type | Platform | Link | Command | Actively maintained |
|----------|----------|------------------|-------------------------|---------------------|
| Homebrew | macOS | [sing-box][brew] | `brew install sing-box` | :material-check: |
| Type | Platform | Command | Link |
|----------|----------|-------------------------|------------------------------------------------------------------------------------------------|
| Homebrew | macOS | `brew install sing-box` | [![Homebrew package](https://repology.org/badge/version-for-repo/homebrew/sing-box.svg)][brew] |
=== ":material-microsoft-windows: Windows"
| Type | Platform | Link | Command | Actively maintained |
|------------|--------------------|---------------------|------------------------------|---------------------|
| Scoop | Windows | [sing-box][scoop] | `scoop install sing-box` | :material-check: |
| Chocolatey | Windows | [sing-box][choco] | `choco install sing-box` | :material-check: |
| winget | Windows | [sing-box][winget] | `winget install sing-box` | :material-alert: |
| Type | Platform | Command | Link |
|------------|----------|---------------------------|-----------------------------------------------------------------------------------------------------|
| Scoop | Windows | `scoop install sing-box` | [![Scoop package](https://repology.org/badge/version-for-repo/scoop/sing-box.svg)][scoop] |
| Chocolatey | Windows | `choco install sing-box` | [![Chocolatey package](https://repology.org/badge/version-for-repo/chocolatey/sing-box.svg)][choco] |
| winget | Windows | `winget install sing-box` | [![winget package](https://repology.org/badge/version-for-repo/winget/sing-box.svg)][winget] |
=== ":material-android: Android"
| Type | Platform | Link | Command | Actively maintained |
|------------|--------------------|---------------------|------------------------------|---------------------|
| Termux | Android | [sing-box][termux] | `pkg add sing-box` | :material-check: |
| Type | Platform | Command | Link |
|--------|----------|--------------------|----------------------------------------------------------------------------------------------|
| Termux | Android | `pkg add sing-box` | [![Termux package](https://repology.org/badge/version-for-repo/termux/sing-box.svg)][termux] |
=== ":material-freebsd: FreeBSD"
| Type | Platform | Link | Command | Actively maintained |
|------------|----------|-------------------|------------------------|---------------------|
| FreshPorts | FreeBSD | [sing-box][ports] | `pkg install sing-box` | :material-alert: |
| Type | Platform | Command | Link |
|------------|----------|------------------------|--------------------------------------------------------------------------------------------|
| FreshPorts | FreeBSD | `pkg install sing-box` | [![FreeBSD port](https://repology.org/badge/version-for-repo/freebsd/sing-box.svg)][ports] |
## :material-book-multiple: Service Management

View File

@@ -57,38 +57,38 @@ icon: material/package
=== ":material-linux: Linux"
| 类型 | 平台 | 链接 | 命令 | 活跃维护 |
|----------|------------|---------------------|------------------------------|------------------|
| Alpine | Alpine | [sing-box][alpine] | `apk add sing-box` | :material-check: |
| AUR | Arch Linux | [sing-box][aur] ᴬᵁᴿ | `? -S sing-box` | :material-check: |
| nixpkgs | NixOS | [sing-box][nixpkgs] | `nix-env -iA nixos.sing-box` | :material-check: |
| Homebrew | Linux | [sing-box][brew] | `brew install sing-box` | :material-check: |
| 类型 | 平台 | 链接 | 命令 |
|----------|---------------|------------------------------|---------------------------------------------------------------------------------------------------------------|
| AUR | Arch Linux | `? -S sing-box` | [![AUR package](https://repology.org/badge/version-for-repo/aur/sing-box.svg)][aur] |
| nixpkgs | NixOS | `nix-env -iA nixos.sing-box` | [![nixpkgs unstable package](https://repology.org/badge/version-for-repo/nix_unstable/sing-box.svg)][nixpkgs] |
| Homebrew | macOS / Linux | `brew install sing-box` | [![Homebrew package](https://repology.org/badge/version-for-repo/homebrew/sing-box.svg)][brew] |
| APK | Alpine | `apk add sing-box` | [![Alpine Linux Edge package](https://repology.org/badge/version-for-repo/alpine_edge/sing-box.svg)][alpine] |
=== ":material-apple: macOS"
| 类型 | 平台 | 链接 | 命令 | 活跃维护 |
|----------|-------|------------------|-------------------------|------------------|
| Homebrew | macOS | [sing-box][brew] | `brew install sing-box` | :material-check: |
| 类型 | 平台 | 链接 | 命令 |
|----------|-------|-------------------------|------------------------------------------------------------------------------------------------|
| Homebrew | macOS | `brew install sing-box` | [![Homebrew package](https://repology.org/badge/version-for-repo/homebrew/sing-box.svg)][brew] |
=== ":material-microsoft-windows: Windows"
| 类型 | 平台 | 链接 | 命令 | 活跃维护 |
|------------|---------|--------------------|---------------------------|------------------|
| Scoop | Windows | [sing-box][scoop] | `scoop install sing-box` | :material-check: |
| Chocolatey | Windows | [sing-box][choco] | `choco install sing-box` | :material-check: |
| winget | Windows | [sing-box][winget] | `winget install sing-box` | :material-alert: |
| 类型 | 平台 | 链接 | 命令 |
|------------|---------|---------------------------|-----------------------------------------------------------------------------------------------------|
| Scoop | Windows | `scoop install sing-box` | [![Scoop package](https://repology.org/badge/version-for-repo/scoop/sing-box.svg)][scoop] |
| Chocolatey | Windows | `choco install sing-box` | [![Chocolatey package](https://repology.org/badge/version-for-repo/chocolatey/sing-box.svg)][choco] |
| winget | Windows | `winget install sing-box` | [![winget package](https://repology.org/badge/version-for-repo/winget/sing-box.svg)][winget] |
=== ":material-android: Android"
| 类型 | 平台 | 链接 | 命令 | 活跃维护 |
|--------|---------|--------------------|--------------------|------------------|
| Termux | Android | [sing-box][termux] | `pkg add sing-box` | :material-check: |
| 类型 | 平台 | 链接 | 命令 |
|--------|---------|--------------------|----------------------------------------------------------------------------------------------|
| Termux | Android | `pkg add sing-box` | [![Termux package](https://repology.org/badge/version-for-repo/termux/sing-box.svg)][termux] |
=== ":material-freebsd: FreeBSD"
| 类型 | 平台 | 链接 | 命令 | 活跃维护 |
|------------|---------|-------------------|------------------------|------------------|
| FreshPorts | FreeBSD | [sing-box][ports] | `pkg install sing-box` | :material-alert: |
| 类型 | 平台 | 链接 | 命令 |
|------------|---------|------------------------|--------------------------------------------------------------------------------------------|
| FreshPorts | FreeBSD | `pkg install sing-box` | [![FreeBSD port](https://repology.org/badge/version-for-repo/freebsd/sing-box.svg)][ports] |
## :material-book-multiple: 服务管理

View File

@@ -1,7 +1,6 @@
[sing-box]
name=sing-box
baseurl=https://rpm.sagernet.org/
metalink=https://sing-box.app/sing-box.repo
enabled=1
repo_gpgcheck=1
gpgcheck=1

View File

@@ -0,0 +1,38 @@
---
icon: material/book-lock-open
---
# TunnelVision
TunnelVision is an attack that uses DHCP option 121 to set higher priority routes
so that traffic does not go through the VPN.
Reference: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-3661
## Status
### Android
Android does not handle DHCP option 121 and is not affected.
### Apple platforms
Update [sing-box graphical client](/clients/apple/#download) to `1.9.0-rc.16` or newer,
then enable `includeAllNetworks` in `Settings``Packet Tunnel` and you will be unaffected.
Note: when `includeAllNetworks` is enabled, the default TUN stack is changed to `gvisor`,
and the `system` and `mixed` stacks are not available.
### Linux
Update sing-box to `1.9.0-rc.16` or newer, rules generated by `auto-route` are unaffected.
### Windows
No solution yet.
## Workarounds
* Don't connect to untrusted networks
* Relay untrusted network through another device
* Just ignore it

View File

@@ -1,208 +0,0 @@
---
icon: material/alpha-t-box
---
# TUIC
A recently popular Chinese-made simple protocol based on QUIC, the selling point is the BBR congestion control algorithm.
!!! warning
Even though GFW rarely blocks UDP-based proxies, such protocols actually have far more characteristics than TCP based proxies.
| Specification | Binary Characteristics | Active Detect Hiddenness |
|-----------------------------------------------------------|------------------------|--------------------------|
| [GitHub](https://github.com/EAimTY/tuic/blob/dev/SPEC.md) | :material-alert: | :material-check: |
## Password Generator
| Generated UUID | Generated Password | Action |
|------------------------|----------------------------|-----------------------------------------------------------------|
| <code id="uuid"><code> | <code id="password"><code> | <button class="md-button" onclick="generate()">Refresh</button> |
<script>
function generateUUID() {
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
let r = Math.random() * 16 | 0,
v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
document.getElementById("uuid").textContent = uuid;
}
function generatePassword() {
const array = new Uint8Array(16);
window.crypto.getRandomValues(array);
document.getElementById("password").textContent = btoa(String.fromCharCode.apply(null, array));
}
function generate() {
generateUUID();
generatePassword();
}
generate();
</script>
## :material-server: Server Example
=== ":material-harddisk: With local certificate"
```json
{
"inbounds": [
{
"type": "tuic",
"listen": "::",
"listen_port": 8080,
"users": [
{
"name": "sekai",
"uuid": "<uuid>",
"password": "<password>"
}
],
"congestion_control": "bbr",
"tls": {
"enabled": true,
"server_name": "example.org",
"key_path": "/path/to/key.pem",
"certificate_path": "/path/to/certificate.pem"
}
}
]
}
```
=== ":material-auto-fix: With ACME"
```json
{
"inbounds": [
{
"type": "tuic",
"listen": "::",
"listen_port": 8080,
"users": [
{
"name": "sekai",
"uuid": "<uuid>",
"password": "<password>"
}
],
"congestion_control": "bbr",
"tls": {
"enabled": true,
"server_name": "example.org",
"acme": {
"domain": "example.org",
"email": "admin@example.org"
}
}
}
]
}
```
=== ":material-cloud: With ACME and Cloudflare API"
```json
{
"inbounds": [
{
"type": "tuic",
"listen": "::",
"listen_port": 8080,
"users": [
{
"name": "sekai",
"uuid": "<uuid>",
"password": "<password>"
}
],
"congestion_control": "bbr",
"tls": {
"enabled": true,
"server_name": "example.org",
"acme": {
"domain": "example.org",
"email": "admin@example.org",
"dns01_challenge": {
"provider": "cloudflare",
"api_token": "my_token"
}
}
}
}
]
}
```
## :material-cellphone-link: Client Example
=== ":material-web-check: With valid certificate"
```json
{
"outbounds": [
{
"type": "tuic",
"server": "127.0.0.1",
"server_port": 8080,
"uuid": "<uuid>",
"password": "<password>",
"congestion_control": "bbr",
"tls": {
"enabled": true,
"server_name": "example.org"
}
}
]
}
```
=== ":material-check: With self-sign certificate"
!!! info "Tip"
Use `sing-box merge` command to merge configuration and certificate into one file.
```json
{
"outbounds": [
{
"type": "tuic",
"server": "127.0.0.1",
"server_port": 8080,
"uuid": "<uuid>",
"password": "<password>",
"congestion_control": "bbr",
"tls": {
"enabled": true,
"server_name": "example.org",
"certificate_path": "/path/to/certificate.pem"
}
}
]
}
```
=== ":material-alert: Ignore certificate verification"
```json
{
"outbounds": [
{
"type": "tuic",
"server": "127.0.0.1",
"server_port": 8080,
"uuid": "<uuid>",
"password": "<password>",
"congestion_control": "bbr",
"tls": {
"enabled": true,
"server_name": "example.org",
"insecure": true
}
}
]
}
```

View File

@@ -471,7 +471,7 @@ flowchart TB
}
],
"server": "google",
"client_subnet": "114.114.114.114" // Any China client IP address
"client_subnet": "114.114.114.114/24" // Any China client IP address
}
]
},

View File

@@ -57,6 +57,7 @@ type CacheFile struct {
type saveRDRCCacheKey struct {
TransportName string
QuestionName string
QType uint16
}
func New(ctx context.Context, options option.CacheFileOptions) *CacheFile {

View File

@@ -9,7 +9,7 @@ import (
"github.com/sagernet/sing/common/logger"
)
var bucketRDRC = []byte("rdrc")
var bucketRDRC = []byte("rdrc2")
func (c *CacheFile) StoreRDRC() bool {
return c.storeRDRC
@@ -19,13 +19,17 @@ func (c *CacheFile) RDRCTimeout() time.Duration {
return c.rdrcTimeout
}
func (c *CacheFile) LoadRDRC(transportName string, qName string) (rejected bool) {
func (c *CacheFile) LoadRDRC(transportName string, qName string, qType uint16) (rejected bool) {
c.saveRDRCAccess.RLock()
rejected, cached := c.saveRDRC[saveRDRCCacheKey{transportName, qName}]
rejected, cached := c.saveRDRC[saveRDRCCacheKey{transportName, qName, qType}]
c.saveRDRCAccess.RUnlock()
if cached {
return
}
key := buf.Get(2 + len(qName))
binary.BigEndian.PutUint16(key, qType)
copy(key[2:], qName)
defer buf.Put(key)
var deleteCache bool
err := c.DB.View(func(tx *bbolt.Tx) error {
bucket := c.bucket(tx, bucketRDRC)
@@ -36,7 +40,7 @@ func (c *CacheFile) LoadRDRC(transportName string, qName string) (rejected bool)
if bucket == nil {
return nil
}
content := bucket.Get([]byte(qName))
content := bucket.Get(key)
if content == nil {
return nil
}
@@ -61,13 +65,13 @@ func (c *CacheFile) LoadRDRC(transportName string, qName string) (rejected bool)
if bucket == nil {
return nil
}
return bucket.Delete([]byte(qName))
return bucket.Delete(key)
})
}
return
}
func (c *CacheFile) SaveRDRC(transportName string, qName string) error {
func (c *CacheFile) SaveRDRC(transportName string, qName string, qType uint16) error {
return c.DB.Batch(func(tx *bbolt.Tx) error {
bucket, err := c.createBucket(tx, bucketRDRC)
if err != nil {
@@ -77,20 +81,24 @@ func (c *CacheFile) SaveRDRC(transportName string, qName string) error {
if err != nil {
return err
}
key := buf.Get(2 + len(qName))
binary.BigEndian.PutUint16(key, qType)
copy(key[2:], qName)
defer buf.Put(key)
expiresAt := buf.Get(8)
defer buf.Put(expiresAt)
binary.BigEndian.PutUint64(expiresAt, uint64(time.Now().Add(c.rdrcTimeout).Unix()))
return bucket.Put([]byte(qName), expiresAt)
return bucket.Put(key, expiresAt)
})
}
func (c *CacheFile) SaveRDRCAsync(transportName string, qName string, logger logger.Logger) {
saveKey := saveRDRCCacheKey{transportName, qName}
func (c *CacheFile) SaveRDRCAsync(transportName string, qName string, qType uint16, logger logger.Logger) {
saveKey := saveRDRCCacheKey{transportName, qName, qType}
c.saveRDRCAccess.Lock()
c.saveRDRC[saveKey] = true
c.saveRDRCAccess.Unlock()
go func() {
err := c.SaveRDRC(transportName, qName)
err := c.SaveRDRC(transportName, qName, qType)
if err != nil {
logger.Warn("save RDRC: ", err)
}

View File

@@ -82,6 +82,10 @@ func (s *platformInterfaceStub) UnderNetworkExtension() bool {
return false
}
func (s *platformInterfaceStub) IncludeAllNetworks() bool {
return false
}
func (s *platformInterfaceStub) ClearDNSCache() {
}

View File

@@ -19,6 +19,7 @@ type PlatformInterface interface {
UsePlatformInterfaceGetter() bool
GetInterfaces() (NetworkInterfaceIterator, error)
UnderNetworkExtension() bool
IncludeAllNetworks() bool
ReadWIFIState() *WIFIState
ClearDNSCache()
}

View File

@@ -21,6 +21,7 @@ type Interface interface {
UsePlatformInterfaceGetter() bool
Interfaces() ([]control.Interface, error)
UnderNetworkExtension() bool
IncludeAllNetworks() bool
ClearDNSCache()
ReadWIFIState() adapter.WIFIState
process.Searcher

View File

@@ -213,6 +213,10 @@ func (w *platformInterfaceWrapper) UnderNetworkExtension() bool {
return w.iif.UnderNetworkExtension()
}
func (w *platformInterfaceWrapper) IncludeAllNetworks() bool {
return w.iif.IncludeAllNetworks()
}
func (w *platformInterfaceWrapper) ClearDNSCache() {
w.iif.ClearDNSCache()
}

24
go.mod
View File

@@ -11,7 +11,7 @@ require (
github.com/go-chi/chi/v5 v5.0.12
github.com/go-chi/cors v1.2.1
github.com/go-chi/render v1.0.3
github.com/gofrs/uuid/v5 v5.1.0
github.com/gofrs/uuid/v5 v5.2.0
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2
github.com/libdns/alidns v1.0.3
github.com/libdns/cloudflare v0.1.1
@@ -24,16 +24,16 @@ require (
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1
github.com/sagernet/gomobile v0.1.3
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f
github.com/sagernet/quic-go v0.43.0-beta.2
github.com/sagernet/quic-go v0.43.1-beta.1
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.4.0-beta.18
github.com/sagernet/sing-dns v0.2.0-beta.16
github.com/sagernet/sing v0.4.0-beta.19
github.com/sagernet/sing-dns v0.2.0-beta.18
github.com/sagernet/sing-mux v0.2.0
github.com/sagernet/sing-quic v0.1.13-beta.5
github.com/sagernet/sing-quic v0.2.0-beta.5
github.com/sagernet/sing-shadowsocks v0.2.6
github.com/sagernet/sing-shadowsocks2 v0.2.0
github.com/sagernet/sing-shadowtls v0.1.4
github.com/sagernet/sing-tun v0.2.7-beta.2
github.com/sagernet/sing-tun v0.3.0-beta.5
github.com/sagernet/sing-vmess v0.1.8
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7
github.com/sagernet/tfo-go v0.0.0-20231209031829-7b5343ac1dc6
@@ -44,9 +44,9 @@ require (
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto v0.22.0
golang.org/x/net v0.24.0
golang.org/x/sys v0.19.0
golang.org/x/crypto v0.23.0
golang.org/x/net v0.25.0
golang.org/x/sys v0.20.0
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
google.golang.org/grpc v1.63.2
google.golang.org/protobuf v1.33.0
@@ -84,12 +84,12 @@ require (
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.20.0 // indirect
golang.org/x/tools v0.21.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

50
go.sum
View File

@@ -34,8 +34,8 @@ github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gofrs/uuid/v5 v5.1.0 h1:S5rqVKIigghZTCBKPCw0Y+bXkn26K3TB5mvQq2Ix8dk=
github.com/gofrs/uuid/v5 v5.1.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/gofrs/uuid/v5 v5.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM=
github.com/gofrs/uuid/v5 v5.2.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
@@ -101,27 +101,27 @@ github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f h1:NkhuupzH5ch7b/Y
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f/go.mod h1:KXmw+ouSJNOsuRpg4wgwwCQuunrGz4yoAqQjsLjc6N0=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/quic-go v0.43.0-beta.2 h1:O10Saj7TkujwFGD0TG47HTcVkrEl3tbW6adtu+BFKqs=
github.com/sagernet/quic-go v0.43.0-beta.2/go.mod h1:3EtxR1Yaa1FZu6jFPiBHpOAdhOxL4A3EPxmiVgjJvVM=
github.com/sagernet/quic-go v0.43.1-beta.1 h1:alizUjpvWYcz08dBCQsULOd+1xu0o7UtlyYf6SLbRNg=
github.com/sagernet/quic-go v0.43.1-beta.1/go.mod h1:BkrQYeop7Jx3hN3TW8/76CXcdhYiNPyYEBL/BVJ1ifc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
github.com/sagernet/sing v0.4.0-beta.18 h1:oK+pvyXnFwxwvQkeUqgxIeATiMHcrH5doLKKDGNmQkU=
github.com/sagernet/sing v0.4.0-beta.18/go.mod h1:PFQKbElc2Pke7faBLv8oEba5ehtKO21Ho+TkYemTI3Y=
github.com/sagernet/sing-dns v0.2.0-beta.16 h1:bzd4B8eHD7/WO3HrYknvgE8A56/R3n5oXBjNF97iPzQ=
github.com/sagernet/sing-dns v0.2.0-beta.16/go.mod h1:XU6Vqr6aHcMz/34Fcv8jmXpRCEuShzW+B7Qg1Xe1nxY=
github.com/sagernet/sing v0.4.0-beta.19 h1:Kzh2f6eaxt09S+bEL8F4Bgy03qkNf+4Tt8g7/5lxp/o=
github.com/sagernet/sing v0.4.0-beta.19/go.mod h1:PFQKbElc2Pke7faBLv8oEba5ehtKO21Ho+TkYemTI3Y=
github.com/sagernet/sing-dns v0.2.0-beta.18 h1:6vzXZThRdA7YUzBOpSbUT48XRumtl/KIpIHFSOP0za8=
github.com/sagernet/sing-dns v0.2.0-beta.18/go.mod h1:k/dmFcQpg6+m08gC1yQBy+13+QkuLqpKr4bIreq4U24=
github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo=
github.com/sagernet/sing-mux v0.2.0/go.mod h1:khzr9AOPocLa+g53dBplwNDz4gdsyx/YM3swtAhlkHQ=
github.com/sagernet/sing-quic v0.1.13-beta.5 h1:smhCPV+U4nM9phDIuxsPvSkCHuqFb23Gq7tf2VXh6So=
github.com/sagernet/sing-quic v0.1.13-beta.5/go.mod h1:tHO6VRzZlnLOEZnD/D9WfDOcZpYwp8UYbvVt6gEM28s=
github.com/sagernet/sing-quic v0.2.0-beta.5 h1:ceKFLd1iS5AtM+pScKmcDp5k7R6WgYIe8vl6nB0aVsE=
github.com/sagernet/sing-quic v0.2.0-beta.5/go.mod h1:lfad61lScAZhAxZ0DHZWvEIcAaT38O6zPTR4vLsHeP0=
github.com/sagernet/sing-shadowsocks v0.2.6 h1:xr7ylAS/q1cQYS8oxKKajhuQcchd5VJJ4K4UZrrpp0s=
github.com/sagernet/sing-shadowsocks v0.2.6/go.mod h1:j2YZBIpWIuElPFL/5sJAj470bcn/3QQ5lxZUNKLDNAM=
github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg=
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
github.com/sagernet/sing-tun v0.2.7-beta.2 h1:UO/Ketf15I+xDSi9XnrS65dxm2AmCZ+dgA6dt/jt7ko=
github.com/sagernet/sing-tun v0.2.7-beta.2/go.mod h1:xPaOkQhngPMILx+/9DMLCFl4vSxUU2tMnCPSlf05HLo=
github.com/sagernet/sing-tun v0.3.0-beta.5 h1:z+4l1mGjPeepxT3mzHzE2pms995iUac/AyKQvRnWbWA=
github.com/sagernet/sing-tun v0.3.0-beta.5/go.mod h1:xPaOkQhngPMILx+/9DMLCFl4vSxUU2tMnCPSlf05HLo=
github.com/sagernet/sing-vmess v0.1.8 h1:XVWad1RpTy9b5tPxdm5MCU8cGfrTGdR8qCq6HV2aCNc=
github.com/sagernet/sing-vmess v0.1.8/go.mod h1:vhx32UNzTDUkNwOyIjcZQohre1CaytquC5mPplId8uA=
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
@@ -163,16 +163,16 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY=
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -184,19 +184,19 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=

View File

@@ -166,6 +166,14 @@ func (t *Tun) Start() error {
}
t.logger.Trace("creating stack")
t.tunIf = tunInterface
var (
forwarderBindInterface bool
includeAllNetworks bool
)
if t.platformInterface != nil {
forwarderBindInterface = true
includeAllNetworks = t.platformInterface.IncludeAllNetworks()
}
t.tunStack, err = tun.NewStack(t.stack, tun.StackOptions{
Context: t.ctx,
Tun: tunInterface,
@@ -174,8 +182,9 @@ func (t *Tun) Start() error {
UDPTimeout: t.udpTimeout,
Handler: t,
Logger: t.logger,
ForwarderBindInterface: t.platformInterface != nil,
ForwarderBindInterface: forwarderBindInterface,
InterfaceFinder: t.router.InterfaceFinder(),
IncludeAllNetworks: includeAllNetworks,
})
if err != nil {
return err

View File

@@ -53,7 +53,9 @@ func NewDefaultFactory(
if platformWriter != nil {
factory.platformFormatter.DisableColors = platformWriter.DisableColors()
}
factory.observer = observable.NewObserver[Entry](factory.subscriber, 64)
if needObservable {
factory.observer = observable.NewObserver[Entry](factory.subscriber, 64)
}
return factory
}
@@ -72,7 +74,7 @@ func (f *defaultFactory) Start() error {
func (f *defaultFactory) Close() error {
return common.Close(
common.PtrOrNil(f.file),
f.observer,
f.subscriber,
)
}

View File

@@ -66,8 +66,9 @@ nav:
- Proxy Protocol:
- Shadowsocks: manual/proxy-protocol/shadowsocks.md
- Trojan: manual/proxy-protocol/trojan.md
- TUIC: manual/proxy-protocol/tuic.md
- Hysteria 2: manual/proxy-protocol/hysteria2.md
- Misc:
- TunnelVision: manual/misc/tunnelvision.md
- Configuration:
- configuration/index.md
- Log:

View File

@@ -19,7 +19,7 @@ type DNSServerOptions struct {
AddressFallbackDelay Duration `json:"address_fallback_delay,omitempty"`
Strategy DomainStrategy `json:"strategy,omitempty"`
Detour string `json:"detour,omitempty"`
ClientSubnet *ListenAddress `json:"client_subnet,omitempty"`
ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"`
}
type DNSClientOptions struct {
@@ -27,7 +27,7 @@ type DNSClientOptions struct {
DisableCache bool `json:"disable_cache,omitempty"`
DisableExpire bool `json:"disable_expire,omitempty"`
IndependentCache bool `json:"independent_cache,omitempty"`
ClientSubnet *ListenAddress `json:"client_subnet,omitempty"`
ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"`
}
type DNSFakeIPOptions struct {

View File

@@ -101,7 +101,7 @@ type DefaultDNSRule struct {
Server string `json:"server,omitempty"`
DisableCache bool `json:"disable_cache,omitempty"`
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
ClientSubnet *ListenAddress `json:"client_subnet,omitempty"`
ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"`
}
func (r DefaultDNSRule) IsValid() bool {
@@ -115,13 +115,13 @@ func (r DefaultDNSRule) IsValid() bool {
}
type LogicalDNSRule struct {
Mode string `json:"mode"`
Rules []DNSRule `json:"rules,omitempty"`
Invert bool `json:"invert,omitempty"`
Server string `json:"server,omitempty"`
DisableCache bool `json:"disable_cache,omitempty"`
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
ClientSubnet *ListenAddress `json:"client_subnet,omitempty"`
Mode string `json:"mode"`
Rules []DNSRule `json:"rules,omitempty"`
Invert bool `json:"invert,omitempty"`
Server string `json:"server,omitempty"`
DisableCache bool `json:"disable_cache,omitempty"`
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
ClientSubnet *AddrPrefix `json:"client_subnet,omitempty"`
}
func (r LogicalDNSRule) IsValid() bool {

View File

@@ -51,6 +51,40 @@ func (a *ListenAddress) Build() netip.Addr {
return (netip.Addr)(*a)
}
type AddrPrefix netip.Prefix
func (a AddrPrefix) MarshalJSON() ([]byte, error) {
prefix := netip.Prefix(a)
if prefix.Bits() == prefix.Addr().BitLen() {
return json.Marshal(prefix.Addr().String())
} else {
return json.Marshal(prefix.String())
}
}
func (a *AddrPrefix) UnmarshalJSON(content []byte) error {
var value string
err := json.Unmarshal(content, &value)
if err != nil {
return err
}
prefix, prefixErr := netip.ParsePrefix(value)
if prefixErr == nil {
*a = AddrPrefix(prefix)
return nil
}
addr, addrErr := netip.ParseAddr(value)
if addrErr == nil {
*a = AddrPrefix(netip.PrefixFrom(addr, addr.BitLen()))
return nil
}
return prefixErr
}
func (a AddrPrefix) Build() netip.Prefix {
return netip.Prefix(a)
}
type NetworkList string
func (v *NetworkList) UnmarshalJSON(content []byte) error {

View File

@@ -287,8 +287,23 @@ func (g *URLTestGroup) Close() error {
func (g *URLTestGroup) Select(network string) (adapter.Outbound, bool) {
var minDelay uint16
var minTime time.Time
var minOutbound adapter.Outbound
switch network {
case N.NetworkTCP:
if g.selectedOutboundTCP != nil {
if history := g.history.LoadURLTestHistory(RealTag(g.selectedOutboundTCP)); history != nil {
minOutbound = g.selectedOutboundTCP
minDelay = history.Delay
}
}
case N.NetworkUDP:
if g.selectedOutboundUDP != nil {
if history := g.history.LoadURLTestHistory(RealTag(g.selectedOutboundUDP)); history != nil {
minOutbound = g.selectedOutboundUDP
minDelay = history.Delay
}
}
}
for _, detour := range g.outbounds {
if !common.Contains(detour.Network(), network) {
continue
@@ -297,9 +312,8 @@ func (g *URLTestGroup) Select(network string) (adapter.Outbound, bool) {
if history == nil {
continue
}
if minDelay == 0 || minDelay > history.Delay+g.tolerance || minDelay > history.Delay-g.tolerance && minTime.Before(history.Time) {
if minDelay == 0 || minDelay > history.Delay+g.tolerance {
minDelay = history.Delay
minTime = history.Time
minOutbound = detour
}
}

View File

@@ -27,7 +27,7 @@ import (
"github.com/sagernet/sing-box/outbound"
"github.com/sagernet/sing-box/transport/fakeip"
"github.com/sagernet/sing-dns"
mux "github.com/sagernet/sing-mux"
"github.com/sagernet/sing-mux"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing-vmess"
"github.com/sagernet/sing/common"
@@ -235,7 +235,7 @@ func NewRouter(
return nil, E.New("parse dns server[", tag, "]: missing address_resolver")
}
}
var clientSubnet netip.Addr
var clientSubnet netip.Prefix
if server.ClientSubnet != nil {
clientSubnet = server.ClientSubnet.Build()
} else if dnsOptions.ClientSubnet != nil {

View File

@@ -40,7 +40,7 @@ type DefaultDNSRule struct {
abstractDefaultRule
disableCache bool
rewriteTTL *uint32
clientSubnet *netip.Addr
clientSubnet *netip.Prefix
}
func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options option.DefaultDNSRule) (*DefaultDNSRule, error) {
@@ -51,7 +51,7 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
},
disableCache: options.DisableCache,
rewriteTTL: options.RewriteTTL,
clientSubnet: (*netip.Addr)(options.ClientSubnet),
clientSubnet: (*netip.Prefix)(options.ClientSubnet),
}
if len(options.Inbound) > 0 {
item := NewInboundRule(options.Inbound)
@@ -234,7 +234,7 @@ func (r *DefaultDNSRule) RewriteTTL() *uint32 {
return r.rewriteTTL
}
func (r *DefaultDNSRule) ClientSubnet() *netip.Addr {
func (r *DefaultDNSRule) ClientSubnet() *netip.Prefix {
return r.clientSubnet
}
@@ -272,7 +272,7 @@ type LogicalDNSRule struct {
abstractLogicalRule
disableCache bool
rewriteTTL *uint32
clientSubnet *netip.Addr
clientSubnet *netip.Prefix
}
func NewLogicalDNSRule(router adapter.Router, logger log.ContextLogger, options option.LogicalDNSRule) (*LogicalDNSRule, error) {
@@ -284,6 +284,7 @@ func NewLogicalDNSRule(router adapter.Router, logger log.ContextLogger, options
},
disableCache: options.DisableCache,
rewriteTTL: options.RewriteTTL,
clientSubnet: (*netip.Prefix)(options.ClientSubnet),
}
switch options.Mode {
case C.LogicalTypeAnd:
@@ -311,7 +312,7 @@ func (r *LogicalDNSRule) RewriteTTL() *uint32 {
return r.rewriteTTL
}
func (r *LogicalDNSRule) ClientSubnet() *netip.Addr {
func (r *LogicalDNSRule) ClientSubnet() *netip.Prefix {
return r.clientSubnet
}