Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force client hostname when proxying https

I'm using toxiproxy. I'm having this exact issue. Both of the curl solutions mentioned in the issue work (solution a, solution b), but I can't use curl. I need to use the go standard net/http library.

Is there any way to use net/http in such a fashion that I can explicitly tell it what host the proxy is using so it can see that the certificate is valid?

I've tried setting Host and Authority headers on the net/http.Request, but that didn't work.

Details

Toxiproxy output:

proxy=[::]:22002 upstream=maps.googleapis.com:443

My code:

url := "https://localhost:22002/maps/api/geocode/json..."
req, err := http.NewRequest("GET", url, nil)
req.Host = "maps.googleapis.com"
req.Header.Set("Host", "maps.googleapis.com")
res, err := httpClient.Do(req)

Error:

x509: certificate is valid for *.googleapis.com, *.clients6.google.com, *.cloudendpointsapis.com, cloudendpointsapis.com, googleapis.com, not localhost

like image 832
lf215 Avatar asked Oct 29 '25 17:10

lf215


1 Answers

You need to set the http.Request.Host field so that the http request has the correct header

req.Host = "maps.googleapis.com"

An you also need to set the hostname in the tls.Config.ServerName field for SNI and host name verification.

If you've already configured a transport for your httpClient, you can set it like so:

httpClient.Transport.(*http.Transport).TLSClientConfig = &tls.Config{
    ServerName: "maps.googleapis.com",
}

Or for small programs you can override the default:

http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{
    ServerName: "maps.googleapis.com",
}

Or create a custom transport for your program

var httpTransport = &http.Transport{
    Proxy: http.ProxyFromEnvironment,
    DialContext: (&net.Dialer{
        Timeout:   30 * time.Second,
        KeepAlive: 30 * time.Second,
        DualStack: true,
    }).DialContext,
    MaxIdleConns:          100,
    IdleConnTimeout:       90 * time.Second,
    TLSHandshakeTimeout:   10 * time.Second,
    ExpectContinueTimeout: 1 * time.Second,
    TLSClientConfig: &tls.Config{
        ServerName: "maps.googleapis.com",
    },
}

Just make sure you reuse the Transport, and don't create a new one for each request.

like image 77
JimB Avatar answered Oct 31 '25 11:10

JimB



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!