如何在docker镜像中添加CA根证书?

Pet*_*ter 21 ubuntu curl ssl-certificate docker

我在Ubuntu 14.04上的Docker 1.13.1容器中运行ASP.NET Core 1.1 Web API.

当代码尝试从HTTPS服务器检索某些数据时,我收到此证书身份验证错误:

 An error occurred while sending the request. ---> System.Net.Http.CurlException: Peer certificate cannot be authenticated with given CA certificates
   at System.Net.Http.CurlHandler.ThrowIfCURLEError(CURLcode error)
   at System.Net.Http.CurlHandler.MultiAgent.FinishRequest(StrongToWeakReference`1 easyWrapper, CURLcode messageResult)
Run Code Online (Sandbox Code Playgroud)

HTTPS服务器是内部的,我们的公司CA签署了证书,因此我知道我可能需要注册内部CA.

到目前为止我发现的关于这个错误的所有内容和Docker谈到让docker本身运行,连接到repos等.我的Docker工作正常,Web API在容器外的Ubuntu服务器上运行没有问题.

1)我是否需要在docker镜像中添加CA根证书?

2)如果是这样,我该怎么办?

3)如果没有,我该如何解决这个问题?

ceb*_*ebe 34

任务本身并不特定于docker,因为您还需要在普通系统上添加该CA. askubuntu社区有一个关于如何做到这一点的答案.

所以在Dockerfile中你会做以下事情:

ADD your_ca_root.crt /usr/local/share/ca-certificates/foo.crt
RUN chmod 644 /usr/local/share/ca-certificates/foo.crt && update-ca-certificates
Run Code Online (Sandbox Code Playgroud)

  • 只是建议使用 COPY 而不是 ADD。请参阅https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#add-or-copy (3认同)
  • @DozParp 没有私有证书之类的东西。私钥是您可能不希望在映像中出现的内容。你想达到什么目的? (3认同)

Pet*_*ter 25

为了简化/标准化所有容器构建,我们现在将证书托管在中央 HTTPS 服务器上,并将它们构建到我们的容器中,如下所示:

# Debian stretch based container
RUN curl -ks 'https://cert.host.server/ssl_certs/EnterpriseRootCA.crt' -o '/usr/local/share/ca-certificates/EnterpriseRootCA.crt'
RUN /usr/sbin/update-ca-certificates
Run Code Online (Sandbox Code Playgroud)

基于 Alpine 的容器没有立即可用的工具,因此需要做更多的工作才能实现相同的目标:

# Alpine based containers
RUN apk update && apk add curl
WORKDIR /usr/local/share/ca-certificates
RUN curl -ks 'https://cert.host.server/ssl_certs/EnterpriseRootCA.crt' -o '/usr/local/share/ca-certificates/EnterpriseRootCA.crt'
RUN /usr/sbin/update-ca-certificates
Run Code Online (Sandbox Code Playgroud)

如果您还想更新您的 Java 信任库(与在任何计算机上相同):

RUN keytool -keystore /usr/lib/jvm/java-8-oracle/jre/lib/security/cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias EnterpriseRootCA -file EnterpriseRootCA.crt
Run Code Online (Sandbox Code Playgroud)


ban*_*der 8

ca-certificates将定位cert_file_name.crt文件安装在与 Dockerfile 相同的目录中。

# Install ca-certificates
# Please locate cert_file_name.crt file in the same directory as Dockerfile.
COPY cert_file_name.crt /usr/share/ca-certificates/
RUN echo cert_file_name.crt >> /etc/ca-certificates.conf
RUN update-ca-certificates
Run Code Online (Sandbox Code Playgroud)

这将更新 Dockerfile 中的证书。

  • 那么这个`*.crt`文件可以签入到代码存储库中吗? (2认同)

小智 5

还值得注意的是,这确实需要使用.crt扩展名。最初,我使用.pem cert文件尝试了此操作(我认为它们是可互换的,因此其他文件也可以),该文件未通过链接update-ca-certificates

  • 哦,哇,谢谢你的留言。由于某种原因,我拥有的证书是“.pem”,但它完全看不到它们。我得到的提示是“update-ca-certificates”命令具有以下输出:“正在更新 /etc/ssl/certs 中的证书... 0 添加,0 删除;完成。修复后,我在 /etc/ssl/certs 中更新证书...添加了 4 个,删除了 0 个;完成了。` (3认同)
  • 我想添加 .pem 到 crt 转换(使用 openssl x509 -outform der)后的 .crt 二进制文件不起作用。也许我的 .pem 并不是真正的 PEM?然而,只需将我的 .pem 重命名为 .crt 就可以了。即保留文本“BEGIN CERTIFICATE...etc”就可以了 (2认同)