DarkSkylo
DarkSkylo

Reputation: 171

How to use a self-signed certificate through proxy server client

I am trying to create an HTTP client that can send self-signed HTTP requests through a proxy server.

I tried this code but I am not sure if there is a problem here, will the following code work?

func CreateProxyClient(serverProxy string, sid string, portProxy int) (*Client, error) {
    http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}

    proxyUrl, _ := url.Parse(serverProxy+":"+strconv.Itoa(portProxy))
    tr := &http.Transport{
        Proxy: http.ProxyURL(proxyUrl),
    }
    var netClient = &http.Client{
        Timeout: time.Second * 10,
        Transport: tr,
    }
    return &Client{netClient, serverProxy, sid}, nil
}

Upvotes: 0

Views: 2730

Answers (1)

Peter
Peter

Reputation: 31751

"Is there a problem"? Only if you consider blindly trusting the certificate a problem (that's why it's called InsecureSkipVerify).

The better option is to configure the client to trust the specific certificate that the server is using, so you get MITM protection in addition to encryption.

To do this, get a copy of the server's certificate via a trusted channel (e.g. copy it from the server's filesystem), then add it to the client's CA pool (this will also trust all certificates signed by the server's cert, if applicable).

Here is an example for the test certificate in net/http, which is used by httptest.NewTLSServer:

package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "log"
    "net/http"
    "net/http/httptest"
)

// cert is used by httptest.NewTLSServer.
//
// In a real application you're going to want to load the certificate from
// disk, rather than hard-coding it. Otherwise you have to recompile the program
// when the certificate is updated.
var cert = []byte(`-----BEGIN CERTIFICATE-----
MIICEzCCAXygAwIBAgIQMIMChMLGrR+QvmQvpwAU6zANBgkqhkiG9w0BAQsFADAS
MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw
MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
iQKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9SjY1bIw4
iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZBl2+XsDul
rKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQABo2gwZjAO
BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw
AwEB/zAuBgNVHREEJzAlggtleGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAA
AAAAATANBgkqhkiG9w0BAQsFAAOBgQCEcetwO59EWk7WiJsG4x8SY+UIAA+flUI9
tyC4lNhbcF2Idq9greZwbYCqTTTr2XiRNSMLCOjKyI7ukPoPjo16ocHj+P3vZGfs
h1fIw3cSS2OolhloGw/XM6RWPWtPAlGykKLciQrBru5NAPvCMsb/I1DAceTiotQM
fblo6RBxUQ==
-----END CERTIFICATE-----`)

func main() {
    pool, err := x509.SystemCertPool()
    if err != nil {
        log.Fatal(err)
    }
    if !pool.AppendCertsFromPEM(cert) {
        log.Fatal("Cannot append self-signed cert to CA pool")
    }

    c := &http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                RootCAs: pool,
            },
        },
    }

    s := httptest.NewTLSServer(nil)
    res, err := c.Get(s.URL)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res.Status)
}

Try it on the playground: https://play.golang.org/p/HsI2RyOd5qd

Upvotes: 1

Related Questions