当使用我自己的“开发人员”证书在我的笔记本电脑上本地运行以访问内部服务时,以下简化的测试用例代码可以工作如果我在具有动态生成的证书(所有这些都由我组织中的一个单独的团队处理)的远程计算机上运行,它会失败并显示 400 和“未发送所需的 SSL 证书”错误但是,如果我在远程机器上使用 curl,并指定与我的 Go 代码中引用的相同的证书,它将起作用所以似乎证书不是问题,而是 Go 代码,但这本身似乎不是问题,因为它在本地与我自己的证书一起使用package mainimport ( "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("\n\ncontents:\n\n%+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}有谁知道为什么会发生这种情况?我认为这可能是 Go 的重新协商错误(从 1.6 开始),但我认为情况并非如此,否则在本地运行应用程序时它会失败(但它不会,使用我自己的开发证书并且在本地运行正常 - 只有在具有不同证书的远程实例上运行时才会出现问题;并且这些证书不是问题,因为它们在使用时工作正常curl)
1 回答
偶然的你
TA贡献1841条经验 获得超3个赞
所以这里的实际问题部分与我的组织基础设施有关,部分与 nginx 的使用方式有关ssl_client_certificate
。
我们有 int、test 和 live 环境
我被引导相信环境可以相互交流。
所以我在 int 上设置了我的服务,并且我能够从那里使用 curl 与实时环境中的另一个服务设置进行通信。
使用 Go 跨环境通信时出现问题。
对我来说,快速的解决方案是确保当我对其他服务进行 GET 时,而不是使用:
https://service.live.me.com
我会使用:
https://service.int.me.com
或者:
https://service.test.me.com
根据我的代码运行的环境。
显然,对于有类似问题但没有相同设置的其他人来说,这不是解决方案。
所以对于那些仍然需要解决方案的人......
我还将尝试(并且显然为这个人工作)是让我试图与之通信的服务来修改他们的 nginx conf,以便他们设置ssl_client_certificate
不只是指向客户端证书,而是指向组合证书(包括整个 CA 链)。
这是因为显然 Go 不会在其响应中发回任何证书,除非服务器已通过 CA 及其响应。
我最初怀疑这是 Go 1.6 及更低版本中的经典重新协商错误,但在这种情况下并非如此。
希望这可以帮助同一条船上的其他人。
- 1 回答
- 0 关注
- 293 浏览
添加回答
举报
0/150
提交
取消