语境

语境

语境

由于某些原因,我需要生成:

  • 根 CA
  • 中间 CA(由根 CA 签名)
  • 证书(由中间 CA 签名)
  • 连锁,链条

我处于 Dockerized 环境中,有 3 个容器:

  • 容器 A:Nginx 反向代理,解码 SSL(使用链 + 密钥)并将请求转发到容器 B
  • 容器 B:Nginx(这里没什么特别的,响应的应用程序)
  • 容器 C:需要 curl A 的应用程序(不使用不安全的标志)。我需要在这个容器上安装中间 CA

这看起来像是一个简单的问题,但当容器 C 基于 Debian 时,我就卡住了。例如,它在 Ubuntu 容器上工作得很好。它还可以与 Ubuntu 桌面虚拟机一起使用。我的中间 CA 也可以在我的 Mac 上使用 OSX 钥匙串存储。

这看起来像是 Debian 特有的问题。

我如何测试

我遵循了几个步骤: - 生成 ca/certs/chain - 在我的 Mac 上安装中间 CA - curl -XGEThttps://service.local在终端内:确定

然后,使用 Docker 在 ubuntu 上挂载中间 CA,然后调用 update-ca-certificates,并使用 curl 进行测试:OK

然后,使用 Docker 在 Debian 上挂载中间 CA,然后调用 update-ca-certificates,并使用 curl 进行测试:KO

脚本部分

我已经编写了整个 certs/ca/chain 生成的脚本,这里没有问题,除非您需要它们,否则我不会详细说明。

用于容器 C 的 Docker-compose

我正在尝试使用不同的操作系统,这就是为什么有几种服务,并且它显示我在 ubuntu 和几个版本的 Debian 之间做了完全相同的事情。

我通过不调用 update-ca-certificates 来采取一些捷径;相反,我直接在 /etc/ssl/certs 中挂载文件,因为它实际上并没有做太多事情...对于那些想知道的人:我也尝试在其他地方挂载文件,然后调用 update-ca-certificates,然后 curl,使用另一个版本的入口点,但最后的结果相同,它在 Ubuntu 上运行,而不是在 Debian 上运行。

version: '2'

services:
    ubuntu:
        image : "ubuntu:16.04"
        volumes :
            - './local_ca/LOCAL_CA.crt:/etc/ssl/certs/local_ca.pem:ro'
            - './entrypoint.sh:/entrypoint.sh'
        command : 'bash -c "/entrypoint.sh"'

    debian7:
        image : "debian:wheezy"
        volumes :
            - './local_ca/LOCAL_CA.crt:/etc/ssl/certs/local_ca.pem:ro'
            - './entrypoint.sh:/entrypoint.sh'
        command : 'bash -c "/entrypoint.sh"'

    debian8:
        image : "debian:jessie"
        volumes :
            - './local_ca/LOCAL_CA.crt:/etc/ssl/certs/local_ca.pem:ro'
            - './entrypoint.sh:/entrypoint.sh'
        command : 'bash -c "/entrypoint.sh"'

    debian9:
        image : "debian:stretch"
        volumes :
            - './local_ca/LOCAL_CA.crt:/etc/ssl/certs/local_ca.pem:ro'
            - './entrypoint.sh:/entrypoint.sh'
        command : 'bash -c "/entrypoint.sh"'

入口点

为了举例,假设 IP 已知,并在以下模板中替换:

#!/bin/bash

apt-get update
apt-get install -y curl
echo '{{ip_of_reverse_proxy}} service.local' >> /etc/hosts
curl -XGET https://service.local

正如我之前所说,我也做了一个版本,其中我调用 update-ca-certificates 而不是直接挂载,但这没有任何区别,它在 Ubuntu 上运行,但在 Debian 上却不行

docker-compose 日志

以下是输出日志,我们将其截断,以便我们只获得有趣的部分。如您所见,ubuntu 上的 curl 使用 JSON 进行回答,而 debian 拒绝证书验证,因为 root ca 不受信任。

ubuntu_1   | {"_links":{"self":{"href":"\/"}}}

debian7_1  | curl performs SSL certificate verification by default, using a "bundle"
[...] (see debian9_1 logs)

debian8_1  | curl performs SSL certificate verification by default, using a "bundle"
[...] (see debian9_1 logs)

debian9_1  | curl: (60) SSL certificate problem: self signed certificate in certificate chain
debian9_1  | More details here: https://curl.haxx.se/docs/sslcerts.html
debian9_1  |
debian9_1  | curl performs SSL certificate verification by default, using a "bundle"
debian9_1  |  of Certificate Authority (CA) public keys (CA certs). If the default
debian9_1  |  bundle file isn't adequate, you can specify an alternate file
debian9_1  |  using the --cacert option.
debian9_1  | If this HTTPS server uses a certificate signed by a CA represented in
debian9_1  |  the bundle, the certificate verification probably failed due to a
debian9_1  |  problem with the certificate (it might be expired, or the name might
debian9_1  |  not match the domain name in the URL).
debian9_1  | If you'd like to turn off curl's verification of the certificate, use
debian9_1  |  the -k (or --insecure) option.

问题

问题 1:我注入了完全相同的文件并遵循完全相同的过程,为什么它在 ubuntu 上有效,但在 debian 上却不行?它们不是共享同一个基础吗?

问题 2:什么是适合 Debian 的解决方案?我真的需要注入并安装根 CA 吗?(这样做是有效的,但对我来说这看起来很奇怪,因为中间 CA 就足够了)

答案1

经过进一步调查,ubuntu 和 debian 之间最大的区别在于所使用的 SSL 库:

  • 在 Debian 上,curl 已使用 OpenSSL 进行预编译
  • 在 Ubuntu 上,curl 已使用 GnuTLS 进行预编译

我在 Debian 上使用 GnuTLS 重新编译了 curl,并且仅使用中间 CA 就可以正常工作。

我在 Ubuntu 上使用 OpenSSL 重新编译了 curl,现在如果我希望我的请求通过,就必须信任根 CA。

答案2

您不需要在依赖方(容器 C)中安装任何从属 CA 证书。

RFC 5246 7.4.2规定服务器必须以链的形式提供所有下属 CA 证书。也就是说,容器 A 中的 Ngnix 服务器必须配置为在连接时将证书(根 CA 证书除外)发送给客户端。

只需要在客户端(容器 C)上安装根 CA 证书,它就可以信任服务器提供的链。

答案3

将根 CA 放入/etc/ssl/certs/yourCAnamehere.pem文件中,然后update-ca-certificates --fresh在容器 C 上运行

由于根 CA 不受信任,因此该链(中间 CA 也是如此)不受信任。通过将其添加到受信任的 CA,您应该能够正常执行请求

相关内容