与中间CA的Debian问题

上下文

出于某些原因,我有必要产生:

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

我在一个Docker化的环境中,有3个容器:

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

它看起来像一个简单的问题,但是当容器C基于Debian时,我被卡住了。 例如,它在Ubuntu容器上就像一个魅力。 它也适用于Ubuntu桌面虚拟机。 我的中级CA也可以在我的Mac上使用OSX钥匙串存储。

这看起来像一个Debian特定的问题。

我是如何testing的

我遵循以下几个步骤: – 生成ca / certs /链 – 在我的mac上安装中间CA – 在terminal内部的curl -XGET https://service.local :OK

然后,使用Docker,在Ubuntu上安装中间CA,然后调用update-ca-certificates,并使用curl进行testing:OK

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

脚本部分

我已经编写了整个certs / ca /​​ chain代码,这里没有问题,除非你需要,否则我不会详述。

Docker-compose为容器C.

我试着用不同的操作系统,这就是为什么有几个服务,它显示了我在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"' 

entrypoint.sh

为了举例,假定IP是已知的并在下面的模板中被replace:

 #!/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工人 – 撰写日志

这里是输出日志,截断,所以我们只得到有趣的部分。 正如你所看到的,在Ubuntu的curl回答与JSON而debian拒绝证书validation,因为根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的正确解决scheme? 我真的需要注入并安装根CA吗? (当我这样做,它工作,但它看起来很奇怪,因为中间CA应该足够了)

经过进一步调查,ubuntu和debian最大的区别就是使用的SSL库:

  • 在Debian上,curl是用OpenSSL预编译的
  • 在Ubuntu上,curl是用GnuTLS预编译的

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

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

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

RFC 5246 7.4.2规定,服务器必须以链的forms提供任何和所有的从属CA证书。 也就是说,Container A中的Ngnix服务器必须configuration为在连接时将证书(除根CA证书外)发送到客户端。

只有根CA证书必须安装在客户端(容器C)上,以便信任由服务器提供的链。

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

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