Skip to content

Commit

Permalink
Further strip unique signatures of tls handshake
Browse files Browse the repository at this point in the history
1. allow users to disable session ticket
2. set default alpn to ["h2", "http/1.1"]
  • Loading branch information
darhwa authored and xiaokangwang committed Jun 18, 2020
1 parent 9e62f4a commit 8e791e9
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 25 deletions.
2 changes: 1 addition & 1 deletion app/proxyman/outbound/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
16 changes: 9 additions & 7 deletions infra/conf/transport_internet.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
}

Expand Down
27 changes: 22 additions & 5 deletions transport/internet/http/dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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{
Expand Down
2 changes: 1 addition & 1 deletion transport/internet/tcp/dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
13 changes: 3 additions & 10 deletions transport/internet/tls/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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()

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion transport/internet/websocket/dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit 8e791e9

Please sign in to comment.