Add custom tls client support for v2ray h2/grpclite transports

This commit is contained in:
世界
2022-09-11 10:22:52 +08:00
parent 7e09beb0c3
commit a2d1f89922
14 changed files with 211 additions and 129 deletions

View File

@@ -30,7 +30,7 @@ func NewClient(router adapter.Router, serverAddress string, options option.Outbo
}
}
func ClientHandshake(ctx context.Context, conn net.Conn, config Config) (net.Conn, error) {
func ClientHandshake(ctx context.Context, conn net.Conn, config Config) (Conn, error) {
tlsConn := config.Client(conn)
ctx, cancel := context.WithTimeout(ctx, C.TCPTimeout)
defer cancel()

View File

@@ -15,6 +15,8 @@ type (
)
type Config interface {
NextProtos() []string
SetNextProtos(nextProto []string)
Config() (*STDConfig, error)
Client(conn net.Conn) Conn
}
@@ -28,6 +30,7 @@ type ServerConfig interface {
type Conn interface {
net.Conn
HandshakeContext(ctx context.Context) error
ConnectionState() tls.ConnectionState
}
func ParseTLSVersion(version string) (uint16, error) {

View File

@@ -4,6 +4,7 @@ package tls
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"net"
@@ -12,7 +13,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/transport/cloudflaretls"
cftls "github.com/sagernet/sing-box/transport/cloudflaretls"
"github.com/sagernet/sing-dns"
E "github.com/sagernet/sing/common/exceptions"
@@ -21,7 +22,15 @@ import (
)
type echClientConfig struct {
config *tls.Config
config *cftls.Config
}
func (e *echClientConfig) NextProtos() []string {
return e.config.NextProtos
}
func (e *echClientConfig) SetNextProtos(nextProto []string) {
e.config.NextProtos = nextProto
}
func (e *echClientConfig) Config() (*STDConfig, error) {
@@ -29,7 +38,29 @@ func (e *echClientConfig) Config() (*STDConfig, error) {
}
func (e *echClientConfig) Client(conn net.Conn) Conn {
return tls.Client(conn, e.config)
return &echConnWrapper{cftls.Client(conn, e.config)}
}
type echConnWrapper struct {
*cftls.Conn
}
func (c *echConnWrapper) ConnectionState() tls.ConnectionState {
state := c.Conn.ConnectionState()
return tls.ConnectionState{
Version: state.Version,
HandshakeComplete: state.HandshakeComplete,
DidResume: state.DidResume,
CipherSuite: state.CipherSuite,
NegotiatedProtocol: state.NegotiatedProtocol,
NegotiatedProtocolIsMutual: state.NegotiatedProtocolIsMutual,
ServerName: state.ServerName,
PeerCertificates: state.PeerCertificates,
VerifiedChains: state.VerifiedChains,
SignedCertificateTimestamps: state.SignedCertificateTimestamps,
OCSPResponse: state.OCSPResponse,
TLSUnique: state.TLSUnique,
}
}
func newECHClient(router adapter.Router, serverAddress string, options option.OutboundTLSOptions) (Config, error) {
@@ -45,7 +76,7 @@ func newECHClient(router adapter.Router, serverAddress string, options option.Ou
return nil, E.New("missing server_name or insecure=true")
}
var tlsConfig tls.Config
var tlsConfig cftls.Config
if options.DisableSNI {
tlsConfig.ServerName = "127.0.0.1"
} else {
@@ -55,7 +86,7 @@ func newECHClient(router adapter.Router, serverAddress string, options option.Ou
tlsConfig.InsecureSkipVerify = options.Insecure
} else if options.DisableSNI {
tlsConfig.InsecureSkipVerify = true
tlsConfig.VerifyConnection = func(state tls.ConnectionState) error {
tlsConfig.VerifyConnection = func(state cftls.ConnectionState) error {
verifyOptions := x509.VerifyOptions{
DNSName: serverName,
Intermediates: x509.NewCertPool(),
@@ -87,7 +118,7 @@ func newECHClient(router adapter.Router, serverAddress string, options option.Ou
if options.CipherSuites != nil {
find:
for _, cipherSuite := range options.CipherSuites {
for _, tlsCipherSuite := range tls.CipherSuites() {
for _, tlsCipherSuite := range cftls.CipherSuites() {
if cipherSuite == tlsCipherSuite.Name {
tlsConfig.CipherSuites = append(tlsConfig.CipherSuites, tlsCipherSuite.ID)
continue find
@@ -124,7 +155,7 @@ func newECHClient(router adapter.Router, serverAddress string, options option.Ou
if err != nil {
return nil, err
}
clientConfig, err := tls.UnmarshalECHConfigs(clientConfigContent)
clientConfig, err := cftls.UnmarshalECHConfigs(clientConfigContent)
if err != nil {
return nil, err
}
@@ -137,8 +168,8 @@ func newECHClient(router adapter.Router, serverAddress string, options option.Ou
const typeHTTPS = 65
func fetchECHClientConfig(router adapter.Router) func(ctx context.Context, serverName string) ([]tls.ECHConfig, error) {
return func(ctx context.Context, serverName string) ([]tls.ECHConfig, error) {
func fetchECHClientConfig(router adapter.Router) func(ctx context.Context, serverName string) ([]cftls.ECHConfig, error) {
return func(ctx context.Context, serverName string) ([]cftls.ECHConfig, error) {
message := &dnsmessage.Message{
Header: dnsmessage.Header{
RecursionDesired: true,
@@ -176,7 +207,7 @@ func fetchECHClientConfig(router adapter.Router) func(ctx context.Context, serve
if err != nil {
return nil, E.Cause(err, "decode ECH config")
}
return tls.UnmarshalECHConfigs(echConfig)
return cftls.UnmarshalECHConfigs(echConfig)
}
}
default:

View File

@@ -99,6 +99,14 @@ func newStdClient(serverAddress string, options option.OutboundTLSOptions) (Conf
return &stdClientConfig{&tlsConfig}, nil
}
func (s *stdClientConfig) NextProtos() []string {
return s.config.NextProtos
}
func (s *stdClientConfig) SetNextProtos(nextProto []string) {
s.config.NextProtos = nextProto
}
func (s *stdClientConfig) Config() (*STDConfig, error) {
return s.config, nil
}

View File

@@ -26,6 +26,14 @@ type STDServerConfig struct {
watcher *fsnotify.Watcher
}
func (c *STDServerConfig) NextProtos() []string {
return c.config.NextProtos
}
func (c *STDServerConfig) SetNextProtos(nextProto []string) {
c.config.NextProtos = nextProto
}
func newSTDServer(ctx context.Context, logger log.Logger, options option.InboundTLSOptions) (ServerConfig, error) {
if !options.Enabled {
return nil, nil

View File

@@ -22,6 +22,14 @@ type utlsClientConfig struct {
id utls.ClientHelloID
}
func (e *utlsClientConfig) NextProtos() []string {
return e.config.NextProtos
}
func (e *utlsClientConfig) SetNextProtos(nextProto []string) {
e.config.NextProtos = nextProto
}
func (e *utlsClientConfig) Config() (*STDConfig, error) {
return nil, E.New("unsupported usage for uTLS")
}
@@ -38,6 +46,24 @@ func (c *utlsConnWrapper) HandshakeContext(ctx context.Context) error {
return c.Conn.Handshake()
}
func (c *utlsConnWrapper) ConnectionState() tls.ConnectionState {
state := c.Conn.ConnectionState()
return tls.ConnectionState{
Version: state.Version,
HandshakeComplete: state.HandshakeComplete,
DidResume: state.DidResume,
CipherSuite: state.CipherSuite,
NegotiatedProtocol: state.NegotiatedProtocol,
NegotiatedProtocolIsMutual: state.NegotiatedProtocolIsMutual,
ServerName: state.ServerName,
PeerCertificates: state.PeerCertificates,
VerifiedChains: state.VerifiedChains,
SignedCertificateTimestamps: state.SignedCertificateTimestamps,
OCSPResponse: state.OCSPResponse,
TLSUnique: state.TLSUnique,
}
}
func newUTLSClient(router adapter.Router, serverAddress string, options option.OutboundTLSOptions) (Config, error) {
var serverName string
if options.ServerName != "" {