mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-08-25 19:47:35 +08:00
Compare commits
110 Commits
e8be848b6f
...
b7a622cac0
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b7a622cac0 | ||
![]() |
a7d14d4044 | ||
![]() |
8802c88243 | ||
![]() |
182d85269d | ||
![]() |
1da72a6532 | ||
![]() |
16e05be1be | ||
![]() |
259a140453 | ||
![]() |
54760eeaaa | ||
![]() |
a870c36d2d | ||
![]() |
1054f58751 | ||
![]() |
6981dfe0c0 | ||
![]() |
719d0d3c31 | ||
![]() |
8f5fad3f9d | ||
![]() |
c2e9c30efc | ||
![]() |
3da06f0db8 | ||
![]() |
acb5065198 | ||
![]() |
c6a7d8c587 | ||
![]() |
a9ff1cbf78 | ||
![]() |
94e0d6b4ab | ||
![]() |
93c866a900 | ||
![]() |
40451f8957 | ||
![]() |
2a2ca1bef6 | ||
![]() |
e156abb0ab | ||
![]() |
94d70a2a97 | ||
![]() |
4b2cda1c76 | ||
![]() |
6e8e007352 | ||
![]() |
d18a35c414 | ||
![]() |
ea31ebb2a3 | ||
![]() |
0951711c08 | ||
![]() |
fdd8d3e23e | ||
![]() |
53feae6a6e | ||
![]() |
b63eba13ef | ||
![]() |
a2c52fb21b | ||
![]() |
01d06c0d29 | ||
![]() |
01b11f3d4e | ||
![]() |
567c98dc9e | ||
![]() |
f8a64a6554 | ||
![]() |
5dd021e979 | ||
![]() |
a3f9196fdc | ||
![]() |
42102b3fc4 | ||
![]() |
c0e5fe78ab | ||
![]() |
ad7bb47bf6 | ||
![]() |
58779f99ce | ||
![]() |
b14782771b | ||
![]() |
51816e0cd2 | ||
![]() |
0b7ea0c6c6 | ||
![]() |
cac33150d8 | ||
![]() |
31bd6bb5cb | ||
![]() |
7f26d21a28 | ||
![]() |
14a8e87e2f | ||
![]() |
38e3766c33 | ||
![]() |
1be391470a | ||
![]() |
560f567881 | ||
![]() |
53dfdd1ec6 | ||
![]() |
69fe3b16f1 | ||
![]() |
85d80deec8 | ||
![]() |
2570b11ea4 | ||
![]() |
d4d1ea7129 | ||
![]() |
5852b5ba94 | ||
![]() |
655674bb9b | ||
![]() |
a55d597212 | ||
![]() |
183aed8253 | ||
![]() |
8f1885bef8 | ||
![]() |
4a13f9828c | ||
![]() |
659b4988ce | ||
![]() |
de1053f2cf | ||
![]() |
f7200c72f2 | ||
![]() |
0febed9b60 | ||
![]() |
ba2ad571d3 | ||
![]() |
36c171aeac | ||
![]() |
76630b474a | ||
![]() |
9a0d4e4ec6 | ||
![]() |
9eaebb970b | ||
![]() |
8f890bcd9a | ||
![]() |
529c0a1e64 | ||
![]() |
00fd52854b | ||
![]() |
043954df8c | ||
![]() |
5acf9344f1 | ||
![]() |
96f96b5b28 | ||
![]() |
2ad59c6bf1 | ||
![]() |
a3bbdaf61e | ||
![]() |
344ee5df43 | ||
![]() |
47c35f5e7a | ||
![]() |
7101407b87 | ||
![]() |
79f84b4333 | ||
![]() |
b9d37ce9f7 | ||
![]() |
e73bb73290 | ||
![]() |
f1623edb5a | ||
![]() |
f42aba5d46 | ||
![]() |
67d934a301 | ||
![]() |
9fbbc0a74e | ||
![]() |
ec0c882efe | ||
![]() |
167a674b8c | ||
![]() |
8df3f470a0 | ||
![]() |
e338c88a5d | ||
![]() |
4b28d626b5 | ||
![]() |
aa9bceecb2 | ||
![]() |
f10bce28a3 | ||
![]() |
7d4f76abea | ||
![]() |
9e27c304b9 | ||
![]() |
b2cb1a39a6 | ||
![]() |
0b790fbabe | ||
![]() |
56e6653c6e | ||
![]() |
5738174060 | ||
![]() |
909893afa9 | ||
![]() |
efdf801332 | ||
![]() |
88fa375f7e | ||
![]() |
f7797e9d34 | ||
![]() |
fb7a7239fd | ||
![]() |
bca97c10a4 |
79
.github/workflows/build.yml
vendored
79
.github/workflows/build.yml
vendored
@ -437,28 +437,24 @@ jobs:
|
||||
platform: ios
|
||||
scheme: SFI
|
||||
destination: 'generic/platform=iOS'
|
||||
archive: build/SFI.xcarchive
|
||||
upload: SFI/Upload.plist
|
||||
- name: macOS
|
||||
if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'macOS' }}
|
||||
platform: macos
|
||||
scheme: SFM
|
||||
destination: 'generic/platform=macOS'
|
||||
archive: build/SFM.xcarchive
|
||||
upload: SFI/Upload.plist
|
||||
- name: tvOS
|
||||
if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'tvOS' }}
|
||||
platform: tvos
|
||||
scheme: SFT
|
||||
destination: 'generic/platform=tvOS'
|
||||
archive: build/SFT.xcarchive
|
||||
upload: SFI/Upload.plist
|
||||
- name: macOS-standalone
|
||||
if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone' }}
|
||||
platform: macos
|
||||
scheme: SFM.System
|
||||
destination: 'generic/platform=macOS'
|
||||
archive: build/SFM.System.xcarchive
|
||||
export: SFM.System/Export.plist
|
||||
export_path: build/SFM.System
|
||||
steps:
|
||||
@ -476,11 +472,11 @@ jobs:
|
||||
- name: Setup Xcode stable
|
||||
if: matrix.if && github.ref == 'refs/heads/main-next'
|
||||
run: |-
|
||||
sudo xcode-select -s /Applications/Xcode_16.4.app
|
||||
sudo xcode-select -s /Applications/Xcode_16.2.app
|
||||
- name: Setup Xcode beta
|
||||
if: matrix.if && github.ref == 'refs/heads/dev-next'
|
||||
run: |-
|
||||
sudo xcode-select -s /Applications/Xcode_16.4.app
|
||||
sudo xcode-select -s /Applications/Xcode_16.2.app
|
||||
- name: Set tag
|
||||
if: matrix.if
|
||||
run: |-
|
||||
@ -543,6 +539,12 @@ jobs:
|
||||
export PATH="$PATH:$(go env GOPATH)/bin"
|
||||
go run ./cmd/internal/build_libbox -target apple -platform ${{ matrix.platform }}
|
||||
mv Libbox.xcframework clients/apple
|
||||
- name: Build library with tailscale
|
||||
if: matrix.if && (matrix.name == 'iOS' || matrix.name == 'tvOS')
|
||||
run: |-
|
||||
export PATH="$PATH:$(go env GOPATH)/bin"
|
||||
go run ./cmd/internal/build_libbox -target apple -platform ${{ matrix.platform }} -tailscale
|
||||
mv Libbox.xcframework clients/apple/Libbox.WithTailscale.xcframework
|
||||
- name: Update macOS version
|
||||
if: matrix.if && matrix.name == 'macOS' && github.event_name == 'workflow_dispatch'
|
||||
run: |-
|
||||
@ -561,18 +563,71 @@ jobs:
|
||||
-scheme "${{ matrix.scheme }}" \
|
||||
-configuration Release \
|
||||
-destination "${{ matrix.destination }}" \
|
||||
-archivePath "${{ matrix.archive }}" \
|
||||
-archivePath "build/${{ matrix.scheme }}.xcarchive" \
|
||||
-allowProvisioningUpdates \
|
||||
-authenticationKeyPath $ASC_KEY_PATH \
|
||||
-authenticationKeyID $ASC_KEY_ID \
|
||||
-authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
|
||||
- name: Build with Tailscale
|
||||
if: matrix.if && (matrix.name == 'iOS' || matrix.name == 'tvOS')
|
||||
run: |-
|
||||
cd clients/apple
|
||||
mv Libbox.xcframework Libbox.WithoutTailscale.xcframework
|
||||
mv Libbox.WithTailscale.xcframework Libbox.xcframework
|
||||
xcodebuild archive \
|
||||
-scheme "${{ matrix.scheme }}" \
|
||||
-configuration Release \
|
||||
-destination "${{ matrix.destination }}" \
|
||||
-archivePath "build/${{ matrix.scheme }}.WithTailscale.xcarchive" \
|
||||
-allowProvisioningUpdates \
|
||||
-authenticationKeyPath $ASC_KEY_PATH \
|
||||
-authenticationKeyID $ASC_KEY_ID \
|
||||
-authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
|
||||
- name: Export IPA
|
||||
if: matrix.if && (matrix.name == 'iOS' || matrix.name == 'tvOS') && github.event_name == 'workflow_dispatch'
|
||||
run: |-
|
||||
pushd clients/apple
|
||||
xcodebuild -exportArchive \
|
||||
-archivePath "build/${{ matrix.scheme }}.xcarchive" \
|
||||
-exportOptionsPlist SFI/Export.plist \
|
||||
-exportPath "build/${{ matrix.scheme }}" \
|
||||
-allowProvisioningUpdates \
|
||||
-authenticationKeyPath $ASC_KEY_PATH \
|
||||
-authenticationKeyID $ASC_KEY_ID \
|
||||
-authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
|
||||
cp build/${{ matrix.scheme }}/sing-box.ipa .
|
||||
popd
|
||||
mkdir -p dist
|
||||
cp clients/apple/sing-box.ipa "dist/${{ matrix.scheme }}-${{ needs.calculate_version.outputs.version }}.ipa"
|
||||
- name: Export IPA with Tailscale
|
||||
if: matrix.if && (matrix.name == 'iOS' || matrix.name == 'tvOS') && github.event_name == 'workflow_dispatch'
|
||||
run: |-
|
||||
pushd clients/apple
|
||||
xcodebuild -exportArchive \
|
||||
-archivePath "build/${{ matrix.scheme }}.WithTailscale.xcarchive" \
|
||||
-exportOptionsPlist SFI/Export.plist \
|
||||
-exportPath "build/${{ matrix.scheme }}.WithTailscale" \
|
||||
-allowProvisioningUpdates \
|
||||
-authenticationKeyPath $ASC_KEY_PATH \
|
||||
-authenticationKeyID $ASC_KEY_ID \
|
||||
-authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
|
||||
cp build/${{ matrix.scheme }}.WithTailscale/sing-box.ipa .
|
||||
popd
|
||||
mkdir -p dist
|
||||
cp clients/apple/sing-box.ipa "dist/${{ matrix.scheme }}-${{ needs.calculate_version.outputs.version }}-WithTailscale.ipa"
|
||||
- name: Upload IPA
|
||||
if: matrix.if && (matrix.name == 'iOS' || matrix.name == 'tvOS') && github.event_name == 'workflow_dispatch'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: binary-${{ matrix.name }}-ipa
|
||||
path: 'dist'
|
||||
- name: Upload to App Store Connect
|
||||
if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch'
|
||||
run: |-
|
||||
go run -v ./cmd/internal/app_store_connect cancel_app_store ${{ matrix.platform }}
|
||||
cd clients/apple
|
||||
xcodebuild -exportArchive \
|
||||
-archivePath "${{ matrix.archive }}" \
|
||||
-archivePath "build/${{ matrix.scheme }}.xcarchive" \
|
||||
-exportOptionsPlist ${{ matrix.upload }} \
|
||||
-allowProvisioningUpdates \
|
||||
-authenticationKeyPath $ASC_KEY_PATH \
|
||||
@ -587,7 +642,7 @@ jobs:
|
||||
run: |-
|
||||
pushd clients/apple
|
||||
xcodebuild -exportArchive \
|
||||
-archivePath "${{ matrix.archive }}" \
|
||||
-archivePath "build/${{ matrix.scheme }}.xcarchive" \
|
||||
-exportOptionsPlist ${{ matrix.export }} \
|
||||
-exportPath "${{ matrix.export_path }}"
|
||||
brew install create-dmg
|
||||
@ -600,13 +655,13 @@ jobs:
|
||||
--skip-jenkins \
|
||||
SFM.dmg "${{ matrix.export_path }}/SFM.app"
|
||||
xcrun notarytool submit "SFM.dmg" --wait --keychain-profile "notarytool-password"
|
||||
cd "${{ matrix.archive }}"
|
||||
cd "build/${{ matrix.scheme }}.xcarchive"
|
||||
zip -r SFM.dSYMs.zip dSYMs
|
||||
popd
|
||||
|
||||
mkdir -p dist
|
||||
cp clients/apple/SFM.dmg "dist/SFM-${VERSION}-universal.dmg"
|
||||
cp "clients/apple/${{ matrix.archive }}/SFM.dSYMs.zip" "dist/SFM-${VERSION}-universal.dSYMs.zip"
|
||||
cp "clients/apple/build/${{ matrix.scheme }}.xcarchive/SFM.dSYMs.zip" "dist/SFM-${VERSION}-universal.dSYMs.zip"
|
||||
- name: Upload image
|
||||
if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
|
||||
uses: actions/upload-artifact@v4
|
||||
@ -615,7 +670,7 @@ jobs:
|
||||
path: 'dist'
|
||||
upload:
|
||||
name: Upload builds
|
||||
if: "!failure() && github.event_name == 'workflow_dispatch' && (inputs.build == 'All' || inputs.build == 'Binary' || inputs.build == 'Android' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone')"
|
||||
if: always() && github.event_name == 'workflow_dispatch' && (inputs.build == 'All' || inputs.build == 'Binary' || inputs.build == 'Android' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone')
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- calculate_version
|
||||
|
@ -26,7 +26,7 @@ func init() {
|
||||
flag.BoolVar(&debugEnabled, "debug", false, "enable debug")
|
||||
flag.StringVar(&target, "target", "android", "target platform")
|
||||
flag.StringVar(&platform, "platform", "", "specify platform")
|
||||
flag.BoolVar(&withTailscale, "with-tailscale", false, "build tailscale for iOS and tvOS")
|
||||
flag.BoolVar(&withTailscale, "tailscale", false, "build tailscale for iOS and tvOS")
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -154,7 +154,7 @@ func buildApple() {
|
||||
"-target", bindTarget,
|
||||
"-libname=box",
|
||||
}
|
||||
if !withTailscale {
|
||||
if withTailscale {
|
||||
args = append(args, "-tags-macos="+strings.Join(memcTags, ","))
|
||||
}
|
||||
|
||||
|
@ -5,13 +5,13 @@ package tls
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
|
||||
"github.com/caddyserver/certmagic"
|
||||
"github.com/libdns/alidns"
|
||||
@ -37,38 +37,7 @@ func (w *acmeWrapper) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type acmeLogWriter struct {
|
||||
logger logger.Logger
|
||||
}
|
||||
|
||||
func (w *acmeLogWriter) Write(p []byte) (n int, err error) {
|
||||
logLine := strings.ReplaceAll(string(p), " ", ": ")
|
||||
switch {
|
||||
case strings.HasPrefix(logLine, "error: "):
|
||||
w.logger.Error(logLine[7:])
|
||||
case strings.HasPrefix(logLine, "warn: "):
|
||||
w.logger.Warn(logLine[6:])
|
||||
case strings.HasPrefix(logLine, "info: "):
|
||||
w.logger.Info(logLine[6:])
|
||||
case strings.HasPrefix(logLine, "debug: "):
|
||||
w.logger.Debug(logLine[7:])
|
||||
default:
|
||||
w.logger.Debug(logLine)
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (w *acmeLogWriter) Sync() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func encoderConfig() zapcore.EncoderConfig {
|
||||
config := zap.NewProductionEncoderConfig()
|
||||
config.TimeKey = zapcore.OmitKey
|
||||
return config
|
||||
}
|
||||
|
||||
func startACME(ctx context.Context, logger logger.Logger, options option.InboundACMEOptions) (*tls.Config, adapter.SimpleLifecycle, error) {
|
||||
func startACME(ctx context.Context, options option.InboundACMEOptions) (*tls.Config, adapter.SimpleLifecycle, error) {
|
||||
var acmeServer string
|
||||
switch options.Provider {
|
||||
case "", "letsencrypt":
|
||||
@ -89,15 +58,14 @@ func startACME(ctx context.Context, logger logger.Logger, options option.Inbound
|
||||
} else {
|
||||
storage = certmagic.Default.Storage
|
||||
}
|
||||
zapLogger := zap.New(zapcore.NewCore(
|
||||
zapcore.NewConsoleEncoder(encoderConfig()),
|
||||
&acmeLogWriter{logger: logger},
|
||||
zap.DebugLevel,
|
||||
))
|
||||
config := &certmagic.Config{
|
||||
DefaultServerName: options.DefaultServerName,
|
||||
Storage: storage,
|
||||
Logger: zapLogger,
|
||||
Logger: zap.New(zapcore.NewCore(
|
||||
zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig()),
|
||||
os.Stderr,
|
||||
zap.InfoLevel,
|
||||
)),
|
||||
}
|
||||
acmeConfig := certmagic.ACMEIssuer{
|
||||
CA: acmeServer,
|
||||
@ -107,7 +75,7 @@ func startACME(ctx context.Context, logger logger.Logger, options option.Inbound
|
||||
DisableTLSALPNChallenge: options.DisableTLSALPNChallenge,
|
||||
AltHTTPPort: int(options.AlternativeHTTPPort),
|
||||
AltTLSALPNPort: int(options.AlternativeTLSPort),
|
||||
Logger: zapLogger,
|
||||
Logger: config.Logger,
|
||||
}
|
||||
if dnsOptions := options.DNS01Challenge; dnsOptions != nil && dnsOptions.Provider != "" {
|
||||
var solver certmagic.DNS01Solver
|
||||
@ -135,7 +103,6 @@ func startACME(ctx context.Context, logger logger.Logger, options option.Inbound
|
||||
GetConfigForCert: func(certificate certmagic.Certificate) (*certmagic.Config, error) {
|
||||
return config, nil
|
||||
},
|
||||
Logger: zapLogger,
|
||||
})
|
||||
config = certmagic.New(cache, *config)
|
||||
var tlsConfig *tls.Config
|
||||
|
@ -9,9 +9,8 @@ import (
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
)
|
||||
|
||||
func startACME(ctx context.Context, logger logger.Logger, options option.InboundACMEOptions) (*tls.Config, adapter.SimpleLifecycle, error) {
|
||||
func startACME(ctx context.Context, options option.InboundACMEOptions) (*tls.Config, adapter.SimpleLifecycle, error) {
|
||||
return nil, nil, E.New(`ACME is not included in this build, rebuild with -tags with_acme`)
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ func NewSTDServer(ctx context.Context, logger log.Logger, options option.Inbound
|
||||
var err error
|
||||
if options.ACME != nil && len(options.ACME.Domain) > 0 {
|
||||
//nolint:staticcheck
|
||||
tlsConfig, acmeService, err = startACME(ctx, logger, common.PtrValueOrDefault(options.ACME))
|
||||
tlsConfig, acmeService, err = startACME(ctx, common.PtrValueOrDefault(options.ACME))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -122,7 +122,6 @@ func NewHTTPSRaw(
|
||||
var transport *http.Transport
|
||||
if tlsConfig != nil {
|
||||
transport = &http.Transport{
|
||||
IdleConnTimeout: C.TCPKeepAliveInitial,
|
||||
ForceAttemptHTTP2: true,
|
||||
DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
tcpConn, hErr := dialer.DialContext(ctx, network, serverAddr)
|
||||
@ -139,7 +138,6 @@ func NewHTTPSRaw(
|
||||
}
|
||||
} else {
|
||||
transport = &http.Transport{
|
||||
IdleConnTimeout: C.TCPKeepAliveInitial,
|
||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return dialer.DialContext(ctx, network, serverAddr)
|
||||
},
|
||||
|
@ -20,8 +20,7 @@ import (
|
||||
)
|
||||
|
||||
func dnsReadConfig(_ context.Context, _ string) *dnsConfig {
|
||||
var state C.res_state
|
||||
if C.res_ninit(state) != 0 {
|
||||
if C.res_init() != 0 {
|
||||
return &dnsConfig{
|
||||
servers: defaultNS,
|
||||
search: dnsDefaultSearch(),
|
||||
@ -34,10 +33,10 @@ func dnsReadConfig(_ context.Context, _ string) *dnsConfig {
|
||||
conf := &dnsConfig{
|
||||
ndots: 1,
|
||||
timeout: 5 * time.Second,
|
||||
attempts: int(state.retry),
|
||||
attempts: int(C._res.retry),
|
||||
}
|
||||
for i := 0; i < int(state.nscount); i++ {
|
||||
ns := state.nsaddr_list[i]
|
||||
for i := 0; i < int(C._res.nscount); i++ {
|
||||
ns := C._res.nsaddr_list[i]
|
||||
addr := C.inet_ntoa(ns.sin_addr)
|
||||
if addr == nil {
|
||||
continue
|
||||
@ -45,7 +44,7 @@ func dnsReadConfig(_ context.Context, _ string) *dnsConfig {
|
||||
conf.servers = append(conf.servers, C.GoString(addr))
|
||||
}
|
||||
for i := 0; ; i++ {
|
||||
search := state.dnsrch[i]
|
||||
search := C._res.dnsrch[i]
|
||||
if search == nil {
|
||||
break
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
icon: material/alert-decagram
|
||||
---
|
||||
|
||||
#### 1.12.0-beta.29
|
||||
#### 1.12.0-beta.28
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
|
@ -19,13 +19,21 @@ platform-specific function implementation, such as TUN transparent proxy impleme
|
||||
## :material-download: Download
|
||||
|
||||
* [App Store](https://apps.apple.com/app/sing-box-vt/id6673731168)
|
||||
* TestFlight (Beta)
|
||||
* TestFlight (Beta) **1**
|
||||
* [GitHub Releases](https://github.com/SagerNet/sing-box/releases) **2**
|
||||
|
||||
**1**:
|
||||
|
||||
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 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).
|
||||
|
||||
**2**:
|
||||
|
||||
You can now download compiled IPAs for iOS and tvOS directly from GitHub releases,
|
||||
but you need to purchase the **Apple Developer Program** to install them through AltStore or SideStore.
|
||||
|
||||
## :material-file-download: Download (macOS standalone version)
|
||||
|
||||
* [Homebrew Cask](https://formulae.brew.sh/cask/sfm)
|
||||
|
@ -25,7 +25,7 @@ icon: material/new-box
|
||||
|
||||
| 类型 | 格式 |
|
||||
|-------------|---------------------------|
|
||||
| `wireguard` | [WireGuard](./wireguard/) |
|
||||
| `wireguard` | [WireGuard](./wiregaurd/) |
|
||||
| `tailscale` | [Tailscale](./tailscale/) |
|
||||
|
||||
#### tag
|
||||
|
@ -59,7 +59,7 @@
|
||||
{
|
||||
"external_controller": "0.0.0.0:9090",
|
||||
"external_ui": "dashboard"
|
||||
// "external_ui_download_detour": "direct"
|
||||
// external_ui_download_detour: "direct"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
||||
{
|
||||
"external_controller": "0.0.0.0:9090",
|
||||
"external_ui": "dashboard"
|
||||
// "external_ui_download_detour": "direct"
|
||||
// external_ui_download_detour: "direct"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -94,13 +94,18 @@ flowchart TB
|
||||
"servers": [
|
||||
{
|
||||
"tag": "google",
|
||||
"type": "tls",
|
||||
"server": "8.8.8.8"
|
||||
"address": "tls://8.8.8.8"
|
||||
},
|
||||
{
|
||||
"tag": "local",
|
||||
"type": "udp",
|
||||
"server": "223.5.5.5"
|
||||
"address": "223.5.5.5",
|
||||
"detour": "direct"
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"outbound": "any",
|
||||
"server": "local"
|
||||
}
|
||||
],
|
||||
"strategy": "ipv4_only"
|
||||
@ -110,8 +115,7 @@ flowchart TB
|
||||
"type": "tun",
|
||||
"inet4_address": "172.19.0.1/30",
|
||||
"auto_route": true,
|
||||
// "auto_redirect": true, // On linux
|
||||
"strict_route": true
|
||||
"strict_route": false
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
@ -119,23 +123,25 @@ flowchart TB
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct"
|
||||
},
|
||||
{
|
||||
"type": "dns",
|
||||
"tag": "dns-out"
|
||||
}
|
||||
],
|
||||
"route": {
|
||||
"rules": [
|
||||
{
|
||||
"action": "sniff"
|
||||
},
|
||||
{
|
||||
"protocol": "dns",
|
||||
"action": "hijack-dns"
|
||||
"outbound": "dns-out"
|
||||
},
|
||||
{
|
||||
"ip_is_private": true,
|
||||
"geoip": [
|
||||
"private"
|
||||
],
|
||||
"outbound": "direct"
|
||||
}
|
||||
],
|
||||
"default_domain_resolver": "local",
|
||||
"auto_detect_interface": true
|
||||
}
|
||||
}
|
||||
@ -149,13 +155,18 @@ flowchart TB
|
||||
"servers": [
|
||||
{
|
||||
"tag": "google",
|
||||
"type": "tls",
|
||||
"server": "8.8.8.8"
|
||||
"address": "tls://8.8.8.8"
|
||||
},
|
||||
{
|
||||
"tag": "local",
|
||||
"type": "udp",
|
||||
"server": "223.5.5.5"
|
||||
"address": "223.5.5.5",
|
||||
"detour": "direct"
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"outbound": "any",
|
||||
"server": "local"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -165,8 +176,7 @@ flowchart TB
|
||||
"inet4_address": "172.19.0.1/30",
|
||||
"inet6_address": "fdfe:dcba:9876::1/126",
|
||||
"auto_route": true,
|
||||
// "auto_redirect": true, // On linux
|
||||
"strict_route": true
|
||||
"strict_route": false
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
@ -174,23 +184,25 @@ flowchart TB
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct"
|
||||
},
|
||||
{
|
||||
"type": "dns",
|
||||
"tag": "dns-out"
|
||||
}
|
||||
],
|
||||
"route": {
|
||||
"rules": [
|
||||
{
|
||||
"action": "sniff"
|
||||
},
|
||||
{
|
||||
"protocol": "dns",
|
||||
"action": "hijack-dns"
|
||||
"outbound": "dns-out"
|
||||
},
|
||||
{
|
||||
"ip_is_private": true,
|
||||
"geoip": [
|
||||
"private"
|
||||
],
|
||||
"outbound": "direct"
|
||||
}
|
||||
],
|
||||
"default_domain_resolver": "local",
|
||||
"auto_detect_interface": true
|
||||
}
|
||||
}
|
||||
@ -204,22 +216,23 @@ flowchart TB
|
||||
"servers": [
|
||||
{
|
||||
"tag": "google",
|
||||
"type": "tls",
|
||||
"server": "8.8.8.8"
|
||||
"address": "tls://8.8.8.8"
|
||||
},
|
||||
{
|
||||
"tag": "local",
|
||||
"type": "udp",
|
||||
"server": "223.5.5.5"
|
||||
"address": "223.5.5.5",
|
||||
"detour": "direct"
|
||||
},
|
||||
{
|
||||
"tag": "remote",
|
||||
"type": "fakeip",
|
||||
"inet4_range": "198.18.0.0/15",
|
||||
"inet6_range": "fc00::/18"
|
||||
"address": "fakeip"
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"outbound": "any",
|
||||
"server": "local"
|
||||
},
|
||||
{
|
||||
"query_type": [
|
||||
"A",
|
||||
@ -228,6 +241,11 @@ flowchart TB
|
||||
"server": "remote"
|
||||
}
|
||||
],
|
||||
"fakeip": {
|
||||
"enabled": true,
|
||||
"inet4_range": "198.18.0.0/15",
|
||||
"inet6_range": "fc00::/18"
|
||||
},
|
||||
"independent_cache": true
|
||||
},
|
||||
"inbounds": [
|
||||
@ -236,7 +254,6 @@ flowchart TB
|
||||
"inet4_address": "172.19.0.1/30",
|
||||
"inet6_address": "fdfe:dcba:9876::1/126",
|
||||
"auto_route": true,
|
||||
// "auto_redirect": true, // On linux
|
||||
"strict_route": true
|
||||
}
|
||||
],
|
||||
@ -245,23 +262,25 @@ flowchart TB
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct"
|
||||
},
|
||||
{
|
||||
"type": "dns",
|
||||
"tag": "dns-out"
|
||||
}
|
||||
],
|
||||
"route": {
|
||||
"rules": [
|
||||
{
|
||||
"action": "sniff"
|
||||
},
|
||||
{
|
||||
"protocol": "dns",
|
||||
"action": "hijack-dns"
|
||||
"outbound": "dns-out"
|
||||
},
|
||||
{
|
||||
"ip_is_private": true,
|
||||
"geoip": [
|
||||
"private"
|
||||
],
|
||||
"outbound": "direct"
|
||||
}
|
||||
],
|
||||
"default_domain_resolver": "local",
|
||||
"auto_detect_interface": true
|
||||
}
|
||||
}
|
||||
@ -271,6 +290,54 @@ flowchart TB
|
||||
|
||||
=== ":material-dns: DNS rules"
|
||||
|
||||
```json
|
||||
{
|
||||
"dns": {
|
||||
"servers": [
|
||||
{
|
||||
"tag": "google",
|
||||
"address": "tls://8.8.8.8"
|
||||
},
|
||||
{
|
||||
"tag": "local",
|
||||
"address": "223.5.5.5",
|
||||
"detour": "direct"
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"outbound": "any",
|
||||
"server": "local"
|
||||
},
|
||||
{
|
||||
"clash_mode": "Direct",
|
||||
"server": "local"
|
||||
},
|
||||
{
|
||||
"clash_mode": "Global",
|
||||
"server": "google"
|
||||
},
|
||||
{
|
||||
"rule_set": "geosite-geolocation-cn",
|
||||
"server": "local"
|
||||
}
|
||||
]
|
||||
},
|
||||
"route": {
|
||||
"rule_set": [
|
||||
{
|
||||
"type": "remote",
|
||||
"tag": "geosite-geolocation-cn",
|
||||
"format": "binary",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-cn.srs"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
=== ":material-dns: DNS rules (Enhanced, but slower) (1.9.0+)"
|
||||
|
||||
=== ":material-shield-off: With DNS leaks"
|
||||
|
||||
```json
|
||||
@ -279,20 +346,35 @@ flowchart TB
|
||||
"servers": [
|
||||
{
|
||||
"tag": "google",
|
||||
"type": "tls",
|
||||
"server": "8.8.8.8"
|
||||
"address": "tls://8.8.8.8"
|
||||
},
|
||||
{
|
||||
"tag": "local",
|
||||
"type": "https",
|
||||
"server": "223.5.5.5"
|
||||
"address": "https://223.5.5.5/dns-query",
|
||||
"detour": "direct"
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"outbound": "any",
|
||||
"server": "local"
|
||||
},
|
||||
{
|
||||
"clash_mode": "Direct",
|
||||
"server": "local"
|
||||
},
|
||||
{
|
||||
"clash_mode": "Global",
|
||||
"server": "google"
|
||||
},
|
||||
{
|
||||
"rule_set": "geosite-geolocation-cn",
|
||||
"server": "local"
|
||||
},
|
||||
{
|
||||
"clash_mode": "Default",
|
||||
"server": "google"
|
||||
},
|
||||
{
|
||||
"type": "logical",
|
||||
"mode": "and",
|
||||
@ -310,7 +392,6 @@ flowchart TB
|
||||
]
|
||||
},
|
||||
"route": {
|
||||
"default_domain_resolver": "local",
|
||||
"rule_set": [
|
||||
{
|
||||
"type": "remote",
|
||||
@ -344,7 +425,7 @@ flowchart TB
|
||||
}
|
||||
```
|
||||
|
||||
=== ":material-security: Without DNS leaks, but slower"
|
||||
=== ":material-security: Without DNS leaks, but slower (1.9.0-alpha.2+)"
|
||||
|
||||
```json
|
||||
{
|
||||
@ -352,16 +433,27 @@ flowchart TB
|
||||
"servers": [
|
||||
{
|
||||
"tag": "google",
|
||||
"type": "tls",
|
||||
"server": "8.8.8.8"
|
||||
"address": "tls://8.8.8.8"
|
||||
},
|
||||
{
|
||||
"tag": "local",
|
||||
"type": "https",
|
||||
"server": "223.5.5.5"
|
||||
"address": "https://223.5.5.5/dns-query",
|
||||
"detour": "direct"
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"outbound": "any",
|
||||
"server": "local"
|
||||
},
|
||||
{
|
||||
"clash_mode": "Direct",
|
||||
"server": "local"
|
||||
},
|
||||
{
|
||||
"clash_mode": "Global",
|
||||
"server": "google"
|
||||
},
|
||||
{
|
||||
"rule_set": "geosite-geolocation-cn",
|
||||
"server": "local"
|
||||
@ -384,7 +476,6 @@ flowchart TB
|
||||
]
|
||||
},
|
||||
"route": {
|
||||
"default_domain_resolver": "local",
|
||||
"rule_set": [
|
||||
{
|
||||
"type": "remote",
|
||||
@ -426,13 +517,14 @@ flowchart TB
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct"
|
||||
},
|
||||
{
|
||||
"type": "block",
|
||||
"tag": "block"
|
||||
}
|
||||
],
|
||||
"route": {
|
||||
"rules": [
|
||||
{
|
||||
"action": "sniff"
|
||||
},
|
||||
{
|
||||
"type": "logical",
|
||||
"mode": "or",
|
||||
@ -444,12 +536,20 @@ flowchart TB
|
||||
"port": 53
|
||||
}
|
||||
],
|
||||
"action": "hijack-dns"
|
||||
"outbound": "dns"
|
||||
},
|
||||
{
|
||||
"ip_is_private": true,
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"clash_mode": "Direct",
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"clash_mode": "Global",
|
||||
"outbound": "default"
|
||||
},
|
||||
{
|
||||
"type": "logical",
|
||||
"mode": "or",
|
||||
@ -465,23 +565,12 @@ flowchart TB
|
||||
"protocol": "stun"
|
||||
}
|
||||
],
|
||||
"action": "reject"
|
||||
"outbound": "block"
|
||||
},
|
||||
{
|
||||
"rule_set": "geosite-geolocation-cn",
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"type": "logical",
|
||||
"mode": "and",
|
||||
"rules": [
|
||||
{
|
||||
"rule_set": "geoip-cn"
|
||||
},
|
||||
{
|
||||
"rule_set": "geosite-geolocation-!cn",
|
||||
"invert": true
|
||||
}
|
||||
"rule_set": [
|
||||
"geoip-cn",
|
||||
"geosite-geolocation-cn"
|
||||
],
|
||||
"outbound": "direct"
|
||||
}
|
||||
|
@ -205,10 +205,6 @@ func (h *inboundTransportHandler) NewConnectionEx(ctx context.Context, conn net.
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Source = source
|
||||
metadata.Destination = destination
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = h.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
|
||||
h.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
|
||||
(*Inbound)(h).NewConnectionEx(ctx, conn, metadata, onClose)
|
||||
}
|
||||
|
@ -219,10 +219,6 @@ func (h *inboundTransportHandler) NewConnectionEx(ctx context.Context, conn net.
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Source = source
|
||||
metadata.Destination = destination
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = h.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
|
||||
h.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
|
||||
(*Inbound)(h).NewConnectionEx(ctx, conn, metadata, onClose)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user