AdguardTeam / gomitmproxy

Simple golang mitm proxy implementation
https://adguard.com/
GNU General Public License v3.0
293 stars 59 forks source link

allow user to process unmitmable stream #12

Closed xxxsen closed 1 year ago

xxxsen commented 1 year ago
xxxsen commented 1 year ago

It's been quite some time since I made any changes to this project.

Please give me a few hours, I'll do some refactoring and then we can discuss your PR.

Generally, it'd be better to start with an issue. I'd like to understand what goal you're trying to achieve. It seems that you want not just to decide whether a host should be mitmed or not, but also you want to have an option to completely take over the connection and avoid tunnelling it in some cases.

My usage scenario is to hijack web traffic and remove their TLS, then forward them to a proxy server for processing, which currently works fine for normal http(s) traffic, but if it's non-http traffic, such as ssh, If I don't take over the underlying connection, then according to the original code logic, a connection to the ssh server will be established, but we need to go through the proxy server to access the network normally, connect directly to the ssh server will be blocked.

You may want to ask why I don't directly implement a proxy server.

Haha, in our country, the network is censored, and currently they can identify TLS over TLS traffic, so I am trying to write a program to remove the underlying TLS(https), and then try to use the normal proxy server to handle the traffic that cannot be removed(like ssh).

ameshkov commented 1 year ago

It sounds as if you actually need to MITM the traffic and then pass the plain HTTP requests/responses through a regular HTTP proxy. Did I get it right?

Also, if I am right, why don't just use OnConnect for that purpose? https://github.com/AdguardTeam/gomitmproxy/blob/master/examples/mitm/main.go#L165

xxxsen commented 1 year ago

It sounds as if you actually need to MITM the traffic and then pass the plain HTTP requests/responses through a regular HTTP proxy. Did I get it right?

Also, if I am right, why don't just use OnConnect for that purpose? https://github.com/AdguardTeam/gomitmproxy/blob/master/examples/mitm/main.go#L165

yes, MITM the traffic and get the plain HTTP then pass them via a proxy server with my own TLS connection

Also, if I am right, why don't just use OnConnect for that purpose?

If the traffic can be MITM, the connection established through OnConnect will be closed, and the connection established at this time is meaningless and wasteful.

ameshkov commented 1 year ago

Here's what I am not getting. If the original request has been sent for an HTTPS resource, the proxy you're trying to re-route the traffic to will also require an HTTP CONNECT method in order to process that request.

If the traffic can be MITM, the connection established through OnConnect will be closed, and the connection established at this time is meaningless and wasteful.

You can return &proxyutil.NoopConn{} there in this case.

The pseudo-code will be something like that:

OnConnect: func() {
    return &proxyutil.NoopConn{}
}

OnRequest: onRequest(session *gomitmproxy.Session) (*http.Request, *http.Response) {
    req := session.Request()

        proxyUrl, err := url.Parse("http://proxyIp:proxyPort")
        client := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}}
        resp, err := client.Do(req)

        return req, resp
}
xxxsen commented 1 year ago

Here's what I am not getting. If the original request has been sent for an HTTPS resource, the proxy you're trying to re-route the traffic to will also require an HTTP CONNECT method in order to process that request.

If the traffic can be MITM, the connection established through OnConnect will be closed, and the connection established at this time is meaningless and wasteful.

You can return &proxyutil.NoopConn{} there in this case.

The pseudo-code will be something like that:

OnConnect: func() {
    return &proxyutil.NoopConn{}
}

OnRequest: onRequest(session *gomitmproxy.Session) (*http.Request, *http.Response) {
  req := session.Request()

        proxyUrl, err := url.Parse("http://proxyIp:proxyPort")
        client := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}}
        resp, err := client.Do(req)

        return req, resp
}

Here's what I am not getting. If the original request has been sent for an HTTPS resource, the proxy you're trying to re-route the traffic to will also require an HTTP CONNECT method in order to process that request.

no, proxy server what i metioned is not a regular http/socks proxy, we dont need using connect to proxy request. like v2ray, they have their own proxy protocol

You can return &proxyutil.NoopConn{} there in this case.

in this case, how can i proxy ssh traffic?