mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-08-28 12:20:53 +00:00
hysteria2: Add gecko obfs
This commit is contained in:
parent
6a8071d1ce
commit
d0ef5c028d
10 changed files with 149 additions and 16 deletions
|
|
@ -1,5 +1,10 @@
|
|||
package constant
|
||||
|
||||
const (
|
||||
Hysteria2ObfsTypeSalamander = "salamander"
|
||||
Hysteria2ObfsTypeGecko = "gecko"
|
||||
)
|
||||
|
||||
const (
|
||||
Hysterai2MasqueradeTypeFile = "file"
|
||||
Hysterai2MasqueradeTypeProxy = "proxy"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ icon: material/alert-decagram
|
|||
!!! quote "Changes in sing-box 1.14.0"
|
||||
|
||||
:material-plus: [bbr_profile](#bbr_profile)
|
||||
:material-plus: [realm](#realm)
|
||||
:material-plus: [realm](#realm)
|
||||
:material-alert: [obfs](#obfstype)
|
||||
|
||||
!!! quote "Changes in sing-box 1.11.0"
|
||||
|
||||
|
|
@ -75,7 +76,7 @@ Conflict with `ignore_client_bandwidth`.
|
|||
|
||||
#### obfs.type
|
||||
|
||||
QUIC traffic obfuscator type, only available with `salamander`.
|
||||
QUIC traffic obfuscator type, one of `salamander` `gecko`.
|
||||
|
||||
Disabled if empty.
|
||||
|
||||
|
|
@ -83,6 +84,22 @@ Disabled if empty.
|
|||
|
||||
QUIC traffic obfuscator password.
|
||||
|
||||
#### obfs.min_packet_size
|
||||
|
||||
!!! question "Since sing-box 1.14.0"
|
||||
|
||||
Minimum on-wire packet size in bytes. Gecko only.
|
||||
|
||||
`512` is used by default.
|
||||
|
||||
#### obfs.max_packet_size
|
||||
|
||||
!!! question "Since sing-box 1.14.0"
|
||||
|
||||
Maximum on-wire packet size in bytes. Gecko only.
|
||||
|
||||
`1200` is used by default.
|
||||
|
||||
#### users
|
||||
|
||||
Hysteria2 users
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ icon: material/alert-decagram
|
|||
!!! quote "sing-box 1.14.0 中的更改"
|
||||
|
||||
:material-plus: [bbr_profile](#bbr_profile)
|
||||
:material-plus: [realm](#realm)
|
||||
:material-plus: [realm](#realm)
|
||||
:material-alert: [obfs](#obfstype)
|
||||
|
||||
!!! quote "sing-box 1.11.0 中的更改"
|
||||
|
||||
|
|
@ -72,13 +73,29 @@ icon: material/alert-decagram
|
|||
|
||||
#### obfs.type
|
||||
|
||||
QUIC 流量混淆器类型,仅可设为 `salamander`。
|
||||
QUIC 流量混淆器类型,可选 `salamander` `gecko`。
|
||||
|
||||
如果为空则禁用。
|
||||
|
||||
#### obfs.password
|
||||
|
||||
QUIC 流量混淆器密码.
|
||||
QUIC 流量混淆器密码。
|
||||
|
||||
#### obfs.min_packet_size
|
||||
|
||||
!!! question "自 sing-box 1.14.0 起"
|
||||
|
||||
最小线上数据包大小(字节)。仅限 Gecko。
|
||||
|
||||
默认使用 `512`。
|
||||
|
||||
#### obfs.max_packet_size
|
||||
|
||||
!!! question "自 sing-box 1.14.0 起"
|
||||
|
||||
最大线上数据包大小(字节)。仅限 Gecko。
|
||||
|
||||
默认使用 `1200`。
|
||||
|
||||
#### users
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
:material-plus: [hop_interval_max](#hop_interval_max)
|
||||
:material-plus: [bbr_profile](#bbr_profile)
|
||||
:material-plus: [realm](#realm)
|
||||
:material-plus: [realm](#realm)
|
||||
:material-alert: [obfs](#obfstype)
|
||||
|
||||
!!! quote "Changes in sing-box 1.11.0"
|
||||
|
||||
|
|
@ -113,7 +114,7 @@ If empty, the BBR congestion control algorithm will be used instead of Hysteria
|
|||
|
||||
#### obfs.type
|
||||
|
||||
QUIC traffic obfuscator type, only available with `salamander`.
|
||||
QUIC traffic obfuscator type, one of `salamander` `gecko`.
|
||||
|
||||
Disabled if empty.
|
||||
|
||||
|
|
@ -121,6 +122,22 @@ Disabled if empty.
|
|||
|
||||
QUIC traffic obfuscator password.
|
||||
|
||||
#### obfs.min_packet_size
|
||||
|
||||
!!! question "Since sing-box 1.14.0"
|
||||
|
||||
Minimum on-wire packet size in bytes. Gecko only.
|
||||
|
||||
`512` is used by default.
|
||||
|
||||
#### obfs.max_packet_size
|
||||
|
||||
!!! question "Since sing-box 1.14.0"
|
||||
|
||||
Maximum on-wire packet size in bytes. Gecko only.
|
||||
|
||||
`1200` is used by default.
|
||||
|
||||
#### password
|
||||
|
||||
Authentication password.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
:material-plus: [hop_interval_max](#hop_interval_max)
|
||||
:material-plus: [bbr_profile](#bbr_profile)
|
||||
:material-plus: [realm](#realm)
|
||||
:material-plus: [realm](#realm)
|
||||
:material-alert: [obfs](#obfstype)
|
||||
|
||||
!!! quote "sing-box 1.11.0 中的更改"
|
||||
|
||||
|
|
@ -111,13 +112,29 @@
|
|||
|
||||
#### obfs.type
|
||||
|
||||
QUIC 流量混淆器类型,仅可设为 `salamander`。
|
||||
QUIC 流量混淆器类型,可选 `salamander` `gecko`。
|
||||
|
||||
如果为空则禁用。
|
||||
|
||||
#### obfs.password
|
||||
|
||||
QUIC 流量混淆器密码.
|
||||
QUIC 流量混淆器密码。
|
||||
|
||||
#### obfs.min_packet_size
|
||||
|
||||
!!! question "自 sing-box 1.14.0 起"
|
||||
|
||||
最小线上数据包大小(字节)。仅限 Gecko。
|
||||
|
||||
默认使用 `512`。
|
||||
|
||||
#### obfs.max_packet_size
|
||||
|
||||
!!! question "自 sing-box 1.14.0 起"
|
||||
|
||||
最大线上数据包大小(字节)。仅限 Gecko。
|
||||
|
||||
默认使用 `1200`。
|
||||
|
||||
#### password
|
||||
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -40,7 +40,7 @@ require (
|
|||
github.com/sagernet/sing v0.8.12-0.20260625092856-31bbf21d4b12
|
||||
github.com/sagernet/sing-cloudflared v0.1.1
|
||||
github.com/sagernet/sing-mux v0.3.5
|
||||
github.com/sagernet/sing-quic v0.6.2-0.20260520073201-c8655743eb6e
|
||||
github.com/sagernet/sing-quic v0.6.2-0.20260525051024-9467ede27fb7
|
||||
github.com/sagernet/sing-shadowsocks v0.2.8
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.1
|
||||
github.com/sagernet/sing-shadowtls v0.2.1
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -248,8 +248,8 @@ github.com/sagernet/sing-cloudflared v0.1.1 h1:By29ZWMJl8QU6UcC5pmBv803rYigAoSmz
|
|||
github.com/sagernet/sing-cloudflared v0.1.1/go.mod h1:bH2NKX+NpDTY1Zkxfboxw6MXB/ZywaNLmrDJYgKMJ2Y=
|
||||
github.com/sagernet/sing-mux v0.3.5 h1:RHnhVEc+SFqkrK4xMygYjDwwLhzp2Bj3lztSukONfhI=
|
||||
github.com/sagernet/sing-mux v0.3.5/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk=
|
||||
github.com/sagernet/sing-quic v0.6.2-0.20260520073201-c8655743eb6e h1:CCJxS/iXhUA2KlQ7vNjcYUVGTYjNeHQ5s5MC32WlVPw=
|
||||
github.com/sagernet/sing-quic v0.6.2-0.20260520073201-c8655743eb6e/go.mod h1:+oqD54aHel4ALKkp1hVXWCgLU/EjLojvm6AUzDfvj0I=
|
||||
github.com/sagernet/sing-quic v0.6.2-0.20260525051024-9467ede27fb7 h1:hFLPJ21uNZSbRnzhOKz4Zv0b4F93mpDorWyN93BeRcM=
|
||||
github.com/sagernet/sing-quic v0.6.2-0.20260525051024-9467ede27fb7/go.mod h1:+oqD54aHel4ALKkp1hVXWCgLU/EjLojvm6AUzDfvj0I=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVCzByXruQWfE=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.8/go.mod h1:lo7TWEMDcN5/h5B8S0ew+r78ZODn6SwVaFhvB6H+PTI=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnqqs2gQ2/Qioo=
|
||||
|
|
|
|||
|
|
@ -38,9 +38,51 @@ type Hysteria2InboundRealm struct {
|
|||
STUNDomainResolver *DomainResolveOptions `json:"stun_domain_resolver,omitempty"`
|
||||
}
|
||||
|
||||
type Hysteria2Obfs struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
type Hysteria2ObfsGecko struct {
|
||||
MinPacketSize int `json:"min_packet_size,omitempty"`
|
||||
MaxPacketSize int `json:"max_packet_size,omitempty"`
|
||||
}
|
||||
|
||||
type _Hysteria2Obfs struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
GeckoOptions Hysteria2ObfsGecko `json:"-"`
|
||||
}
|
||||
|
||||
type Hysteria2Obfs _Hysteria2Obfs
|
||||
|
||||
func (o Hysteria2Obfs) MarshalJSON() ([]byte, error) {
|
||||
var v any
|
||||
switch o.Type {
|
||||
case C.Hysteria2ObfsTypeSalamander:
|
||||
case C.Hysteria2ObfsTypeGecko:
|
||||
v = o.GeckoOptions
|
||||
default:
|
||||
return nil, E.New("unknown obfs type: ", o.Type)
|
||||
}
|
||||
if v == nil {
|
||||
return json.Marshal((_Hysteria2Obfs)(o))
|
||||
}
|
||||
return badjson.MarshallObjects((_Hysteria2Obfs)(o), v)
|
||||
}
|
||||
|
||||
func (o *Hysteria2Obfs) UnmarshalJSON(bytes []byte) error {
|
||||
err := json.Unmarshal(bytes, (*_Hysteria2Obfs)(o))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var v any
|
||||
switch o.Type {
|
||||
case C.Hysteria2ObfsTypeSalamander:
|
||||
case C.Hysteria2ObfsTypeGecko:
|
||||
v = &o.GeckoOptions
|
||||
default:
|
||||
return E.New("unknown obfs type: ", o.Type)
|
||||
}
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
return badjson.UnmarshallExcluded(bytes, (*_Hysteria2Obfs)(o), v)
|
||||
}
|
||||
|
||||
type Hysteria2User struct {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
|||
return nil, err
|
||||
}
|
||||
var salamanderPassword string
|
||||
var geckoPassword string
|
||||
var geckoMinPacketSize, geckoMaxPacketSize int
|
||||
if options.Obfs != nil {
|
||||
if options.Obfs.Password == "" {
|
||||
return nil, E.New("missing obfs password")
|
||||
|
|
@ -59,6 +61,10 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
|||
switch options.Obfs.Type {
|
||||
case hysteria2.ObfsTypeSalamander:
|
||||
salamanderPassword = options.Obfs.Password
|
||||
case hysteria2.ObfsTypeGecko:
|
||||
geckoPassword = options.Obfs.Password
|
||||
geckoMinPacketSize = options.Obfs.GeckoOptions.MinPacketSize
|
||||
geckoMaxPacketSize = options.Obfs.GeckoOptions.MaxPacketSize
|
||||
default:
|
||||
return nil, E.New("unknown obfs type: ", options.Obfs.Type)
|
||||
}
|
||||
|
|
@ -154,6 +160,9 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
|||
SendBPS: uint64(options.UpMbps * hysteria.MbpsToBps),
|
||||
ReceiveBPS: uint64(options.DownMbps * hysteria.MbpsToBps),
|
||||
SalamanderPassword: salamanderPassword,
|
||||
GeckoPassword: geckoPassword,
|
||||
GeckoMinPacketSize: geckoMinPacketSize,
|
||||
GeckoMaxPacketSize: geckoMaxPacketSize,
|
||||
TLSConfig: tlsConfig,
|
||||
QUICOptions: qtls.QUICOptions{
|
||||
IdleTimeout: options.IdleTimeout.Build(),
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
|||
return nil, err
|
||||
}
|
||||
var salamanderPassword string
|
||||
var geckoPassword string
|
||||
var geckoMinPacketSize, geckoMaxPacketSize int
|
||||
if options.Obfs != nil {
|
||||
if options.Obfs.Password == "" {
|
||||
return nil, E.New("missing obfs password")
|
||||
|
|
@ -66,6 +68,10 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
|||
switch options.Obfs.Type {
|
||||
case hysteria2.ObfsTypeSalamander:
|
||||
salamanderPassword = options.Obfs.Password
|
||||
case hysteria2.ObfsTypeGecko:
|
||||
geckoPassword = options.Obfs.Password
|
||||
geckoMinPacketSize = options.Obfs.GeckoOptions.MinPacketSize
|
||||
geckoMaxPacketSize = options.Obfs.GeckoOptions.MaxPacketSize
|
||||
default:
|
||||
return nil, E.New("unknown obfs type: ", options.Obfs.Type)
|
||||
}
|
||||
|
|
@ -121,6 +127,9 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
|||
SendBPS: uint64(options.UpMbps * hysteria.MbpsToBps),
|
||||
ReceiveBPS: uint64(options.DownMbps * hysteria.MbpsToBps),
|
||||
SalamanderPassword: salamanderPassword,
|
||||
GeckoPassword: geckoPassword,
|
||||
GeckoMinPacketSize: geckoMinPacketSize,
|
||||
GeckoMaxPacketSize: geckoMaxPacketSize,
|
||||
Password: options.Password,
|
||||
TLSConfig: tlsConfig,
|
||||
QUICOptions: qtls.QUICOptions{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue