This following reduced test case code works when run locally on my laptop using my own 'developer' certs for accessing internal services
If I run on a remote machine with dynamically generated certs (all of which is handled by a separate team in my organisation) it fails with a 400 and "No required SSL certificate was sent" error
But if I use curl on the remote machine, and specify the same certs as referenced in my Go code, it will work
So seems the certs aren't the issue but the Go code, but that itself doesn't seem to be the issue as it works with my own certs locally
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"net/http"
"os"
"time"
)
func main() {
transport, transErr := configureTLS()
if transErr != nil {
fmt.Printf("trans error: %s", transErr.Error())
return
}
timeout := time.Duration(1 * time.Second)
client := http.Client{
Transport: transport,
Timeout: timeout,
}
resp, clientErr := client.Get("https://my-service-with-nginx/")
if clientErr != nil {
fmt.Printf("client error: %s", clientErr.Error())
} else {
defer resp.Body.Close()
contents, contErr := ioutil.ReadAll(resp.Body)
if contErr != nil {
fmt.Printf("contents error: %s", contErr.Error())
}
fmt.Printf("
contents:
%+v", string(contents))
}
}
func configureTLS() (*http.Transport, error) {
certPath := "/path/to/client.crt"
keyPath := "/path/to/client.key"
caPath := "/path/to/ca.crt"
// Load client cert
cert, err := tls.LoadX509KeyPair(certPath, keyPath)
if err != nil {
return nil, err
}
// Load CA cert
caCert, err := ioutil.ReadFile(caPath)
if err != nil {
return nil, err
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
// Setup HTTPS client
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
InsecureSkipVerify: true,
}
tlsConfig.BuildNameToCertificate()
return &http.Transport{TLSClientConfig: tlsConfig}, nil
}
Does anyone know why this would be happening?
I thought it might be the renegotiation bug that Go has (as of 1.6) but I don't think that's the case here as otherwise it would fail for me when running the app locally (but it doesn't, using my own dev certs and running locally works fine - the problem only occurs when run on a remote instance with different certs; and those certs aren't the problem as they work fine when used by curl
)