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))
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)
}

16
infra/conf/transport_internet.go

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

27
transport/internet/http/dialer.go

@ -20,12 +20,12 @@ import (
var (
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) {
globalDailerAccess.Lock()
defer globalDailerAccess.Unlock()
globalDialerAccess.Lock()
defer globalDialerAccess.Unlock()
if globalDialerMap == nil {
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 {
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{

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 {
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("h2"))
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
if config.IsExperiment8357() {
conn = tls.UClient(conn, tlsConfig)
} else {

13
transport/internet/tls/config.go

@ -176,6 +176,8 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
config := &tls.Config{
ClientSessionCache: globalSessionCache,
RootCAs: root,
InsecureSkipVerify: c.AllowInsecure,
NextProtos: c.NextProtocol,
SessionTicketsDisabled: c.DisableSessionResumption,
}
if c == nil {
@ -186,12 +188,6 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.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.BuildNameToCertificate()
@ -204,11 +200,8 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
config.ServerName = sn
}
if len(c.NextProtocol) > 0 {
config.NextProtos = c.NextProtocol
}
if len(config.NextProtos) == 0 {
config.NextProtos = []string{"http/1.1"}
config.NextProtos = []string{"h2", "http/1.1"}
}
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 {
protocol = "wss"
dialer.TLSClientConfig = config.GetTLSConfig(tls.WithDestination(dest))
dialer.TLSClientConfig = config.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("http/1.1"))
}
host := dest.NetAddr()

Loading…
Cancel
Save