我正在尝试将此证书用于 nginx 反向代理后面的 InfluxDB 休息端点与我用 GoLang 编写的简单客户端之间的连接。
我开始使用由 openssl 生成的 SSL 证书,使用的教程位于 this link。这让我完成了创建和自唱证书的过程。
但每次尝试建立此连接时都会出现此错误:
x509: certificate signed by unknown authority (possibly because of "x509: invalid signature: parent certificate cannot sign this kind of certificate" while trying to verify candidate authority certificate "<My Certificate Name>")
我还没有找到解决这个问题的方法,但我会展示我认为相关的内容:
据我所知,InfluxDB 的 nginx 规则很容易编写,最终看起来像这样:
# InfluxDB
server {
ssl on;
ssl_protocols TLSV1.2 TLSV1.1 TLSV1;
ssl_certificate /etc/nginx/server.crt;
ssl_certificate_key /etc/nginx/server.key;
listen 8086;
access_log /var/log/nginx/influxdb.access.log;
error_log /var/log/nginx/influxdb.error.log;
location / {
include /etc/nginx/conf.d/options.conf.inc;
include /etc/nginx/conf.d/auth.conf.inc;
proxy_pass http://127.0.0.1:8087;
}
}
options.conf.inc 在哪里:
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin $served_at;
add_header Access-Control-Allow-Methods "GET, OPTIONS";
add_header Access-Control-Allow-Headers "Authorization";
add_header Access-Control-Allow-Credentials "true";
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
auto.conf.inc 在哪里:
add_header Access-Control-Allow-Headers "Authorization";
add_header Access-Control-Allow-Credentials "true";
auth_basic "Restricted";
auth_basic_user_file <pathTo>.htpasswd;
error_page 401 /401.html;
我的 golang 客户端是这样的:
func main() {
flag.Parse()
// Load client cert
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
log.Fatal(err)
}
// Load CA cert
caCert, err := ioutil.ReadFile(caFile)
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
// Setup HTTPS client
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
// InsecureSkipVerify: true,
}
//tlsConfig.BuildNameToCertificate()
transport := &http.Transport{TLSClientConfig: tlsConfig}
client := &http.Client{Transport: transport}
// Do GET something
resp, err := client.Get("https://fillerBasicAuthCredentials:password!1@192.168.223.128:8086/query?q=show+databases")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// Dump response
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
log.Println(string(data))
}
正如您在我的 golang 代码中看到的那样,我在 tlsConfig 对象上使用了 InsecureSkipVerify
标志。将此设置为 true 可以使一切正常,但这样做似乎本质上是不好的,因为它一开始就破坏了很多使用证书的意义。
看来,我剩下的选择是生成一个 CA 证书并使用它来签署我的常规证书,但这似乎比我需要做的更像是一种黑客攻击。
编辑(解决方案):
在探索创建我自己的 CA 证书来签署这些证书后,我能够让一切正常工作。现在我有一个 CA 证书,我将用它来签署我的其他证书,我将把这个 CA 证书安装在盒子上,这样他们就知道它是一个受信任的证书。
对我如何解决这个问题有帮助的部分:
我正在使用我试图避免使用的开源 influxdb 客户端。它目前使用 golang 的 net/http
包,而不是 crypto
这意味着我不能像我的示例那样在代码中指定我的 CA 证书。我必须将 CA 证书安装到我的盒子上,这样它才能被正确识别。我发现一篇对这个主题有帮助的文章是 [这篇] https://www.happyassassin.net/2015/01/14/trusting-additional-cas-in-fedora-rhel-centos-dont-append-to-etcpkitlscertsca-bundle-crt-or-etcpkitlscert-pem/
最佳答案
该错误消息来自 go 的 CheckSignatureFrom方法。看起来它需要将 basicConstraints
中的 CA 标志设置为 true,并且如果 keyUsage
字段存在(它在您链接的示例中,但在大多数情况下不存在)我见过的使用自签名证书的说明)它必须包含 keyCertSign
值。
当我遇到类似问题时,我创建了一个独立于服务器证书的 CA。这需要更多的工作,但不是“hack”;如果将自签名证书设置为被正确识别为其自己的 CA 是更黑客的解决方案。
关于ssl - 使用自签名 SSL 证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35972742/