mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-22 10:08:15 -05:00
Add uTLS support for Security Engine
This commit is contained in:
parent
4a887e3b77
commit
e4188c8604
7
go.mod
7
go.mod
@ -19,6 +19,7 @@ require (
|
||||
github.com/mustafaturan/bus v1.0.2
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
github.com/pires/go-proxyproto v0.6.2
|
||||
github.com/refraction-networking/utls v1.2.0
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/v2fly/BrowserBridge v0.0.0-20210430233438-0570fc1d7d08
|
||||
@ -27,8 +28,8 @@ require (
|
||||
github.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432
|
||||
go.starlark.net v0.0.0-20220817180228-f738f5508c12
|
||||
go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
|
||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591
|
||||
golang.org/x/crypto v0.1.0
|
||||
golang.org/x/net v0.1.0
|
||||
golang.org/x/sync v0.0.0-20220907140024-f12130a52804
|
||||
golang.org/x/sys v0.1.1-0.20221102194838-fc697a31fa06
|
||||
google.golang.org/grpc v1.51.0
|
||||
@ -40,6 +41,7 @@ require (
|
||||
require (
|
||||
github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 // indirect
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 // indirect
|
||||
@ -48,6 +50,7 @@ require (
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
||||
github.com/klauspost/compress v1.15.12 // indirect
|
||||
github.com/klauspost/cpuid v1.2.3 // indirect
|
||||
github.com/klauspost/reedsolomon v1.9.3 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
|
14
go.sum
14
go.sum
@ -23,6 +23,8 @@ github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
@ -173,6 +175,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM=
|
||||
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||
github.com/klauspost/cpuid v1.2.3 h1:CCtW0xUnWGVINKvE/WWOYKdsPV6mawAtvQuSl8guwQs=
|
||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/reedsolomon v1.9.3 h1:N/VzgeMfHmLc+KHMD1UL/tNkfXAt8FnUqlgXGIduwAY=
|
||||
@ -263,6 +267,8 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/refraction-networking/utls v1.2.0 h1:U5f8wkij2NVinfLuJdFP3gCMwIHs+EzvhxmYdXgiapo=
|
||||
github.com/refraction-networking/utls v1.2.0/go.mod h1:NPq+cVqzH7D1BeOkmOcb5O/8iVewAsiVt2x1/eO0hgQ=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
@ -348,8 +354,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/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/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -395,8 +401,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI=
|
||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -61,6 +61,7 @@ import (
|
||||
_ "github.com/v2fly/v2ray-core/v5/transport/internet/quic"
|
||||
_ "github.com/v2fly/v2ray-core/v5/transport/internet/tcp"
|
||||
_ "github.com/v2fly/v2ray-core/v5/transport/internet/tls"
|
||||
_ "github.com/v2fly/v2ray-core/v5/transport/internet/tls/utls"
|
||||
_ "github.com/v2fly/v2ray-core/v5/transport/internet/udp"
|
||||
_ "github.com/v2fly/v2ray-core/v5/transport/internet/websocket"
|
||||
|
||||
|
180
transport/internet/tls/utls/config.pb.go
Normal file
180
transport/internet/tls/utls/config.pb.go
Normal file
@ -0,0 +1,180 @@
|
||||
package utls
|
||||
|
||||
import (
|
||||
_ "github.com/v2fly/v2ray-core/v5/common/protoext"
|
||||
tls "github.com/v2fly/v2ray-core/v5/transport/internet/tls"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
TlsConfig *tls.Config `protobuf:"bytes,1,opt,name=tls_config,json=tlsConfig,proto3" json:"tls_config,omitempty"`
|
||||
Imitate string `protobuf:"bytes,2,opt,name=imitate,proto3" json:"imitate,omitempty"`
|
||||
NoSNI bool `protobuf:"varint,3,opt,name=noSNI,proto3" json:"noSNI,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Config) Reset() {
|
||||
*x = Config{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_transport_internet_tls_utls_config_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Config) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Config) ProtoMessage() {}
|
||||
|
||||
func (x *Config) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_transport_internet_tls_utls_config_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Config.ProtoReflect.Descriptor instead.
|
||||
func (*Config) Descriptor() ([]byte, []int) {
|
||||
return file_transport_internet_tls_utls_config_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Config) GetTlsConfig() *tls.Config {
|
||||
if x != nil {
|
||||
return x.TlsConfig
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetImitate() string {
|
||||
if x != nil {
|
||||
return x.Imitate
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Config) GetNoSNI() bool {
|
||||
if x != nil {
|
||||
return x.NoSNI
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var File_transport_internet_tls_utls_config_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_transport_internet_tls_utls_config_proto_rawDesc = []byte{
|
||||
0x0a, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0x2f, 0x75, 0x74, 0x6c, 0x73, 0x2f, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x26, 0x76, 0x32, 0x72, 0x61,
|
||||
0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74,
|
||||
0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x2e, 0x75, 0x74,
|
||||
0x6c, 0x73, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f,
|
||||
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0x2f, 0x63, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9c, 0x01, 0x0a, 0x06, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x12, 0x48, 0x0a, 0x0a, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79,
|
||||
0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e,
|
||||
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x2e, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x52, 0x09, 0x74, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x69, 0x6d, 0x69, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x69, 0x6d, 0x69, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x53, 0x4e,
|
||||
0x49, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6e, 0x6f, 0x53, 0x4e, 0x49, 0x3a, 0x18,
|
||||
0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x82, 0xb5,
|
||||
0x18, 0x06, 0x12, 0x04, 0x75, 0x74, 0x6c, 0x73, 0x42, 0x93, 0x01, 0x0a, 0x2a, 0x63, 0x6f, 0x6d,
|
||||
0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e,
|
||||
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74,
|
||||
0x6c, 0x73, 0x2e, 0x75, 0x74, 0x6c, 0x73, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61,
|
||||
0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70,
|
||||
0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73,
|
||||
0x2f, 0x75, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x26, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f,
|
||||
0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x6c, 0x73, 0x2e, 0x55, 0x54, 0x6c, 0x73, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_transport_internet_tls_utls_config_proto_rawDescOnce sync.Once
|
||||
file_transport_internet_tls_utls_config_proto_rawDescData = file_transport_internet_tls_utls_config_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_transport_internet_tls_utls_config_proto_rawDescGZIP() []byte {
|
||||
file_transport_internet_tls_utls_config_proto_rawDescOnce.Do(func() {
|
||||
file_transport_internet_tls_utls_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_transport_internet_tls_utls_config_proto_rawDescData)
|
||||
})
|
||||
return file_transport_internet_tls_utls_config_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_transport_internet_tls_utls_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_transport_internet_tls_utls_config_proto_goTypes = []interface{}{
|
||||
(*Config)(nil), // 0: v2ray.core.transport.internet.tls.utls.Config
|
||||
(*tls.Config)(nil), // 1: v2ray.core.transport.internet.tls.Config
|
||||
}
|
||||
var file_transport_internet_tls_utls_config_proto_depIdxs = []int32{
|
||||
1, // 0: v2ray.core.transport.internet.tls.utls.Config.tls_config:type_name -> v2ray.core.transport.internet.tls.Config
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_transport_internet_tls_utls_config_proto_init() }
|
||||
func file_transport_internet_tls_utls_config_proto_init() {
|
||||
if File_transport_internet_tls_utls_config_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_transport_internet_tls_utls_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Config); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_transport_internet_tls_utls_config_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_transport_internet_tls_utls_config_proto_goTypes,
|
||||
DependencyIndexes: file_transport_internet_tls_utls_config_proto_depIdxs,
|
||||
MessageInfos: file_transport_internet_tls_utls_config_proto_msgTypes,
|
||||
}.Build()
|
||||
File_transport_internet_tls_utls_config_proto = out.File
|
||||
file_transport_internet_tls_utls_config_proto_rawDesc = nil
|
||||
file_transport_internet_tls_utls_config_proto_goTypes = nil
|
||||
file_transport_internet_tls_utls_config_proto_depIdxs = nil
|
||||
}
|
19
transport/internet/tls/utls/config.proto
Normal file
19
transport/internet/tls/utls/config.proto
Normal file
@ -0,0 +1,19 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package v2ray.core.transport.internet.tls.utls;
|
||||
option csharp_namespace = "V2Ray.Core.Transport.Internet.Tls.UTls";
|
||||
option go_package = "github.com/v2fly/v2ray-core/v5/transport/internet/tls/utls";
|
||||
option java_package = "com.v2ray.core.transport.internet.tls.utls";
|
||||
option java_multiple_files = true;
|
||||
|
||||
import "common/protoext/extensions.proto";
|
||||
import "transport/internet/tls/config.proto";
|
||||
|
||||
message Config {
|
||||
option (v2ray.core.common.protoext.message_opt).type = "security";
|
||||
option (v2ray.core.common.protoext.message_opt).short_name = "utls";
|
||||
|
||||
v2ray.core.transport.internet.tls.Config tls_config = 1;
|
||||
string imitate = 2;
|
||||
bool noSNI = 3;
|
||||
}
|
9
transport/internet/tls/utls/errors.generated.go
Normal file
9
transport/internet/tls/utls/errors.generated.go
Normal file
@ -0,0 +1,9 @@
|
||||
package utls
|
||||
|
||||
import "github.com/v2fly/v2ray-core/v5/common/errors"
|
||||
|
||||
type errPathObjHolder struct{}
|
||||
|
||||
func newError(values ...interface{}) *errors.Error {
|
||||
return errors.New(values...).WithPathObj(errPathObjHolder{})
|
||||
}
|
51
transport/internet/tls/utls/nameMapper.go
Normal file
51
transport/internet/tls/utls/nameMapper.go
Normal file
@ -0,0 +1,51 @@
|
||||
package utls
|
||||
|
||||
import utls "github.com/refraction-networking/utls"
|
||||
|
||||
var clientHelloIDMap = map[string]*utls.ClientHelloID{
|
||||
"randomized": &utls.HelloRandomized,
|
||||
"randomizedalpn": &utls.HelloRandomizedALPN,
|
||||
"randomizednoalpn": &utls.HelloRandomizedNoALPN,
|
||||
"firefox_auto": &utls.HelloFirefox_Auto,
|
||||
"firefox_55": &utls.HelloFirefox_55,
|
||||
"firefox_56": &utls.HelloFirefox_56,
|
||||
"firefox_63": &utls.HelloFirefox_63,
|
||||
"firefox_65": &utls.HelloFirefox_65,
|
||||
"firefox_99": &utls.HelloFirefox_99,
|
||||
"firefox_102": &utls.HelloFirefox_102,
|
||||
"firefox_105": &utls.HelloFirefox_105,
|
||||
"chrome_auto": &utls.HelloChrome_Auto,
|
||||
"chrome_58": &utls.HelloChrome_58,
|
||||
"chrome_62": &utls.HelloChrome_62,
|
||||
"chrome_70": &utls.HelloChrome_70,
|
||||
"chrome_72": &utls.HelloChrome_72,
|
||||
"chrome_83": &utls.HelloChrome_83,
|
||||
"chrome_87": &utls.HelloChrome_87,
|
||||
"chrome_96": &utls.HelloChrome_96,
|
||||
"chrome_100": &utls.HelloChrome_100,
|
||||
"chrome_102": &utls.HelloChrome_102,
|
||||
"ios_auto": &utls.HelloIOS_Auto,
|
||||
"ios_11_1": &utls.HelloIOS_11_1,
|
||||
"ios_12_1": &utls.HelloIOS_12_1,
|
||||
"ios_13": &utls.HelloIOS_13,
|
||||
"ios_14": &utls.HelloIOS_14,
|
||||
"android_11_okhttp": &utls.HelloAndroid_11_OkHttp,
|
||||
"edge_auto": &utls.HelloEdge_Auto,
|
||||
"edge_85": &utls.HelloEdge_85,
|
||||
"edge_106": &utls.HelloEdge_106,
|
||||
"safari_auto": &utls.HelloSafari_Auto,
|
||||
"safari_16_0": &utls.HelloSafari_16_0,
|
||||
"360_auto": &utls.Hello360_Auto,
|
||||
"360_7_5": &utls.Hello360_7_5,
|
||||
"360_11_0": &utls.Hello360_11_0,
|
||||
"qq_auto": &utls.HelloQQ_Auto,
|
||||
"qq_11_1": &utls.HelloQQ_11_1,
|
||||
}
|
||||
|
||||
func nameToUTLSPreset(name string) (*utls.ClientHelloID, error) {
|
||||
preset, ok := clientHelloIDMap[name]
|
||||
if !ok {
|
||||
return nil, newError("unknown preset name")
|
||||
}
|
||||
return preset, nil
|
||||
}
|
102
transport/internet/tls/utls/utls.go
Normal file
102
transport/internet/tls/utls/utls.go
Normal file
@ -0,0 +1,102 @@
|
||||
package utls
|
||||
|
||||
import (
|
||||
"context"
|
||||
systls "crypto/tls"
|
||||
|
||||
utls "github.com/refraction-networking/utls"
|
||||
|
||||
"github.com/v2fly/v2ray-core/v5/common"
|
||||
"github.com/v2fly/v2ray-core/v5/common/net"
|
||||
"github.com/v2fly/v2ray-core/v5/transport/internet/security"
|
||||
"github.com/v2fly/v2ray-core/v5/transport/internet/tls"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen
|
||||
|
||||
func NewUTLSSecurityEngineFromConfig(config *Config) (security.Engine, error) {
|
||||
if config.TlsConfig == nil {
|
||||
return nil, newError("mandatory field tls_config is not specified")
|
||||
}
|
||||
return &Engine{config: config}, nil
|
||||
}
|
||||
|
||||
type Engine struct {
|
||||
config *Config
|
||||
}
|
||||
|
||||
func (e Engine) Client(conn net.Conn, opts ...security.Option) (security.Conn, error) {
|
||||
var options []tls.Option
|
||||
for _, v := range opts {
|
||||
switch s := v.(type) {
|
||||
case security.OptionWithALPN:
|
||||
options = append(options, tls.WithNextProto(s.ALPNs...))
|
||||
case security.OptionWithDestination:
|
||||
options = append(options, tls.WithDestination(s.Dest))
|
||||
default:
|
||||
return nil, newError("unknown option")
|
||||
}
|
||||
}
|
||||
tlsConfig := e.config.TlsConfig.GetTLSConfig(options...)
|
||||
utlsConfig, err := uTLSConfigFromTLSConfig(tlsConfig)
|
||||
if err != nil {
|
||||
return nil, newError("unable to generate utls config from tls config").Base(err)
|
||||
}
|
||||
|
||||
preset, err := nameToUTLSPreset(e.config.Imitate)
|
||||
if err != nil {
|
||||
return nil, newError("unable to get utls preset from name").Base(err)
|
||||
}
|
||||
|
||||
utlsClientConn := utls.UClient(conn, utlsConfig, *preset)
|
||||
|
||||
if e.config.NoSNI {
|
||||
err = utlsClientConn.RemoveSNIExtension()
|
||||
if err != nil {
|
||||
return nil, newError("unable to remove server name indication from utls client hello").Base(err)
|
||||
}
|
||||
}
|
||||
|
||||
err = utlsClientConn.BuildHandshakeState()
|
||||
if err != nil {
|
||||
return nil, newError("unable to build utls handshake state").Base(err)
|
||||
}
|
||||
|
||||
// ALPN is necessary for protocols like websocket to work. The uTLS setting may be overwritten on call into
|
||||
// BuildHandshakeState, so we need to check the original tls settings.
|
||||
if tlsConfig.NextProtos != nil {
|
||||
for _, v := range utlsClientConn.Extensions {
|
||||
if aplnExtension, ok := v.(*utls.ALPNExtension); ok {
|
||||
aplnExtension.AlpnProtocols = tlsConfig.NextProtos
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = utlsClientConn.BuildHandshakeState()
|
||||
if err != nil {
|
||||
return nil, newError("unable to build utls handshake state after modification").Base(err)
|
||||
}
|
||||
|
||||
err = utlsClientConn.Handshake()
|
||||
if err != nil {
|
||||
return nil, newError("unable to finish utls handshake").Base(err)
|
||||
}
|
||||
return utlsClientConn, nil
|
||||
}
|
||||
|
||||
func uTLSConfigFromTLSConfig(config *systls.Config) (*utls.Config, error) { // nolint: unparam
|
||||
uconfig := &utls.Config{
|
||||
Rand: config.Rand,
|
||||
Time: config.Time,
|
||||
RootCAs: config.RootCAs,
|
||||
NextProtos: config.NextProtos,
|
||||
ServerName: config.ServerName,
|
||||
}
|
||||
return uconfig, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
||||
return NewUTLSSecurityEngineFromConfig(config.(*Config))
|
||||
}))
|
||||
}
|
@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"github.com/v2fly/v2ray-core/v5/transport/internet/security"
|
||||
"io"
|
||||
gonet "net"
|
||||
"net/http"
|
||||
@ -18,6 +17,7 @@ import (
|
||||
"github.com/v2fly/v2ray-core/v5/common/session"
|
||||
"github.com/v2fly/v2ray-core/v5/features/extension"
|
||||
"github.com/v2fly/v2ray-core/v5/transport/internet"
|
||||
"github.com/v2fly/v2ray-core/v5/transport/internet/security"
|
||||
)
|
||||
|
||||
// Dial dials a WebSocket connection to the given destination.
|
||||
|
Loading…
Reference in New Issue
Block a user