Force proxy server to resolve a domain to a custom Ip

166 Views Asked by At

I have a goproxy (github.com/elazarl/goproxy) server running locally

proxy := goproxy.NewProxyHttpServer()
http.ListenAndServe(":4242", proxy)

I'm proxying my requests through it, for some domains i'd like to resolve them to a custom IP for both http & https requests

I tried

proxy.OnRequest().HandleConnectFunc(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
    // Allow the connection to proceed for specific hosts
    if host == "mydomain.com" {
        host = "myip:443"
        ctx.Req.URL.Host = host
        ctx.Req.Host = host
    }
    return goproxy.MitmConnect, host
})

which would give me this error with curl (without the --insecure flag)

curl failed to verify the legitimacy of the server and therefore could not 
establish a secure connection to it. To learn more about this situation and 
how to fix it, please visit the web page mentioned above.

and not work with browser.

Any other approaches to make this work

Edit 1. Tried this for a server whose certificate would be trusted by my certificate store, got this in browser enter image description here

Edit 2. Tried modifying net.DefaultResolver and change dns resolver to a custom server

net.DefaultResolver = &net.Resolver{
    PreferGo: true,
    Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
        // Use the default address resolution for other hosts
        fmt.Println("domaIN", network, address)
        return (&net.Dialer{}).DialContext(ctx, network, "127.0.0.1:53")
    },
}

but this also only works for http requests I can change the DialContext of the proxy's transport but that too only would work for http requests & DialTLSContext doesn't work for proxied requests.

I would like to know if i can make this work for proxied https requests too, or is a change to /etc/hosts is my only option.

2

There are 2 best solutions below

0
On BEST ANSWER

For https requests I made it work by adding a https handler to the proxy

proxy.OnRequest().HandleConnectFunc(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
    
    if host == "mycustomdomain.com:443" {
        newIp := fmt.Sprintf("%v:443", myCustomIP)

        host = newIp
        ctx.Req.URL.Host = newIp
        ctx.Req.Host = newIp
    }

    return goproxy.OkConnect, host
})
4
On

You don't have the problem claimed in the title, i.e. set another target IP address. Instead you have the problem that the certificate this host then returns can not be validated by the client - likely because it is not issued by a CA trusted by the client.

This is a problem which need to be solved at each client (trust the CA which issued the CA) or on the server (use a certificate issued by a CA trusted by the client) but cannot be solved at the proxy. Otherwise man in the middle attacks would be easy.