diff --git a/README.md b/README.md index 12503c95..fa72efdb 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,7 @@ proxies: # udp: true # tls: true # skip-cert-verify: true + # servername: example.com # priority over wss host # network: ws # ws-path: /path # ws-headers: diff --git a/adapters/outbound/vmess.go b/adapters/outbound/vmess.go index a9365526..51ff044b 100644 --- a/adapters/outbound/vmess.go +++ b/adapters/outbound/vmess.go @@ -35,6 +35,7 @@ type VmessOption struct { WSPath string `proxy:"ws-path,omitempty"` WSHeaders map[string]string `proxy:"ws-headers,omitempty"` SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"` + ServerName string `proxy:"servername,omitempty"` } type HTTPOptions struct { @@ -66,6 +67,7 @@ func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) { wsOpts.TLS = true wsOpts.SessionCache = getClientSessionCache() wsOpts.SkipCertVerify = v.option.SkipCertVerify + wsOpts.ServerName = v.option.ServerName } c, err = vmess.StreamWebsocketConn(c, wsOpts) case "http": @@ -87,6 +89,11 @@ func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) { SkipCertVerify: v.option.SkipCertVerify, SessionCache: getClientSessionCache(), } + + if v.option.ServerName != "" { + tlsOpts.Host = v.option.ServerName + } + c, err = vmess.StreamTLSConn(c, tlsOpts) } } diff --git a/component/vmess/websocket.go b/component/vmess/websocket.go index 625905b8..499f15c8 100644 --- a/component/vmess/websocket.go +++ b/component/vmess/websocket.go @@ -31,6 +31,7 @@ type WebsocketConfig struct { Headers http.Header TLS bool SkipCertVerify bool + ServerName string SessionCache tls.ClientSessionCache } @@ -132,7 +133,9 @@ func StreamWebsocketConn(conn net.Conn, c *WebsocketConfig) (net.Conn, error) { ClientSessionCache: c.SessionCache, } - if host := c.Headers.Get("Host"); host != "" { + if c.ServerName != "" { + dialer.TLSClientConfig.ServerName = c.ServerName + } else if host := c.Headers.Get("Host"); host != "" { dialer.TLSClientConfig.ServerName = host } }