LoginSignup
1
1

More than 3 years have passed since last update.

KubernetesのDockerコンテナ内で自己署名証明書を信頼する

Last updated at Posted at 2019-12-30

... 自己署名証明書を使うほうが最早難しい時代だよねメモその2。

"自己署名証明書を信頼する" とは

HTTPにおけるSSL/TLSは基本的に "有名な会社(CA)から信頼されている証明書は信頼できる" というモデルで成立している。有名な会社から発行されていない自己署名証明書(歴史的事情でオレオレ証明書とも呼ばれる)は何らかの方法で信頼させる必要がある。

証明書が信頼されていない場合、unable to get local issuer certificate とか unable to verify the first certificate のようなエラーが出て接続に失敗してしまうことが多い。

この信頼させる方法がOSディストリビューションごとにかなりマチマチで、かつ、覚えづらい。例えば、以前書いた CygwinでHTTPSの自己署名証明書を信頼する はCygwinや、その他Red Hat系OSで使える。

今回は、Debian系OS(DebianやUbuntu)のコンテナイメージで自己署名証明書を信頼するようにしてみる。

コンテナ起動時に証明書をインストールする

... 色々試してはみたけど、これが一番安定するということで。。流れとしては、

  1. /usr/local/share/ca-certificates 以下に 拡張子crt 公開鍵ファイルを置く
  2. update-ca-certificates を実行する
  3. (通常のエントリーポイントを実行する)

KubernetesのPod内にファイルを導入するには ConfigMap が使える:

apiVersion: v1
kind: ConfigMap
metadata:
    name: localcacerts
    namespace: default
data:
    local.cer: |
        -----BEGIN CERTIFICATE-----
        MIIFMTCCAxmgAwIBAgIQcD70x1cge65BwtMjAd3ljDANBgkqhkiG9w0BAQsFADAV
        MRMwEQYDVQQDDApmbG93LmxvY2FsMCAXDTE5MTIzMDE3MjExMVoYDzIwNjkxMjMw
(後略)

で、 ConfigMap をファイルシステムとしてマウントした上で、適当な位置への配置と update-ca-certificates を一緒に実行するように、 command を書いてしまえば良い:

cp /cer/local.cer /usr/local/share/ca-certificates/local.crt && update-ca-certificates && /entrypoint.sh apache2-foreground

ファイルが正常に認識されている場合は、 update-ca-certificates の実行時に 1 added のように表示される。

Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
Initializing nextcloud 17.0.2.1 ...

うまく行かない場合

コピーされている筈なのにうまくSSL接続できない場合は、 kubectl exec 等でシェルに入り、 curl なりなんなりでリクエストを手動で発行してみる。これで上手くいく場合は、そもそもアプリがOS側の設定を見ていない可能性がある。

ホスト名が合っていないケース

常識的なSSL/TLS証明書にはホスト名が含まれているため、接続に使用するホスト名も揃える必要がある。幸い、最近のKubernetesには hosts を設定する機能(hostAliases)が付いているので、それで設定してしまう手がある。

        spec:
            hostAliases:
                - ip: "192.168.1.209"
                  hostnames:
                      - "flow.local"

CA証明書として認識されないケース

環境変数 SSL_CERT_FILE で直接指定すると上手くいくのに update-ca-certificates で上手くいかない場合、鍵ペアの用途として"証明書の署名"が含まれていない等といった理由でCA証明書として認識されていないケースがある。

openssl コマンドで openssl x509 -text -noout -in key.pem のようにして中身を確認すると:

        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment, Certificate Sign ★
            X509v3 Extended Key Usage:
                TLS Web Client Authentication, TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:flow.local
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:0 ★
            X509v3 Subject Key Identifier:
                55:A2:3A:79:F1:72:73:91:4B:FB:D7:5E:65:BF:D7:F5:10:4E:08:4E

Certificate Sign のKey Usageと、 CA:TRUE のBasic Constraintsが揃っていないと(少くとも手元の検証では)ダメだった。一個前のエントリ(KubernetesのIngressで使うSSL自己署名証明書をPowerShellで作る)で引いたように、これは OpenSSL側のバグ っぽい挙動で、ひとまず CA:TRUE を立ててワークアラウンドするしか無いようだ。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1