dskm94301 2016-05-06 10:44
浏览 501
已采纳

通过自签名证书进行TLS连接失败

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)

  • 写回答

1条回答 默认 最新

  • dsds33222 2016-05-06 12:35
    关注

    So the actual problem here is part related to my organisations infrastructure and part related to how nginx uses ssl_client_certificate.

    We have int, test and live environments

    I was led to believe that the environments could communicate between each other.

    So I had my service setup on int, and I was able to use curl from there to communicate with another service setup in a live environment.

    The problem occurred when using Go to communicate across environments.

    The quick solution for me was to ensure when I made a GET to this other service, that instead of using:

    https://service.live.me.com
    

    I would use:

    https://service.int.me.com
    

    Or:

    https://service.test.me.com
    

    Depending on the environment my code was running within.

    Obviously this isn't a solution for other people who have a similar issue but don't have the same setup.


    So for those of you who still need a solution...


    What I was also going to try (and apparently worked for this guy) was to get the service that I was trying to communicate with to modify their nginx conf so that they set ssl_client_certificate to not point to just a client cert, but a combined cert (one that includes the entire CA chain).

    This was because apparently Go doesn't send back any certs with its response unless the server has passed a CA along with its response.

    I had originally suspected this was the classic renegotiation bug in Go 1.6 and below, but that wasn't the case in this scenario.

    Hope this helps anyone else in the same boat.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码