mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2026-10-10 04:03:11 +08:00
feat: support hysteria2 gecko obfs
This commit is contained in:
@@ -38,26 +38,28 @@ type Hysteria2 struct {
|
||||
|
||||
type Hysteria2Option struct {
|
||||
BasicOption
|
||||
Name string `proxy:"name"`
|
||||
Server string `proxy:"server"`
|
||||
Port int `proxy:"port,omitempty"`
|
||||
Ports string `proxy:"ports,omitempty"`
|
||||
HopInterval string `proxy:"hop-interval,omitempty"`
|
||||
Up string `proxy:"up,omitempty"`
|
||||
Down string `proxy:"down,omitempty"`
|
||||
Password string `proxy:"password,omitempty"`
|
||||
Obfs string `proxy:"obfs,omitempty"`
|
||||
ObfsPassword string `proxy:"obfs-password,omitempty"`
|
||||
SNI string `proxy:"sni,omitempty"`
|
||||
ECHOpts ECHOptions `proxy:"ech-opts,omitempty"`
|
||||
SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"`
|
||||
Fingerprint string `proxy:"fingerprint,omitempty"`
|
||||
Certificate string `proxy:"certificate,omitempty"`
|
||||
PrivateKey string `proxy:"private-key,omitempty"`
|
||||
ALPN []string `proxy:"alpn,omitempty"`
|
||||
CWND int `proxy:"cwnd,omitempty"`
|
||||
BBRProfile string `proxy:"bbr-profile,omitempty"`
|
||||
UdpMTU int `proxy:"udp-mtu,omitempty"`
|
||||
Name string `proxy:"name"`
|
||||
Server string `proxy:"server"`
|
||||
Port int `proxy:"port,omitempty"`
|
||||
Ports string `proxy:"ports,omitempty"`
|
||||
HopInterval string `proxy:"hop-interval,omitempty"`
|
||||
Up string `proxy:"up,omitempty"`
|
||||
Down string `proxy:"down,omitempty"`
|
||||
Password string `proxy:"password,omitempty"`
|
||||
Obfs string `proxy:"obfs,omitempty"`
|
||||
ObfsPassword string `proxy:"obfs-password,omitempty"`
|
||||
ObfsMinPacketSize int `proxy:"obfs-min-packet-size,omitempty"`
|
||||
ObfsMaxPacketSize int `proxy:"obfs-max-packet-size,omitempty"`
|
||||
SNI string `proxy:"sni,omitempty"`
|
||||
ECHOpts ECHOptions `proxy:"ech-opts,omitempty"`
|
||||
SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"`
|
||||
Fingerprint string `proxy:"fingerprint,omitempty"`
|
||||
Certificate string `proxy:"certificate,omitempty"`
|
||||
PrivateKey string `proxy:"private-key,omitempty"`
|
||||
ALPN []string `proxy:"alpn,omitempty"`
|
||||
CWND int `proxy:"cwnd,omitempty"`
|
||||
BBRProfile string `proxy:"bbr-profile,omitempty"`
|
||||
UdpMTU int `proxy:"udp-mtu,omitempty"`
|
||||
|
||||
RealmOpts Hysteria2RealmOption `proxy:"realm-opts,omitempty"`
|
||||
|
||||
@@ -139,6 +141,8 @@ func NewHysteria2(option Hysteria2Option) (*Hysteria2, error) {
|
||||
outbound.dialer = option.NewDialer(outbound.DialOptions())
|
||||
|
||||
var salamanderPassword string
|
||||
var geckoPassword string
|
||||
var geckoMinPacketSize, geckoMaxPacketSize int
|
||||
if len(option.Obfs) > 0 {
|
||||
if option.ObfsPassword == "" {
|
||||
return nil, errors.New("missing obfs password")
|
||||
@@ -146,6 +150,10 @@ func NewHysteria2(option Hysteria2Option) (*Hysteria2, error) {
|
||||
switch option.Obfs {
|
||||
case hysteria2.ObfsTypeSalamander:
|
||||
salamanderPassword = option.ObfsPassword
|
||||
case hysteria2.ObfsTypeGecko:
|
||||
geckoPassword = option.ObfsPassword
|
||||
geckoMinPacketSize = option.ObfsMinPacketSize
|
||||
geckoMaxPacketSize = option.ObfsMaxPacketSize
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown obfs type: %s", option.Obfs)
|
||||
}
|
||||
@@ -199,6 +207,9 @@ func NewHysteria2(option Hysteria2Option) (*Hysteria2, error) {
|
||||
SendBPS: utils.StringToBps(option.Up),
|
||||
ReceiveBPS: utils.StringToBps(option.Down),
|
||||
SalamanderPassword: salamanderPassword,
|
||||
GeckoPassword: geckoPassword,
|
||||
GeckoMinPacketSize: geckoMinPacketSize,
|
||||
GeckoMaxPacketSize: geckoMaxPacketSize,
|
||||
Password: option.Password,
|
||||
TLSConfig: tlsClientConfig,
|
||||
QUICConfig: quicConfig,
|
||||
|
||||
+6
-2
@@ -1055,8 +1055,10 @@ proxies: # socks5
|
||||
# down: "200 Mbps" # 若不写单位,默认为 Mbps
|
||||
# bbr-profile: "" # Available: "standard", "conservative", "aggressive". Default: "standard"
|
||||
password: yourpassword
|
||||
# obfs: salamander # 默认为空,如果填写则开启 obfs,目前仅支持 salamander
|
||||
# obfs: salamander # 默认为空,如果填写则开启 obfs,目前支持 salamander 和 gecko
|
||||
# obfs-password: yourpassword
|
||||
# obfs-min-packet-size: 512 # 最小线上数据包大小(字节)。仅限 Gecko。
|
||||
# obfs-max-packet-size: 1200 # 最大线上数据包大小(字节)。仅限 Gecko。
|
||||
# sni: server.com
|
||||
# ech-opts:
|
||||
# enable: true # 必须手动开启
|
||||
@@ -2033,8 +2035,10 @@ listeners:
|
||||
## up 和 down 均不写或为 0 则使用 BBR 流控
|
||||
# up: "30 Mbps" # 若不写单位,默认为 Mbps
|
||||
# down: "200 Mbps" # 若不写单位,默认为 Mbps
|
||||
# obfs: salamander # 默认为空,如果填写则开启 obfs,目前仅支持 salamander
|
||||
# obfs: salamander # 默认为空,如果填写则开启 obfs,目前支持 salamander 和 gecko
|
||||
# obfs-password: yourpassword
|
||||
# obfs-min-packet-size: 512 # 最小线上数据包大小(字节)。仅限 Gecko。
|
||||
# obfs-max-packet-size: 1200 # 最大线上数据包大小(字节)。仅限 Gecko。
|
||||
# bbr-profile: "" # Available: "standard", "conservative", "aggressive". Default: "standard"
|
||||
# max-idle-time: 15000
|
||||
# alpn:
|
||||
|
||||
@@ -30,7 +30,7 @@ require (
|
||||
github.com/metacubex/restls-client-go v0.1.7
|
||||
github.com/metacubex/sing v0.5.7
|
||||
github.com/metacubex/sing-mux v0.3.9
|
||||
github.com/metacubex/sing-quic v0.0.0-20260512151354-8475655be853
|
||||
github.com/metacubex/sing-quic v0.0.0-20260525071347-7f961b1132a0
|
||||
github.com/metacubex/sing-shadowsocks v0.2.12
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.7
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20260517015314-c11c36474edc
|
||||
|
||||
@@ -147,8 +147,8 @@ github.com/metacubex/sing v0.5.7 h1:8OC+fhKFSv/l9ehEhJRaZZAOuthfZo68SteBVLe8QqM=
|
||||
github.com/metacubex/sing v0.5.7/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
|
||||
github.com/metacubex/sing-mux v0.3.9 h1:/aoBD2+sK2qsXDlNDe3hkR0GZuFDtwIZhOeGUx9W0Yk=
|
||||
github.com/metacubex/sing-mux v0.3.9/go.mod h1:8bT7ZKT3clRrJjYc/x5CRYibC1TX/bK73a3r3+2E+Fc=
|
||||
github.com/metacubex/sing-quic v0.0.0-20260512151354-8475655be853 h1:nZ5WNU6kjj6kBu4+2eMySFkUVGCop64rZnLMm+HPh8w=
|
||||
github.com/metacubex/sing-quic v0.0.0-20260512151354-8475655be853/go.mod h1:6ayFGfzzBE85csgQkM3gf4neFq6s0losHlPRSxY+nuk=
|
||||
github.com/metacubex/sing-quic v0.0.0-20260525071347-7f961b1132a0 h1:0qK4rNASJ4DbzHCAtcLisDx4g459yzQOzncr4FsjAYI=
|
||||
github.com/metacubex/sing-quic v0.0.0-20260525071347-7f961b1132a0/go.mod h1:6ayFGfzzBE85csgQkM3gf4neFq6s0losHlPRSxY+nuk=
|
||||
github.com/metacubex/sing-shadowsocks v0.2.12 h1:Wqzo8bYXrK5aWqxu/TjlTnYZzAKtKsaFQBdr6IHFaBE=
|
||||
github.com/metacubex/sing-shadowsocks v0.2.12/go.mod h1:2e5EIaw0rxKrm1YTRmiMnDulwbGxH9hAFlrwQLQMQkU=
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.7 h1:hSuuc0YpsfiqYqt1o+fP4m34BQz4e6wVj3PPBVhor3A=
|
||||
|
||||
@@ -12,6 +12,8 @@ type Hysteria2Server struct {
|
||||
Users map[string]string `yaml:"users" json:"users,omitempty"`
|
||||
Obfs string `yaml:"obfs" json:"obfs,omitempty"`
|
||||
ObfsPassword string `yaml:"obfs-password" json:"obfs-password,omitempty"`
|
||||
ObfsMinPacketSize int `yaml:"obfs-min-packet-size" json:"obfs-min-packet-size,omitempty"`
|
||||
ObfsMaxPacketSize int `yaml:"obfs-max-packet-size" json:"obfs-max-packet-size,omitempty"`
|
||||
Certificate string `yaml:"certificate" json:"certificate"`
|
||||
PrivateKey string `yaml:"private-key" json:"private-key"`
|
||||
ClientAuthType string `yaml:"client-auth-type" json:"client-auth-type,omitempty"`
|
||||
|
||||
@@ -14,6 +14,8 @@ type Hysteria2Option struct {
|
||||
Users map[string]string `inbound:"users,omitempty"`
|
||||
Obfs string `inbound:"obfs,omitempty"`
|
||||
ObfsPassword string `inbound:"obfs-password,omitempty"`
|
||||
ObfsMinPacketSize int `inbound:"obfs-min-packet-size,omitempty"`
|
||||
ObfsMaxPacketSize int `inbound:"obfs-max-packet-size,omitempty"`
|
||||
Certificate string `inbound:"certificate"`
|
||||
PrivateKey string `inbound:"private-key"`
|
||||
ClientAuthType string `inbound:"client-auth-type,omitempty"`
|
||||
@@ -98,6 +100,8 @@ func NewHysteria2(options *Hysteria2Option) (*Hysteria2, error) {
|
||||
Users: options.Users,
|
||||
Obfs: options.Obfs,
|
||||
ObfsPassword: options.ObfsPassword,
|
||||
ObfsMinPacketSize: options.ObfsMinPacketSize,
|
||||
ObfsMaxPacketSize: options.ObfsMaxPacketSize,
|
||||
Certificate: options.Certificate,
|
||||
PrivateKey: options.PrivateKey,
|
||||
ClientAuthType: options.ClientAuthType,
|
||||
|
||||
@@ -114,6 +114,21 @@ func TestInboundHysteria2_Salamander(t *testing.T) {
|
||||
testInboundHysteria2TLS(t, inboundOptions, outboundOptions)
|
||||
}
|
||||
|
||||
func TestInboundHysteria2_Gecko(t *testing.T) {
|
||||
inboundOptions := inbound.Hysteria2Option{
|
||||
Certificate: tlsCertificate,
|
||||
PrivateKey: tlsPrivateKey,
|
||||
Obfs: "gecko",
|
||||
ObfsPassword: userUUID,
|
||||
}
|
||||
outboundOptions := outbound.Hysteria2Option{
|
||||
Fingerprint: tlsFingerprint,
|
||||
Obfs: "gecko",
|
||||
ObfsPassword: userUUID,
|
||||
}
|
||||
testInboundHysteria2TLS(t, inboundOptions, outboundOptions)
|
||||
}
|
||||
|
||||
func TestInboundHysteria2_Brutal(t *testing.T) {
|
||||
inboundOptions := inbound.Hysteria2Option{
|
||||
Certificate: tlsCertificate,
|
||||
|
||||
@@ -100,6 +100,8 @@ func New(config LC.Hysteria2Server, tunnel C.Tunnel, additions ...inbound.Additi
|
||||
}
|
||||
|
||||
var salamanderPassword string
|
||||
var geckoPassword string
|
||||
var geckoMinPacketSize, geckoMaxPacketSize int
|
||||
if len(config.Obfs) > 0 {
|
||||
if config.ObfsPassword == "" {
|
||||
return nil, errors.New("missing obfs password")
|
||||
@@ -107,6 +109,10 @@ func New(config LC.Hysteria2Server, tunnel C.Tunnel, additions ...inbound.Additi
|
||||
switch config.Obfs {
|
||||
case hysteria2.ObfsTypeSalamander:
|
||||
salamanderPassword = config.ObfsPassword
|
||||
case hysteria2.ObfsTypeGecko:
|
||||
geckoPassword = config.ObfsPassword
|
||||
geckoMinPacketSize = config.ObfsMinPacketSize
|
||||
geckoMaxPacketSize = config.ObfsMaxPacketSize
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown obfs type: %s", config.Obfs)
|
||||
}
|
||||
@@ -212,6 +218,9 @@ func New(config LC.Hysteria2Server, tunnel C.Tunnel, additions ...inbound.Additi
|
||||
SendBPS: utils.StringToBps(config.Up),
|
||||
ReceiveBPS: utils.StringToBps(config.Down),
|
||||
SalamanderPassword: salamanderPassword,
|
||||
GeckoPassword: geckoPassword,
|
||||
GeckoMinPacketSize: geckoMinPacketSize,
|
||||
GeckoMaxPacketSize: geckoMaxPacketSize,
|
||||
TLSConfig: tlsConfig,
|
||||
QUICConfig: quicConfig,
|
||||
IgnoreClientBandwidth: config.IgnoreClientBandwidth,
|
||||
|
||||
Reference in New Issue
Block a user