-
Notifications
You must be signed in to change notification settings - Fork 70
Description
Hey, I stumbled upon a very interesting GO extension this afternoon, it seems to avoid a lot of code changes in Gomitmproxy and implement the function of adding a transparent proxy, I found that adding to Gomitmproxy this afternoon, there seems to be progress, and under the transparent proxy, there is no Before the failed to read request: malformed HTTP request appeared, this seems to be a good start, and I only changed a small range, but I still encountered some problems, which may need the author's help (there is a certificate verification problem , I debug test, but my ability is not enough, I hope the author can solve it).
I found a very interesting extension library, I believe the author must be very interested, https://github.com/inconshreveable/go-vhost, it can get the real hostname in the case of transparent proxy, including the one passed by the client Key information, which seems to be in line with Gomitmproxy's small changes to have the function of transparent proxy.
The only thing I changed is:
https://github.com/AdguardTeam/gomitmproxy/blob/master/proxy.go#L210
type dumbResponseWriter struct {
net.Conn
}
func (dumb dumbResponseWriter) Header() http.Header {
panic("Header() should not be called on this ResponseWriter")
}
func (dumb dumbResponseWriter) Write(buf []byte) (int, error) {
if bytes.Equal(buf, []byte("HTTP/1.0 200 OK\r\n\r\n")) {
return len(buf), nil // throw away the HTTP OK response from the faux CONNECT request
}
return dumb.Conn.Write(buf)
}
func (dumb dumbResponseWriter) WriteHeader(code int) {
panic("WriteHeader() should not be called on this ResponseWriter")
}
func (dumb dumbResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return dumb, bufio.NewReadWriter(bufio.NewReader(dumb), bufio.NewWriter(dumb)), nil
}
func (p *Proxy) connHijacker(w http.ResponseWriter) net.Conn {
hij, ok := w.(http.Hijacker)
if !ok {
log.Error("httpserver does not support hijacking")
}
proxyClient, _, e := hij.Hijack()
if e != nil {
log.Error("Cannot hijack connection " + e.Error())
}
proxyClient.Write([]byte("HTTP/1.0 200 OK\r\n\r\n"))
return proxyClient
}
// handleRequest reads an incoming request and processes it
func (p *Proxy) handleRequest(ctx *Context) error {
tlsConn, err := vhost.TLS(ctx.conn)
origReq := &http.Request{
Method: "CONNECT",
URL: &url.URL{
Opaque: tlsConn.Host(),
Host: net.JoinHostPort(tlsConn.Host(), "443"),
},
Host: tlsConn.Host(),
Header: make(http.Header),
RemoteAddr: ctx.conn.RemoteAddr().String(),
}
hijackerConn := p.connHijacker(dumbResponseWriter{tlsConn})
ctx.conn = hijackerConn
//origReq, err := p.readRequest(ctx)
Then, pass the traffic to Gomitmproxy again via iptable:
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to 10.20.1.1:12345
sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to 10.20.1.1:12345
After execution, I found that, hey, failed to read request: malformed HTTP request did not appear, it seems to be good:
proxy.go.zip
2022/04/09 10:28:59 12416#6 [debug] id=100476: accepted connection from 10.20.1.92:51399
2022/04/09 10:29:00 12416#3207 [debug] id=100474-1: tunnel finished copying
2022/04/09 10:29:00 12416#3201 [debug] id=100474-1: closed CONNECT tunnel
2022/04/09 10:29:00 12416#3201 [debug] id=100474: closing connection due to: closing connection
2022/04/09 10:29:00 12416#3218 [debug] id=100476-1: handle request CONNECT http:init.push.apple.com
2022/04/09 10:29:00 12416#3218 [debug] id=100476-1: connecting to host: init.push.apple.com:443
2022/04/09 10:29:00 12416#3217 [debug] id=100475-1: tunnel finished copying
2022/04/09 10:29:00 12416#3218 [debug] id=100476-1: connecting to tcp://init.push.apple.com:443
Then, the browser cannot display the normal page and prompts:
safari cannot open the page because it could not establish a secure connection to the server
It seems that the problem appears in the certificate. Can the author reproduce it and help solve it?