如何通过HTTP代理隧道发送客户端Hello请求

huangapple go评论75阅读模式
英文:

How to send Client Hello over http proxy tunnel

问题

我有一个客户端,它将与后端服务建立TLS连接。
我遇到了两种情况。

  1. 直接网络:客户端--->服务器
    在这种环境下,客户端直接连接到服务器,代码如下:
   var d tls.Dialer
   //...
   d.Config = &tls.Config{
	    //...
   }
   //...
   c1 := d.Dial("tcp", addr)
  1. 代理网络:客户端--->代理--->服务器
    在这种环境下,客户端位于一个HTTP代理后面,客户端需要利用代理的HTTP隧道来转发客户端和服务器之间的流量。
    我在客户端使用了golang.org/x/net/proxy来连接代理,由于代理是HTTP代理,客户端应该使用net.Dialer通过TCP连接代理。
   dailer, err := proxy.FromURL(proxy, &net.Dialer{
		Timeout:   TCP_CONNECT_TIMEOUT,
		KeepAlive: TCP_KEEPALIVE_TIMEOUT,
	})
   c2 := dailer.Dial("tcp", addr)

在情况1中,客户端启动了一个TLS连接,在网络流量数据包中,客户端触发TCP连接,在三次握手之后,客户端向服务器发送Client Hello

在情况2中,客户端首先使用TCP连接到HTTP代理(例如,10.0.0.1:8080),然后发送CONNECT到代理,然后代理返回Connection Established,但是客户端不会向服务器发送Client Hello

对于情况2,我不知道在客户端如何以及在哪里实现发送Client Hello

提前感谢。

英文:

I have a client which will establish TLS connection to backend service.
There are two kind of scenarios that I encounter.

  1. Direct network: client--->server
    In this environment, The client connect directly to server as below code.
   var d tls.Dialer
   //...
   d.Config = &tls.Config{
	    //...
   }
   //...
   c1 := d.Dial("tcp", addr)
  1. Proxy network: client--->proxy--->server
    In this environment, The client is behind a http proxy, client need leverage proxy http tunnel to forward traffic between client and server.
    I use golang.org/x/net/proxy in client to connect proxy, as proxy is http proxy, client should use net.Dialer to connect proxy via tcp.
   dailer, err := proxy.FromURL(proxy, &net.Dialer{
		Timeout:   TCP_CONNECT_TIMEOUT,
		KeepAlive: TCP_KEEPALIVE_TIMEOUT,
	})
   c2 := dailer.Dial("tcp", addr)

In case1, client start a TLS connection, in network traffic packets, client trigger TCP connection, after 3 way handshakes, client send Client Hello to server.

In case2, client first use TCP to connect http proxy (ex, 10.0.0.1:8080), next, send CONNECT to proxy, then proxy return Connection Established, however, client do NOT send Client Hello to server.

For case2, I do not know how and where to implement to send Client Hello in client?

Thanks in advance.

答案1

得分: 0

在搜索了go doc之后,我找到了解决方案,希望对以后遇到类似问题的人有用。

tls包中,有一个名为Client的函数,可以从现有的net.Conn构建,然后使用Handshake方法。

tlsConn := tls.Client(conn, &tls.Config{
    Certificates:       []tls.Certificate{*cert},
    InsecureSkipVerify: true,
    ServerName:         sni,
    ClientAuth:         tls.RequestClientCert,
})
err = tlsConn.Handshake()
英文:

After searched go doc, I found the solution, Hope useful for later comer with similar problem.

In tls, there is a function Client which can construct from exist net.Conn, then use Handshake

tlsConn := tls.Client(conn, &tls.Config{
	Certificates:       []tls.Certificate{*cert},
	InsecureSkipVerify: true,
	ServerName:         sni,
	ClientAuth:         tls.RequestClientCert,
})
err = tlsConn.Handshake()

huangapple
  • 本文由 发表于 2023年2月17日 15:16:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75481192.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定