Golang: How to execute an https request with a bad certificate?

Let's say I want to get https://golang.org programmatically. Golang.org (ssl) currently has a bad certificate issued by *.appspot.com So when I run this:

 package main import ( "log" "net/http" ) func main() { _, err := http.Get("https://golang.org/") if err != nil { log.Fatal(err) } } 

I get (as expected)

 Get https://golang.org/: certificate is valid for *.appspot.com, *.*.appspot.com, appspot.com, not golang.org 

Now I want to trust this certificate myself (imagine a self-signed certificate, where I can check the fingerprint, etc.): how can I make a request and verify / trust the certificate?

I probably need to use openssl to upload the certificate, upload it to a file and populate tls.Config struct !?

+76
ssl go
Aug 25 2018-12-12T00:
source share
4 answers

You can disable the security check (at your own risk):

 package main import ( "fmt" "net/http" "crypto/tls" ) func main() { tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} _, err := client.Get("https://golang.org/") if err != nil { fmt.Println(err) } } 
+153
Aug 25 2018-12-12T00:
source

If you want to use the default settings from the http package, so you do not need to create a new Transport and Client object, you can change to ignore certificate verification as follows:

 tr := http.DefaultTransport.(*http.Transport) tr.TLSClientConfig.InsecureSkipVerify = true 
+7
Jan 20 '17 at 15:36
source

Here you can do this without losing the default settings of DefaultTransport and without needing a fake request in accordance with user comments.

 defaultTransport := http.DefaultTransport.(*http.Transport) // Create new Transport that ignores self-signed SSL httpClientWithSelfSignedTLS := &http.Transport{ Proxy: defaultTransport.Proxy, DialContext: defaultTransport.DialContext, MaxIdleConns: defaultTransport.MaxIdleConns, IdleConnTimeout: defaultTransport.IdleConnTimeout, ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout, TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout, TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } 
+1
02 Sep '17 at 7:02 on
source

All of these answers are incorrect! Do not use InsecureSkipVerify to work with a CN that does not match the host name. Go developers were unreasonable, not refusing to verify the host name (which has legitimate uses - tunnels, nats, general cluster certificates, etc.), and also have something similar, but actually completely ignore certificate verification. You must know that the certificate is valid and signed by a certificate that you trust. But in common scenarios, you know that CN will not match the host name you are associated with. For them, set ServerName to tls.Config. If tls.Config.ServerName == remoteServerCN, then certificate verification will be successful. Is this what you want. InsecureSkipVerify means no authentication; and he is ripe for Man-in-the-Middle; defeating the goal of using TLS.

There is one legitimate use for InsecureSkipVerify ... Use it to connect to the host and obtain its certificate, and then disconnect it immediately. If you configure your code to use InsecureSkipVerify, this is usually because you did not set the server_name correctly (it will need to switch from env var or something else - do not be afraid of this requirement ... do it right).

In particular, if you use client certificates and rely on them for authentication, you basically have a fake login that is no longer registered. The failure code that InsecureSkipVerify does, or you'll find out what's not so difficult with it!

0
Nov 08 '17 at 1:12
source



All Articles