英文:
How to send Client Hello over http proxy tunnel
问题
我有一个客户端,它将与后端服务建立TLS连接。
我遇到了两种情况。
- 直接网络:客户端--->服务器
在这种环境下,客户端直接连接到服务器,代码如下:
var d tls.Dialer
//...
d.Config = &tls.Config{
//...
}
//...
c1 := d.Dial("tcp", addr)
- 代理网络:客户端--->代理--->服务器
在这种环境下,客户端位于一个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.
- 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)
- 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 usegolang.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()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论