diff --git a/connector/http/connector.go b/connector/http/connector.go index deeafdf4..83e1ec02 100644 --- a/connector/http/connector.go +++ b/connector/http/connector.go @@ -2,9 +2,12 @@ package http import ( "bufio" + "bytes" "context" "encoding/base64" + "encoding/binary" "fmt" + "hash/crc32" "net" "net/http" "net/http/httputil" @@ -53,10 +56,16 @@ func (c *httpConnector) Connect(ctx context.Context, conn net.Conn, network, add }) log.Debugf("connect %s/%s", address, network) + connectHost := address + if c.md.host != "" { + // 伪装的地址 + connectHost = c.md.host + } + req := &http.Request{ Method: http.MethodConnect, - URL: &url.URL{Host: address}, - Host: address, + URL: &url.URL{Host: connectHost}, + Host: connectHost, ProtoMajor: 1, ProtoMinor: 1, Header: c.md.header, @@ -67,6 +76,12 @@ func (c *httpConnector) Connect(ctx context.Context, conn net.Conn, network, add } req.Header.Set("Proxy-Connection", "keep-alive") + // 真实连接的地址 + if c.md.host != "" { + targetAddr := encodeServerName(address) + req.Header.Set("Gost-Target", targetAddr) + } + if user := c.options.Auth; user != nil { u := user.Username() p, _ := user.Password() @@ -129,3 +144,10 @@ func (c *httpConnector) Connect(ctx context.Context, conn net.Conn, network, add return conn, nil } + +func encodeServerName(name string) string { + buf := &bytes.Buffer{} + binary.Write(buf, binary.BigEndian, crc32.ChecksumIEEE([]byte(name))) + buf.WriteString(base64.RawURLEncoding.EncodeToString([]byte(name))) + return base64.RawURLEncoding.EncodeToString(buf.Bytes()) +} diff --git a/connector/http/metadata.go b/connector/http/metadata.go index 44561201..7d02ff82 100644 --- a/connector/http/metadata.go +++ b/connector/http/metadata.go @@ -11,15 +11,19 @@ import ( type metadata struct { connectTimeout time.Duration header http.Header + //伪装混淆用host + host string } func (c *httpConnector) parseMetadata(md mdata.Metadata) (err error) { const ( connectTimeout = "timeout" header = "header" + host = "host" ) c.md.connectTimeout = mdutil.GetDuration(md, connectTimeout) + c.md.host = mdutil.GetString(md, host) if mm := mdutil.GetStringMapString(md, header); len(mm) > 0 { hd := http.Header{}