Browse Source

Further strip unique signatures of tls handshake

1. allow users to disable session ticket
2. set default alpn to ["h2", "http/1.1"]
pull/2582/head
Darhwa 5 years ago committed by Shelikhoo
parent
commit
8e791e92bc
No known key found for this signature in database
GPG Key ID: C4D5E79D22B25316
  1. 2
      app/proxyman/outbound/handler.go
  2. 16
      infra/conf/transport_internet.go
  3. 27
      transport/internet/http/dialer.go
  4. 2
      transport/internet/tcp/dialer.go
  5. 13
      transport/internet/tls/config.go
  6. 2
      transport/internet/websocket/dialer.go

2
app/proxyman/outbound/handler.go

@ -144,7 +144,7 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Conn
conn := net.NewConnection(net.ConnectionInputMulti(uplinkWriter), net.ConnectionOutputMulti(downlinkReader)) conn := net.NewConnection(net.ConnectionInputMulti(uplinkWriter), net.ConnectionOutputMulti(downlinkReader))
if config := tls.ConfigFromStreamSettings(h.streamSettings); config != nil { if config := tls.ConfigFromStreamSettings(h.streamSettings); config != nil {
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("h2")) tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
conn = tls.Client(conn, tlsConfig) conn = tls.Client(conn, tlsConfig)
} }

16
infra/conf/transport_internet.go

@ -274,12 +274,13 @@ func (c *TLSCertConfig) Build() (*tls.Certificate, error) {
} }
type TLSConfig struct { type TLSConfig struct {
Insecure bool `json:"allowInsecure"` Insecure bool `json:"allowInsecure"`
InsecureCiphers bool `json:"allowInsecureCiphers"` InsecureCiphers bool `json:"allowInsecureCiphers"`
Certs []*TLSCertConfig `json:"certificates"` Certs []*TLSCertConfig `json:"certificates"`
ServerName string `json:"serverName"` ServerName string `json:"serverName"`
ALPN *StringList `json:"alpn"` ALPN *StringList `json:"alpn"`
DiableSystemRoot bool `json:"disableSystemRoot"` DisableSessionResumption bool `json:"disableSessionResumption"`
DisableSystemRoot bool `json:"disableSystemRoot"`
} }
// Build implements Buildable. // Build implements Buildable.
@ -302,7 +303,8 @@ func (c *TLSConfig) Build() (proto.Message, error) {
if c.ALPN != nil && len(*c.ALPN) > 0 { if c.ALPN != nil && len(*c.ALPN) > 0 {
config.NextProtocol = []string(*c.ALPN) config.NextProtocol = []string(*c.ALPN)
} }
config.DisableSystemRoot = c.DiableSystemRoot config.DisableSessionResumption = c.DisableSessionResumption
config.DisableSystemRoot = c.DisableSystemRoot
return config, nil return config, nil
} }

27
transport/internet/http/dialer.go

@ -20,12 +20,12 @@ import (
var ( var (
globalDialerMap map[net.Destination]*http.Client globalDialerMap map[net.Destination]*http.Client
globalDailerAccess sync.Mutex globalDialerAccess sync.Mutex
) )
func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.Config) (*http.Client, error) { func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.Config) (*http.Client, error) {
globalDailerAccess.Lock() globalDialerAccess.Lock()
defer globalDailerAccess.Unlock() defer globalDialerAccess.Unlock()
if globalDialerMap == nil { if globalDialerMap == nil {
globalDialerMap = make(map[net.Destination]*http.Client) globalDialerMap = make(map[net.Destination]*http.Client)
@ -54,9 +54,26 @@ func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.C
if err != nil { if err != nil {
return nil, err return nil, err
} }
return gotls.Client(pconn, tlsConfig), nil
cn := gotls.Client(pconn, tlsConfig)
if err := cn.Handshake(); err != nil {
return nil, err
}
if !tlsConfig.InsecureSkipVerify {
if err := cn.VerifyHostname(tlsConfig.ServerName); err != nil {
return nil, err
}
}
state := cn.ConnectionState()
if p := state.NegotiatedProtocol; p != http2.NextProtoTLS {
return nil, newError("http2: unexpected ALPN protocol " + p + "; want q" + http2.NextProtoTLS).AtError()
}
if !state.NegotiatedProtocolIsMutual {
return nil, newError("http2: could not negotiate protocol mutually").AtError()
}
return cn, nil
}, },
TLSClientConfig: tlsSettings.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("h2")), TLSClientConfig: tlsSettings.GetTLSConfig(tls.WithDestination(dest)),
} }
client := &http.Client{ client := &http.Client{

2
transport/internet/tcp/dialer.go

@ -21,7 +21,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
} }
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil { if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("h2")) tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
if config.IsExperiment8357() { if config.IsExperiment8357() {
conn = tls.UClient(conn, tlsConfig) conn = tls.UClient(conn, tlsConfig)
} else { } else {

13
transport/internet/tls/config.go

@ -176,6 +176,8 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
config := &tls.Config{ config := &tls.Config{
ClientSessionCache: globalSessionCache, ClientSessionCache: globalSessionCache,
RootCAs: root, RootCAs: root,
InsecureSkipVerify: c.AllowInsecure,
NextProtos: c.NextProtocol,
SessionTicketsDisabled: c.DisableSessionResumption, SessionTicketsDisabled: c.DisableSessionResumption,
} }
if c == nil { if c == nil {
@ -186,12 +188,6 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
opt(config) opt(config)
} }
if !c.AllowInsecureCiphers && len(config.CipherSuites) == 0 {
// crypto/tls will use the proper ciphers
config.CipherSuites = nil
}
config.InsecureSkipVerify = c.AllowInsecure
config.Certificates = c.BuildCertificates() config.Certificates = c.BuildCertificates()
config.BuildNameToCertificate() config.BuildNameToCertificate()
@ -204,11 +200,8 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
config.ServerName = sn config.ServerName = sn
} }
if len(c.NextProtocol) > 0 {
config.NextProtos = c.NextProtocol
}
if len(config.NextProtos) == 0 { if len(config.NextProtos) == 0 {
config.NextProtos = []string{"http/1.1"} config.NextProtos = []string{"h2", "http/1.1"}
} }
return config return config

2
transport/internet/websocket/dialer.go

@ -45,7 +45,7 @@ func dialWebsocket(ctx context.Context, dest net.Destination, streamSettings *in
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil { if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
protocol = "wss" protocol = "wss"
dialer.TLSClientConfig = config.GetTLSConfig(tls.WithDestination(dest)) dialer.TLSClientConfig = config.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("http/1.1"))
} }
host := dest.NetAddr() host := dest.NetAddr()

Loading…
Cancel
Save