mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-10-21 00:34:24 +00:00
Compare commits
51
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bf321e778 | ||
|
|
eb01cb93b3 | ||
|
|
762539bc74 | ||
|
|
28d3481fac | ||
|
|
eb5fbce8e0 | ||
|
|
c1e196d184 | ||
|
|
83ea023aa3 | ||
|
|
19346d5fef | ||
|
|
7e76f22180 | ||
|
|
e7185220a8 | ||
|
|
9fa61ee28f | ||
|
|
4cfe862879 | ||
|
|
c810e80e7d | ||
|
|
4a71d4d17f | ||
|
|
8e4062eddf | ||
|
|
f200adf4c5 | ||
|
|
a84eec361e | ||
|
|
c7e91d2128 | ||
|
|
3e0122474a | ||
|
|
97a5e2c944 | ||
|
|
dd78c4f664 | ||
|
|
89e9f1a141 | ||
|
|
82ed833ec1 | ||
|
|
35a4b2bc19 | ||
|
|
b389137fc1 | ||
|
|
712155982e | ||
|
|
f5554dd8b8 | ||
|
|
4d0362d530 | ||
|
|
97ccd2ca04 | ||
|
|
1ed6654ad4 | ||
|
|
5385f75f53 | ||
|
|
ad97d4e11f | ||
|
|
09d4e91b77 | ||
|
|
3dbdda9555 | ||
|
|
1f4ed6ff8f | ||
|
|
6ddbe19bc0 | ||
|
|
d7205ecc60 | ||
|
|
9e243e0ff9 | ||
|
|
02bc3e0a0a | ||
|
|
87be6dc235 | ||
|
|
c1c30976dc | ||
|
|
9bac18bcd1 | ||
|
|
ceda5cc95d | ||
|
|
27d6b63e71 | ||
|
|
b57abcc73c | ||
|
|
f1147965dd | ||
|
|
45f3234c73 | ||
|
|
aae3fded32 | ||
|
|
090494faf5 | ||
|
|
db5719e22f | ||
|
|
064fb9b873 |
@@ -28,8 +28,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.22
|
||||
continue-on-error: true
|
||||
go-version: ^1.23
|
||||
- name: Run Test
|
||||
run: |
|
||||
go test -v ./...
|
||||
@@ -73,6 +72,26 @@ jobs:
|
||||
key: go121-${{ hashFiles('**/go.sum') }}
|
||||
- name: Run Test
|
||||
run: make ci_build
|
||||
build_go122:
|
||||
name: Debug build (Go 1.22)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ~1.22
|
||||
- name: Cache go module
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/go/pkg/mod
|
||||
key: go122-${{ hashFiles('**/go.sum') }}
|
||||
- name: Run Test
|
||||
run: make ci_build
|
||||
cross:
|
||||
strategy:
|
||||
matrix:
|
||||
|
||||
@@ -1,16 +1,83 @@
|
||||
name: Build Docker Images
|
||||
name: Publish Docker Images
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- released
|
||||
- published
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "The tag version you want to build"
|
||||
|
||||
env:
|
||||
REGISTRY_IMAGE: ghcr.io/sagernet/sing-box
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
platform:
|
||||
- linux/amd64
|
||||
- linux/arm/v6
|
||||
- linux/arm/v7
|
||||
- linux/arm64
|
||||
- linux/386
|
||||
- linux/ppc64le
|
||||
- linux/riscv64
|
||||
- linux/s390x
|
||||
- linux/mips64le
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
||||
with:
|
||||
ref: ${{ steps.ref.outputs.ref }}
|
||||
- name: Prepare
|
||||
run: |
|
||||
platform=${{ matrix.platform }}
|
||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||
- name: Setup QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY_IMAGE }}
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
platforms: ${{ matrix.platform }}
|
||||
context: .
|
||||
build-args: |
|
||||
BUILDKIT_CONTEXT_KEEP_GIT_DIR=1
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
|
||||
- name: Export digest
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
touch "/tmp/digests/${digest#sha256:}"
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: /tmp/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
merge:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build
|
||||
steps:
|
||||
- name: Get commit to build
|
||||
id: ref
|
||||
@@ -29,34 +96,28 @@ jobs:
|
||||
fi
|
||||
echo "latest=$latest"
|
||||
echo "latest=$latest" >> $GITHUB_OUTPUT
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
ref: ${{ steps.ref.outputs.ref }}
|
||||
- name: Setup Docker Buildx
|
||||
path: /tmp/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Setup QEMU for Docker Buildx
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Docker metadata
|
||||
id: metadata
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/sagernet/sing-box
|
||||
- name: Build and release Docker images
|
||||
uses: docker/build-push-action@v6
|
||||
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:${{ steps.ref.outputs.latest }}
|
||||
ghcr.io/sagernet/sing-box:${{ steps.ref.outputs.ref }}
|
||||
push: true
|
||||
- name: Create manifest list and push
|
||||
working-directory: /tmp/digests
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
-t "${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.latest }}" \
|
||||
-t "${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.ref }}" \
|
||||
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
|
||||
- name: Inspect image
|
||||
run: |
|
||||
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.latest }}
|
||||
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.ref.outputs.ref }}
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.22
|
||||
go-version: ^1.23
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.22
|
||||
go-version: ^1.23
|
||||
- name: Extract signing key
|
||||
run: |-
|
||||
mkdir -p $HOME/.gnupg
|
||||
|
||||
@@ -12,4 +12,5 @@ jobs:
|
||||
with:
|
||||
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days'
|
||||
days-before-stale: 60
|
||||
days-before-close: 5
|
||||
days-before-close: 5
|
||||
exempt-issue-labels: 'bug,enhancement'
|
||||
|
||||
@@ -26,6 +26,7 @@ builds:
|
||||
- linux_arm_7
|
||||
- linux_s390x
|
||||
- linux_riscv64
|
||||
- linux_mips64le
|
||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||
snapshot:
|
||||
name_template: "{{ .Version }}.{{ .ShortCommit }}"
|
||||
|
||||
+2
-5
@@ -10,7 +10,6 @@ builds:
|
||||
- -X github.com/sagernet/sing-box/constant.Version={{ .Version }}
|
||||
- -s
|
||||
- -buildid=
|
||||
- -checklinkname=0
|
||||
tags:
|
||||
- with_gvisor
|
||||
- with_quic
|
||||
@@ -28,9 +27,11 @@ builds:
|
||||
- linux_amd64_v1
|
||||
- linux_amd64_v3
|
||||
- linux_arm64
|
||||
- linux_arm_6
|
||||
- linux_arm_7
|
||||
- linux_s390x
|
||||
- linux_riscv64
|
||||
- linux_mips64le
|
||||
- windows_amd64_v1
|
||||
- windows_amd64_v3
|
||||
- windows_386
|
||||
@@ -49,10 +50,6 @@ builds:
|
||||
- with_reality_server
|
||||
- with_acme
|
||||
- with_clash_api
|
||||
ldflags:
|
||||
- -X github.com/sagernet/sing-box/constant.Version={{ .Version }}
|
||||
- -s
|
||||
- -buildid=
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
- GOROOT={{ .Env.GOPATH }}/go1.20.14
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
FROM --platform=$BUILDPLATFORM golang:1.22-alpine AS builder
|
||||
FROM --platform=$BUILDPLATFORM golang:1.23-alpine AS builder
|
||||
LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
|
||||
COPY . /go/src/github.com/sagernet/sing-box
|
||||
WORKDIR /go/src/github.com/sagernet/sing-box
|
||||
@@ -21,7 +21,7 @@ FROM --platform=$TARGETPLATFORM alpine AS dist
|
||||
LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
|
||||
RUN set -ex \
|
||||
&& apk upgrade \
|
||||
&& apk add bash tzdata ca-certificates \
|
||||
&& apk add bash tzdata ca-certificates nftables \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
COPY --from=builder /go/bin/sing-box /usr/local/bin/sing-box
|
||||
ENTRYPOINT ["sing-box"]
|
||||
|
||||
@@ -99,10 +99,12 @@ publish_android:
|
||||
publish_android_appcenter:
|
||||
cd ../sing-box-for-android && ./gradlew :app:appCenterAssembleAndUploadPlayRelease
|
||||
|
||||
|
||||
# TODO: find why and remove `-destination 'generic/platform=iOS'`
|
||||
build_ios:
|
||||
cd ../sing-box-for-apple && \
|
||||
rm -rf build/SFI.xcarchive && \
|
||||
xcodebuild archive -scheme SFI -configuration Release -archivePath build/SFI.xcarchive
|
||||
xcodebuild archive -scheme SFI -configuration Release -destination 'generic/platform=iOS' -archivePath build/SFI.xcarchive -allowProvisioningUpdates
|
||||
|
||||
upload_ios_app_store:
|
||||
cd ../sing-box-for-apple && \
|
||||
@@ -113,55 +115,62 @@ release_ios: build_ios upload_ios_app_store
|
||||
build_macos:
|
||||
cd ../sing-box-for-apple && \
|
||||
rm -rf build/SFM.xcarchive && \
|
||||
xcodebuild archive -scheme SFM -configuration Release -archivePath build/SFM.xcarchive
|
||||
xcodebuild archive -scheme SFM -configuration Release -archivePath build/SFM.xcarchive -allowProvisioningUpdates
|
||||
|
||||
upload_macos_app_store:
|
||||
cd ../sing-box-for-apple && \
|
||||
xcodebuild -exportArchive -archivePath build/SFM.xcarchive -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates
|
||||
xcodebuild -exportArchive -archivePath build/SFM.xcarchive -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates
|
||||
|
||||
release_macos: build_macos upload_macos_app_store
|
||||
|
||||
build_macos_independent:
|
||||
build_macos_standalone:
|
||||
cd ../sing-box-for-apple && \
|
||||
rm -rf build/SFT.System.xcarchive && \
|
||||
xcodebuild archive -scheme SFM.System -configuration Release -archivePath build/SFM.System.xcarchive
|
||||
rm -rf build/SFM.System.xcarchive && \
|
||||
xcodebuild archive -scheme SFM.System -configuration Release -archivePath build/SFM.System.xcarchive -allowProvisioningUpdates
|
||||
|
||||
notarize_macos_independent:
|
||||
cd ../sing-box-for-apple && \
|
||||
xcodebuild -exportArchive -archivePath "build/SFM.System.xcarchive" -exportOptionsPlist SFM.System/Upload.plist -allowProvisioningUpdates
|
||||
|
||||
wait_notarize_macos_independent:
|
||||
sleep 60
|
||||
|
||||
export_macos_independent:
|
||||
build_macos_dmg:
|
||||
rm -rf dist/SFM
|
||||
mkdir -p dist/SFM
|
||||
cd ../sing-box-for-apple && \
|
||||
xcodebuild -exportNotarizedApp -archivePath build/SFM.System.xcarchive -exportPath "../sing-box/dist/SFM"
|
||||
rm -rf build/SFM.System && \
|
||||
rm -rf build/SFM.dmg && \
|
||||
xcodebuild -exportArchive \
|
||||
-archivePath "build/SFM.System.xcarchive" \
|
||||
-exportOptionsPlist SFM.System/Export.plist -allowProvisioningUpdates \
|
||||
-exportPath "build/SFM.System" && \
|
||||
create-dmg \
|
||||
--volname "sing-box" \
|
||||
--volicon "build/SFM.System/SFM.app/Contents/Resources/AppIcon.icns" \
|
||||
--icon "SFM.app" 0 0 \
|
||||
--hide-extension "SFM.app" \
|
||||
--app-drop-link 0 0 \
|
||||
--skip-jenkins \
|
||||
--codesign "B2324162A090F01F96111CF802A83F0F36674F80" \
|
||||
--notarize "notarytool-password" \
|
||||
"../sing-box/dist/SFM/SFM.dmg" "build/SFM.System/SFM.app"
|
||||
|
||||
upload_macos_independent:
|
||||
upload_macos_dmg:
|
||||
cd dist/SFM && \
|
||||
rm -f *.zip && \
|
||||
zip -ry "SFM-${VERSION}-universal.zip" SFM.app && \
|
||||
ghr --replace --draft --prerelease "v${VERSION}" *.zip
|
||||
cp SFM.dmg "SFM-${VERSION}-universal.dmg" && \
|
||||
ghr --replace --draft --prerelease "v${VERSION}" "SFM-${VERSION}-universal.dmg"
|
||||
|
||||
release_macos_independent: build_macos_independent notarize_macos_independent wait_notarize_macos_independent export_macos_independent upload_macos_independent
|
||||
release_macos_standalone: build_macos_standalone build_macos_dmg upload_macos_dmg
|
||||
|
||||
build_tvos:
|
||||
cd ../sing-box-for-apple && \
|
||||
rm -rf build/SFT.xcarchive && \
|
||||
xcodebuild archive -scheme SFT -configuration Release -archivePath build/SFT.xcarchive
|
||||
xcodebuild archive -scheme SFT -configuration Release -archivePath build/SFT.xcarchive -allowProvisioningUpdates
|
||||
|
||||
upload_tvos_app_store:
|
||||
cd ../sing-box-for-apple && \
|
||||
xcodebuild -exportArchive -archivePath "build/SFT.xcarchive" -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates
|
||||
xcodebuild -exportArchive -archivePath "build/SFT.xcarchive" -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates
|
||||
|
||||
release_tvos: build_tvos upload_tvos_app_store
|
||||
|
||||
update_apple_version:
|
||||
go run ./cmd/internal/update_apple_version
|
||||
|
||||
release_apple: lib_ios update_apple_version release_ios release_macos release_tvos release_macos_independent
|
||||
release_apple: lib_ios update_apple_version release_ios release_macos release_tvos
|
||||
|
||||
release_apple_beta: update_apple_version release_ios release_macos release_tvos
|
||||
|
||||
@@ -188,8 +197,8 @@ lib:
|
||||
go run ./cmd/internal/build_libbox -target ios
|
||||
|
||||
lib_install:
|
||||
go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.1.3
|
||||
go install -v github.com/sagernet/gomobile/cmd/gobind@v0.1.3
|
||||
go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.1.4
|
||||
go install -v github.com/sagernet/gomobile/cmd/gobind@v0.1.4
|
||||
|
||||
docs:
|
||||
venv/bin/mkdocs serve
|
||||
|
||||
@@ -4,9 +4,9 @@ The universal proxy platform.
|
||||
|
||||
[](https://repology.org/project/sing-box/versions)
|
||||
|
||||
## Support
|
||||
## Documentation
|
||||
|
||||
https://community.sagernet.org/c/sing-box/
|
||||
https://sing-box.sagernet.org
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+1
-1
Submodule clients/android updated: 440aaa9a1a...dcf6e1f20a
+1
-1
Submodule clients/apple updated: aa4ce98421...8b5ad1928f
@@ -26,8 +26,8 @@ func main() {
|
||||
common.Must(decoder.Decode(&project))
|
||||
objectsMap := project["objects"].(map[string]any)
|
||||
projectContent := string(common.Must1(os.ReadFile("sing-box.xcodeproj/project.pbxproj")))
|
||||
newContent, updated0 := findAndReplace(objectsMap, projectContent, []string{"io.nekohasekai.sfa"}, newVersion.VersionString())
|
||||
newContent, updated1 := findAndReplace(objectsMap, newContent, []string{"io.nekohasekai.sfa.independent", "io.nekohasekai.sfa.system"}, newVersion.String())
|
||||
newContent, updated0 := findAndReplace(objectsMap, projectContent, []string{"io.nekohasekai.sfavt"}, newVersion.VersionString())
|
||||
newContent, updated1 := findAndReplace(objectsMap, newContent, []string{"io.nekohasekai.sfa.standalone", "io.nekohasekai.sfa.system"}, newVersion.String())
|
||||
if updated0 || updated1 {
|
||||
log.Info("updated version to ", newVersion.VersionString(), " (", newVersion.String(), ")")
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ package dialer
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/sagernet/tfo-go"
|
||||
"github.com/metacubex/tfo-go"
|
||||
)
|
||||
|
||||
type tcpDialer = tfo.Dialer
|
||||
|
||||
@@ -28,13 +28,12 @@ func New(router adapter.Router, options option.DialerOptions) (N.Dialer, error)
|
||||
} else {
|
||||
dialer = NewDetour(router, options.Detour)
|
||||
}
|
||||
domainStrategy := dns.DomainStrategy(options.DomainStrategy)
|
||||
if domainStrategy != dns.DomainStrategyAsIS || options.Detour == "" {
|
||||
if options.Detour == "" {
|
||||
dialer = NewResolveDialer(
|
||||
router,
|
||||
dialer,
|
||||
options.Detour == "" && !options.TCPFastOpen,
|
||||
domainStrategy,
|
||||
dns.DomainStrategy(options.DomainStrategy),
|
||||
time.Duration(options.FallbackDelay))
|
||||
}
|
||||
return dialer, nil
|
||||
|
||||
@@ -15,7 +15,8 @@ import (
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/tfo-go"
|
||||
|
||||
"github.com/metacubex/tfo-go"
|
||||
)
|
||||
|
||||
type slowOpenConn struct {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package geosite_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/sagernet/sing-box/common/geosite"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGeosite(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var buffer bytes.Buffer
|
||||
err := geosite.Write(&buffer, map[string][]geosite.Item{
|
||||
"test": {
|
||||
{
|
||||
Type: geosite.RuleTypeDomain,
|
||||
Value: "example.org",
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
reader, codes, err := geosite.NewReader(bytes.NewReader(buffer.Bytes()))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []string{"test"}, codes)
|
||||
items, err := reader.Read("test")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []geosite.Item{{
|
||||
Type: geosite.RuleTypeDomain,
|
||||
Value: "example.org",
|
||||
}}, items)
|
||||
}
|
||||
@@ -26,14 +26,22 @@ func Open(path string) (*Reader, []string, error) {
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
reader := &Reader{
|
||||
reader: content,
|
||||
}
|
||||
err = reader.readMetadata()
|
||||
reader, codes, err := NewReader(content)
|
||||
if err != nil {
|
||||
content.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
return reader, codes, nil
|
||||
}
|
||||
|
||||
func NewReader(readSeeker io.ReadSeeker) (*Reader, []string, error) {
|
||||
reader := &Reader{
|
||||
reader: readSeeker,
|
||||
}
|
||||
err := reader.readMetadata()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
codes := make([]string, 0, len(reader.domainIndex))
|
||||
for code := range reader.domainIndex {
|
||||
codes = append(codes, code)
|
||||
|
||||
@@ -19,9 +19,11 @@ func Write(writer varbin.Writer, domains map[string][]Item) error {
|
||||
index := make(map[string]int)
|
||||
for _, code := range keys {
|
||||
index[code] = content.Len()
|
||||
err := varbin.Write(content, binary.BigEndian, domains[code])
|
||||
if err != nil {
|
||||
return err
|
||||
for _, item := range domains[code] {
|
||||
err := varbin.Write(content, binary.BigEndian, item)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package sniff
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing/common/rw"
|
||||
)
|
||||
|
||||
func RDP(_ context.Context, metadata *adapter.InboundContext, reader io.Reader) error {
|
||||
var tpktVersion uint8
|
||||
err := binary.Read(reader, binary.BigEndian, &tpktVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tpktVersion != 0x03 {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
var tpktReserved uint8
|
||||
err = binary.Read(reader, binary.BigEndian, &tpktReserved)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tpktReserved != 0x00 {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
var tpktLength uint16
|
||||
err = binary.Read(reader, binary.BigEndian, &tpktLength)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if tpktLength != 19 {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
var cotpLength uint8
|
||||
err = binary.Read(reader, binary.BigEndian, &cotpLength)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cotpLength != 14 {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
var cotpTpduType uint8
|
||||
err = binary.Read(reader, binary.BigEndian, &cotpTpduType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cotpTpduType != 0xE0 {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
err = rw.SkipN(reader, 5)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var rdpType uint8
|
||||
err = binary.Read(reader, binary.BigEndian, &rdpType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rdpType != 0x01 {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
var rdpFlags uint8
|
||||
err = binary.Read(reader, binary.BigEndian, &rdpFlags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var rdpLength uint8
|
||||
err = binary.Read(reader, binary.BigEndian, &rdpLength)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rdpLength != 8 {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
metadata.Protocol = C.ProtocolRDP
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package sniff_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/sniff"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSniffRDP(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
pkt, err := hex.DecodeString("030000130ee00000000000010008000b000000010008000b000000")
|
||||
require.NoError(t, err)
|
||||
var metadata adapter.InboundContext
|
||||
err = sniff.RDP(context.TODO(), &metadata, bytes.NewReader(pkt))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, C.ProtocolRDP, metadata.Protocol)
|
||||
}
|
||||
+29
-19
@@ -18,33 +18,43 @@ type (
|
||||
PacketSniffer = func(ctx context.Context, metadata *adapter.InboundContext, packet []byte) error
|
||||
)
|
||||
|
||||
func Skip(metadata adapter.InboundContext) bool {
|
||||
// skip server first protocols
|
||||
switch metadata.Destination.Port {
|
||||
case 25, 465, 587:
|
||||
// SMTP
|
||||
return true
|
||||
case 143, 993:
|
||||
// IMAP
|
||||
return true
|
||||
case 110, 995:
|
||||
// POP3
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func PeekStream(ctx context.Context, metadata *adapter.InboundContext, conn net.Conn, buffer *buf.Buffer, timeout time.Duration, sniffers ...StreamSniffer) error {
|
||||
if timeout == 0 {
|
||||
timeout = C.ReadPayloadTimeout
|
||||
}
|
||||
deadline := time.Now().Add(timeout)
|
||||
var errors []error
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
err := conn.SetReadDeadline(deadline)
|
||||
if err != nil {
|
||||
return E.Cause(err, "set read deadline")
|
||||
err := conn.SetReadDeadline(deadline)
|
||||
if err != nil {
|
||||
return E.Cause(err, "set read deadline")
|
||||
}
|
||||
defer conn.SetReadDeadline(time.Time{})
|
||||
for _, sniffer := range sniffers {
|
||||
if buffer.IsEmpty() {
|
||||
err = sniffer(ctx, metadata, io.TeeReader(conn, buffer))
|
||||
} else {
|
||||
err = sniffer(ctx, metadata, io.MultiReader(bytes.NewReader(buffer.Bytes()), io.TeeReader(conn, buffer)))
|
||||
}
|
||||
_, err = buffer.ReadOnceFrom(conn)
|
||||
err = E.Errors(err, conn.SetReadDeadline(time.Time{}))
|
||||
if err != nil {
|
||||
if i > 0 {
|
||||
break
|
||||
}
|
||||
return E.Cause(err, "read payload")
|
||||
}
|
||||
for _, sniffer := range sniffers {
|
||||
err = sniffer(ctx, metadata, bytes.NewReader(buffer.Bytes()))
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
return E.Errors(errors...)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package sniff
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
)
|
||||
|
||||
func SSH(_ context.Context, metadata *adapter.InboundContext, reader io.Reader) error {
|
||||
scanner := bufio.NewScanner(reader)
|
||||
if !scanner.Scan() {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
fistLine := scanner.Text()
|
||||
if !strings.HasPrefix(fistLine, "SSH-2.0-") {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
metadata.Protocol = C.ProtocolSSH
|
||||
metadata.Client = fistLine[8:]
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package sniff_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/sniff"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSniffSSH(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
pkt, err := hex.DecodeString("5353482d322e302d64726f70626561720d0a000001a40a1492892570d1223aef61b0d647972c8bd30000009f637572766532353531392d7368613235362c637572766532353531392d736861323536406c69627373682e6f72672c6469666669652d68656c6c6d616e2d67726f757031342d7368613235362c6469666669652d68656c6c6d616e2d67726f757031342d736861312c6b6578677565737332406d6174742e7563632e61736e2e61752c6b65782d7374726963742d732d763030406f70656e7373682e636f6d000000207373682d656432353531392c7273612d736861322d3235362c7373682d7273610000003363686163686132302d706f6c7931333035406f70656e7373682e636f6d2c6165733132382d6374722c6165733235362d6374720000003363686163686132302d706f6c7931333035406f70656e7373682e636f6d2c6165733132382d6374722c6165733235362d63747200000017686d61632d736861312c686d61632d736861322d32353600000017686d61632d736861312c686d61632d736861322d323536000000046e6f6e65000000046e6f6e65000000000000000000000000002aa6ed090585b7d635b6")
|
||||
require.NoError(t, err)
|
||||
var metadata adapter.InboundContext
|
||||
err = sniff.SSH(context.TODO(), &metadata, bytes.NewReader(pkt))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, C.ProtocolSSH, metadata.Protocol)
|
||||
require.Equal(t, "dropbear", metadata.Client)
|
||||
}
|
||||
@@ -8,6 +8,8 @@ const (
|
||||
ProtocolSTUN = "stun"
|
||||
ProtocolBitTorrent = "bittorrent"
|
||||
ProtocolDTLS = "dtls"
|
||||
ProtocolSSH = "ssh"
|
||||
ProtocolRDP = "rdp"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
+54
-3
@@ -2,11 +2,57 @@
|
||||
icon: material/alert-decagram
|
||||
---
|
||||
|
||||
!!! failure "Help needed"
|
||||
#### 1.10.0-beta.9
|
||||
|
||||
Due to problems with our Apple developer account, sing-box apps on Apple platforms are temporarily unavailable for download or update.
|
||||
* Fixes and improvements
|
||||
|
||||
If your company or organization is willing to help us return to the App Store, please [contact us](mailto:contact@sagernet.org).
|
||||
### 1.9.5
|
||||
|
||||
* Update quic-go to v0.47.0
|
||||
* Fix direct dialer not resolving domain
|
||||
* Fix no error return when empty DNS cache retrieved
|
||||
* Fix build with go1.23
|
||||
* Fix stream sniffer
|
||||
* Fix bad redirect in clash-api
|
||||
* Fix wireguard events chan leak
|
||||
* Fix cached conn eats up read deadlines
|
||||
* Fix disconnected interface selected as default in windows
|
||||
* Update Bundle Identifiers for Apple platform clients **1**
|
||||
|
||||
**1**:
|
||||
|
||||
See [Migration](/migration/#bundle-identifier-updates-in-apple-platform-clients).
|
||||
|
||||
We are still working on getting all sing-box apps back on the App Store.
|
||||
|
||||
This work is expected to be completed within a week
|
||||
(SFI on the App Store and others on TestFlight are already available).
|
||||
|
||||
#### 1.10.0-beta.8
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
_With the help of a netizen, we are in the process of getting sing-box apps back on the App Store, which should be completed within a month (TestFlight is already available)._
|
||||
|
||||
#### 1.10.0-beta.7
|
||||
|
||||
* Update quic-go to v0.47.0
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.10.0-beta.6
|
||||
|
||||
* Add RDP sniffer
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.10.0-beta.5
|
||||
|
||||
* Add PNA support for [Clash API](/configuration/experimental/clash-api/)
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.10.0-beta.3
|
||||
|
||||
* Add SSH sniffer
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.10.0-beta.2
|
||||
|
||||
@@ -28,6 +74,11 @@ icon: material/alert-decagram
|
||||
* Fix UDP connnection leak when sniffing
|
||||
* Fixes and improvements
|
||||
|
||||
_Due to problems with our Apple developer account,
|
||||
sing-box apps on Apple platforms are temporarily unavailable for download or update.
|
||||
If your company or organization is willing to help us return to the App Store,
|
||||
please [contact us](mailto:contact@sagernet.org)._
|
||||
|
||||
#### 1.10.0-alpha.29
|
||||
|
||||
* Update quic-go to v0.46.0
|
||||
|
||||
@@ -11,8 +11,7 @@ platform-specific function implementation, such as TUN transparent proxy impleme
|
||||
|
||||
Due to problems with our Apple developer account, sing-box apps on Apple platforms are temporarily unavailable for download or update.
|
||||
|
||||
If your company or organization is willing to help us return to the App Store, please [contact us](mailto:contact@sagernet.org).
|
||||
|
||||
We are working on getting sing-box apps back on the App Store, which should be completed within a week (SFI on the App Store and others on TestFlight are already available).
|
||||
|
||||
## :material-graph: Requirements
|
||||
|
||||
@@ -21,13 +20,13 @@ platform-specific function implementation, such as TUN transparent proxy impleme
|
||||
|
||||
## :material-download: Download
|
||||
|
||||
* [App Store](https://apps.apple.com/us/app/sing-box/id6451272673)
|
||||
* ~~TestFlight (Beta)~~
|
||||
* [App Store](https://apps.apple.com/app/sing-box-vt/id6673731168)
|
||||
* TestFlight (Beta)
|
||||
|
||||
TestFlight quota is only available to [sponsors](https://github.com/sponsors/nekohasekai)
|
||||
(one-time sponsorships are accepted).
|
||||
Once you donate, you can get an invitation by sending us your Apple ID [via email](mailto:contact@sagernet.org),
|
||||
or join our Telegram group for sponsors from [@yet_another_sponsor_bot](https://t.me/yet_another_sponsor_bot).
|
||||
Once you donate, you can get an invitation by join our Telegram group for sponsors from [@yet_another_sponsor_bot](https://t.me/yet_another_sponsor_bot)
|
||||
or sending us your Apple ID [via email](mailto:contact@sagernet.org).
|
||||
|
||||
## :material-file-download: Download (macOS standalone version)
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
Maintained by Project S to provide a unified experience and platform-specific functionality.
|
||||
|
||||
| Platform | Client |
|
||||
| ------------------------------------- | ---------------------------------------- |
|
||||
|---------------------------------------|------------------------------------------|
|
||||
| :material-android: Android | [sing-box for Android](./android/) |
|
||||
| :material-apple: iOS/macOS/Apple tvOS | :material-alert: [Unavailable](./apple/) |
|
||||
| :material-apple: iOS/macOS/Apple tvOS | [sing-box for Apple platforms](./apple/) |
|
||||
| :material-laptop: Desktop | Working in progress |
|
||||
|
||||
Some third-party projects that claim to use sing-box or use sing-box as a selling point are not listed here. The core
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
由 Project S 维护,提供统一的体验与平台特定的功能。
|
||||
|
||||
| 平台 | 客户端 |
|
||||
| ------------------------------------- | ----------------------------------- |
|
||||
| :material-android: Android | [sing-box for Android](./android/) |
|
||||
| :material-apple: iOS/macOS/Apple tvOS | :material-alert: [不可用](./apple/) |
|
||||
| :material-laptop: Desktop | 施工中 |
|
||||
| 平台 | 客户端 |
|
||||
|---------------------------------------|------------------------------------------|
|
||||
| :material-android: Android | [sing-box for Android](./android/) |
|
||||
| :material-apple: iOS/macOS/Apple tvOS | [sing-box for Apple platforms](./apple/) |
|
||||
| :material-laptop: Desktop | 施工中 |
|
||||
|
||||
此处没有列出一些声称使用或以 sing-box 为卖点的第三方项目。此类项目维护者的动机是获得更多用户,即使它们提供友好的商业
|
||||
VPN 客户端功能, 但代码质量很差且包含广告。
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
---
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! quote "Changes in sing-box 1.10.0"
|
||||
|
||||
:material-plus: [access_control_allow_origin](#access_control_allow_origin)
|
||||
:material-plus: [access_control_allow_private_network](#access_control_allow_private_network)
|
||||
|
||||
!!! quote "Changes in sing-box 1.8.0"
|
||||
|
||||
:material-delete-alert: [store_mode](#store_mode)
|
||||
@@ -8,24 +17,59 @@
|
||||
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"external_controller": "127.0.0.1:9090",
|
||||
"external_ui": "",
|
||||
"external_ui_download_url": "",
|
||||
"external_ui_download_detour": "",
|
||||
"secret": "",
|
||||
"default_mode": "",
|
||||
|
||||
// Deprecated
|
||||
|
||||
"store_mode": false,
|
||||
"store_selected": false,
|
||||
"store_fakeip": false,
|
||||
"cache_file": "",
|
||||
"cache_id": ""
|
||||
}
|
||||
```
|
||||
=== "Structure"
|
||||
|
||||
```json
|
||||
{
|
||||
"external_controller": "127.0.0.1:9090",
|
||||
"external_ui": "",
|
||||
"external_ui_download_url": "",
|
||||
"external_ui_download_detour": "",
|
||||
"secret": "",
|
||||
"default_mode": "",
|
||||
"access_control_allow_origin": [],
|
||||
"access_control_allow_private_network": false,
|
||||
|
||||
// Deprecated
|
||||
|
||||
"store_mode": false,
|
||||
"store_selected": false,
|
||||
"store_fakeip": false,
|
||||
"cache_file": "",
|
||||
"cache_id": ""
|
||||
}
|
||||
```
|
||||
|
||||
=== "Example (online)"
|
||||
|
||||
!!! question "Since sing-box 1.10.0"
|
||||
|
||||
```json
|
||||
{
|
||||
"external_controller": "127.0.0.1:9090",
|
||||
"access_control_allow_origin": [
|
||||
"http://127.0.0.1",
|
||||
"http://yacd.haishan.me"
|
||||
],
|
||||
"access_control_allow_private_network": true
|
||||
}
|
||||
```
|
||||
|
||||
=== "Example (download)"
|
||||
|
||||
!!! question "Since sing-box 1.10.0"
|
||||
|
||||
```json
|
||||
{
|
||||
"external_controller": "0.0.0.0:9090",
|
||||
"external_ui": "dashboard"
|
||||
// external_ui_download_detour: "direct"
|
||||
}
|
||||
```
|
||||
|
||||
!!! note ""
|
||||
|
||||
You can ignore the JSON Array [] tag when the content is only one item
|
||||
|
||||
### Fields
|
||||
|
||||
@@ -63,6 +107,22 @@ Default mode in clash, `Rule` will be used if empty.
|
||||
|
||||
This setting has no direct effect, but can be used in routing and DNS rules via the `clash_mode` rule item.
|
||||
|
||||
#### access_control_allow_origin
|
||||
|
||||
!!! question "Since sing-box 1.10.0"
|
||||
|
||||
CORS allowed origins, `*` will be used if empty.
|
||||
|
||||
To access the Clash API on a private network from a public website, you must explicitly specify it in `access_control_allow_origin` instead of using `*`.
|
||||
|
||||
#### access_control_allow_private_network
|
||||
|
||||
!!! question "Since sing-box 1.10.0"
|
||||
|
||||
Allow access from private network.
|
||||
|
||||
To access the Clash API on a private network from a public website, `access_control_allow_private_network` must be enabled.
|
||||
|
||||
#### store_mode
|
||||
|
||||
!!! failure "Deprecated in sing-box 1.8.0"
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
---
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! quote "sing-box 1.10.0 中的更改"
|
||||
|
||||
:material-plus: [access_control_allow_origin](#access_control_allow_origin)
|
||||
:material-plus: [access_control_allow_private_network](#access_control_allow_private_network)
|
||||
|
||||
!!! quote "sing-box 1.8.0 中的更改"
|
||||
|
||||
:material-delete-alert: [store_mode](#store_mode)
|
||||
@@ -8,24 +17,59 @@
|
||||
|
||||
### 结构
|
||||
|
||||
```json
|
||||
{
|
||||
"external_controller": "127.0.0.1:9090",
|
||||
"external_ui": "",
|
||||
"external_ui_download_url": "",
|
||||
"external_ui_download_detour": "",
|
||||
"secret": "",
|
||||
"default_mode": "",
|
||||
|
||||
// Deprecated
|
||||
|
||||
"store_mode": false,
|
||||
"store_selected": false,
|
||||
"store_fakeip": false,
|
||||
"cache_file": "",
|
||||
"cache_id": ""
|
||||
}
|
||||
```
|
||||
=== "结构"
|
||||
|
||||
```json
|
||||
{
|
||||
"external_controller": "127.0.0.1:9090",
|
||||
"external_ui": "",
|
||||
"external_ui_download_url": "",
|
||||
"external_ui_download_detour": "",
|
||||
"secret": "",
|
||||
"default_mode": "",
|
||||
"access_control_allow_origin": [],
|
||||
"access_control_allow_private_network": false,
|
||||
|
||||
// Deprecated
|
||||
|
||||
"store_mode": false,
|
||||
"store_selected": false,
|
||||
"store_fakeip": false,
|
||||
"cache_file": "",
|
||||
"cache_id": ""
|
||||
}
|
||||
```
|
||||
|
||||
=== "示例 (在线)"
|
||||
|
||||
!!! question "自 sing-box 1.10.0 起"
|
||||
|
||||
```json
|
||||
{
|
||||
"external_controller": "127.0.0.1:9090",
|
||||
"access_control_allow_origin": [
|
||||
"http://127.0.0.1",
|
||||
"http://yacd.haishan.me"
|
||||
],
|
||||
"access_control_allow_private_network": true
|
||||
}
|
||||
```
|
||||
|
||||
=== "示例 (下载)"
|
||||
|
||||
!!! question "自 sing-box 1.10.0 起"
|
||||
|
||||
```json
|
||||
{
|
||||
"external_controller": "0.0.0.0:9090",
|
||||
"external_ui": "dashboard"
|
||||
// external_ui_download_detour: "direct"
|
||||
}
|
||||
```
|
||||
|
||||
!!! note ""
|
||||
|
||||
当内容只有一项时,可以忽略 JSON 数组 [] 标签
|
||||
|
||||
### Fields
|
||||
|
||||
@@ -61,6 +105,22 @@ Clash 中的默认模式,默认使用 `Rule`。
|
||||
|
||||
此设置没有直接影响,但可以通过 `clash_mode` 规则项在路由和 DNS 规则中使用。
|
||||
|
||||
#### access_control_allow_origin
|
||||
|
||||
!!! question "自 sing-box 1.10.0 起"
|
||||
|
||||
允许的 CORS 来源,默认使用 `*`。
|
||||
|
||||
要从公共网站访问私有网络上的 Clash API,必须在 `access_control_allow_origin` 中明确指定它而不是使用 `*`。
|
||||
|
||||
#### access_control_allow_private_network
|
||||
|
||||
!!! question "自 sing-box 1.10.0 起"
|
||||
|
||||
允许从私有网络访问。
|
||||
|
||||
要从公共网站访问私有网络上的 Clash API,必须启用 `access_control_allow_private_network`。
|
||||
|
||||
#### store_mode
|
||||
|
||||
!!! failure "已在 sing-box 1.8.0 废弃"
|
||||
|
||||
@@ -7,7 +7,9 @@ icon: material/new-box
|
||||
:material-plus: QUIC client type detect support for QUIC
|
||||
:material-plus: Chromium support for QUIC
|
||||
:material-plus: BitTorrent support
|
||||
:material-plus: DTLS support
|
||||
:material-plus: DTLS support
|
||||
:material-plus: SSH support
|
||||
:material-plus: RDP support
|
||||
|
||||
If enabled in the inbound, the protocol and domain name (if present) of by the connection can be sniffed.
|
||||
|
||||
@@ -22,6 +24,8 @@ If enabled in the inbound, the protocol and domain name (if present) of by the c
|
||||
| TCP/UDP | `dns` | / | / |
|
||||
| TCP/UDP | `bittorrent` | / | / |
|
||||
| UDP | `dtls` | / | / |
|
||||
| TCP | `ssh` | / | SSH Client Name |
|
||||
| TCP | `rdp` | / | / |
|
||||
|
||||
| QUIC Client | Type |
|
||||
|:------------------------:|:----------:|
|
||||
|
||||
@@ -7,7 +7,9 @@ icon: material/new-box
|
||||
:material-plus: QUIC 的 客户端类型探测支持
|
||||
:material-plus: QUIC 的 Chromium 支持
|
||||
:material-plus: BitTorrent 支持
|
||||
:material-plus: DTLS 支持
|
||||
:material-plus: DTLS 支持
|
||||
:material-plus: SSH 支持
|
||||
:material-plus: RDP 支持
|
||||
|
||||
如果在入站中启用,则可以嗅探连接的协议和域名(如果存在)。
|
||||
|
||||
@@ -22,6 +24,8 @@ icon: material/new-box
|
||||
| TCP/UDP | `dns` | / | / |
|
||||
| TCP/UDP | `bittorrent` | / | / |
|
||||
| UDP | `dtls` | / | / |
|
||||
| TCP | `ssh` | / | SSH 客户端名称 |
|
||||
| TCP | `rdp` | / | / |
|
||||
|
||||
| QUIC 客户端 | 类型 |
|
||||
|:------------------------:|:----------:|
|
||||
|
||||
@@ -83,7 +83,10 @@
|
||||
|
||||
如果设置,域名将在请求发出之前解析为 IP。
|
||||
|
||||
默认使用 `dns.strategy`。
|
||||
| 出站 | 受影响的域名 | 默认回退值 |
|
||||
|----------|--------------------------|-------------------------------------------|
|
||||
| `direct` | 请求中的域名 | `inbound.domain_strategy` |
|
||||
| others | 服务器地址中的域名 | / |
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
|
||||
@@ -4,12 +4,6 @@ description: Welcome to the wiki page for the sing-box project.
|
||||
|
||||
# :material-home: Home
|
||||
|
||||
!!! failure "Help needed"
|
||||
|
||||
Due to problems with our Apple developer account, sing-box apps on Apple platforms are temporarily unavailable for download or update.
|
||||
|
||||
If your company or organization is willing to help us return to the App Store, please [contact us](mailto:contact@sagernet.org).
|
||||
|
||||
Welcome to the wiki page for the sing-box project.
|
||||
|
||||
The universal proxy platform.
|
||||
|
||||
@@ -6,26 +6,18 @@ icon: material/file-code
|
||||
|
||||
## :material-graph: Requirements
|
||||
|
||||
Before sing-box 1.4.0:
|
||||
### sing-box 1.10
|
||||
|
||||
* Go 1.18.5 - 1.20.x
|
||||
|
||||
Since sing-box 1.4.0:
|
||||
|
||||
* Go 1.18.5 - ~
|
||||
* Go 1.20.0 - ~ with tag `with_quic` enabled
|
||||
|
||||
Since sing-box 1.5.0:
|
||||
|
||||
* Go 1.18.5 - ~
|
||||
* Go 1.20.0 - ~ with tag `with_quic` or `with_ech` enabled
|
||||
|
||||
Since sing-box 1.8.0:
|
||||
|
||||
* Go 1.18.5 - ~
|
||||
* Go 1.20.0 - ~
|
||||
* Go 1.20.0 - ~ with tag `with_quic`, or `with_utls` enabled
|
||||
* Go 1.21.0 - ~ with tag `with_ech` enabled
|
||||
|
||||
### sing-box 1.9
|
||||
|
||||
* Go 1.18.5 - 1.22.x
|
||||
* Go 1.20.0 - 1.22.x with tag `with_quic`, or `with_utls` enabled
|
||||
* Go 1.21.0 - 1.22.x with tag `with_ech` enabled
|
||||
|
||||
You can download and install Go from: https://go.dev/doc/install, latest version is recommended.
|
||||
|
||||
## :material-fast-forward: Simple Build
|
||||
|
||||
@@ -6,25 +6,17 @@ icon: material/file-code
|
||||
|
||||
## :material-graph: 要求
|
||||
|
||||
sing-box 1.4.0 前:
|
||||
### sing-box 1.10
|
||||
|
||||
* Go 1.18.5 - 1.20.x
|
||||
* Go 1.20.0 - ~
|
||||
* Go 1.20.0 - ~ with tag `with_quic`, or `with_utls` enabled
|
||||
* Go 1.21.0 - ~ with tag `with_ech` enabled
|
||||
|
||||
从 sing-box 1.4.0:
|
||||
### sing-box 1.9
|
||||
|
||||
* Go 1.18.5 - ~
|
||||
* Go 1.20.0 - ~ 如果启用构建标记 `with_quic`
|
||||
|
||||
从 sing-box 1.5.0:
|
||||
|
||||
* Go 1.18.5 - ~
|
||||
* Go 1.20.0 - ~ 如果启用构建标记 `with_quic` 或 `with_ech`
|
||||
|
||||
从 sing-box 1.8.0:
|
||||
|
||||
* Go 1.18.5 - ~
|
||||
* Go 1.20.0 - ~ 如果启用构建标记 `with_quic` 或 `with_utls`
|
||||
* Go 1.20.1 - ~ 如果启用构建标记 `with_ech`
|
||||
* Go 1.18.5 - 1.22.x
|
||||
* Go 1.20.0 - 1.22.x with tag `with_quic`, or `with_utls` enabled
|
||||
* Go 1.21.0 - 1.22.x with tag `with_ech` enabled
|
||||
|
||||
您可以从 https://go.dev/doc/install 下载并安装 Go,推荐使用最新版本。
|
||||
|
||||
|
||||
@@ -24,14 +24,7 @@ icon: material/package
|
||||
sudo dnf config-manager --add-repo https://sing-box.app/sing-box.repo
|
||||
sudo dnf install sing-box # or sing-box-beta
|
||||
```
|
||||
|
||||
=== ":material-redhat: CentOS / YUM"
|
||||
|
||||
```bash
|
||||
sudo yum install -y yum-utils
|
||||
sudo yum-config-manager --add-repo https://sing-box.app/sing-box.repo
|
||||
sudo yum install sing-box # or sing-box-beta
|
||||
```
|
||||
(This applies to any distribution that uses `dnf` as the package manager: Fedora, CentOS, even OpenSUSE with DNF installed.)
|
||||
|
||||
## :material-download-box: Manual Installation
|
||||
|
||||
@@ -46,6 +39,7 @@ icon: material/package
|
||||
```bash
|
||||
bash <(curl -fsSL https://sing-box.app/rpm-install.sh)
|
||||
```
|
||||
(This applies to any distribution that uses `rpm` and `systemd`. Because of how `rpm` defines dependencies, if it installs, it probably works.)
|
||||
|
||||
=== ":simple-archlinux: Archlinux / PKG"
|
||||
|
||||
@@ -63,6 +57,7 @@ icon: material/package
|
||||
| nixpkgs | NixOS | `nix-env -iA nixos.sing-box` | [][nixpkgs] |
|
||||
| Homebrew | macOS / Linux | `brew install sing-box` | [][brew] |
|
||||
| APK | Alpine | `apk add sing-box` | [][alpine] |
|
||||
| DEB | AOSC | `apt install sing-box` | [][aosc] |
|
||||
|
||||
=== ":material-apple: macOS"
|
||||
|
||||
@@ -90,6 +85,22 @@ icon: material/package
|
||||
|------------|----------|------------------------|--------------------------------------------------------------------------------------------|
|
||||
| FreshPorts | FreeBSD | `pkg install sing-box` | [][ports] |
|
||||
|
||||
## :material-alert: Problematic Sources
|
||||
|
||||
| Type | Platform | Link | Promblem(s) |
|
||||
|------------|----------|-------------------------------------------------------------------------------------------|------------------------------------------------------------------|
|
||||
| DEB | AOSC | [aosc-os-abbs](https://github.com/AOSC-Dev/aosc-os-abbs/tree/stable/app-network/sing-box) | Problematic build tag list modification; Not actively maintained |
|
||||
| Homebrew | / | [homebrew-core][brew] | Problematic build tag list modification |
|
||||
| Termux | Android | [termux-packages][termux] | Problematic build tag list modification |
|
||||
| FreshPorts | FreeBSD | [FreeBSD ports][ports] | Old Go (go1.20) |
|
||||
|
||||
If you are a user of them, please report issues to them:
|
||||
|
||||
1. Please do not modify release build tags without full understanding of the related functionality: enabling non-default
|
||||
labels may result in decreased performance; the lack of default labels may cause user confusion.
|
||||
2. sing-box supports compiling with some older Go versions, but it is not recommended (especially versions that are no
|
||||
longer supported by Go).
|
||||
|
||||
## :material-book-multiple: Service Management
|
||||
|
||||
For Linux systems with [systemd][systemd], usually the installation already includes a sing-box service,
|
||||
@@ -128,4 +139,6 @@ you can manage the service using the following command:
|
||||
|
||||
[ports]: https://www.freshports.org/net/sing-box
|
||||
|
||||
[aosc]: https://packages.aosc.io/packages/sing-box
|
||||
|
||||
[systemd]: https://systemd.io/
|
||||
|
||||
@@ -24,14 +24,7 @@ icon: material/package
|
||||
sudo dnf config-manager --add-repo https://sing-box.app/sing-box.repo
|
||||
sudo dnf install sing-box # or sing-box-beta
|
||||
```
|
||||
|
||||
=== ":material-redhat: CentOS / YUM"
|
||||
|
||||
```bash
|
||||
sudo yum install -y yum-utils
|
||||
sudo yum-config-manager --add-repo https://sing-box.app/sing-box.repo
|
||||
sudo yum install sing-box # or sing-box-beta
|
||||
```
|
||||
(这适用于任何使用 `dnf` 作为包管理器的发行版:Fedora、CentOS,甚至安装了 DNF 的 OpenSUSE。)
|
||||
|
||||
## :material-download-box: 手动安装
|
||||
|
||||
@@ -46,6 +39,7 @@ icon: material/package
|
||||
```bash
|
||||
bash <(curl -fsSL https://sing-box.app/rpm-install.sh)
|
||||
```
|
||||
(这适用于任何使用 `rpm` 和 `systemd` 的发行版。由于 `rpm` 定义依赖关系的方式,如果安装成功,就多半能用。)
|
||||
|
||||
=== ":simple-archlinux: Archlinux / PKG"
|
||||
|
||||
@@ -63,6 +57,7 @@ icon: material/package
|
||||
| nixpkgs | NixOS | `nix-env -iA nixos.sing-box` | [][nixpkgs] |
|
||||
| Homebrew | macOS / Linux | `brew install sing-box` | [][brew] |
|
||||
| APK | Alpine | `apk add sing-box` | [][alpine] |
|
||||
| DEB | AOSC | `apt install sing-box` | [][aosc] |
|
||||
|
||||
=== ":material-apple: macOS"
|
||||
|
||||
@@ -90,6 +85,21 @@ icon: material/package
|
||||
|------------|---------|------------------------|--------------------------------------------------------------------------------------------|
|
||||
| FreshPorts | FreeBSD | `pkg install sing-box` | [][ports] |
|
||||
|
||||
|
||||
## :material-alert: 存在问题的源
|
||||
|
||||
| 类型 | 平台 | 链接 | 原因 |
|
||||
|------------|---------|-------------------------------------------------------------------------------------------|-----------------------|
|
||||
| DEB | AOSC | [aosc-os-abbs](https://github.com/AOSC-Dev/aosc-os-abbs/tree/stable/app-network/sing-box) | 存在问题的构建标志列表修改; 没有活跃维护 |
|
||||
| Homebrew | / | [homebrew-core][brew] | 存在问题的构建标志列表修改 |
|
||||
| Termux | Android | [termux-packages][termux] | 存在问题的构建标志列表修改 |
|
||||
| FreshPorts | FreeBSD | [FreeBSD ports][ports] | 太旧的 Go (go1.20) |
|
||||
|
||||
如果您是其用户,请向他们报告问题:
|
||||
|
||||
1. 在未完全了解相关功能的情况下,请勿修改发布版本标签:启用非默认标签可能会导致性能下降;缺少默认标签可能会引起用户混淆。
|
||||
2. sing-box 支持使用一些较旧的 Go 版本进行编译,但不推荐使用(特别是已不再受 Go 支持的版本)。
|
||||
|
||||
## :material-book-multiple: 服务管理
|
||||
|
||||
对于带有 [systemd][systemd] 的 Linux 系统,通常安装已经包含 sing-box 服务,
|
||||
@@ -124,4 +134,6 @@ icon: material/package
|
||||
|
||||
[ports]: https://www.freshports.org/net/sing-box
|
||||
|
||||
[aosc]: https://packages.aosc.io/packages/sing-box
|
||||
|
||||
[systemd]: https://systemd.io/
|
||||
|
||||
@@ -4,16 +4,17 @@ icon: material/lightning-bolt
|
||||
|
||||
# Hysteria 2
|
||||
|
||||
The most popular Chinese-made simple protocol based on QUIC, the selling point is Brutal,
|
||||
a congestion control algorithm that can resist packet loss by manually specifying the required rate by the user.
|
||||
Hysteria 2 is a simple, Chinese-made protocol based on QUIC.
|
||||
The selling point is Brutal, a congestion control algorithm that
|
||||
tries to achieve a user-defined bandwidth despite packet loss.
|
||||
|
||||
!!! warning
|
||||
|
||||
Even though GFW rarely blocks UDP-based proxies, such protocols actually have far more characteristics than TCP based proxies.
|
||||
Even though GFW rarely blocks UDP-based proxies, such protocols actually have far more obvious characteristics than TCP based proxies.
|
||||
|
||||
| Specification | Binary Characteristics | Active Detect Hiddenness |
|
||||
|---------------------------------------------------------------------------|------------------------|--------------------------|
|
||||
| [hysteria.network](https://v2.hysteria.network/docs/developers/Protocol/) | :material-alert: | :material-check: |
|
||||
| Specification | Resists passive detection | Resists active probes |
|
||||
|---------------------------------------------------------------------------|---------------------------|-----------------------|
|
||||
| [hysteria.network](https://v2.hysteria.network/docs/developers/Protocol/) | :material-alert: | :material-check: |
|
||||
|
||||
## :material-text-box-check: Password Generator
|
||||
|
||||
@@ -44,7 +45,7 @@ To use sing-box with the official program, you need to fill in that combination
|
||||
Replace `up_mbps` and `down_mbps` values with the actual bandwidth of your server.
|
||||
|
||||
=== ":material-harddisk: With local certificate"
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"inbounds": [
|
||||
|
||||
@@ -4,15 +4,18 @@ icon: material/send
|
||||
|
||||
# Shadowsocks
|
||||
|
||||
As the most well-known Chinese-made proxy protocol,
|
||||
Shadowsocks exists in multiple versions,
|
||||
but only AEAD 2022 ciphers TCP with multiplexing is recommended.
|
||||
Shadowsocks is the most well-known Chinese-made proxy protocol.
|
||||
It exists in multiple versions, but only AEAD 2022 ciphers
|
||||
over TCP with multiplexing is recommended.
|
||||
|
||||
| Ciphers | Specification | Cryptographic Security | Binary Characteristics | Active Detect Hiddenness |
|
||||
|----------------|------------------------------------------------------------|------------------------|------------------------|--------------------------|
|
||||
| Stream Ciphers | [shadowsocks.org](https://shadowsocks.org/doc/stream.html) | :material-alert: | :material-alert: | :material-alert: |
|
||||
| AEAD | [shadowsocks.org](https://shadowsocks.org/doc/aead.html) | :material-check: | :material-alert: | :material-alert: |
|
||||
| AEAD 2022 | [shadowsocks.org](https://shadowsocks.org/doc/sip022.html) | :material-check: | :material-check: | :material-help: |
|
||||
| Ciphers | Specification | Cryptographically sound | Resists passive detection | Resists active probes |
|
||||
|----------------|------------------------------------------------------------|-------------------------|---------------------------|-----------------------|
|
||||
| Stream Ciphers | [shadowsocks.org](https://shadowsocks.org/doc/stream.html) | :material-alert: | :material-alert: | :material-alert: |
|
||||
| AEAD | [shadowsocks.org](https://shadowsocks.org/doc/aead.html) | :material-check: | :material-alert: | :material-alert: |
|
||||
| AEAD 2022 | [shadowsocks.org](https://shadowsocks.org/doc/sip022.html) | :material-check: | :material-check: | :material-help: |
|
||||
|
||||
(We strongly recommend using multiplexing to send UDP traffic over TCP, because
|
||||
doing otherwise is vulnerable to passive detection.)
|
||||
|
||||
## :material-text-box-check: Password Generator
|
||||
|
||||
|
||||
@@ -4,15 +4,15 @@ icon: material/horse
|
||||
|
||||
# Trojan
|
||||
|
||||
As the most commonly used TLS proxy made in China, Trojan can be used in various combinations,
|
||||
Torjan is the most commonly used TLS proxy made in China. It can be used in various combinations,
|
||||
but only the combination of uTLS and multiplexing is recommended.
|
||||
|
||||
| Protocol and implementation combination | Specification | Binary Characteristics | Active Detect Hiddenness |
|
||||
|-----------------------------------------|----------------------------------------------------------------------|------------------------|--------------------------|
|
||||
| Origin / trojan-gfw | [trojan-gfw.github.io](https://trojan-gfw.github.io/trojan/protocol) | :material-check: | :material-check: |
|
||||
| Basic Go implementation | / | :material-alert: | :material-check: |
|
||||
| with privates transport by V2Ray | No formal definition | :material-alert: | :material-alert: |
|
||||
| with uTLS enabled | No formal definition | :material-help: | :material-check: |
|
||||
| Protocol and implementation combination | Specification | Resists passive detection | Resists active probes |
|
||||
|-----------------------------------------|----------------------------------------------------------------------|---------------------------|-----------------------|
|
||||
| Origin / trojan-gfw | [trojan-gfw.github.io](https://trojan-gfw.github.io/trojan/protocol) | :material-check: | :material-check: |
|
||||
| Basic Go implementation | / | :material-alert: | :material-check: |
|
||||
| with privates transport by V2Ray | No formal definition | :material-alert: | :material-alert: |
|
||||
| with uTLS enabled | No formal definition | :material-help: | :material-check: |
|
||||
|
||||
## :material-text-box-check: Password Generator
|
||||
|
||||
@@ -211,4 +211,3 @@ but only the combination of uTLS and multiplexing is recommended.
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -70,6 +70,23 @@ Old fields are deprecated and will be removed in sing-box 1.11.0.
|
||||
}
|
||||
```
|
||||
|
||||
## 1.9.5
|
||||
|
||||
### Bundle Identifier updates in Apple platform clients
|
||||
|
||||
Due to problems with our old Apple developer account,
|
||||
we can only change Bundle Identifiers to re-list sing-box apps,
|
||||
which means the data will not be automatically inherited.
|
||||
|
||||
For iOS, you need to back up your old data yourself (if you still have access to it);
|
||||
for tvOS, you need to re-import profiles from your iPhone or iPad or create it manually;
|
||||
for macOS, you can migrate the data folder using the following command:
|
||||
|
||||
```bash
|
||||
cd ~/Library/Group\ Containers && \
|
||||
mv group.io.nekohasekai.sfa group.io.nekohasekai.sfavt
|
||||
```
|
||||
|
||||
## 1.9.0
|
||||
|
||||
### `domain_suffix` behavior update
|
||||
|
||||
@@ -70,6 +70,22 @@ icon: material/arrange-bring-forward
|
||||
}
|
||||
```
|
||||
|
||||
## 1.9.5
|
||||
|
||||
### Apple 平台客户端的 Bundle Identifier 更新
|
||||
|
||||
由于我们旧的苹果开发者账户存在问题,我们只能通过更新 Bundle Identifiers
|
||||
来重新上架 sing-box 应用, 这意味着数据不会自动继承。
|
||||
|
||||
对于 iOS,您需要自行备份旧的数据(如果您仍然可以访问);
|
||||
对于 Apple tvOS,您需要从 iPhone 或 iPad 重新导入配置或者手动创建;
|
||||
对于 macOS,您可以使用以下命令迁移数据文件夹:
|
||||
|
||||
```bash
|
||||
cd ~/Library/Group\ Containers && \
|
||||
mv group.io.nekohasekai.sfa group.io.nekohasekai.sfavt
|
||||
```
|
||||
|
||||
## 1.9.0
|
||||
|
||||
### `domain_suffix` 行为更新
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
icon: material/hand-coin
|
||||
---
|
||||
|
||||
# Sponsors
|
||||
|
||||
Do you or your friends use sing-box?
|
||||
|
||||
You can help keep the project bug-free and feature rich by sponsoring
|
||||
the project maintainer via [GitHub Sponsors](https://github.com/sponsors/nekohasekai).
|
||||
|
||||

|
||||
|
||||
### Special Sponsors
|
||||
|
||||
**Viral Tech, Inc.**
|
||||
|
||||
Helping us re-list sing-box apps on the Apple Store.
|
||||
|
||||
---
|
||||
|
||||
[](https://www.jetbrains.com)
|
||||
|
||||
Free license for the amazing IDEs.
|
||||
|
||||
---
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/cors"
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/urltest"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
@@ -29,7 +30,6 @@ import (
|
||||
"github.com/sagernet/ws/wsutil"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/cors"
|
||||
"github.com/go-chi/render"
|
||||
)
|
||||
|
||||
@@ -90,11 +90,16 @@ func NewServer(ctx context.Context, router adapter.Router, logFactory log.Observ
|
||||
if options.StoreMode || options.StoreSelected || options.StoreFakeIP || options.CacheFile != "" || options.CacheID != "" {
|
||||
return nil, E.New("cache_file and related fields in Clash API is deprecated in sing-box 1.8.0, use experimental.cache_file instead.")
|
||||
}
|
||||
allowedOrigins := options.AccessControlAllowOrigin
|
||||
if len(allowedOrigins) == 0 {
|
||||
allowedOrigins = []string{"*"}
|
||||
}
|
||||
cors := cors.New(cors.Options{
|
||||
AllowedOrigins: []string{"*"},
|
||||
AllowedMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE"},
|
||||
AllowedHeaders: []string{"Content-Type", "Authorization"},
|
||||
MaxAge: 300,
|
||||
AllowedOrigins: allowedOrigins,
|
||||
AllowedMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE"},
|
||||
AllowedHeaders: []string{"Content-Type", "Authorization"},
|
||||
AllowPrivateNetwork: options.AccessControlAllowPrivateNetwork,
|
||||
MaxAge: 300,
|
||||
})
|
||||
chiRouter.Use(cors.Handler)
|
||||
chiRouter.Group(func(r chi.Router) {
|
||||
@@ -277,10 +282,11 @@ func authentication(serverSecret string) func(next http.Handler) http.Handler {
|
||||
|
||||
func hello(redirect bool) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if redirect {
|
||||
http.Redirect(w, r, "/ui/", http.StatusTemporaryRedirect)
|
||||
} else {
|
||||
contentType := r.Header.Get("Content-Type")
|
||||
if !redirect || contentType == "application/json" {
|
||||
render.JSON(w, r, render.M{"hello": "clash"})
|
||||
} else {
|
||||
http.Redirect(w, r, "/ui/", http.StatusTemporaryRedirect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,35 +8,35 @@ require (
|
||||
github.com/cloudflare/circl v1.3.7
|
||||
github.com/cretz/bine v0.2.0
|
||||
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.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
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||
github.com/metacubex/tfo-go v0.0.0-20240821025650-e9be0afd5e7d
|
||||
github.com/mholt/acmez v1.2.0
|
||||
github.com/miekg/dns v1.1.61
|
||||
github.com/ooni/go-libtor v1.1.8
|
||||
github.com/oschwald/maxminddb-golang v1.12.0
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1
|
||||
github.com/sagernet/cors v1.2.1
|
||||
github.com/sagernet/fswatch v0.1.1
|
||||
github.com/sagernet/gomobile v0.1.3
|
||||
github.com/sagernet/gomobile v0.1.4
|
||||
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f
|
||||
github.com/sagernet/quic-go v0.46.0-beta.4
|
||||
github.com/sagernet/quic-go v0.47.0-beta.2
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
|
||||
github.com/sagernet/sing v0.5.0-beta.1
|
||||
github.com/sagernet/sing v0.5.0-beta.2
|
||||
github.com/sagernet/sing-dns v0.3.0-beta.14
|
||||
github.com/sagernet/sing-mux v0.2.0
|
||||
github.com/sagernet/sing-quic v0.3.0-beta.2
|
||||
github.com/sagernet/sing-quic v0.3.0-beta.3
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0
|
||||
github.com/sagernet/sing-shadowtls v0.1.4
|
||||
github.com/sagernet/sing-tun v0.4.0-beta.13.0.20240703164908-1f043289199d
|
||||
github.com/sagernet/sing-tun v0.4.0-beta.16
|
||||
github.com/sagernet/sing-vmess v0.1.12
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7
|
||||
github.com/sagernet/tfo-go v0.0.0-20231209031829-7b5343ac1dc6
|
||||
github.com/sagernet/utls v1.5.4
|
||||
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8
|
||||
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854
|
||||
@@ -47,7 +47,7 @@ require (
|
||||
golang.org/x/crypto v0.25.0
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
|
||||
golang.org/x/net v0.27.0
|
||||
golang.org/x/sys v0.22.0
|
||||
golang.org/x/sys v0.25.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
|
||||
@@ -91,8 +91,8 @@ require (
|
||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/mod v0.19.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/text v0.18.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.23.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
|
||||
@@ -21,8 +21,6 @@ github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXb
|
||||
github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
|
||||
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
|
||||
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
|
||||
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
@@ -74,6 +72,8 @@ github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/
|
||||
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
|
||||
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
|
||||
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
|
||||
github.com/metacubex/tfo-go v0.0.0-20240821025650-e9be0afd5e7d h1:j9LtzkYstLFoNvXW824QQeN7Y26uPL5249kzWKbzO9U=
|
||||
github.com/metacubex/tfo-go v0.0.0-20240821025650-e9be0afd5e7d/go.mod h1:c7bVFM9f5+VzeZ/6Kg77T/jrg1Xp8QpqlSHvG/aXVts=
|
||||
github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
|
||||
github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
|
||||
github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
|
||||
@@ -100,43 +100,43 @@ github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a h1:+NkI2670SQpQWvkk
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM=
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1 h1:YbmpqPQEMdlk9oFSKYWRqVuu9qzNiOayIonKmv1gCXY=
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1/go.mod h1:J2yAxTFPDjrDPhuAi9aWFz2L3ox9it4qAluBBbN0H5k=
|
||||
github.com/sagernet/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ=
|
||||
github.com/sagernet/cors v1.2.1/go.mod h1:O64VyOjjhrkLmQIjF4KGRrJO/5dVXFdpEmCW/eISRAI=
|
||||
github.com/sagernet/fswatch v0.1.1 h1:YqID+93B7VRfqIH3PArW/XpJv5H4OLEVWDfProGoRQs=
|
||||
github.com/sagernet/fswatch v0.1.1/go.mod h1:nz85laH0mkQqJfaOrqPpkwtU1znMFNVTpT/5oRsVz/o=
|
||||
github.com/sagernet/gomobile v0.1.3 h1:ohjIb1Ou2+1558PnZour3od69suSuvkdSVOlO1tC4B8=
|
||||
github.com/sagernet/gomobile v0.1.3/go.mod h1:Pqq2+ZVvs10U7xK+UwJgwYWUykewi8H6vlslAO73n9E=
|
||||
github.com/sagernet/gomobile v0.1.4 h1:WzX9ka+iHdupMgy2Vdich+OAt7TM8C2cZbIbzNjBrJY=
|
||||
github.com/sagernet/gomobile v0.1.4/go.mod h1:Pqq2+ZVvs10U7xK+UwJgwYWUykewi8H6vlslAO73n9E=
|
||||
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f h1:NkhuupzH5ch7b/Y/6ZHJWrnNLoiNnSJaow6DPb8VW2I=
|
||||
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f/go.mod h1:KXmw+ouSJNOsuRpg4wgwwCQuunrGz4yoAqQjsLjc6N0=
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis=
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||
github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=
|
||||
github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8=
|
||||
github.com/sagernet/quic-go v0.46.0-beta.4 h1:k9f7VSKaM47AY6MPND0Qf1KRN7HwimPg9zdOFTXTiCk=
|
||||
github.com/sagernet/quic-go v0.46.0-beta.4/go.mod h1:zJmVdJUNqEDXfubf4KtIOUHHerggjBduiGRLNzJspcM=
|
||||
github.com/sagernet/quic-go v0.47.0-beta.2 h1:1tCGWFOSaXIeuQaHrwOMJIYvlupjTcaVInGQw5ArULU=
|
||||
github.com/sagernet/quic-go v0.47.0-beta.2/go.mod h1:bLVKvElSEMNv7pu7SZHscW02TYigzQ5lQu3Nh4wNh8Q=
|
||||
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.5.0-beta.1 h1:THZMZgJcDQxutE++6Ckih1HlvMtXple94RBGa6GSg2I=
|
||||
github.com/sagernet/sing v0.5.0-beta.1/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing v0.5.0-beta.2 h1:V12EpwtsgYo5OLGjAiGoJobDJZeUsKv0b5y+yGAM6W0=
|
||||
github.com/sagernet/sing v0.5.0-beta.2/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing-dns v0.3.0-beta.14 h1:/s+fJzYKsvLaNDt/2rjpsrDcN8wmCO2JbX6OFrl8Nww=
|
||||
github.com/sagernet/sing-dns v0.3.0-beta.14/go.mod h1:rscgSr5ixOPk8XM9ZMLuMXCyldEQ1nLvdl0nfv+lp00=
|
||||
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.3.0-beta.2 h1:9TiaW4js4fXD6GPCGMbwb3/bIRKpXm7skJBdV1OdvMs=
|
||||
github.com/sagernet/sing-quic v0.3.0-beta.2/go.mod h1:YLV1dUDv8Eyp/8e55O/EvfsrwxOgEDVgDCIoPqmDREE=
|
||||
github.com/sagernet/sing-quic v0.3.0-beta.3 h1:8S98VXZxtSiOqVCFbCNbMEvKDPhOF/VNBYMjVC3xMhw=
|
||||
github.com/sagernet/sing-quic v0.3.0-beta.3/go.mod h1:rFPUlYnSj1Bx9gFSghjCqrCzfGvpjhkisOiTKpjq5vQ=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
|
||||
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.4.0-beta.13.0.20240703164908-1f043289199d h1:2nBM9W9fOCM45hjlu1Fh9qyzBCgKEkq+SOuRCbCCs7c=
|
||||
github.com/sagernet/sing-tun v0.4.0-beta.13.0.20240703164908-1f043289199d/go.mod h1:81JwnnYw8X9W9XvmZetSTTiPgIE3SbAbnc+EHKwPJ5U=
|
||||
github.com/sagernet/sing-tun v0.4.0-beta.16 h1:05VdL5BZiKLQsDNrpdXMseSO1NwPfl9Y4o76PqAd9sY=
|
||||
github.com/sagernet/sing-tun v0.4.0-beta.16/go.mod h1:81JwnnYw8X9W9XvmZetSTTiPgIE3SbAbnc+EHKwPJ5U=
|
||||
github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg=
|
||||
github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I=
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo=
|
||||
github.com/sagernet/tfo-go v0.0.0-20231209031829-7b5343ac1dc6 h1:z3SJQhVyU63FT26Wn/UByW6b7q8QKB0ZkPqsyqcz2PI=
|
||||
github.com/sagernet/tfo-go v0.0.0-20231209031829-7b5343ac1dc6/go.mod h1:73xRZuxwkFk4aiLw28hG8W6o9cr2UPrGL9pdY2UTbvY=
|
||||
github.com/sagernet/utls v1.5.4 h1:KmsEGbB2dKUtCNC+44NwAdNAqnqQ6GA4pTO0Yik56co=
|
||||
github.com/sagernet/utls v1.5.4/go.mod h1:CTGxPWExIloRipK3XFpYv0OVyhO8kk3XCGW/ieyTh1s=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8 h1:R0OMYAScomNAVpTfbHFpxqJpvwuhxSRi+g6z7gZhABs=
|
||||
@@ -182,8 +182,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -192,14 +192,14 @@ 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.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.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.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
||||
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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
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=
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"github.com/sagernet/tfo-go"
|
||||
"github.com/metacubex/tfo-go"
|
||||
)
|
||||
|
||||
const go120Available = true
|
||||
|
||||
@@ -44,6 +44,7 @@ nav:
|
||||
- Migration: migration.md
|
||||
- Deprecated: deprecated.md
|
||||
- Support: support.md
|
||||
- Sponsors: sponsors.md
|
||||
- Installation:
|
||||
- Package Manager: installation/package-manager.md
|
||||
- Docker: installation/docker.md
|
||||
|
||||
@@ -17,13 +17,15 @@ type CacheFileOptions struct {
|
||||
}
|
||||
|
||||
type ClashAPIOptions struct {
|
||||
ExternalController string `json:"external_controller,omitempty"`
|
||||
ExternalUI string `json:"external_ui,omitempty"`
|
||||
ExternalUIDownloadURL string `json:"external_ui_download_url,omitempty"`
|
||||
ExternalUIDownloadDetour string `json:"external_ui_download_detour,omitempty"`
|
||||
Secret string `json:"secret,omitempty"`
|
||||
DefaultMode string `json:"default_mode,omitempty"`
|
||||
ModeList []string `json:"-"`
|
||||
ExternalController string `json:"external_controller,omitempty"`
|
||||
ExternalUI string `json:"external_ui,omitempty"`
|
||||
ExternalUIDownloadURL string `json:"external_ui_download_url,omitempty"`
|
||||
ExternalUIDownloadDetour string `json:"external_ui_download_detour,omitempty"`
|
||||
Secret string `json:"secret,omitempty"`
|
||||
DefaultMode string `json:"default_mode,omitempty"`
|
||||
ModeList []string `json:"-"`
|
||||
AccessControlAllowOrigin Listable[string] `json:"access_control_allow_origin,omitempty"`
|
||||
AccessControlAllowPrivateNetwork bool `json:"access_control_allow_private_network,omitempty"`
|
||||
|
||||
// Deprecated: migrated to global cache file
|
||||
CacheFile string `json:"cache_file,omitempty"`
|
||||
|
||||
+2
-2
@@ -14,9 +14,9 @@ import (
|
||||
)
|
||||
|
||||
type _RuleSet struct {
|
||||
Type string `json:"type"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Tag string `json:"tag"`
|
||||
Format string `json:"format"`
|
||||
Format string `json:"format,omitempty"`
|
||||
InlineOptions PlainRuleSet `json:"-"`
|
||||
LocalOptions LocalRuleSet `json:"-"`
|
||||
RemoteOptions RemoteRuleSet `json:"-"`
|
||||
|
||||
@@ -152,6 +152,10 @@ func (w *WireGuard) start() error {
|
||||
}
|
||||
bind = wireguard.NewClientBind(w.ctx, w, w.listener, isConnect, connectAddr, reserved)
|
||||
}
|
||||
err = w.tunDevice.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wgDevice := device.NewDevice(w.tunDevice, bind, &device.Logger{
|
||||
Verbosef: func(format string, args ...interface{}) {
|
||||
w.logger.Debug(fmt.Sprintf(strings.ToLower(format), args...))
|
||||
@@ -170,7 +174,7 @@ func (w *WireGuard) start() error {
|
||||
}
|
||||
w.device = wgDevice
|
||||
w.pauseCallback = w.pauseManager.RegisterCallback(w.onPauseUpdated)
|
||||
return w.tunDevice.Start()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *WireGuard) Close() error {
|
||||
@@ -180,7 +184,6 @@ func (w *WireGuard) Close() error {
|
||||
if w.pauseCallback != nil {
|
||||
w.pauseManager.UnregisterCallback(w.pauseCallback)
|
||||
}
|
||||
w.tunDevice.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -852,7 +852,7 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
|
||||
conn = deadline.NewConn(conn)
|
||||
}
|
||||
|
||||
if metadata.InboundOptions.SniffEnabled {
|
||||
if metadata.InboundOptions.SniffEnabled && !sniff.Skip(metadata) {
|
||||
buffer := buf.NewPacket()
|
||||
err := sniff.PeekStream(
|
||||
ctx,
|
||||
@@ -860,9 +860,10 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
|
||||
conn,
|
||||
buffer,
|
||||
time.Duration(metadata.InboundOptions.SniffTimeout),
|
||||
sniff.StreamDomainNameQuery,
|
||||
sniff.TLSClientHello,
|
||||
sniff.HTTPHost,
|
||||
sniff.StreamDomainNameQuery,
|
||||
sniff.SSH,
|
||||
sniff.BitTorrent,
|
||||
)
|
||||
if err == nil {
|
||||
@@ -1055,7 +1056,9 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
|
||||
}
|
||||
}
|
||||
}
|
||||
conn = bufio.NewCachedPacketConn(conn, buffer, destination)
|
||||
if err == nil {
|
||||
conn = bufio.NewCachedPacketConn(conn, buffer, destination)
|
||||
}
|
||||
for _, cachedBuffer := range common.Reverse(bufferList) {
|
||||
conn = bufio.NewCachedPacketConn(conn, cachedBuffer, destination)
|
||||
}
|
||||
|
||||
@@ -189,6 +189,9 @@ func (r *Router) Lookup(ctx context.Context, domain string, strategy dns.DomainS
|
||||
)
|
||||
responseAddrs, cached = r.dnsClient.LookupCache(ctx, domain, strategy)
|
||||
if cached {
|
||||
if len(responseAddrs) == 0 {
|
||||
return nil, dns.RCodeNameError
|
||||
}
|
||||
return responseAddrs, nil
|
||||
}
|
||||
r.dnsLogger.DebugContext(ctx, "lookup domain ", domain)
|
||||
|
||||
@@ -230,17 +230,13 @@ func (w *StackDevice) Events() <-chan wgTun.Event {
|
||||
}
|
||||
|
||||
func (w *StackDevice) Close() error {
|
||||
select {
|
||||
case <-w.done:
|
||||
return os.ErrClosed
|
||||
default:
|
||||
}
|
||||
close(w.done)
|
||||
close(w.events)
|
||||
w.stack.Close()
|
||||
for _, endpoint := range w.stack.CleanupEndpoints() {
|
||||
endpoint.Abort()
|
||||
}
|
||||
w.stack.Wait()
|
||||
close(w.done)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/dialer"
|
||||
@@ -21,14 +22,16 @@ import (
|
||||
var _ Device = (*SystemDevice)(nil)
|
||||
|
||||
type SystemDevice struct {
|
||||
dialer N.Dialer
|
||||
device tun.Tun
|
||||
batchDevice tun.LinuxTUN
|
||||
name string
|
||||
mtu int
|
||||
events chan wgTun.Event
|
||||
addr4 netip.Addr
|
||||
addr6 netip.Addr
|
||||
dialer N.Dialer
|
||||
device tun.Tun
|
||||
batchDevice tun.LinuxTUN
|
||||
name string
|
||||
mtu uint32
|
||||
inet4Addresses []netip.Prefix
|
||||
inet6Addresses []netip.Prefix
|
||||
gso bool
|
||||
events chan wgTun.Event
|
||||
closeOnce sync.Once
|
||||
}
|
||||
|
||||
func NewSystemDevice(router adapter.Router, interfaceName string, localPrefixes []netip.Prefix, mtu uint32, gso bool) (*SystemDevice, error) {
|
||||
@@ -44,43 +47,17 @@ func NewSystemDevice(router adapter.Router, interfaceName string, localPrefixes
|
||||
if interfaceName == "" {
|
||||
interfaceName = tun.CalculateInterfaceName("wg")
|
||||
}
|
||||
tunInterface, err := tun.New(tun.Options{
|
||||
Name: interfaceName,
|
||||
Inet4Address: inet4Addresses,
|
||||
Inet6Address: inet6Addresses,
|
||||
MTU: mtu,
|
||||
GSO: gso,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var inet4Address netip.Addr
|
||||
var inet6Address netip.Addr
|
||||
if len(inet4Addresses) > 0 {
|
||||
inet4Address = inet4Addresses[0].Addr()
|
||||
}
|
||||
if len(inet6Addresses) > 0 {
|
||||
inet6Address = inet6Addresses[0].Addr()
|
||||
}
|
||||
var batchDevice tun.LinuxTUN
|
||||
if gso {
|
||||
batchTUN, isBatchTUN := tunInterface.(tun.LinuxTUN)
|
||||
if !isBatchTUN {
|
||||
return nil, E.New("GSO is not supported on current platform")
|
||||
}
|
||||
batchDevice = batchTUN
|
||||
}
|
||||
|
||||
return &SystemDevice{
|
||||
dialer: common.Must1(dialer.NewDefault(router, option.DialerOptions{
|
||||
BindInterface: interfaceName,
|
||||
})),
|
||||
device: tunInterface,
|
||||
batchDevice: batchDevice,
|
||||
name: interfaceName,
|
||||
mtu: int(mtu),
|
||||
events: make(chan wgTun.Event),
|
||||
addr4: inet4Address,
|
||||
addr6: inet6Address,
|
||||
name: interfaceName,
|
||||
mtu: mtu,
|
||||
inet4Addresses: inet4Addresses,
|
||||
inet6Addresses: inet6Addresses,
|
||||
gso: gso,
|
||||
events: make(chan wgTun.Event),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -93,14 +70,39 @@ func (w *SystemDevice) ListenPacket(ctx context.Context, destination M.Socksaddr
|
||||
}
|
||||
|
||||
func (w *SystemDevice) Inet4Address() netip.Addr {
|
||||
return w.addr4
|
||||
if len(w.inet4Addresses) == 0 {
|
||||
return netip.Addr{}
|
||||
}
|
||||
return w.inet4Addresses[0].Addr()
|
||||
}
|
||||
|
||||
func (w *SystemDevice) Inet6Address() netip.Addr {
|
||||
return w.addr6
|
||||
if len(w.inet6Addresses) == 0 {
|
||||
return netip.Addr{}
|
||||
}
|
||||
return w.inet6Addresses[0].Addr()
|
||||
}
|
||||
|
||||
func (w *SystemDevice) Start() error {
|
||||
tunInterface, err := tun.New(tun.Options{
|
||||
Name: w.name,
|
||||
Inet4Address: w.inet4Addresses,
|
||||
Inet6Address: w.inet6Addresses,
|
||||
MTU: w.mtu,
|
||||
GSO: w.gso,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.device = tunInterface
|
||||
if w.gso {
|
||||
batchTUN, isBatchTUN := tunInterface.(tun.LinuxTUN)
|
||||
if !isBatchTUN {
|
||||
tunInterface.Close()
|
||||
return E.New("GSO is not supported on current platform")
|
||||
}
|
||||
w.batchDevice = batchTUN
|
||||
}
|
||||
w.events <- wgTun.EventUp
|
||||
return nil
|
||||
}
|
||||
@@ -143,7 +145,7 @@ func (w *SystemDevice) Flush() error {
|
||||
}
|
||||
|
||||
func (w *SystemDevice) MTU() (int, error) {
|
||||
return w.mtu, nil
|
||||
return int(w.mtu), nil
|
||||
}
|
||||
|
||||
func (w *SystemDevice) Name() (string, error) {
|
||||
@@ -155,6 +157,7 @@ func (w *SystemDevice) Events() <-chan wgTun.Event {
|
||||
}
|
||||
|
||||
func (w *SystemDevice) Close() error {
|
||||
close(w.events)
|
||||
return w.device.Close()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user