Open lls275 opened 2 years ago
The above should be a good start and hopefully it will be resolved.Below I provide the Debug information of the Vhost extension, which seems to be very rich
This is a simple example of vhost officially available, and I can run through it and run it normally, but I don't know how to add it to gomitmproxy. Can the author add it? vhost_package_demo.go.zip
package main
import (
"bufio"
"bytes"
"github.com/AdguardTeam/golibs/log"
"goproxy/go-vhost"
"io"
"net"
"net/http"
"net/url"
)
func main() {
l, err := net.Listen("tcp", ":12345")
log.Printf("start listening to %s", l.Addr())
if err != nil {
log.Fatalf("Error listening for https connections - %v", err)
}
for {
c, err := l.Accept()
if err != nil {
log.Printf("Error accepting new connection - %v", err)
continue
}
go func(c net.Conn) {
tlsConn, err := vhost.TLS(c)
if err != nil {
log.Printf("Error accepting new connection - %v", err)
}
if tlsConn.Host() == "" {
log.Printf("Cannot support non-SNI enabled clients")
return
}
connectReq := makeRequest(c, tlsConn)
resp := dumbResponseWriter{tlsConn}
ServeHTTP(resp, connectReq)
}(c)
}
}
func makeRequest(c net.Conn, tlsConn *vhost.TLSConn) *http.Request {
return &http.Request{
Method: "CONNECT",
URL: &url.URL{
Opaque: tlsConn.Host(),
Host: net.JoinHostPort(tlsConn.Host(), "443"),
},
Host: tlsConn.Host(),
Header: make(http.Header),
RemoteAddr: c.RemoteAddr().String(),
}
}
func ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method == "CONNECT" {
hij, ok := w.(http.Hijacker)
if !ok {
panic("httpserver does not support hijacking")
}
proxyClient, _, e := hij.Hijack()
proxyClient.Write([]byte("HTTP/1.0 200 OK\r\n\r\n"))
if e != nil {
panic("Cannot hijack connection " + e.Error())
}
targetSiteCon, _ := net.Dial("tcp", r.URL.Host)
log.Info("Accepting CONNECT to %s", r.URL.Host)
donec := make(chan bool, 2)
go copyConnectTunnel(targetSiteCon, proxyClient, donec)
go copyConnectTunnel(proxyClient, targetSiteCon, donec)
<-donec
<-donec
}
}
func copyConnectTunnel(w io.Writer, r io.Reader, donec chan<- bool) {
if _, err := io.Copy(w, r); err != nil {
log.Error("Error copying to client: %s", err)
}
donec <- true
}
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
}
At this point it'd be better to fork gomitmproxy to another repo and implement it there.
Eventually, we'll add transparent proxy support here as well, but we'll really need to devote quite some time to do that.
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
Then, pass the traffic to Gomitmproxy again via iptable:
After execution, I found that, hey,
failed to read request: malformed HTTP request
did not appear, it seems to be good: proxy.go.zipThen, the browser cannot display the normal page and prompts:
It seems that the problem appears in the certificate. Can the author reproduce it and help solve it?