Ubuntu

中間 CA 的 Debian 問題

  • September 29, 2017

語境

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

  • 根 CA
  • 中間 CA(由根 CA 簽名)
  • 證書(由中間 CA 簽名)
  • 連鎖,鏈條

我在一個 Dockerized 環境中,有 3 個容器:

  • 容器 A:Nginx 反向代理,解碼 SSL(使用鏈 + 密鑰)並將請求轉發到容器 B
  • 容器 B:Nginx(這裡沒什麼特別的,響應的應用程序)
  • 容器 C :需要捲曲 A 的應用程序(沒有不安全標誌)。我需要在這個上安裝中間 CA

這看起來像一個簡單的問題,但是當 Container C 基於 Debian 時,我被困住了。例如,它在 Ubuntu 容器上就像一個魅力。它也適用於 Ubuntu 桌面虛擬機。我的中間 CA 也可以在我的 Mac 上使用 OSX 鑰匙串儲存。

這看起來像是 Debian 特定的問題。

我是如何測試的

我遵循了幾個步驟: - 生成 ca/certs/chain - 在我的 mac 上安裝中間 CA - curl -XGET https://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"'

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

碼頭工人撰寫日誌

這是輸出日誌,被截斷以便我們只得到有趣的部分。如您所見,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 應該就足夠了)

經過進一步調查,ubuntu 和 debian 最大的區別在於使用的 SSL 庫:

  • 在 Debian 上,curl 是使用 OpenSSL 預編譯的
  • 在 Ubuntu 上,curl 是使用 GnuTLS 預編譯的

我在 Debian 上用 GnuTLS 重新編譯了 curl,它只使用中間 CA 就可以正常工作。

我在 Ubuntu 上使用 OpenSSL 重新編譯了 curl,如果我希望我的請求通過,現在必須信任根 CA。

您不需要在依賴方(容器 C)中安裝任何從屬 CA 證書。

RFC 5246 7.4.2規定伺服器必須以鏈的形式提供任何和所有從屬 CA 證書。也就是說,您在容器 A 中的 Ngnix 伺服器必須配置為在連接時向客戶端發送證書(根 CA 證書除外)。

只有根 CA 證書必須安裝在客戶端(容器 C)上,才能信任伺服器提供的鏈。

引用自:https://serverfault.com/questions/875912