elazarl / goproxy

An HTTP proxy library for Go
BSD 3-Clause "New" or "Revised" License
5.89k stars 1.07k forks source link

Reddit example and URL matching does not work #293

Open 7twin opened 6 years ago

7twin commented 6 years ago

The reddit example and matching against a destination url does not work, it just passes the request through, instead of returning a StatusForbidden

package main

import (
    "github.com/elazarl/goproxy"
    "log"
    "net/http"
)

func main() {
    proxy := goproxy.NewProxyHttpServer()
    proxy.OnRequest(goproxy.DstHostIs("www.reddit.com")).DoFunc(
        func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
            return r, goproxy.NewResponse(r,
                goproxy.ContentTypeText, http.StatusForbidden,
                "Don't waste your time!")
        })
    log.Fatalln(http.ListenAndServe(":8080", proxy))
}
cedricve commented 6 years ago

noticed the same

berkant commented 5 years ago

It's most likely that you're requesting Reddit with HTTPS or your browser is somehow redirecting you from HTTP to HTTPS without drawing your attention.

If the case is so, you will have to use Mitm if I'm not wrong.

You may test this using curl: curl -x <ProxyIP>:<ProxyPort> http://www.reddit.com/ --verbose

Watch out that I'm using http above. It should return your custom message.

Now test the command also for https. It possibly won't return your custom message. This is because you're spawning a CONNECT to watch the response from website in HTTPS case. You're a spectator here and can't intercept response.

Using Mitm, you will have two TLS channels one of which will be your Man-in-the-Middle where the request and response gets exchanged and the other one will be used to CONNECT to real HTTPS.

7twin commented 5 years ago

@illenialx that's what I thought might be the issue too, but if I remember right, the eavesdropper example wasn't properly working either, even though it resolves a https connection into a plain http connection iirc

berkant commented 5 years ago

@7twin I don't know but I am using master version and I made my browser trust cert.pem and cert.key and it works seamlessly for me.

7twin commented 5 years ago

@illenialx are you using the eavesdropper example? and did you modify the source at all?

berkant commented 5 years ago

@7twin I think the problem is with your ReqCondition which is the value returned by DstHostIs in your case. If you check it, it will return (www.)reddit.com:443 (= req.URL.Host). Not www.reddit.com. I think it should be corrected to req.Host and a PR may be assessed for this.

7twin commented 5 years ago

@c-r-o-s-s I'm not sure how I could check what the input for the reqcondition is, since I am just starting with golang, but I did try all combinations of the domain, including :443 and other reqconditions and none of them matched, what script are you using that works?

berkant commented 5 years ago

@7twin Here you go.

https://play.golang.org/p/O4OMbmPfARV https://asciinema.org/a/kpm13g8F6fnQOavaShRMeF56H

7twin commented 5 years ago

@c-r-o-s-s thanks, what certs did you trust, did you generate them via the bash script inside the certs folder? or used the root ones?

berkant commented 5 years ago

@7twin It doesn't matter. The pregenerated custom root CA in https://github.com/elazarl/goproxy are already generated using that script and OpenSSL conf. If you're OK with the name of the repository and domain to show up, you can use it. Otherwise you're free to generate your own. I also imported ca.key and ca.pem both in system and browser.

HackProAIT commented 3 years ago

tried proxy.OnRequest(goproxy.UrlHasPrefix("www.google.com")).HandleConnect(goproxy.AlwaysReject) it worked!

pguardiario commented 3 years ago

So is there a solution for blocking https://www.reddit.com/ ?