... 自己署名証明書を使うほうが最早難しい時代だよねメモその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)のコンテナイメージで自己署名証明書を信頼するようにしてみる。
コンテナ起動時に証明書をインストールする
... 色々試してはみたけど、これが一番安定するということで。。流れとしては、
-
/usr/local/share/ca-certificates
以下に 拡張子crt
で 公開鍵ファイルを置く -
update-ca-certificates
を実行する - (通常のエントリーポイントを実行する)
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
を立ててワークアラウンドするしか無いようだ。