ssl - 使用自签名 SSL 证书

标签 ssl nginx go https self-signed

我正在尝试将此证书用于 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/

相关文章:

ssl - 托管不面向用户且仅供 API 使用的服务器的常见做法是什么?

NGINX:如何返回内联 html?

go - Go标准库中的最大堆和最小堆

arrays - 如何通过在 slice 上查找来从 slice 复制到数组

java - 通过 TLS 实现 LDAP

c# - 使用服务访问控制台应用程序中的服务需要证书

php - 在 Wordpress 网站上将 https 重定向到 http

php - Nginx/SSI独立分片缓存

node.js - 使用 2 个 Express 应用程序阻止私有(private)端口 NGINX 反向代理

go - 将函数应用于golang列表中所有元素的简短方法