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.

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

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘