Compare commits

...

56 Commits

Author SHA1 Message Date
世界
d2add33723 Bump version 2022-09-15 13:12:18 +08:00
世界
ab0daf31c1 Fix clash api proxy type 2022-09-15 13:11:52 +08:00
世界
3d94b948dd Fix port rule match logic 2022-09-15 13:11:20 +08:00
世界
1659ae5d79 Fix close grpc conn 2022-09-15 13:10:18 +08:00
世界
7279855b08 Bump version 2022-09-13 11:25:38 +08:00
世界
925fbca363 Fix concurrent write 2022-09-13 10:36:37 +08:00
世界
a5163e3e3c Fix hysteria inbound 2022-09-13 10:32:14 +08:00
世界
62859e0c6b Fix socks4 client 2022-09-13 10:32:12 +08:00
世界
a37cab48d2 Bump version 2022-09-10 23:13:58 +08:00
世界
c586c8f361 Fix socks4 request 2022-09-10 22:53:06 +08:00
世界
e68fa3e12d Fix processing empty dns result 2022-09-10 22:52:54 +08:00
世界
7f5b9e0e3b Run build on main branch 2022-09-10 22:52:54 +08:00
世界
f7bed32c6f Bump version 2022-09-09 14:43:42 +08:00
世界
ef7f2d82c0 Fix match 4in6 address in ip_cidr 2022-09-09 14:07:02 +08:00
世界
7aa97a332e Fix documentation 2022-09-09 13:54:02 +08:00
世界
7c30dde96b Minor fixes 2022-09-08 18:33:59 +08:00
GyDi
9cef2a0a8f Fix clashapi log level format error 2022-09-08 18:04:06 +08:00
世界
f376683fc3 Update documentation 2022-09-07 23:10:36 +08:00
世界
4b61d6e875 Fix hysteria stream error 2022-09-07 19:16:20 +08:00
世界
7d83e350fd Refine test 2022-09-07 19:16:20 +08:00
世界
500ba69548 Fix processing vmess termination signal 2022-09-07 19:16:20 +08:00
世界
9a422549b1 Fix json format error message 2022-09-07 13:23:26 +08:00
世界
3b48fa455e Fix naive inbound temporary 2022-09-07 12:30:54 +08:00
zakuwaki
ef013e0639 Suppress accept proxyproto failed #65 2022-09-06 23:16:31 +08:00
世界
8f8437a88d Fix wireguard reconnect 2022-09-06 00:11:43 +08:00
世界
1b091c9b07 Update documentation 2022-09-04 13:15:10 +08:00
世界
4801b6f057 Fix DNS routing 2022-09-04 12:49:38 +08:00
世界
9078bc2de5 Fix write trojan udp 2022-09-03 16:58:55 +08:00
世界
b69464dfe9 Update documentation for dial fields 2022-09-03 13:02:41 +08:00
世界
62fa48293a Merge dialer options 2022-09-03 12:55:10 +08:00
世界
b206d0889b Fix dial parallel in direct outbound 2022-09-03 12:01:48 +08:00
世界
ee691d81bf Fix write zero 2022-09-03 09:25:30 +08:00
void aire()
56876a67cc Fix documentation typo (#60) 2022-09-02 19:04:03 +08:00
世界
4a0df713aa Add ws compatibility test 2022-09-01 20:32:47 +08:00
世界
ef801cbfbe Fix server install script 2022-09-01 20:32:47 +08:00
世界
9378fc88d2 Add with_wireguard to default server tag 2022-09-01 20:16:20 +08:00
世界
f46bfcc3d8 Move unstable branch to dev-next 2022-08-31 23:45:42 +08:00
0x7d274284
ccdb238843 Fix documentation typo (#57) 2022-08-31 23:42:36 +08:00
世界
f1f61b4e2b Fix install documentation 2022-08-31 23:37:30 +08:00
世界
a44cb745d9 Fix write log timestamp 2022-08-31 23:35:43 +08:00
世界
f5f5cb023c Update documentation 2022-08-31 14:34:32 +08:00
世界
5813e0ce7a Add shadowtls (#49)
* Add shadowtls outbound

* Add shadowtls inbound

* Add shadowtls example

* Add shadowtls documentation
2022-08-31 14:21:53 +08:00
dyhkwong
5a9c2b1e80 darwin pf support (#52) 2022-08-31 14:21:37 +08:00
世界
bda34fdb3b Refactor outbound documentation 2022-08-31 13:42:30 +08:00
世界
426b677eb8 Fix process_name rule item 2022-08-31 12:51:38 +08:00
世界
67c7e9fd86 Refactor inbound documetation 2022-08-31 12:50:26 +08:00
世界
d8028a8632 Fix smux session status 2022-08-31 10:00:15 +08:00
dyhkwong
374743d022 Add process_path rule item (#51)
* process matching supports full path
* Remove strings.ToLower
2022-08-30 10:44:40 +08:00
世界
cd98ea5008 Fix socksaddr type condition 2022-08-29 19:58:58 +08:00
世界
dbda0ed98a Add chained inbound support 2022-08-29 19:50:28 +08:00
世界
f5e0ead01c Fix inject conn 2022-08-29 19:02:41 +08:00
0x7d274284
44818701bc Fix issue template (#48)
The correct command to get the version is `sing-box version`
2022-08-29 16:52:15 +08:00
世界
e0f7387dff Fix search android package in non-owner users 2022-08-29 12:02:29 +08:00
世界
d440a01792 Add grpc compatibility test 2022-08-29 10:15:25 +08:00
世界
665c84ee42 Fix log item on document menu 2022-08-28 12:47:23 +08:00
Hellojack
e0de96eb4c Minor fixes (#45)
* Cleanup code
* Fix documentation typo
2022-08-28 12:40:44 +08:00
180 changed files with 3617 additions and 3822 deletions

View File

@@ -31,7 +31,7 @@ body:
<details>
```console
$ sing-box --version
$ sing-box version
# Paste output here
```

View File

@@ -1,10 +1,5 @@
#!/usr/bin/env bash
PROJECTS=$(dirname "$0")/../..
go get -x github.com/sagernet/sing@$(git -C $PROJECTS/sing rev-parse HEAD)
go get -x github.com/sagernet/sing-dns@$(git -C $PROJECTS/sing-dns rev-parse HEAD)
go get -x github.com/sagernet/sing-tun@$(git -C $PROJECTS/sing-tun rev-parse HEAD)
go get -x github.com/sagernet/sing-shadowsocks@$(git -C $PROJECTS/sing-shadowsocks rev-parse HEAD)
go get -x github.com/sagernet/sing-vmess@$(git -C $PROJECTS/sing-vmess rev-parse HEAD)
go get -x github.com/sagernet/$1@$(git -C $PROJECTS/$1 rev-parse HEAD)
go mod tidy

View File

@@ -3,14 +3,18 @@ name: Debug build
on:
push:
branches:
- main
- dev
- dev-next
paths-ignore:
- '**.md'
- '.github/**'
- '!.github/workflows/debug.yml'
pull_request:
branches:
- main
- dev
- dev-next
jobs:
build:

View File

@@ -2,7 +2,7 @@ name: Generate Documents
on:
push:
branches:
- main
- dev
paths:
- docs/**
- .github/workflows/mkdocs.yml

View File

@@ -7,8 +7,8 @@ ENV GOPROXY ${GOPROXY}
ENV CGO_ENABLED=0
RUN set -ex \
&& apk add git build-base \
&& export COMMIT=$(git rev-parse HEAD) \
&& go build -v -trimpath -tags 'with_quic,with_acme,with_wireguard,with_clash_api' \
&& export COMMIT=$(git rev-parse --short HEAD) \
&& go build -v -trimpath -tags 'no_gvisor,with_quic,with_wireguard,with_acme' \
-o /go/bin/sing-box \
-ldflags "-X github.com/sagernet/sing-box/constant.Commit=${COMMIT} -w -s -buildid=" \
./cmd/sing-box

View File

@@ -2,11 +2,13 @@ package adapter
import (
"context"
"net"
"net/netip"
"github.com/sagernet/sing-box/common/process"
"github.com/sagernet/sing-dns"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type Inbound interface {
@@ -15,6 +17,13 @@ type Inbound interface {
Tag() string
}
type InjectableInbound interface {
Inbound
Network() []string
NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}
type InboundContext struct {
Inbound string
InboundType string
@@ -29,6 +38,8 @@ type InboundContext struct {
// cache
InboundDetour string
LastInbound string
OriginDestination M.Socksaddr
DomainStrategy dns.DomainStrategy
SniffEnabled bool

2
box.go
View File

@@ -138,7 +138,7 @@ func New(ctx context.Context, options option.Options) (*Box, error) {
}
outbounds = append(outbounds, out)
}
err = router.Initialize(outbounds, func() adapter.Outbound {
err = router.Initialize(inbounds, outbounds, func() adapter.Outbound {
out, oErr := outbound.New(ctx, router, logFactory.NewLogger("outbound/direct"), option.Outbound{Type: "direct", Tag: "default"})
common.Must(oErr)
outbounds = append(outbounds, out)

View File

@@ -38,7 +38,7 @@ func format() error {
return E.Cause(err, "read config")
}
var options option.Options
err = json.Unmarshal(configContent, &options)
err = options.UnmarshalJSON(configContent)
if err != nil {
return E.Cause(err, "decode config")
}

View File

@@ -9,7 +9,6 @@ import (
"syscall"
"github.com/sagernet/sing-box"
"github.com/sagernet/sing-box/common/json"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
@@ -46,7 +45,7 @@ func readConfig() (option.Options, error) {
return option.Options{}, E.Cause(err, "read config")
}
var options option.Options
err = json.Unmarshal(configContent, &options)
err = options.UnmarshalJSON(configContent)
if err != nil {
return option.Options{}, E.Cause(err, "decode config")
}

View File

@@ -0,0 +1,62 @@
package baderror
import (
"context"
"io"
"net"
"strings"
E "github.com/sagernet/sing/common/exceptions"
)
func Contains(err error, msgList ...string) bool {
for _, msg := range msgList {
if strings.Contains(err.Error(), msg) {
return true
}
}
return false
}
func WrapH2(err error) error {
if err == nil {
return nil
}
err = E.Unwrap(err)
if err == io.ErrUnexpectedEOF {
return io.EOF
}
if Contains(err, "client disconnected", "body closed by handler") {
return net.ErrClosed
}
return err
}
func WrapGRPC(err error) error {
// grpc uses stupid internal error types
if err == nil {
return nil
}
if Contains(err, "EOF") {
return io.EOF
}
if Contains(err, "Canceled") {
return context.Canceled
}
if Contains(err,
"the client connection is closing",
"server closed the stream without sending trailers") {
return net.ErrClosed
}
return err
}
func WrapQUIC(err error) error {
if err == nil {
return nil
}
if Contains(err, "canceled with error code 0") {
return net.ErrClosed
}
return err
}

View File

@@ -11,6 +11,7 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common/control"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
@@ -130,6 +131,9 @@ func NewDefault(router adapter.Router, options option.DialerOptions) *DefaultDia
}
func (d *DefaultDialer) DialContext(ctx context.Context, network string, address M.Socksaddr) (net.Conn, error) {
if !address.IsValid() {
return nil, E.New("invalid address")
}
switch N.NetworkName(network) {
case N.NetworkUDP:
return d.udpDialer.DialContext(ctx, network, address.String())

View File

@@ -10,15 +10,12 @@ import (
)
func New(router adapter.Router, options option.DialerOptions) N.Dialer {
var dialer N.Dialer
if options.Detour == "" {
return NewDefault(router, options)
dialer = NewDefault(router, options)
} else {
return NewDetour(router, options.Detour)
dialer = NewDetour(router, options.Detour)
}
}
func NewOutbound(router adapter.Router, options option.OutboundDialerOptions) N.Dialer {
dialer := New(router, options.DialerOptions)
domainStrategy := dns.DomainStrategy(options.DomainStrategy)
if domainStrategy != dns.DomainStrategyAsIS || options.Detour == "" {
dialer = NewResolveDialer(router, dialer, domainStrategy, time.Duration(options.FallbackDelay))

View File

@@ -51,7 +51,7 @@ func (d *ResolveDialer) DialContext(ctx context.Context, network string, destina
}
func (d *ResolveDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
if !destination.IsFqdn() || destination.Fqdn == "" {
if !destination.IsFqdn() {
return d.dialer.ListenPacket(ctx, destination)
}
ctx, metadata := adapter.AppendContext(ctx)

View File

@@ -22,13 +22,13 @@ func (s *androidSearcher) FindProcessInfo(ctx context.Context, network string, s
if err != nil {
return nil, err
}
if sharedPackage, loaded := s.packageManager.SharedPackageByID(uid); loaded {
if sharedPackage, loaded := s.packageManager.SharedPackageByID(uid % 100000); loaded {
return &Info{
UserId: int32(uid),
PackageName: sharedPackage,
}, nil
}
if packageName, loaded := s.packageManager.PackageByID(uid); loaded {
if packageName, loaded := s.packageManager.PackageByID(uid % 100000); loaded {
return &Info{
UserId: int32(uid),
PackageName: packageName,

View File

@@ -0,0 +1,64 @@
package redir
import (
"net"
"net/netip"
"syscall"
"unsafe"
M "github.com/sagernet/sing/common/metadata"
)
const (
PF_OUT = 0x2
DIOCNATLOOK = 0xc0544417
)
func GetOriginalDestination(conn net.Conn) (destination netip.AddrPort, err error) {
fd, err := syscall.Open("/dev/pf", 0, syscall.O_RDONLY)
if err != nil {
return netip.AddrPort{}, err
}
defer syscall.Close(fd)
nl := struct {
saddr, daddr, rsaddr, rdaddr [16]byte
sxport, dxport, rsxport, rdxport [4]byte
af, proto, protoVariant, direction uint8
}{
af: syscall.AF_INET,
proto: syscall.IPPROTO_TCP,
direction: PF_OUT,
}
la := conn.LocalAddr().(*net.TCPAddr)
ra := conn.RemoteAddr().(*net.TCPAddr)
raIP, laIP := ra.IP, la.IP
raPort, laPort := ra.Port, la.Port
switch {
case raIP.To4() != nil:
copy(nl.saddr[:net.IPv4len], raIP.To4())
copy(nl.daddr[:net.IPv4len], laIP.To4())
nl.af = syscall.AF_INET
default:
copy(nl.saddr[:], raIP.To16())
copy(nl.daddr[:], laIP.To16())
nl.af = syscall.AF_INET6
}
nl.sxport[0], nl.sxport[1] = byte(raPort>>8), byte(raPort)
nl.dxport[0], nl.dxport[1] = byte(laPort>>8), byte(laPort)
if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), DIOCNATLOOK, uintptr(unsafe.Pointer(&nl))); errno != 0 {
return netip.AddrPort{}, errno
}
var ip net.IP
switch nl.af {
case syscall.AF_INET:
ip = make(net.IP, net.IPv4len)
copy(ip, nl.rdaddr[:net.IPv4len])
case syscall.AF_INET6:
ip = make(net.IP, net.IPv6len)
copy(ip, nl.rdaddr[:])
}
port := uint16(nl.rdxport[0])<<8 | uint16(nl.rdxport[1])
destination = netip.AddrPortFrom(M.AddrFromIP(ip), port)
return
}

View File

@@ -1,4 +1,4 @@
//go:build !linux
//go:build !linux && !darwin
package redir

View File

@@ -18,6 +18,7 @@ const (
TypeHysteria = "hysteria"
TypeTor = "tor"
TypeSSH = "ssh"
TypeShadowTLS = "shadowtls"
)
const (

View File

@@ -1,6 +1,6 @@
package constant
var (
Version = "1.0-beta2"
Version = "1.0.4"
Commit = ""
)

View File

@@ -1,3 +1,41 @@
#### 1.0.1
* Fix match 4in6 address in ip_cidr
* Fix clash api log level format error
* Fix clash api unknown proxy type
#### 1.0
* Fix wireguard reconnect
* Fix naive inbound
* Fix json format error message
* Fix processing vmess termination signal
* Fix hysteria stream error
* Fix listener close when proxyproto failed
#### 1.0-rc1
* Fix write log timestamp
* Fix write zero
* Fix dial parallel in direct outbound
* Fix write trojan udp
* Fix DNS routing
* Add attribute support for geosite
* Update documentation for [Dial Fields](/configuration/shared/dial)
#### 1.0-beta3
* Add [chained inbound](/configuration/shared/listen#detour) support
* Add process_path rule item
* Add macOS redirect support
* Add ShadowTLS [Inbound](/configuration/inbound/shadowtls), [Outbound](/configuration/outbound/shadowtls)
and [Examples](/examples/shadowtls)
* Fix search android package in non-owner users
* Fix socksaddr type condition
* Fix smux session status
* Refactor inbound and outbound documentation
* Minor fixes
#### 1.0-beta2
* Add strict_route option for [Tun inbound](/configuration/inbound/tun#strict_route)
@@ -111,4 +149,4 @@
No changelog before.
[#9]: https://github.com/SagerNet/sing-box/pull/9
[#9]: https://github.com/SagerNet/sing-box/pull/9

View File

@@ -61,6 +61,9 @@
"process_name": [
"curl"
],
"process_path": [
"/usr/bin/curl"
],
"package_name": [
"com.termux"
],
@@ -177,6 +180,14 @@ Match port range.
Match process name.
#### process_path
!!! error ""
Only supported on Linux, Windows, and macOS.
Match process path.
#### package_name
Match android package name.

View File

@@ -60,6 +60,9 @@
"process_name": [
"curl"
],
"process_path": [
"/usr/bin/curl"
],
"package_name": [
"com.termux"
],
@@ -176,6 +179,14 @@
匹配进程名称。
#### process_path
!!! error ""
仅支持 Linux、Windows 和 macOS.
匹配进程路径。
#### package_name
匹配 Android 应用包名。

View File

@@ -4,29 +4,22 @@
```json
{
"inbounds": [
{
"type": "direct",
"tag": "direct-in",
"listen": "::",
"listen_port": 5353,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"udp_timeout": 300,
"proxy_protocol": false,
"type": "direct",
"tag": "direct-in",
... // Listen Fields
"network": "udp",
"override_address": "1.0.0.1",
"override_port": 53
}
]
"network": "udp",
"override_address": "1.0.0.1",
"override_port": 53
}
```
### Direct Fields
### Listen Fields
See [Listen Fields](/configuration/shared/listen) for details.
### Fields
#### network
@@ -40,50 +33,4 @@ Override the connection destination address.
#### override_port
Override the connection destination port.
### Listen Fields
#### listen
==Required==
Listen address.
#### listen_port
==Required==
Listen port.
#### tcp_fast_open
Enable tcp fast open for listener.
#### sniff
Enable sniffing.
See [Protocol Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
#### udp_timeout
UDP NAT expiration time in seconds, default is 300 (5 minutes).
#### proxy_protocol
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.
Override the connection destination port.

View File

@@ -4,29 +4,22 @@
```json
{
"inbounds": [
{
"type": "direct",
"tag": "direct-in",
"type": "direct",
"tag": "direct-in",
"listen": "::",
"listen_port": 5353,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"udp_timeout": 300,
"network": "udp",
"proxy_protocol": false,
"override_address": "1.0.0.1",
"override_port": 53
}
]
... // 监听字段
"network": "udp",
"override_address": "1.0.0.1",
"override_port": 53
}
```
### Direct 字段
### 监听字段
参阅 [监听字段](/zh/configuration/shared/listen/)。
### 字段
#### network
@@ -42,48 +35,3 @@
覆盖连接目标端口。
### 监听字段
#### listen
==必填==
监听地址。
#### listen_port
==必填==
监听端口。
#### tcp_fast_open
为监听器启用 TCP 快速打开。
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
#### udp_timeout
UDP NAT 过期时间,以秒为单位,默认为 3005 分钟)。
#### proxy_protocol
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。

View File

@@ -2,33 +2,27 @@
```json
{
"inbounds": [
"type": "http",
"tag": "http-in",
... // Listen Fields
"users": [
{
"type": "http",
"tag": "http-in",
"listen": "::",
"listen_port": 2080,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"proxy_protocol": false,
"users": [
{
"username": "admin",
"password": "admin"
}
],
"tls": {},
"set_system_proxy": false
"username": "admin",
"password": "admin"
}
]
],
"tls": {},
"set_system_proxy": false
}
```
### HTTP Fields
### Listen Fields
See [Listen Fields](/configuration/shared/listen) for details.
### Fields
#### tls
@@ -47,45 +41,3 @@ No authentication required if empty.
Only supported on Linux, Android, Windows, and macOS.
Automatically set system proxy configuration when start and clean up when stop.
### Listen Fields
#### listen
==Required==
Listen address.
#### listen_port
==Required==
Listen port.
#### tcp_fast_open
Enable tcp fast open for listener.
#### sniff
Enable sniffing.
See [Protocol Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
#### proxy_protocol
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.

View File

@@ -2,33 +2,27 @@
```json
{
"inbounds": [
"type": "http",
"tag": "http-in",
... // 监听字段
"users": [
{
"type": "http",
"tag": "http-in",
"listen": "::",
"listen_port": 2080,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"proxy_protocol": false,
"users": [
{
"username": "admin",
"password": "admin"
}
],
"tls": {},
"set_system_proxy": false
"username": "admin",
"password": "admin"
}
]
],
"tls": {},
"set_system_proxy": false
}
```
### HTTP 字段
### 监听字段
参阅 [监听字段](/zh/configuration/shared/listen/)。
### 字段
#### tls
@@ -38,7 +32,7 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
HTTP 用户
默认不需要验证。
如果为空则不需要验证。
#### set_system_proxy
@@ -46,46 +40,4 @@ HTTP 用户
仅支持 Linux、Android、Windows 和 macOS。
启动时自动设置系统代理,停止时自动清理。
### 监听字段
#### listen
==必填==
监听地址。
#### listen_port
==必填==
监听端口。
#### tcp_fast_open
为监听器启用 TCP 快速打开。
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
#### proxy_protocol
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
启动时自动设置系统代理,停止时自动清理。

View File

@@ -2,31 +2,23 @@
```json
{
"inbounds": [
{
"type": "hysteria",
"tag": "hysteria-in",
"listen": "::",
"listen_port": 443,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"up": "100 Mbps",
"up_mbps": 100,
"down": "100 Mbps",
"down_mbps": 100,
"obfs": "fuck me till the daylight",
"auth": "",
"auth_str": "password",
"recv_window_conn": 0,
"recv_window_client": 0,
"max_conn_client": 0,
"disable_mtu_discovery": false,
"tls": {}
}
]
"type": "hysteria",
"tag": "hysteria-in",
... // Listen Fields
"up": "100 Mbps",
"up_mbps": 100,
"down": "100 Mbps",
"down_mbps": 100,
"obfs": "fuck me till the daylight",
"auth": "",
"auth_str": "password",
"recv_window_conn": 0,
"recv_window_client": 0,
"max_conn_client": 0,
"disable_mtu_discovery": false,
"tls": {}
}
```
@@ -34,7 +26,11 @@
QUIC, which is required by hysteria is not included by default, see [Installation](/#installation).
### Hysteria Fields
### Listen Fields
See [Listen Fields](/configuration/shared/listen) for details.
### Fields
#### up, down
@@ -101,38 +97,4 @@ Force enabled on for systems other than Linux and Windows (according to upstream
==Required==
TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
### Listen Fields
#### listen
==Required==
Listen address.
#### listen_port
==Required==
Listen port.
#### sniff
Enable sniffing.
See [Protocol Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
TLS configuration, see [TLS](/configuration/shared/tls/#inbound).

View File

@@ -2,31 +2,23 @@
```json
{
"inbounds": [
{
"type": "hysteria",
"tag": "hysteria-in",
"listen": "::",
"listen_port": 443,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"up": "100 Mbps",
"up_mbps": 100,
"down": "100 Mbps",
"down_mbps": 100,
"obfs": "fuck me till the daylight",
"auth": "",
"auth_str": "password",
"recv_window_conn": 0,
"recv_window_client": 0,
"max_conn_client": 0,
"disable_mtu_discovery": false,
"tls": {}
}
]
"type": "hysteria",
"tag": "hysteria-in",
... // 监听字段
"up": "100 Mbps",
"up_mbps": 100,
"down": "100 Mbps",
"down_mbps": 100,
"obfs": "fuck me till the daylight",
"auth": "",
"auth_str": "password",
"recv_window_conn": 0,
"recv_window_client": 0,
"max_conn_client": 0,
"disable_mtu_discovery": false,
"tls": {}
}
```
@@ -34,7 +26,11 @@
默认安装不包含被 Hysteria 依赖的 QUIC参阅 [安装](/zh/#_2)。
### Hysteria 字段
### 监听字段
参阅 [监听字段](/zh/configuration/shared/listen/)。
### 字段
#### up, down
@@ -101,38 +97,4 @@ base64 编码的认证密码。
==必填==
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
### 监听字段
#### listen
==必填==
监听地址。
#### listen_port
==必填==
监听端口。
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)。
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。

View File

@@ -15,20 +15,20 @@
### Fields
| Type | Format |
|---------------|------------------------------|
| `direct` | [Direct](./direct) |
| `mixed` | [Mixed](./mixed) |
| `socks` | [SOCKS](./socks) |
| `http` | [HTTP](./http) |
| `shadowsocks` | [Shadowsocks](./shadowsocks) |
| `vmess` | [VMess](./vmess) |
| `trojan` | [Trojan](./trojan) |
| `naive` | [Naive](./naive) |
| `hysteria` | [Hysteria](./hysteria) |
| `tun` | [Tun](./tun) |
| `redirect` | [Redirect](./redirect) |
| `tproxy` | [TProxy](./tproxy) |
| Type | Format | Injectable |
|---------------|------------------------------|------------|
| `direct` | [Direct](./direct) | X |
| `mixed` | [Mixed](./mixed) | TCP |
| `socks` | [SOCKS](./socks) | TCP |
| `http` | [HTTP](./http) | TCP |
| `shadowsocks` | [Shadowsocks](./shadowsocks) | TCP |
| `vmess` | [VMess](./vmess) | TCP |
| `trojan` | [Trojan](./trojan) | TCP |
| `naive` | [Naive](./naive) | X |
| `hysteria` | [Hysteria](./hysteria) | X |
| `tun` | [Tun](./tun) | X |
| `redirect` | [Redirect](./redirect) | X |
| `tproxy` | [TProxy](./tproxy) | X |
#### tag

View File

@@ -15,20 +15,20 @@
### 字段
| 类型 | 格式 |
|---------------|------------------------------|
| `direct` | [Direct](./direct) |
| `mixed` | [Mixed](./mixed) |
| `socks` | [SOCKS](./socks) |
| `http` | [HTTP](./http) |
| `shadowsocks` | [Shadowsocks](./shadowsocks) |
| `vmess` | [VMess](./vmess) |
| `trojan` | [Trojan](./trojan) |
| `naive` | [Naive](./naive) |
| `hysteria` | [Hysteria](./hysteria) |
| `tun` | [Tun](./tun) |
| `redirect` | [Redirect](./redirect) |
| `tproxy` | [TProxy](./tproxy) |
| 类型 | 格式 | 注入支持 |
|---------------|------------------------------|------|
| `direct` | [Direct](./direct) | X |
| `mixed` | [Mixed](./mixed) | TCP |
| `socks` | [SOCKS](./socks) | TCP |
| `http` | [HTTP](./http) | TCP |
| `shadowsocks` | [Shadowsocks](./shadowsocks) | TCP |
| `vmess` | [VMess](./vmess) | TCP |
| `trojan` | [Trojan](./trojan) | TCP |
| `naive` | [Naive](./naive) | X |
| `hysteria` | [Hysteria](./hysteria) | X |
| `tun` | [Tun](./tun) | X |
| `redirect` | [Redirect](./redirect) | X |
| `tproxy` | [TProxy](./tproxy) | X |
#### tag

View File

@@ -4,32 +4,26 @@
```json
{
"inbounds": [
"type": "mixed",
"tag": "mixed-in",
... // Listen Fields
"users": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "::",
"listen_port": 2080,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"proxy_protocol": false,
"users": [
{
"username": "admin",
"password": "admin"
}
],
"set_system_proxy": false
"username": "admin",
"password": "admin"
}
]
],
"set_system_proxy": false
}
```
### Mixed Fields
### Listen Fields
See [Listen Fields](/configuration/shared/listen) for details.
### Fields
#### users
@@ -39,52 +33,6 @@ No authentication required if empty.
#### set_system_proxy
!!! error ""
Only supported on Linux, Android, Windows, and macOS.
Automatically set system proxy configuration when start and clean up when stop.
### Listen Fields
#### listen
==Required==
Listen address.
#### listen_port
==Required==
Listen port.
#### tcp_fast_open
Enable tcp fast open for listener.
#### sniff
Enable sniffing.
See [Protocol Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
#### set_system_proxy
!!! error ""
Only supported on Linux, Android, Windows, and macOS.

View File

@@ -4,38 +4,32 @@
```json
{
"inbounds": [
"type": "mixed",
"tag": "mixed-in",
... // 监听字段
"users": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "::",
"listen_port": 2080,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"proxy_protocol": false,
"users": [
{
"username": "admin",
"password": "admin"
}
],
"set_system_proxy": false
"username": "admin",
"password": "admin"
}
]
],
"set_system_proxy": false
}
```
### Mixed 字段
### 监听字段
参阅 [监听字段](/zh/configuration/shared/listen/)。
### 字段
#### users
SOCKS 和 HTTP 用户
默认不需要验证。
如果为空则不需要验证。
#### set_system_proxy
@@ -43,46 +37,4 @@ SOCKS 和 HTTP 用户
仅支持 Linux、Android、Windows 和 macOS。
启动时自动设置系统代理,停止时自动清理。
### 监听字段
#### listen
==必填==
监听地址。
#### listen_port
==必填==
监听端口。
#### tcp_fast_open
为监听器启用 TCP 快速打开。
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)。
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
#### proxy_protocol
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
启动时自动设置系统代理,停止时自动清理。

View File

@@ -2,29 +2,19 @@
```json
{
"inbounds": [
"type": "naive",
"tag": "naive-in",
"network": "udp",
... // Listen Fields
"users": [
{
"type": "naive",
"tag": "naive-in",
"listen": "::",
"listen_port": 443,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"proxy_protocol": false,
"network": "udp",
"users": [
{
"username": "sekai",
"password": "password"
}
],
"tls": {}
"username": "sekai",
"password": "password"
}
]
],
"tls": {}
}
```
@@ -32,7 +22,11 @@
HTTP3 transport is not included by default, see [Installation](/#installation).
### Naive Fields
### Listen Fields
See [Listen Fields](/configuration/shared/listen) for details.
### Fields
#### network
@@ -48,46 +42,4 @@ Naive users.
#### tls
TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
### Listen Fields
#### listen
==Required==
Listen address.
#### listen_port
==Required==
Listen port.
#### tcp_fast_open
Enable tcp fast open for listener.
#### sniff
Enable sniffing.
See [Protocol Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
#### proxy_protocol
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.
TLS configuration, see [TLS](/configuration/shared/tls/#inbound).

View File

@@ -2,29 +2,19 @@
```json
{
"inbounds": [
{
"type": "naive",
"tag": "naive-in",
"listen": "::",
"listen_port": 443,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"proxy_protocol": false,
"type": "naive",
"tag": "naive-in",
"network": "udp",
"network": "udp",
"users": [
{
"username": "sekai",
"password": "password"
}
],
"tls": {}
... // 监听字段
"users": [
{
"username": "sekai",
"password": "password"
}
]
],
"tls": {}
}
```
@@ -32,7 +22,11 @@
默认安装不包含 HTTP3 传输层, 参阅 [安装](/zh/#_2)。
### Naive 字段
### 监听字段
参阅 [监听字段](/zh/configuration/shared/listen/)。
### 字段
#### network
@@ -48,46 +42,4 @@ Naive 用户。
#### tls
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
### 监听字段
#### listen
==必填==
监听地址。
#### listen_port
==必填==
监听端口。
#### tcp_fast_open
为监听器启用 TCP 快速打开。
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)。
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
#### proxy_protocol
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。

View File

@@ -1,52 +1,18 @@
!!! error ""
Only supported on Linux and macOS.
### Structure
```json
{
"inbounds": [
{
"type": "redirect",
"tag": "redirect-in",
"listen": "::",
"listen_port": 5353,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6"
}
]
"type": "redirect",
"tag": "redirect-in",
... // Listen Fields
}
```
### Listen Fields
#### listen
==Required==
Listen address.
#### listen_port
==Required==
Listen port.
#### sniff
Enable sniffing.
See [Protocol Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
See [Listen Fields](/configuration/shared/listen) for details.

View File

@@ -1,52 +1,17 @@
!!! error ""
仅支持 Linux 和 macOS。
### 结构
```json
{
"inbounds": [
{
"type": "redirect",
"tag": "redirect-in",
"listen": "::",
"listen_port": 5353,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6"
}
]
"type": "redirect",
"tag": "redirect-in",
... // 监听字段
}
```
### 监听字段
#### listen
==必填==
监听地址。
#### listen_port
==必填==
监听端口。
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)。
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
参阅 [监听字段](/zh/configuration/shared/listen/)。

View File

@@ -2,25 +2,13 @@
```json
{
"inbounds": [
{
"type": "shadowsocks",
"tag": "ss-in",
"listen": "::",
"listen_port": 5353,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"udp_timeout": 300,
"network": "udp",
"proxy_protocol": false,
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg=="
}
]
"type": "shadowsocks",
"tag": "ss-in",
... // Listen Fields
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg=="
}
```
@@ -28,17 +16,12 @@
```json
{
"inbounds": [
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"users": [
{
"type": "shadowsocks",
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"users": [
{
"name": "sekai",
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
}
]
"name": "sekai",
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
}
]
}
@@ -48,25 +31,25 @@
```json
{
"inbounds": [
"type": "shadowsocks",
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"destinations": [
{
"type": "shadowsocks",
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"destinations": [
{
"name": "test",
"server": "example.com",
"server_port": 8080,
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
}
]
"name": "test",
"server": "example.com",
"server_port": 8080,
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
}
]
}
```
### Shadowsocks Fields
### Listen Fields
See [Listen Fields](/configuration/shared/listen) for details.
### Fields
#### network

View File

@@ -2,25 +2,13 @@
```json
{
"inbounds": [
{
"type": "shadowsocks",
"tag": "ss-in",
"listen": "::",
"listen_port": 5353,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"udp_timeout": 300,
"network": "udp",
"proxy_protocol": false,
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg=="
}
]
"type": "shadowsocks",
"tag": "ss-in",
... // 监听字段
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg=="
}
```
@@ -28,17 +16,12 @@
```json
{
"inbounds": [
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"users": [
{
"type": "shadowsocks",
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"users": [
{
"name": "sekai",
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
}
]
"name": "sekai",
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
}
]
}
@@ -48,25 +31,25 @@
```json
{
"inbounds": [
"type": "shadowsocks",
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"destinations": [
{
"type": "shadowsocks",
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"destinations": [
{
"name": "test",
"server": "example.com",
"server_port": 8080,
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
}
]
"name": "test",
"server": "example.com",
"server_port": 8080,
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
}
]
}
```
### Shadowsocks 字段
### Listen Fields
See [Listen Fields](/configuration/shared/listen) for details.
### 字段
#### network
@@ -98,50 +81,4 @@
|---------------|-------------------------------|
| none | / |
| 2022 methods | `openssl rand -base64 <密钥长度>` |
| other methods | 任意字符串 |
### 监听字段
#### listen
==必填==
监听地址。
#### listen_port
==必填==
监听端口。
#### tcp_fast_open
为监听器启用 TCP 快速打开。
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)。
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
#### udp_timeout
UDP NAT 过期时间,以秒为单位,默认为 3005 分钟)。
#### proxy_protocol
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
| other methods | 任意字符串 |

View File

@@ -0,0 +1,31 @@
### Structure
```json
{
"type": "shadowtls",
"tag": "st-in",
... // Listen Fields
"handshake": {
"server": "google.com",
"server_port": 443,
... // Dial Fields
}
}
```
### Listen Fields
See [Listen Fields](/configuration/shared/listen) for details.
### Fields
#### handshake
==Required==
Handshake server address and [dial options](/configuration/shared/dial).

View File

@@ -0,0 +1,29 @@
### 结构
```json
{
"type": "shadowtls",
"tag": "st-in",
... // 监听字段
"handshake": {
"server": "google.com",
"server_port": 443,
... // 拨号字段
}
}
```
### 监听字段
参阅 [监听字段](/zh/configuration/shared/listen/)。
### 字段
#### handshake
==必填==
握手服务器地址和 [拨号参数](/zh/configuration/shared/dial/)。

View File

@@ -4,76 +4,28 @@
```json
{
"inbounds": [
{
"type": "socks",
"tag": "socks-in",
"listen": "::",
"listen_port": 2080,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"proxy_protocol": false,
"type": "socks",
"tag": "socks-in",
"users": [
{
"username": "admin",
"password": "admin"
}
]
... // Listen Fields
"users": [
{
"username": "admin",
"password": "admin"
}
]
}
```
### SOCKS Fields
### Listen Fields
See [Listen Fields](/configuration/shared/listen) for details.
### Fields
#### users
SOCKS users.
No authentication required if empty.
### Listen Fields
#### listen
==Required==
Listen address.
#### listen_port
==Required==
Listen port.
#### tcp_fast_open
Enable tcp fast open for listener.
#### sniff
Enable sniffing.
See [Protocol Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
#### proxy_protocol
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.

View File

@@ -4,76 +4,28 @@
```json
{
"inbounds": [
{
"type": "socks",
"tag": "socks-in",
"listen": "::",
"listen_port": 2080,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"proxy_protocol": false,
"type": "socks",
"tag": "socks-in",
"users": [
{
"username": "admin",
"password": "admin"
}
]
... // 监听字段
"users": [
{
"username": "admin",
"password": "admin"
}
]
}
```
### SOCKS 字段
### 监听字段
参阅 [监听字段](/zh/configuration/shared/listen/)。
### 字段
#### users
SOCKS 用户
默认不需要验证。
### Listen Fields
#### listen
==必填==
监听地址。
#### listen_port
==必填==
监听端口。
#### tcp_fast_open
为监听器启用 TCP 快速打开。
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)。
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
#### proxy_protocol
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
如果为空则不需要验证。

View File

@@ -1,67 +1,28 @@
!!! error ""
Only supported on Linux.
### Structure
```json
{
"inbounds": [
{
"type": "tproxy",
"tag": "tproxy-in",
"listen": "::",
"listen_port": 5353,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"udp_timeout": 300,
"network": "udp"
}
]
"type": "tproxy",
"tag": "tproxy-in",
... // Listen Fields
"network": "udp"
}
```
### TProxy Fields
### Listen Fields
See [Listen Fields](/configuration/shared/listen) for details.
### Fields
#### network
Listen network, one of `tcp` `udp`.
Both if empty.
### Listen Fields
#### listen
==Required==
Listen address.
#### listen_port
==Required==
Listen port.
#### sniff
Enable sniffing.
See [Protocol Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
#### udp_timeout
UDP NAT expiration time in seconds, default is 300 (5 minutes).

View File

@@ -1,67 +1,28 @@
!!! error ""
仅支持 Linux。
### 结构
```json
{
"inbounds": [
{
"type": "tproxy",
"tag": "tproxy-in",
"listen": "::",
"listen_port": 5353,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"udp_timeout": 300,
"network": "udp"
}
]
"type": "tproxy",
"tag": "tproxy-in",
... // 监听字段
"network": "udp"
}
```
### TProxy 字段
### 监听字段
参阅 [监听字段](/zh/configuration/shared/listen/)。
### 字段
#### network
监听的网络协议,`tcp` `udp` 之一。
默认所有。
### 监听字段
#### listen
==必填==
监听地址。
#### listen_port
==必填==
监听端口。
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)。
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
#### udp_timeout
UDP NAT 过期时间,以秒为单位,默认为 3005 分钟)。

View File

@@ -2,43 +2,37 @@
```json
{
"inbounds": [
{
"type": "trojan",
"tag": "trojan-in",
"listen": "::",
"listen_port": 2080,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"proxy_protocol": false,
"type": "trojan",
"tag": "trojan-in",
"users": [
{
"name": "sekai",
"password": "8JCsPssfgS8tiRwiMlhARg=="
}
],
"tls": {},
"fallback": {
"server": "127.0.0.1",
"server_port": 8080
},
"fallback_for_alpn": {
"http/1.1": {
"server": "127.0.0.1",
"server_port": 8081
}
},
"transport": {}
... // Listen Fields
"users": [
{
"name": "sekai",
"password": "8JCsPssfgS8tiRwiMlhARg=="
}
]
],
"tls": {},
"fallback": {
"server": "127.0.0.1",
"server_port": 8080
},
"fallback_for_alpn": {
"http/1.1": {
"server": "127.0.0.1",
"server_port": 8081
}
},
"transport": {}
}
```
### Trojan Fields
### Listen Fields
See [Listen Fields](/configuration/shared/listen) for details.
### Fields
#### users
@@ -67,45 +61,3 @@ If not empty, TLS fallback requests with ALPN not in this table will be rejected
#### transport
V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray-transport).
### Listen Fields
#### listen
==Required==
Listen address.
#### listen_port
==Required==
Listen port.
#### tcp_fast_open
Enable tcp fast open for listener.
#### sniff
Enable sniffing.
See [Protocol Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
#### proxy_protocol
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.

View File

@@ -2,41 +2,37 @@
```json
{
"inbounds": [
"type": "trojan",
"tag": "trojan-in",
... // 监听字段
"users": [
{
"type": "trojan",
"tag": "trojan-in",
"listen": "::",
"listen_port": 2080,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"proxy_protocol": false,
"users": [
{
"name": "sekai",
"password": "8JCsPssfgS8tiRwiMlhARg=="
}
],
"tls": {},
"fallback": {
"server": "127.0.0.1",
"server_port": 8080
},
"fallback_for_alpn": {
"http/1.1": {
"server": "127.0.0.1",
"server_port": 8081
}
},
"transport": {}
"name": "sekai",
"password": "8JCsPssfgS8tiRwiMlhARg=="
}
]
],
"tls": {},
"fallback": {
"server": "127.0.0.1",
"server_port": 8080
},
"fallback_for_alpn": {
"http/1.1": {
"server": "127.0.0.1",
"server_port": 8081
}
},
"transport": {}
}
```
### Trojan 字段
### 监听字段
参阅 [监听字段](/zh/configuration/shared/listen/)。
### 字段
#### users
@@ -54,7 +50,7 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
!!! error ""
没有证据表明 GFW 基于 HTTP 响应检测并阻止木马服务器,并且在服务器上打开标准 http/s 端口是一个更大的特征。
没有证据表明 GFW 基于 HTTP 响应检测并阻止 Trojan 服务器,并且在服务器上打开标准 http/s 端口是一个更大的特征。
回退服务器配置。如果 `fallback``fallback_for_alpn` 为空,则禁用回退。
@@ -66,46 +62,4 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
#### transport
V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-transport)。
### 监听字段
#### listen
==必填==
监听地址。
#### listen_port
==必填==
监听端口。
#### tcp_fast_open
为监听器启用 TCP 快速打开。
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)。
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
#### proxy_protocol
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-transport)。

View File

@@ -6,48 +6,41 @@
```json
{
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"interface_name": "tun0",
"inet4_address": "172.19.0.1/30",
"inet6_address": "fdfe:dcba:9876::1/128",
"mtu": 1500,
"auto_route": true,
"strict_route": true,
"endpoint_independent_nat": false,
"udp_timeout": 300,
"stack": "gvisor",
"include_uid": [
0
],
"include_uid_range": [
[
"1000-99999"
]
],
"exclude_uid": [
1000
],
"exclude_uid_range": [
"1000-99999"
],
"include_android_user": [
0,
10
],
"include_package": [
"com.android.chrome"
],
"exclude_package": [
"com.android.captiveportallogin"
],
"sniff": true,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv4"
}
]
"type": "tun",
"tag": "tun-in",
"interface_name": "tun0",
"inet4_address": "172.19.0.1/30",
"inet6_address": "fdfe:dcba:9876::1/128",
"mtu": 1500,
"auto_route": true,
"strict_route": true,
"endpoint_independent_nat": false,
"stack": "gvisor",
"include_uid": [
0
],
"include_uid_range": [
"1000-99999"
],
"exclude_uid": [
1000
],
"exclude_uid_range": [
"1000-99999"
],
"include_android_user": [
0,
10
],
"include_package": [
"com.android.chrome"
],
"exclude_package": [
"com.android.captiveportallogin"
],
... // Listen Fields
}
```
@@ -59,7 +52,7 @@
If tun is running in non-privileged mode, addresses and MTU will not be configured automatically, please make sure the settings are accurate.
### Tun Fields
### Fields
#### interface_name
@@ -163,22 +156,4 @@ Exclude android packages in route.
### Listen Fields
#### sniff
Enable sniffing.
See [Protocol Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
See [Listen Fields](/configuration/shared/listen) for details.

View File

@@ -6,48 +6,41 @@
```json
{
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"interface_name": "tun0",
"inet4_address": "172.19.0.1/30",
"inet6_address": "fdfe:dcba:9876::1/128",
"mtu": 1500,
"auto_route": true,
"strict_route": true,
"endpoint_independent_nat": false,
"udp_timeout": 300,
"stack": "gvisor",
"include_uid": [
0
],
"include_uid_range": [
[
"1000-99999"
]
],
"exclude_uid": [
1000
],
"exclude_uid_range": [
"1000-99999"
],
"include_android_user": [
0,
10
],
"include_package": [
"com.android.chrome"
],
"exclude_package": [
"com.android.captiveportallogin"
],
"sniff": true,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv4"
}
]
"type": "tun",
"tag": "tun-in",
"interface_name": "tun0",
"inet4_address": "172.19.0.1/30",
"inet6_address": "fdfe:dcba:9876::1/128",
"mtu": 1500,
"auto_route": true,
"strict_route": true,
"endpoint_independent_nat": false,
"stack": "gvisor",
"include_uid": [
0
],
"include_uid_range": [
"1000-99999"
],
"exclude_uid": [
1000
],
"exclude_uid_range": [
"1000-99999"
],
"include_android_user": [
0,
10
],
"include_package": [
"com.android.chrome"
],
"exclude_package": [
"com.android.captiveportallogin"
],
... // 监听字段
}
```
@@ -162,22 +155,4 @@ TCP/IP 栈。
### 监听字段
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)。
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
参阅 [监听字段](/zh/configuration/shared/listen/)。

View File

@@ -2,34 +2,28 @@
```json
{
"inbounds": [
{
"type": "vmess",
"tag": "vmess-in",
"listen": "::",
"listen_port": 2080,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"proxy_protocol": false,
"type": "vmess",
"tag": "vmess-in",
"users": [
{
"name": "sekai",
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
"alterId": 0
}
],
"tls": {},
"transport": {}
... // Listen Fields
"users": [
{
"name": "sekai",
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
"alterId": 0
}
]
],
"tls": {},
"transport": {}
}
```
### VMess Fields
### Listen Fields
See [Listen Fields](/configuration/shared/listen) for details.
### Fields
#### users
@@ -53,45 +47,3 @@ TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
#### transport
V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray-transport).
### Listen Fields
#### listen
==Required==
Listen address.
#### listen_port
==Required==
Listen port.
#### tcp_fast_open
Enable tcp fast open for listener.
#### sniff
Enable sniffing.
See [Protocol Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
#### proxy_protocol
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.

View File

@@ -2,34 +2,28 @@
```json
{
"inbounds": [
{
"type": "vmess",
"tag": "vmess-in",
"listen": "::",
"listen_port": 2080,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"proxy_protocol": false,
"type": "vmess",
"tag": "vmess-in",
"users": [
{
"name": "sekai",
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
"alterId": 0
}
],
"tls": {},
"transport": {}
... // 监听字段
"users": [
{
"name": "sekai",
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
"alterId": 0
}
]
],
"tls": {},
"transport": {}
}
```
### VMess 字段
### 监听字段
参阅 [监听字段](/zh/configuration/shared/listen/)。
### 字段
#### users
@@ -53,45 +47,3 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
#### transport
V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-transport)。
### 监听字段
#### listen
==必填==
监听地址。
#### listen_port
==必填==
监听端口。
#### tcp_fast_open
为监听器启用 TCP 快速打开。
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)。
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
#### proxy_protocol
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。

View File

@@ -8,8 +8,8 @@ sing-box uses JSON for configuration files.
{
"log": {},
"dns": {},
"inbounds": {},
"outbounds": {},
"inbounds": [],
"outbounds": [],
"route": {},
"experimental": {}
}

View File

@@ -8,8 +8,8 @@ sing-box 使用 JSON 作为配置文件格式。
{
"log": {},
"dns": {},
"inbounds": {},
"outbounds": {},
"inbounds": [],
"outbounds": [],
"route": {},
"experimental": {}
}

View File

@@ -1,3 +1,5 @@
# Log
### Structure
```json

View File

@@ -1,3 +1,5 @@
# 日志
### 结构
```json

View File

@@ -4,12 +4,8 @@
```json
{
"outbounds": [
{
"type": "block",
"tag": "block"
}
]
"type": "block",
"tag": "block"
}
```

View File

@@ -4,12 +4,8 @@
```json
{
"outbounds": [
{
"type": "block",
"tag": "block"
}
]
"type": "block",
"tag": "block"
}
```

View File

@@ -4,30 +4,18 @@
```json
{
"outbounds": [
{
"type": "direct",
"tag": "direct-out",
"override_address": "1.0.0.1",
"override_port": 53,
"proxy_protocol": 0,
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "direct",
"tag": "direct-out",
"override_address": "1.0.0.1",
"override_port": 53,
"proxy_protocol": 0,
... // Dial Fields
}
```
### Direct Fields
### Fields
#### override_address
@@ -45,54 +33,4 @@ Protocol value can be `1` or `2`.
### Dial Fields
#### detour
The tag of the upstream outbound.
Other dial fields will be ignored when enabled.
#### bind_interface
The network interface to bind to.
#### bind_address
The address to bind to.
#### routing_mark
!!! error ""
Only supported on Linux.
Set netfilter routing mark.
#### reuse_addr
Reuse listener address.
#### connect_timeout
Connect timeout, in golang's Duration format.
A duration string is a possibly signed sequence of
decimal numbers, each with optional fraction and a unit suffix,
such as "300ms", "-1.5h" or "2h45m".
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before connect.
`dns.strategy` will be used if empty.
#### fallback_delay
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
That is, is the amount of time to wait for IPv6 to succeed before assuming
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
If zero, a default delay of 300ms is used.
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
See [Dial Fields](/configuration/shared/dial) for details.

View File

@@ -4,30 +4,18 @@
```json
{
"outbounds": [
{
"type": "direct",
"tag": "direct-out",
"override_address": "1.0.0.1",
"override_port": 53,
"proxy_protocol": 0,
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "direct",
"tag": "direct-out",
"override_address": "1.0.0.1",
"override_port": 53,
"proxy_protocol": 0,
... // 拨号字段
}
```
### Direct 字段
### 字段
#### override_address
@@ -45,51 +33,4 @@
### 拨号字段
#### detour
上游出站的标签。
启用时,其他拨号字段将被忽略。
#### bind_interface
要绑定到的网络接口。
#### bind_address
要绑定的地址。
#### routing_mark
!!! error ""
仅支持 Linux。
设置 netfilter 路由标记。
#### reuse_addr
重用监听地址。
#### connect_timeout
连接超时,采用 golang 的 Duration 格式。
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
#### domain_strategy
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,域名将在请求发出之前解析为 IP。
默认使用 `dns.strategy`
#### fallback_delay
在生成 RFC 6555 快速回退连接之前等待的时间长度。
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
如果为零,则使用 300 毫秒的默认延迟。
仅当 `domain_strategy``prefer_ipv4``prefer_ipv6` 时生效。
参阅 [拨号字段](/zh/configuration/shared/dial/)。

View File

@@ -4,12 +4,8 @@
```json
{
"outbounds": [
{
"type": "dns",
"tag": "dns-out"
}
]
"type": "dns",
"tag": "dns-out"
}
```

View File

@@ -4,12 +4,8 @@
```json
{
"outbounds": [
{
"type": "dns",
"tag": "dns-out"
}
]
"type": "dns",
"tag": "dns-out"
}
```

View File

@@ -4,32 +4,20 @@
```json
{
"outbounds": [
{
"type": "http",
"tag": "http-out",
"server": "127.0.0.1",
"server_port": 1080,
"username": "sekai",
"password": "admin",
"tls": {},
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "http",
"tag": "http-out",
"server": "127.0.0.1",
"server_port": 1080,
"username": "sekai",
"password": "admin",
"tls": {},
... // Dial Fields
}
```
### HTTP Fields
### Fields
#### server
@@ -57,54 +45,4 @@ TLS configuration, see [TLS](/configuration/shared/tls/#outbound).
### Dial Fields
#### detour
The tag of the upstream outbound.
Other dial fields will be ignored when enabled.
#### bind_interface
The network interface to bind to.
#### bind_address
The address to bind to.
#### routing_mark
!!! error ""
Only supported on Linux.
Set netfilter routing mark.
#### reuse_addr
Reuse listener address.
#### connect_timeout
Connect timeout, in golang's Duration format.
A duration string is a possibly signed sequence of
decimal numbers, each with optional fraction and a unit suffix,
such as "300ms", "-1.5h" or "2h45m".
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the server domain name will be resolved to IP before connecting.
`dns.strategy` will be used if empty.
#### fallback_delay
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
That is, is the amount of time to wait for IPv6 to succeed before assuming
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
If zero, a default delay of 300ms is used.
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
See [Dial Fields](/configuration/shared/dial) for details.

View File

@@ -4,32 +4,20 @@
```json
{
"outbounds": [
{
"type": "http",
"tag": "http-out",
"server": "127.0.0.1",
"server_port": 1080,
"username": "sekai",
"password": "admin",
"tls": {},
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "http",
"tag": "http-out",
"server": "127.0.0.1",
"server_port": 1080,
"username": "sekai",
"password": "admin",
"tls": {},
... // 拨号字段
}
```
### HTTP 字段
### 字段
#### server
@@ -57,51 +45,4 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#outbound)。
### 拨号字段
#### detour
上游出站的标签。
启用时,其他拨号字段将被忽略。
#### bind_interface
要绑定到的网络接口。
#### bind_address
要绑定的地址。
#### routing_mark
!!! error ""
仅支持 Linux。
设置 netfilter 路由标记。
#### reuse_addr
重用监听地址。
#### connect_timeout
连接超时,采用 golang 的 Duration 格式。
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
#### domain_strategy
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,服务器域名将在连接前解析为 IP。
默认使用 `dns.strategy`
#### fallback_delay
在生成 RFC 6555 快速回退连接之前等待的时间长度。
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
如果为零,则使用 300 毫秒的默认延迟。
仅当 `domain_strategy``prefer_ipv4``prefer_ipv6` 时生效。
参阅 [拨号字段](/zh/configuration/shared/dial/)。

View File

@@ -2,37 +2,25 @@
```json
{
"outbounds": [
{
"type": "hysteria",
"tag": "hysteria-out",
"server": "127.0.0.1",
"server_port": 1080,
"up": "100 Mbps",
"up_mbps": 100,
"down": "100 Mbps",
"down_mbps": 100,
"obfs": "fuck me till the daylight",
"auth": "",
"auth_str": "password",
"recv_window_conn": 0,
"recv_window": 0,
"disable_mtu_discovery": false,
"network": "tcp",
"tls": {},
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "hysteria",
"tag": "hysteria-out",
"server": "127.0.0.1",
"server_port": 1080,
"up": "100 Mbps",
"up_mbps": 100,
"down": "100 Mbps",
"down_mbps": 100,
"obfs": "fuck me till the daylight",
"auth": "",
"auth_str": "password",
"recv_window_conn": 0,
"recv_window": 0,
"disable_mtu_discovery": false,
"network": "tcp",
"tls": {},
... // Dial Fields
}
```
@@ -40,7 +28,7 @@
QUIC, which is required by hysteria is not included by default, see [Installation](/#installation).
### Hysteria Fields
### Fields
#### server
@@ -125,54 +113,4 @@ Both is enabled by default.
### Dial Fields
#### detour
The tag of the upstream outbound.
Other dial fields will be ignored when enabled.
#### bind_interface
The network interface to bind to.
#### bind_address
The address to bind to.
#### routing_mark
!!! error ""
Only supported on Linux.
Set netfilter routing mark.
#### reuse_addr
Reuse listener address.
#### connect_timeout
Connect timeout, in golang's Duration format.
A duration string is a possibly signed sequence of
decimal numbers, each with optional fraction and a unit suffix,
such as "300ms", "-1.5h" or "2h45m".
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the server domain name will be resolved to IP before connecting.
`dns.strategy` will be used if empty.
#### fallback_delay
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
That is, is the amount of time to wait for IPv6 to succeed before assuming
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
If zero, a default delay of 300ms is used.
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
See [Dial Fields](/configuration/shared/dial) for details.

View File

@@ -2,37 +2,25 @@
```json
{
"outbounds": [
{
"type": "hysteria",
"tag": "hysteria-out",
"server": "127.0.0.1",
"server_port": 1080,
"up": "100 Mbps",
"up_mbps": 100,
"down": "100 Mbps",
"down_mbps": 100,
"obfs": "fuck me till the daylight",
"auth": "",
"auth_str": "password",
"recv_window_conn": 0,
"recv_window": 0,
"disable_mtu_discovery": false,
"network": "tcp",
"tls": {},
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "hysteria",
"tag": "hysteria-out",
"server": "127.0.0.1",
"server_port": 1080,
"up": "100 Mbps",
"up_mbps": 100,
"down": "100 Mbps",
"down_mbps": 100,
"obfs": "fuck me till the daylight",
"auth": "",
"auth_str": "password",
"recv_window_conn": 0,
"recv_window": 0,
"disable_mtu_discovery": false,
"network": "tcp",
"tls": {},
... // 拨号字段
}
```
@@ -40,7 +28,7 @@
默认安装不包含被 Hysteria 依赖的 QUIC参阅 [安装](/zh/#_2)。
### Hysteria 字段
### 字段
#### server
@@ -123,51 +111,4 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#outbound)。
### 拨号字段
#### detour
上游出站的标签。
启用时,其他拨号字段将被忽略。
#### bind_interface
要绑定到的网络接口。
#### bind_address
要绑定的地址。
#### routing_mark
!!! error ""
仅支持 Linux。
设置 netfilter 路由标记。
#### reuse_addr
重用监听地址
#### connect_timeout
连接超时,采用 golang 的 Duration 格式。
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
#### domain_strategy
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,服务器域名将在连接前解析为 IP。
默认使用 `dns.strategy`
#### fallback_delay
在生成 RFC 6555 快速回退连接之前等待的时间长度。
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
如果为零,则使用 300 毫秒的默认延迟。
仅当 `domain_strategy``prefer_ipv4``prefer_ipv6` 时生效。
参阅 [拨号字段](/zh/configuration/shared/dial/)。

View File

@@ -2,19 +2,15 @@
```json
{
"type": "selector",
"tag": "select",
"outbounds": [
{
"type": "selector",
"tag": "select",
"outbounds": [
"proxy-a",
"proxy-b",
"proxy-c"
],
"default": "proxy-c"
}
]
"proxy-a",
"proxy-b",
"proxy-c"
],
"default": "proxy-c"
}
```

View File

@@ -2,19 +2,15 @@
```json
{
"type": "selector",
"tag": "select",
"outbounds": [
{
"type": "selector",
"tag": "select",
"outbounds": [
"proxy-a",
"proxy-b",
"proxy-c"
],
"default": "proxy-c"
}
]
"proxy-a",
"proxy-b",
"proxy-c"
],
"default": "proxy-c"
}
```

View File

@@ -2,34 +2,22 @@
```json
{
"outbounds": [
{
"type": "shadowsocks",
"tag": "ss-out",
"server": "127.0.0.1",
"server_port": 1080,
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"network": "udp",
"udp_over_tcp": false,
"multiplex": {},
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "shadowsocks",
"tag": "ss-out",
"server": "127.0.0.1",
"server_port": 1080,
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"network": "udp",
"udp_over_tcp": false,
"multiplex": {},
... // Dial Fields
}
```
### Shadowsocks Fields
### Fields
#### server
@@ -97,54 +85,4 @@ Multiplex configuration, see [Multiplex](/configuration/shared/multiplex).
### Dial Fields
#### detour
The tag of the upstream outbound.
Other dial fields will be ignored when enabled.
#### bind_interface
The network interface to bind to.
#### bind_address
The address to bind to.
#### routing_mark
!!! error ""
Only supported on Linux.
Set netfilter routing mark.
#### reuse_addr
Reuse listener address.
#### connect_timeout
Connect timeout, in golang's Duration format.
A duration string is a possibly signed sequence of
decimal numbers, each with optional fraction and a unit suffix,
such as "300ms", "-1.5h" or "2h45m".
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the server domain name will be resolved to IP before connecting.
`dns.strategy` will be used if empty.
#### fallback_delay
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
That is, is the amount of time to wait for IPv6 to succeed before assuming
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
If zero, a default delay of 300ms is used.
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
See [Dial Fields](/configuration/shared/dial) for details.

View File

@@ -1,35 +1,23 @@
### Structure
### 结构
```json
{
"outbounds": [
{
"type": "shadowsocks",
"tag": "ss-out",
"server": "127.0.0.1",
"server_port": 1080,
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"network": "udp",
"udp_over_tcp": false,
"multiplex": {},
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "shadowsocks",
"tag": "ss-out",
"server": "127.0.0.1",
"server_port": 1080,
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"network": "udp",
"udp_over_tcp": false,
"multiplex": {},
... // 拨号字段
}
```
### Shadowsocks 字段
### 字段
#### server
@@ -97,51 +85,4 @@ Shadowsocks 密码。
### 拨号字段
#### detour
上游出站的标签。
启用时,其他拨号字段将被忽略。
#### bind_interface
要绑定到的网络接口。
#### bind_address
要绑定的地址。
#### routing_mark
!!! error ""
仅支持 Linux。
设置 netfilter 路由标记。
#### reuse_addr
重用监听地址。
#### connect_timeout
连接超时,采用 golang 的 Duration 格式。
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
#### domain_strategy
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,服务器域名将在连接前解析为 IP。
默认使用 `dns.strategy`
#### fallback_delay
在生成 RFC 6555 快速回退连接之前等待的时间长度。
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
如果为零,则使用 300 毫秒的默认延迟。
仅当 `domain_strategy``prefer_ipv4``prefer_ipv6` 时生效。
参阅 [拨号字段](/zh/configuration/shared/dial/)。

View File

@@ -0,0 +1,38 @@
### Structure
```json
{
"type": "shadowtls",
"tag": "st-out",
"server": "127.0.0.1",
"server_port": 1080,
"tls": {},
... // Dial Fields
}
```
### Fields
#### server
==Required==
The server address.
#### server_port
==Required==
The server port.
#### tls
==Required==
TLS configuration, see [TLS](/configuration/shared/tls/#outbound).
### Dial Fields
See [Dial Fields](/configuration/shared/dial) for details.

View File

@@ -0,0 +1,38 @@
### 结构
```json
{
"type": "shadowtls",
"tag": "st-out",
"server": "127.0.0.1",
"server_port": 1080,
"tls": {},
... // 拨号字段
}
```
### 字段
#### server
==必填==
服务器地址。
#### server_port
==必填==
服务器端口。
#### tls
==必填==
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#outbound)。
### 拨号字段
参阅 [拨号字段](/zh/configuration/shared/dial/)。

View File

@@ -4,34 +4,22 @@
```json
{
"outbounds": [
{
"type": "socks",
"tag": "socks-out",
"server": "127.0.0.1",
"server_port": 1080,
"version": "5",
"username": "sekai",
"password": "admin",
"network": "udp",
"udp_over_tcp": false,
"type": "socks",
"tag": "socks-out",
"server": "127.0.0.1",
"server_port": 1080,
"version": "5",
"username": "sekai",
"password": "admin",
"network": "udp",
"udp_over_tcp": false,
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
... // Dial Fields
}
```
### SOCKS Fields
### Fields
#### server
@@ -73,54 +61,4 @@ Enable the UDP over TCP protocol.
### Dial Fields
#### detour
The tag of the upstream outbound.
Other dial fields will be ignored when enabled.
#### bind_interface
The network interface to bind to.
#### bind_address
The address to bind to.
#### routing_mark
!!! error ""
Only supported on Linux.
Set netfilter routing mark.
#### reuse_addr
Reuse listener address.
#### connect_timeout
Connect timeout, in golang's Duration format.
A duration string is a possibly signed sequence of
decimal numbers, each with optional fraction and a unit suffix,
such as "300ms", "-1.5h" or "2h45m".
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the server domain name will be resolved to IP before connecting.
`dns.strategy` will be used if empty.
#### fallback_delay
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
That is, is the amount of time to wait for IPv6 to succeed before assuming
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
If zero, a default delay of 300ms is used.
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
See [Dial Fields](/configuration/shared/dial) for details.

View File

@@ -1,37 +1,25 @@
`socks` 出站是 socks4/socks4a/socks5 客户端
### Structure
### 结构
```json
{
"outbounds": [
{
"type": "socks",
"tag": "socks-out",
"server": "127.0.0.1",
"server_port": 1080,
"version": "5",
"username": "sekai",
"password": "admin",
"network": "udp",
"udp_over_tcp": false,
"type": "socks",
"tag": "socks-out",
"server": "127.0.0.1",
"server_port": 1080,
"version": "5",
"username": "sekai",
"password": "admin",
"network": "udp",
"udp_over_tcp": false,
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
... // 拨号字段
}
```
### SOCKS 字段
### 字段
#### server
@@ -73,51 +61,4 @@ SOCKS5 密码。
### 拨号字段
#### detour
上游出站的标签。
启用时,其他拨号字段将被忽略。
#### bind_interface
要绑定到的网络接口。
#### bind_address
要绑定的地址。
#### routing_mark
!!! error ""
仅支持 Linux。
设置 netfilter 路由标记。
#### reuse_addr
重用监听地址。
#### connect_timeout
连接超时,采用 golang 的 Duration 格式。
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
#### domain_strategy
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,服务器域名将在连接前解析为 IP。
默认使用 `dns.strategy`
#### fallback_delay
在生成 RFC 6555 快速回退连接之前等待的时间长度。
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
如果为零,则使用 300 毫秒的默认延迟。
仅当 `domain_strategy``prefer_ipv4``prefer_ipv6` 时生效。
参阅 [拨号字段](/zh/configuration/shared/dial/)。

View File

@@ -2,36 +2,24 @@
```json
{
"outbounds": [
{
"type": "ssh",
"tag": "ssh-out",
"server": "127.0.0.1",
"server_port": 22,
"user": "root",
"password": "admin",
"private_key": "",
"private_key_path": "$HOME/.ssh/id_rsa",
"private_key_passphrase": "",
"host_key_algorithms": [],
"client_version": "SSH-2.0-OpenSSH_7.4p1",
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "ssh",
"tag": "ssh-out",
"server": "127.0.0.1",
"server_port": 22,
"user": "root",
"password": "admin",
"private_key": "",
"private_key_path": "$HOME/.ssh/id_rsa",
"private_key_passphrase": "",
"host_key_algorithms": [],
"client_version": "SSH-2.0-OpenSSH_7.4p1",
... // Dial Fields
}
```
### SSH Fields
### Fields
#### server
@@ -73,54 +61,4 @@ Client version. Random version will be used if empty.
### Dial Fields
#### detour
The tag of the upstream outbound.
Other dial fields will be ignored when enabled.
#### bind_interface
The network interface to bind to.
#### bind_address
The address to bind to.
#### routing_mark
!!! error ""
Only supported on Linux.
Set netfilter routing mark.
#### reuse_addr
Reuse listener address.
#### connect_timeout
Connect timeout, in golang's Duration format.
A duration string is a possibly signed sequence of
decimal numbers, each with optional fraction and a unit suffix,
such as "300ms", "-1.5h" or "2h45m".
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the server domain name will be resolved to IP before connecting.
`dns.strategy` will be used if empty.
#### fallback_delay
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
That is, is the amount of time to wait for IPv6 to succeed before assuming
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
If zero, a default delay of 300ms is used.
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
See [Dial Fields](/configuration/shared/dial) for details.

View File

@@ -1,37 +1,25 @@
### Structure
### 结构
```json
{
"outbounds": [
{
"type": "ssh",
"tag": "ssh-out",
"server": "127.0.0.1",
"server_port": 22,
"user": "root",
"password": "admin",
"private_key": "",
"private_key_path": "$HOME/.ssh/id_rsa",
"private_key_passphrase": "",
"host_key_algorithms": [],
"client_version": "SSH-2.0-OpenSSH_7.4p1",
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "ssh",
"tag": "ssh-out",
"server": "127.0.0.1",
"server_port": 22,
"user": "root",
"password": "admin",
"private_key": "",
"private_key_path": "$HOME/.ssh/id_rsa",
"private_key_passphrase": "",
"host_key_algorithms": [],
"client_version": "SSH-2.0-OpenSSH_7.4p1",
... // 拨号字段
}
```
### SSH 字段
### 字段
#### server
@@ -73,51 +61,4 @@ SSH 用户, 默认使用 root。
### 拨号字段
#### detour
上游出站的标签。
启用时,其他拨号字段将被忽略。
#### bind_interface
要绑定到的网络接口。
#### bind_address
要绑定的地址。
#### routing_mark
!!! error ""
仅支持 Linux。
设置 netfilter 路由标记。
#### reuse_addr
重用监听地址。
#### connect_timeout
连接超时,采用 golang 的 Duration 格式。
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
#### domain_strategy
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,服务器域名将在连接前解析为 IP。
默认使用 `dns.strategy`
#### fallback_delay
在生成 RFC 6555 快速回退连接之前等待的时间长度。
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
如果为零,则使用 300 毫秒的默认延迟。
仅当 `domain_strategy``prefer_ipv4``prefer_ipv6` 时生效。
参阅 [拨号字段](/zh/configuration/shared/dial/)。

View File

@@ -2,29 +2,17 @@
```json
{
"outbounds": [
{
"type": "tor",
"tag": "tor-out",
"executable_path": "/usr/bin/tor",
"extra_args": [],
"data_directory": "$HOME/.cache/tor",
"torrc": {
"ClientOnly": 1
},
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "tor",
"tag": "tor-out",
"executable_path": "/usr/bin/tor",
"extra_args": [],
"data_directory": "$HOME/.cache/tor",
"torrc": {
"ClientOnly": 1
},
... // Dial Fields
}
```
@@ -32,7 +20,7 @@
Embedded tor is not included by default, see [Installation](/#installation).
### Tor Fields
### Fields
#### executable_path
@@ -56,58 +44,8 @@ Each start will be very slow if not specified.
Map of torrc options.
See [tor(1)](https://linux.die.net/man/1/tor)
See [tor(1)](https://linux.die.net/man/1/tor) for details.
### Dial Fields
#### detour
The tag of the upstream outbound.
Other dial fields will be ignored when enabled.
#### bind_interface
The network interface to bind to.
#### bind_address
The address to bind to.
#### routing_mark
!!! error ""
Only supported on Linux.
Set netfilter routing mark.
#### reuse_addr
Reuse listener address.
#### connect_timeout
Connect timeout, in golang's Duration format.
A duration string is a possibly signed sequence of
decimal numbers, each with optional fraction and a unit suffix,
such as "300ms", "-1.5h" or "2h45m".
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the server domain name will be resolved to IP before connecting.
`dns.strategy` will be used if empty.
#### fallback_delay
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
That is, is the amount of time to wait for IPv6 to succeed before assuming
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
If zero, a default delay of 300ms is used.
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
See [Dial Fields](/configuration/shared/dial) for details.

View File

@@ -2,29 +2,17 @@
```json
{
"outbounds": [
{
"type": "tor",
"tag": "tor-out",
"executable_path": "/usr/bin/tor",
"extra_args": [],
"data_directory": "$HOME/.cache/tor",
"torrc": {
"ClientOnly": 1
},
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "tor",
"tag": "tor-out",
"executable_path": "/usr/bin/tor",
"extra_args": [],
"data_directory": "$HOME/.cache/tor",
"torrc": {
"ClientOnly": 1
},
... // 拨号字段
}
```
@@ -32,7 +20,7 @@
默认安装不包含嵌入式 Tor, 参阅 [安装](/zh/#_2)。
### Tor 字段
### 字段
#### executable_path
@@ -60,51 +48,4 @@ torrc 参数表。
### 拨号字段
#### detour
上游出站的标签。
启用时,其他拨号字段将被忽略。
#### bind_interface
要绑定到的网络接口。
#### bind_address
要绑定的地址。
#### routing_mark
!!! error ""
仅支持 Linux。
设置 netfilter 路由标记。
#### reuse_addr
重用监听地址。
#### connect_timeout
连接超时,采用 golang 的 Duration 格式。
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
#### domain_strategy
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,服务器域名将在连接前解析为 IP。
默认使用 `dns.strategy`
#### fallback_delay
在生成 RFC 6555 快速回退连接之前等待的时间长度。
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
如果为零,则使用 300 毫秒的默认延迟。
仅当 `domain_strategy``prefer_ipv4``prefer_ipv6` 时生效。
参阅 [拨号字段](/zh/configuration/shared/dial/)。

View File

@@ -2,34 +2,22 @@
```json
{
"outbounds": [
{
"type": "trojan",
"tag": "trojan-out",
"server": "127.0.0.1",
"server_port": 1080,
"password": "8JCsPssfgS8tiRwiMlhARg==",
"network": "tcp",
"tls": {},
"multiplex": {},
"transport": {},
"type": "trojan",
"tag": "trojan-out",
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"server": "127.0.0.1",
"server_port": 1080,
"password": "8JCsPssfgS8tiRwiMlhARg==",
"network": "tcp",
"tls": {},
"multiplex": {},
"transport": {},
... // Dial Fields
}
```
### Trojan Fields
### Fields
#### server
@@ -71,54 +59,4 @@ V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray
### Dial Fields
#### detour
The tag of the upstream outbound.
Other dial fields will be ignored when enabled.
#### bind_interface
The network interface to bind to.
#### bind_address
The address to bind to.
#### routing_mark
!!! error ""
Only supported on Linux.
Set netfilter routing mark.
#### reuse_addr
Reuse listener address.
#### connect_timeout
Connect timeout, in golang's Duration format.
A duration string is a possibly signed sequence of
decimal numbers, each with optional fraction and a unit suffix,
such as "300ms", "-1.5h" or "2h45m".
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the server domain name will be resolved to IP before connecting.
`dns.strategy` will be used if empty.
#### fallback_delay
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
That is, is the amount of time to wait for IPv6 to succeed before assuming
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
If zero, a default delay of 300ms is used.
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
See [Dial Fields](/configuration/shared/dial) for details.

View File

@@ -2,34 +2,22 @@
```json
{
"outbounds": [
{
"type": "trojan",
"tag": "trojan-out",
"server": "127.0.0.1",
"server_port": 1080,
"password": "8JCsPssfgS8tiRwiMlhARg==",
"network": "tcp",
"tls": {},
"multiplex": {},
"transport": {},
"type": "trojan",
"tag": "trojan-out",
"server": "127.0.0.1",
"server_port": 1080,
"password": "8JCsPssfgS8tiRwiMlhARg==",
"network": "tcp",
"tls": {},
"multiplex": {},
"transport": {},
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
... // 拨号字段
}
```
### Trojan 字段
### 字段
#### server
@@ -71,51 +59,4 @@ V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-tra
### 拨号字段
#### detour
上游出站的标签。
启用时,其他拨号字段将被忽略。
#### bind_interface
要绑定到的网络接口。
#### bind_address
要绑定的地址。
#### routing_mark
!!! error ""
仅支持 Linux。
设置 netfilter 路由标记。
#### reuse_addr
重用监听地址。
#### connect_timeout
连接超时,采用 golang 的 Duration 格式。
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
#### domain_strategy
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,服务器域名将在连接前解析为 IP。
默认使用 `dns.strategy`
#### fallback_delay
在生成 RFC 6555 快速回退连接之前等待的时间长度。
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
如果为零,则使用 300 毫秒的默认延迟。
仅当 `domain_strategy``prefer_ipv4``prefer_ipv6` 时生效。
参阅 [拨号字段](/zh/configuration/shared/dial/)。

View File

@@ -2,39 +2,27 @@
```json
{
"outbounds": [
{
"type": "vmess",
"tag": "vmess-out",
"server": "127.0.0.1",
"server_port": 1080,
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
"security": "auto",
"alter_id": 0,
"global_padding": false,
"authenticated_length": true,
"network": "tcp",
"tls": {},
"packet_addr": false,
"multiplex": {},
"transport": {},
"type": "vmess",
"tag": "vmess-out",
"server": "127.0.0.1",
"server_port": 1080,
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
"security": "auto",
"alter_id": 0,
"global_padding": false,
"authenticated_length": true,
"network": "tcp",
"tls": {},
"packet_addr": false,
"multiplex": {},
"transport": {},
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
... // Dial Fields
}
```
### VMess Fields
### Fields
#### server
@@ -110,54 +98,4 @@ V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray
### Dial Fields
#### detour
The tag of the upstream outbound.
Other dial fields will be ignored when enabled.
#### bind_interface
The network interface to bind to.
#### bind_address
The address to bind to.
#### routing_mark
!!! error ""
Only supported on Linux.
Set netfilter routing mark.
#### reuse_addr
Reuse listener address.
#### connect_timeout
Connect timeout, in golang's Duration format.
A duration string is a possibly signed sequence of
decimal numbers, each with optional fraction and a unit suffix,
such as "300ms", "-1.5h" or "2h45m".
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the server domain name will be resolved to IP before connecting.
`dns.strategy` will be used if empty.
#### fallback_delay
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
That is, is the amount of time to wait for IPv6 to succeed before assuming
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
If zero, a default delay of 300ms is used.
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
See [Dial Fields](/configuration/shared/dial) for details.

View File

@@ -2,39 +2,27 @@
```json
{
"outbounds": [
{
"type": "vmess",
"tag": "vmess-out",
"server": "127.0.0.1",
"server_port": 1080,
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
"security": "auto",
"alter_id": 0,
"global_padding": false,
"authenticated_length": true,
"network": "tcp",
"tls": {},
"packet_addr": false,
"multiplex": {},
"transport": {},
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "vmess",
"tag": "vmess-out",
"server": "127.0.0.1",
"server_port": 1080,
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
"security": "auto",
"alter_id": 0,
"global_padding": false,
"authenticated_length": true,
"network": "tcp",
"tls": {},
"packet_addr": false,
"multiplex": {},
"transport": {},
... // 拨号字段
}
```
### VMess 字段
### 字段
#### server
@@ -110,51 +98,4 @@ V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-tra
### 拨号字段
#### detour
上游出站的标签。
启用时,其他拨号字段将被忽略。
#### bind_interface
要绑定到的网络接口。
#### bind_address
要绑定的地址。
#### routing_mark
!!! error ""
仅支持 Linux。
设置 netfilter 路由标记。
#### reuse_addr
重用监听地址。
#### connect_timeout
连接超时,采用 golang 的 Duration 格式。
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
#### domain_strategy
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,服务器域名将在连接前解析为 IP。
默认使用 `dns.strategy`
#### fallback_delay
在生成 RFC 6555 快速回退连接之前等待的时间长度。
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
如果为零,则使用 300 毫秒的默认延迟。
仅当 `domain_strategy``prefer_ipv4``prefer_ipv6` 时生效。
参阅 [拨号字段](/zh/configuration/shared/dial/)。

View File

@@ -2,34 +2,22 @@
```json
{
"outbounds": [
{
"type": "wireguard",
"tag": "wireguard-out",
"server": "127.0.0.1",
"server_port": 1080,
"local_address": [
"10.0.0.1",
"10.0.0.2/32"
],
"private_key": "YNXtAzepDqRv9H52osJVDQnznT5AM11eCK3ESpwSt04=",
"peer_public_key": "Z1XXLsKYkYxuiYjJIkRvtIKFepCYHTgON+GwPq7SOV4=",
"pre_shared_key": "31aIhAPwktDGpH4JDhA8GNvjFXEf/a6+UaQRyOAiyfM=",
"mtu": 1408,
"network": "tcp",
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "wireguard",
"tag": "wireguard-out",
"server": "127.0.0.1",
"server_port": 1080,
"local_address": [
"10.0.0.1",
"10.0.0.2/32"
],
"private_key": "YNXtAzepDqRv9H52osJVDQnznT5AM11eCK3ESpwSt04=",
"peer_public_key": "Z1XXLsKYkYxuiYjJIkRvtIKFepCYHTgON+GwPq7SOV4=",
"pre_shared_key": "31aIhAPwktDGpH4JDhA8GNvjFXEf/a6+UaQRyOAiyfM=",
"mtu": 1408,
"network": "tcp",
... // Dial Fields
}
```
@@ -37,7 +25,7 @@
WireGuard is not included by default, see [Installation](/#installation).
### WireGuard Fields
### Fields
#### server
@@ -92,54 +80,4 @@ Both is enabled by default.
### Dial Fields
#### detour
The tag of the upstream outbound.
Other dial fields will be ignored when enabled.
#### bind_interface
The network interface to bind to.
#### bind_address
The address to bind to.
#### routing_mark
!!! error ""
Only supported on Linux.
Set netfilter routing mark.
#### reuse_addr
Reuse listener address.
#### connect_timeout
Connect timeout, in golang's Duration format.
A duration string is a possibly signed sequence of
decimal numbers, each with optional fraction and a unit suffix,
such as "300ms", "-1.5h" or "2h45m".
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the server domain name will be resolved to IP before connecting.
`dns.strategy` will be used if empty.
#### fallback_delay
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
That is, is the amount of time to wait for IPv6 to succeed before assuming
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
If zero, a default delay of 300ms is used.
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
See [Dial Fields](/configuration/shared/dial) for details.

View File

@@ -2,34 +2,22 @@
```json
{
"outbounds": [
{
"type": "wireguard",
"tag": "wireguard-out",
"server": "127.0.0.1",
"server_port": 1080,
"local_address": [
"10.0.0.1",
"10.0.0.2/32"
],
"private_key": "YNXtAzepDqRv9H52osJVDQnznT5AM11eCK3ESpwSt04=",
"peer_public_key": "Z1XXLsKYkYxuiYjJIkRvtIKFepCYHTgON+GwPq7SOV4=",
"pre_shared_key": "31aIhAPwktDGpH4JDhA8GNvjFXEf/a6+UaQRyOAiyfM=",
"mtu": 1408,
"network": "tcp",
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
"type": "wireguard",
"tag": "wireguard-out",
"server": "127.0.0.1",
"server_port": 1080,
"local_address": [
"10.0.0.1",
"10.0.0.2/32"
],
"private_key": "YNXtAzepDqRv9H52osJVDQnznT5AM11eCK3ESpwSt04=",
"peer_public_key": "Z1XXLsKYkYxuiYjJIkRvtIKFepCYHTgON+GwPq7SOV4=",
"pre_shared_key": "31aIhAPwktDGpH4JDhA8GNvjFXEf/a6+UaQRyOAiyfM=",
"mtu": 1408,
"network": "tcp",
... // 拨号字段
}
```
@@ -37,7 +25,7 @@
默认安装不包含 WireGuard, 参阅 [安装](/zh/#_2)。
### WireGuard 字段
### 字段
#### server
@@ -94,51 +82,4 @@ WireGuard MTU。 默认1408。
### 拨号字段
#### detour
上游出站的标签。
启用时,其他拨号字段将被忽略。
#### bind_interface
要绑定到的网络接口。
#### bind_address
要绑定的地址。
#### routing_mark
!!! error ""
仅支持 Linux。
设置 netfilter 路由标记。
#### reuse_addr
重用监听地址。
#### connect_timeout
连接超时,采用 golang 的 Duration 格式。
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
#### domain_strategy
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,服务器域名将在连接前解析为 IP。
默认使用 `dns.strategy`
#### fallback_delay
在生成 RFC 6555 快速回退连接之前等待的时间长度。
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
如果为零,则使用 300 毫秒的默认延迟。
仅当 `domain_strategy``prefer_ipv4``prefer_ipv6` 时生效。
参阅 [拨号字段](/zh/configuration/shared/dial/)。

View File

@@ -68,6 +68,9 @@
"process_name": [
"curl"
],
"process_path": [
"/usr/bin/curl"
],
"package_name": [
"com.termux"
],
@@ -188,6 +191,14 @@ Match port range.
Match process name.
#### process_path
!!! error ""
Only supported on Linux, Windows, and macOS.
Match process path.
#### package_name
Match android package name.

View File

@@ -66,6 +66,9 @@
"process_name": [
"curl"
],
"process_path": [
"/usr/bin/curl"
],
"package_name": [
"com.termux"
],
@@ -186,6 +189,14 @@
匹配进程名称。
#### process_path
!!! error ""
仅支持 Linux、Windows 和 macOS.
匹配进程路径。
#### package_name
匹配 Android 应用包名。

View File

@@ -0,0 +1,74 @@
### Structure
```json
{
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
```
### Fields
| Field | Available Context |
|-----------------------------------------------------------------------------------|-------------------|
| `bind_interface` /`bind_address` /`routing_mark` /`reuse_addr` /`connect_timeout` | `detour` not set |
#### detour
The tag of the upstream outbound.
#### bind_interface
The network interface to bind to.
#### bind_address
The address to bind to.
#### routing_mark
!!! error ""
Only supported on Linux.
Set netfilter routing mark.
#### reuse_addr
Reuse listener address.
#### connect_timeout
Connect timeout, in golang's Duration format.
A duration string is a possibly signed sequence of
decimal numbers, each with optional fraction and a unit suffix,
such as "300ms", "-1.5h" or "2h45m".
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before connect.
| Outbound | Effected domains | Fallback Value |
|----------|--------------------------|-------------------------------------------|
| `direct` | Domain in request | Take `inbound.domain_strategy` if not set |
| others | Domain in server address | / |
#### fallback_delay
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
That is, is the amount of time to wait for connection to succeed before assuming
that IPv4/IPv6 is misconfigured and falling back to other type of addresses.
If zero, a default delay of 300ms is used.
Only take effect when `domain_strategy` is set.

View File

@@ -0,0 +1,66 @@
### 结构
```json
{
"detour": "upstream-out",
"bind_interface": "en0",
"bind_address": "0.0.0.0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"tcp_fast_open": false,
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
```
### 字段
#### detour
上游出站的标签。
启用时,其他拨号字段将被忽略。
#### bind_interface
要绑定到的网络接口。
#### bind_address
要绑定的地址。
#### routing_mark
!!! error ""
仅支持 Linux。
设置 netfilter 路由标记。
#### reuse_addr
重用监听地址。
#### connect_timeout
连接超时,采用 golang 的 Duration 格式。
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
#### domain_strategy
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,域名将在请求发出之前解析为 IP。
默认使用 `dns.strategy`
#### fallback_delay
在生成 RFC 6555 快速回退连接之前等待的时间长度。
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
如果为零,则使用 300 毫秒的默认延迟。
仅当 `domain_strategy``prefer_ipv4``prefer_ipv6` 时生效。

View File

@@ -0,0 +1,73 @@
### Structure
```json
{
"listen": "::",
"listen_port": 5353,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"udp_timeout": 300,
"proxy_protocol": false,
"detour": "another-in"
}
```
### Fields
| Field | Available Context |
|------------------|-------------------------------------------------------------------|
| `listen` | Needs to listen on TCP or UDP. |
| `listen_port` | Needs to listen on TCP or UDP. |
| `tcp_fast_open` | Needs to listen on TCP. |
| `udp_timeout` | Needs to assemble UDP connections, currently Tun and Shadowsocks. |
| `proxy_protocol` | Needs to listen on TCP. |
#### listen
==Required==
Listen address.
#### listen_port
Listen port.
#### tcp_fast_open
Enable tcp fast open for listener.
#### sniff
Enable sniffing.
See [Protocol Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
#### udp_timeout
UDP NAT expiration time in seconds, default is 300 (5 minutes).
#### proxy_protocol
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.
#### detour
If set, connections will be forwarded to the specified inbound.
Requires target inbound support, see [Injectable](/configuration/inbound/#fields).

View File

@@ -0,0 +1,72 @@
### 结构
```json
{
"listen": "::",
"listen_port": 5353,
"tcp_fast_open": false,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"udp_timeout": 300,
"detour": "another-in"
}
```
| 字段 | 可用上下文 |
|------------------|-------------------------------------|
| `listen` | 需要监听 TCP 或 UDP。 |
| `listen_port` | 需要监听 TCP 或 UDP。 |
| `tcp_fast_open` | 需要监听 TCP。 |
| `udp_timeout` | 需要组装 UDP 连接, 当前为 Tun 和 Shadowsocks。 |
| `proxy_protocol` | 需要监听 TCP。 |
### 字段
#### listen
==必填==
监听地址。
#### listen_port
监听端口。
#### tcp_fast_open
为监听器启用 TCP 快速打开。
#### sniff
启用协议探测。
参阅 [协议探测](/zh/configuration/route/sniff/)
#### sniff_override_destination
用探测出的域名覆盖连接目标地址。
如果域名无效(如 Tor将不生效。
#### domain_strategy
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`
如果设置,请求的域名将在路由之前解析为 IP。
如果 `sniff_override_destination` 生效,它的值将作为后备。
#### udp_timeout
UDP NAT 过期时间,以秒为单位,默认为 3005 分钟)。
#### proxy_protocol
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
#### detour
如果设置,连接将被转发到指定的入站。
需要目标入站支持,参阅 [注入支持](/zh/configuration/inbound/#_3)。

View File

@@ -0,0 +1,55 @@
#### Server
```json
{
"inbounds": [
{
"type": "shadowtls",
"listen": "::",
"listen_port": 4443,
"handshake": {
"server": "google.com",
"server_port": 443
},
"detour": "shadowsocks-in"
},
{
"type": "shadowsocks",
"tag": "shadowsocks-in",
"listen": "127.0.0.1",
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg=="
}
]
}
```
#### Client
```json
{
"outbounds": [
{
"type": "shadowsocks",
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"detour": "shadowtls-out",
"multiplex": {
"enabled": true,
"max_connections": 4,
"min_streams": 4
}
},
{
"type": "shadowtls",
"tag": "shadowtls-out",
"server": "127.0.0.1",
"server_port": 4443,
"tls": {
"enabled": true,
"server_name": "google.com"
}
}
]
}
```

View File

@@ -11,7 +11,7 @@ the public internet.
##### on Linux
`auto-route` cannot automatically hijack DNS requests with `systemd-resoled` enabled, you can switch to NetworkManager.
`auto-route` cannot automatically hijack DNS requests with `systemd-resolved` enabled, you can switch to NetworkManager.
#### System proxy

View File

@@ -10,7 +10,7 @@
##### Linux
`auto-route` 无法自动劫持 DNS 请求如果 `systemd-resoled` 开启, 您可以切换到 NetworkManager.
`auto-route` 无法自动劫持 DNS 请求如果 `systemd-resolved` 开启, 您可以切换到 NetworkManager.
#### 系统代理

View File

@@ -36,7 +36,7 @@ func getConfigs(logFactory log.Factory) func(w http.ResponseWriter, r *http.Requ
logLevel := logFactory.Level()
if logLevel == log.LevelTrace {
logLevel = log.LevelDebug
} else if logLevel > log.LevelError {
} else if logLevel < log.LevelError {
logLevel = log.LevelError
}
render.JSON(w, r, &configSchema{

View File

@@ -8,10 +8,10 @@ import (
"github.com/sagernet/sing-box/common/json"
"github.com/sagernet/sing-box/experimental/clashapi/trafficontrol"
"github.com/sagernet/websocket"
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
"github.com/gorilla/websocket"
)
func connectionRouter(trafficManager *trafficontrol.Manager) http.Handler {

View File

@@ -70,16 +70,26 @@ func proxyInfo(server *Server, detour adapter.Outbound) *badjson.JSONObject {
case C.TypeSocks:
clashType = "Socks"
case C.TypeHTTP:
clashType = "Http"
clashType = "HTTP"
case C.TypeShadowsocks:
clashType = "Shadowsocks"
case C.TypeVMess:
clashType = "Vmess"
clashType = "VMess"
case C.TypeTrojan:
clashType = "Trojan"
case C.TypeHysteria:
clashType = "Hysteria"
case C.TypeWireGuard:
clashType = "WireGuard"
case C.TypeTor:
clashType = "Tor"
case C.TypeSSH:
clashType = "SSH"
case C.TypeSelector:
clashType = "Selector"
isGroup = true
default:
clashType = "Unknown"
clashType = "Direct"
}
info.Put("type", clashType)
info.Put("name", detour.Tag())

View File

@@ -21,11 +21,11 @@ import (
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/websocket"
"github.com/go-chi/chi/v5"
"github.com/go-chi/cors"
"github.com/go-chi/render"
"github.com/gorilla/websocket"
)
var _ adapter.ClashServer = (*Server)(nil)

16
go.mod
View File

@@ -12,7 +12,6 @@ require (
github.com/go-chi/cors v1.2.1
github.com/go-chi/render v1.0.2
github.com/gofrs/uuid v4.2.0+incompatible
github.com/gorilla/websocket v1.5.0
github.com/hashicorp/yamux v0.1.1
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/mholt/acmez v1.0.4
@@ -20,25 +19,28 @@ require (
github.com/pires/go-proxyproto v0.6.2
github.com/sagernet/certmagic v0.0.0-20220819042630-4a57f8b6853a
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb
github.com/sagernet/sing v0.0.0-20220826124916-d4ba8fdfac88
github.com/sagernet/sing v0.0.0-20220913004915-27ddefbb8921
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83
github.com/sagernet/sing-vmess v0.0.0-20220827032426-01665c9c4e31
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939
github.com/sagernet/sing-vmess v0.0.0-20220913015714-c4ab86d40e12
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e
github.com/spf13/cobra v1.5.0
github.com/stretchr/testify v1.8.0
go.uber.org/atomic v1.10.0
go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b
google.golang.org/grpc v1.49.0
google.golang.org/protobuf v1.28.1
gvisor.dev/gvisor v0.0.0-20220819163037-ba6e795b139a
)
//replace github.com/sagernet/sing => ../sing
require (
github.com/ajg/form v1.5.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect

28
go.sum
View File

@@ -73,8 +73,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
@@ -135,18 +133,20 @@ github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb h1:wc0yQ+SBn4TaTY
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb/go.mod h1:MIccjRKnPTjWwAOpl+AUGWOkzyTd9tERytudxu+1ra4=
github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.0.0-20220826124916-d4ba8fdfac88 h1:wxUQfVBqiUtAemytzP9mNjAkSiI0nVsRZBQvCLP8r5g=
github.com/sagernet/sing v0.0.0-20220826124916-d4ba8fdfac88/go.mod h1:kZvzh1VDa/Dg/Bt5WaYKU0jl5ept8KKDpl3Ay4gRtRQ=
github.com/sagernet/sing v0.0.0-20220913004915-27ddefbb8921 h1:xUHzlIbdlPV/fkToIO9futp9lmKIY+72ezk/whQ8XsI=
github.com/sagernet/sing v0.0.0-20220913004915-27ddefbb8921/go.mod h1:kZvzh1VDa/Dg/Bt5WaYKU0jl5ept8KKDpl3Ay4gRtRQ=
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 h1:XUTocA/Ek0dFxUX+xJCWMPPFZCn2GC/uLrBjTSr1vHY=
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666/go.mod h1:eDyH7AJmqBGjZQdQmpZIzlbTREudZuWDExMuGKgjRVM=
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4=
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83 h1:SoWiHYuOCVedqA7T/CJSZUUrcPGKQb2wFKEq8DphiAI=
github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83/go.mod h1:76r07HS1WRcEI4mE9pFsohfTBUt1j/G9Avz6DaOP3VU=
github.com/sagernet/sing-vmess v0.0.0-20220827032426-01665c9c4e31 h1:FAsJsVwpPcoITcj6/9JxRKxy8n3bIKLqKmDGVzmfeOo=
github.com/sagernet/sing-vmess v0.0.0-20220827032426-01665c9c4e31/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps=
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4=
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8=
github.com/sagernet/sing-vmess v0.0.0-20220913015714-c4ab86d40e12 h1:4HYGbTDDemgBVTmaspXbkgjJlXc3hYVjNxSddJndq8Y=
github.com/sagernet/sing-vmess v0.0.0-20220913015714-c4ab86d40e12/go.mod h1:u66Vv7NHXJWfeAmhh7JuJp/cwxmuQlM56QoZ7B7Mmd0=
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38=
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8=
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e h1:7uw2njHFGE+VpWamge6o56j2RWk4omF6uLKKxMmcWvs=
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e/go.mod h1:45TUl8+gH4SIKr4ykREbxKWTxkDlSzFENzctB1dVRRY=
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
@@ -181,8 +181,8 @@ golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaE
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
@@ -244,8 +244,8 @@ golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM=
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -276,8 +276,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478 h1:vDy//hdR+GnROE3OdYbQKt9rdtNdHkDtONvpRwmls/0=
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478/go.mod h1:bVQfyl2sCM/QIIGHpWbFGfHPuDvqnCNkT6MQLTCjO/U=
golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b h1:qgrKnOfe1zyURRNdmDlGbN32i38Zjmw0B1+TMdHcOvg=
golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b/go.mod h1:6y4CqPAy54NwiN4nC8K+R1eMpQDB1P2d25qmunh2RSA=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=

View File

@@ -39,6 +39,8 @@ func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, o
return NewNaive(ctx, router, logger, options.Tag, options.NaiveOptions)
case C.TypeHysteria:
return NewHysteria(ctx, router, logger, options.Tag, options.HysteriaOptions)
case C.TypeShadowTLS:
return NewShadowTLS(ctx, router, logger, options.Tag, options.ShadowTLSOptions)
default:
return nil, E.New("unknown inbound type: ", options.Type)
}

View File

@@ -3,25 +3,17 @@ package inbound
import (
"context"
"net"
"net/netip"
"os"
"sync"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/proxyproto"
"github.com/sagernet/sing-box/common/settings"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-dns"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/database64128/tfo-go"
)
var _ adapter.Inbound = (*myInboundAdapter)(nil)
@@ -49,7 +41,6 @@ type myInboundAdapter struct {
tcpListener net.Listener
udpConn *net.UDPConn
udpAddr M.Socksaddr
packetAccess sync.RWMutex
packetOutboundClosed chan struct{}
packetOutbound chan *myInboundPacket
}
@@ -62,6 +53,10 @@ func (a *myInboundAdapter) Tag() string {
return a.tag
}
func (a *myInboundAdapter) Network() []string {
return a.network
}
func (a *myInboundAdapter) Start() error {
var err error
if common.Contains(a.network, N.NetworkTCP) {
@@ -102,38 +97,6 @@ func (a *myInboundAdapter) Start() error {
return nil
}
func (a *myInboundAdapter) ListenTCP() (net.Listener, error) {
var err error
bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort)
var tcpListener net.Listener
if !a.listenOptions.TCPFastOpen {
tcpListener, err = net.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
} else {
tcpListener, err = tfo.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
}
if err == nil {
a.logger.Info("tcp server started at ", tcpListener.Addr())
}
if a.listenOptions.ProxyProtocol {
a.logger.Debug("proxy protocol enabled")
tcpListener = &proxyproto.Listener{Listener: tcpListener}
}
a.tcpListener = tcpListener
return tcpListener, err
}
func (a *myInboundAdapter) ListenUDP() (net.PacketConn, error) {
bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort)
udpConn, err := net.ListenUDP(M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.UDPAddr())
if err != nil {
return nil, err
}
a.udpConn = udpConn
a.udpAddr = bindAddr
a.logger.Info("udp server started at ", udpConn.LocalAddr())
return udpConn, err
}
func (a *myInboundAdapter) Close() error {
var err error
if a.clearSystemProxy != nil {
@@ -170,20 +133,10 @@ func (a *myInboundAdapter) newPacketConnection(ctx context.Context, conn N.Packe
return a.router.RoutePacketConnection(ctx, conn, metadata)
}
func (a *myInboundAdapter) loopTCPIn() {
tcpListener := a.tcpListener
for {
conn, err := tcpListener.Accept()
if err != nil {
return
}
go a.injectTCP(conn)
}
}
func (a *myInboundAdapter) createMetadata(conn net.Conn, metadata adapter.InboundContext) adapter.InboundContext {
metadata.Inbound = a.tag
metadata.InboundType = a.protocol
metadata.InboundDetour = a.listenOptions.Detour
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
@@ -199,166 +152,6 @@ func (a *myInboundAdapter) createMetadata(conn net.Conn, metadata adapter.Inboun
return metadata
}
func (a *myInboundAdapter) injectTCP(conn net.Conn) {
ctx := log.ContextWithNewID(a.ctx)
metadata := a.createMetadata(conn, adapter.InboundContext{})
a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
hErr := a.connHandler.NewConnection(ctx, conn, metadata)
if hErr != nil {
conn.Close()
a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source))
}
}
func (a *myInboundAdapter) routeTCP(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) {
a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
hErr := a.newConnection(ctx, conn, metadata)
if hErr != nil {
conn.Close()
a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source))
}
}
func (a *myInboundAdapter) loopUDPIn() {
defer close(a.packetOutboundClosed)
_buffer := buf.StackNewPacket()
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release()
buffer.IncRef()
defer buffer.DecRef()
packetService := (*myInboundPacketAdapter)(a)
for {
buffer.Reset()
n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
if err != nil {
return
}
buffer.Truncate(n)
var metadata adapter.InboundContext
metadata.Inbound = a.tag
metadata.InboundType = a.protocol
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
metadata.Source = M.SocksaddrFromNetIP(addr)
metadata.OriginDestination = a.udpAddr
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
if err != nil {
a.newError(E.Cause(err, "process packet from ", metadata.Source))
}
}
}
func (a *myInboundAdapter) loopUDPOOBIn() {
defer close(a.packetOutboundClosed)
_buffer := buf.StackNewPacket()
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release()
buffer.IncRef()
defer buffer.DecRef()
packetService := (*myInboundPacketAdapter)(a)
oob := make([]byte, 1024)
for {
buffer.Reset()
n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
if err != nil {
return
}
buffer.Truncate(n)
var metadata adapter.InboundContext
metadata.Inbound = a.tag
metadata.InboundType = a.protocol
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
metadata.Source = M.SocksaddrFromNetIP(addr)
metadata.OriginDestination = a.udpAddr
err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
if err != nil {
a.newError(E.Cause(err, "process packet from ", metadata.Source))
}
}
}
func (a *myInboundAdapter) loopUDPInThreadSafe() {
defer close(a.packetOutboundClosed)
packetService := (*myInboundPacketAdapter)(a)
for {
buffer := buf.NewPacket()
n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
if err != nil {
buffer.Release()
return
}
buffer.Truncate(n)
var metadata adapter.InboundContext
metadata.Inbound = a.tag
metadata.InboundType = a.protocol
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
metadata.Source = M.SocksaddrFromNetIP(addr)
metadata.OriginDestination = a.udpAddr
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
if err != nil {
buffer.Release()
a.newError(E.Cause(err, "process packet from ", metadata.Source))
}
}
}
func (a *myInboundAdapter) loopUDPOOBInThreadSafe() {
defer close(a.packetOutboundClosed)
packetService := (*myInboundPacketAdapter)(a)
oob := make([]byte, 1024)
for {
buffer := buf.NewPacket()
n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
if err != nil {
buffer.Release()
return
}
buffer.Truncate(n)
var metadata adapter.InboundContext
metadata.Inbound = a.tag
metadata.InboundType = a.protocol
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
metadata.Source = M.SocksaddrFromNetIP(addr)
metadata.OriginDestination = a.udpAddr
err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
if err != nil {
buffer.Release()
a.newError(E.Cause(err, "process packet from ", metadata.Source))
}
}
}
func (a *myInboundAdapter) loopUDPOut() {
for {
select {
case packet := <-a.packetOutbound:
err := a.writePacket(packet.buffer, packet.destination)
if err != nil && !E.IsClosed(err) {
a.newError(E.New("write back udp: ", err))
}
continue
case <-a.packetOutboundClosed:
}
for {
select {
case packet := <-a.packetOutbound:
packet.buffer.Release()
default:
return
}
}
}
}
func (a *myInboundAdapter) newError(err error) {
a.logger.Error(err)
}
@@ -375,72 +168,3 @@ func NewError(logger log.ContextLogger, ctx context.Context, err error) {
}
logger.ErrorContext(ctx, err)
}
func (a *myInboundAdapter) writePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
defer buffer.Release()
if destination.IsFqdn() {
udpAddr, err := net.ResolveUDPAddr(N.NetworkUDP, destination.String())
if err != nil {
return err
}
return common.Error(a.udpConn.WriteTo(buffer.Bytes(), udpAddr))
}
return common.Error(a.udpConn.WriteToUDPAddrPort(buffer.Bytes(), destination.AddrPort()))
}
type myInboundPacketAdapter myInboundAdapter
func (s *myInboundPacketAdapter) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) {
n, addr, err := s.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
if err != nil {
return M.Socksaddr{}, err
}
buffer.Truncate(n)
return M.SocksaddrFromNetIP(addr), nil
}
func (s *myInboundPacketAdapter) WriteIsThreadUnsafe() {
}
type myInboundPacket struct {
buffer *buf.Buffer
destination M.Socksaddr
}
func (s *myInboundPacketAdapter) Upstream() any {
return s.udpConn
}
func (s *myInboundPacketAdapter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
s.packetAccess.RLock()
defer s.packetAccess.RUnlock()
select {
case <-s.packetOutboundClosed:
return os.ErrClosed
default:
}
s.packetOutbound <- &myInboundPacket{buffer, destination}
return nil
}
func (s *myInboundPacketAdapter) Close() error {
return s.udpConn.Close()
}
func (s *myInboundPacketAdapter) LocalAddr() net.Addr {
return s.udpConn.LocalAddr()
}
func (s *myInboundPacketAdapter) SetDeadline(t time.Time) error {
return s.udpConn.SetDeadline(t)
}
func (s *myInboundPacketAdapter) SetReadDeadline(t time.Time) error {
return s.udpConn.SetReadDeadline(t)
}
func (s *myInboundPacketAdapter) SetWriteDeadline(t time.Time) error {
return s.udpConn.SetWriteDeadline(t)
}

71
inbound/default_tcp.go Normal file
View File

@@ -0,0 +1,71 @@
package inbound
import (
"context"
"net"
"net/netip"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/proxyproto"
"github.com/sagernet/sing-box/log"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/database64128/tfo-go"
)
func (a *myInboundAdapter) ListenTCP() (net.Listener, error) {
var err error
bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort)
var tcpListener net.Listener
if !a.listenOptions.TCPFastOpen {
tcpListener, err = net.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
} else {
tcpListener, err = tfo.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
}
if err == nil {
a.logger.Info("tcp server started at ", tcpListener.Addr())
}
if a.listenOptions.ProxyProtocol {
a.logger.Debug("proxy protocol enabled")
tcpListener = &proxyproto.Listener{Listener: tcpListener}
}
a.tcpListener = tcpListener
return tcpListener, err
}
func (a *myInboundAdapter) loopTCPIn() {
tcpListener := a.tcpListener
for {
conn, err := tcpListener.Accept()
if err != nil {
if E.IsClosed(err) {
return
}
a.logger.Error("accept: ", err)
continue
}
go a.injectTCP(conn, adapter.InboundContext{})
}
}
func (a *myInboundAdapter) injectTCP(conn net.Conn, metadata adapter.InboundContext) {
ctx := log.ContextWithNewID(a.ctx)
metadata = a.createMetadata(conn, metadata)
a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
hErr := a.connHandler.NewConnection(ctx, conn, metadata)
if hErr != nil {
conn.Close()
a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source))
}
}
func (a *myInboundAdapter) routeTCP(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) {
a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
hErr := a.newConnection(ctx, conn, metadata)
if hErr != nil {
conn.Close()
a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source))
}
}

232
inbound/default_udp.go Normal file
View File

@@ -0,0 +1,232 @@
package inbound
import (
"net"
"net/netip"
"os"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-dns"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
func (a *myInboundAdapter) ListenUDP() (net.PacketConn, error) {
bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort)
udpConn, err := net.ListenUDP(M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.UDPAddr())
if err != nil {
return nil, err
}
a.udpConn = udpConn
a.udpAddr = bindAddr
a.logger.Info("udp server started at ", udpConn.LocalAddr())
return udpConn, err
}
func (a *myInboundAdapter) loopUDPIn() {
defer close(a.packetOutboundClosed)
_buffer := buf.StackNewPacket()
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release()
buffer.IncRef()
defer buffer.DecRef()
packetService := (*myInboundPacketAdapter)(a)
for {
buffer.Reset()
n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
if err != nil {
return
}
buffer.Truncate(n)
var metadata adapter.InboundContext
metadata.Inbound = a.tag
metadata.InboundType = a.protocol
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
metadata.Source = M.SocksaddrFromNetIP(addr)
metadata.OriginDestination = a.udpAddr
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
if err != nil {
a.newError(E.Cause(err, "process packet from ", metadata.Source))
}
}
}
func (a *myInboundAdapter) loopUDPOOBIn() {
defer close(a.packetOutboundClosed)
_buffer := buf.StackNewPacket()
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release()
buffer.IncRef()
defer buffer.DecRef()
packetService := (*myInboundPacketAdapter)(a)
oob := make([]byte, 1024)
for {
buffer.Reset()
n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
if err != nil {
return
}
buffer.Truncate(n)
var metadata adapter.InboundContext
metadata.Inbound = a.tag
metadata.InboundType = a.protocol
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
metadata.Source = M.SocksaddrFromNetIP(addr)
metadata.OriginDestination = a.udpAddr
err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
if err != nil {
a.newError(E.Cause(err, "process packet from ", metadata.Source))
}
}
}
func (a *myInboundAdapter) loopUDPInThreadSafe() {
defer close(a.packetOutboundClosed)
packetService := (*myInboundPacketAdapter)(a)
for {
buffer := buf.NewPacket()
n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
if err != nil {
buffer.Release()
return
}
buffer.Truncate(n)
var metadata adapter.InboundContext
metadata.Inbound = a.tag
metadata.InboundType = a.protocol
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
metadata.Source = M.SocksaddrFromNetIP(addr)
metadata.OriginDestination = a.udpAddr
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
if err != nil {
buffer.Release()
a.newError(E.Cause(err, "process packet from ", metadata.Source))
}
}
}
func (a *myInboundAdapter) loopUDPOOBInThreadSafe() {
defer close(a.packetOutboundClosed)
packetService := (*myInboundPacketAdapter)(a)
oob := make([]byte, 1024)
for {
buffer := buf.NewPacket()
n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
if err != nil {
buffer.Release()
return
}
buffer.Truncate(n)
var metadata adapter.InboundContext
metadata.Inbound = a.tag
metadata.InboundType = a.protocol
metadata.SniffEnabled = a.listenOptions.SniffEnabled
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
metadata.Source = M.SocksaddrFromNetIP(addr)
metadata.OriginDestination = a.udpAddr
err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
if err != nil {
buffer.Release()
a.newError(E.Cause(err, "process packet from ", metadata.Source))
}
}
}
func (a *myInboundAdapter) loopUDPOut() {
for {
select {
case packet := <-a.packetOutbound:
err := a.writePacket(packet.buffer, packet.destination)
if err != nil && !E.IsClosed(err) {
a.newError(E.New("write back udp: ", err))
}
continue
case <-a.packetOutboundClosed:
}
for {
select {
case packet := <-a.packetOutbound:
packet.buffer.Release()
default:
return
}
}
}
}
func (a *myInboundAdapter) writePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
defer buffer.Release()
if destination.IsFqdn() {
udpAddr, err := net.ResolveUDPAddr(N.NetworkUDP, destination.String())
if err != nil {
return err
}
return common.Error(a.udpConn.WriteTo(buffer.Bytes(), udpAddr))
}
return common.Error(a.udpConn.WriteToUDPAddrPort(buffer.Bytes(), destination.AddrPort()))
}
type myInboundPacketAdapter myInboundAdapter
func (s *myInboundPacketAdapter) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) {
n, addr, err := s.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
if err != nil {
return M.Socksaddr{}, err
}
buffer.Truncate(n)
return M.SocksaddrFromNetIP(addr), nil
}
func (s *myInboundPacketAdapter) WriteIsThreadUnsafe() {
}
type myInboundPacket struct {
buffer *buf.Buffer
destination M.Socksaddr
}
func (s *myInboundPacketAdapter) Upstream() any {
return s.udpConn
}
func (s *myInboundPacketAdapter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
select {
case s.packetOutbound <- &myInboundPacket{buffer, destination}:
return nil
case <-s.packetOutboundClosed:
return os.ErrClosed
}
}
func (s *myInboundPacketAdapter) Close() error {
return s.udpConn.Close()
}
func (s *myInboundPacketAdapter) LocalAddr() net.Addr {
return s.udpConn.LocalAddr()
}
func (s *myInboundPacketAdapter) SetDeadline(t time.Time) error {
return s.udpConn.SetDeadline(t)
}
func (s *myInboundPacketAdapter) SetReadDeadline(t time.Time) error {
return s.udpConn.SetReadDeadline(t)
}
func (s *myInboundPacketAdapter) SetWriteDeadline(t time.Time) error {
return s.udpConn.SetWriteDeadline(t)
}

Some files were not shown because too many files have changed in this diff Show More