前回は、CoreDNSのk8s_gatewayプラグインを使って、DNSサーバーへの連携について試してみました。その際に、ブラウザで信頼されない証明書の警告が表示されました。今回は、IngressでSSL/TLSを有効にする方法を試してみました。
構成
- vCenter 7.0 U3
- ESXi 7.0 Update 3
- Ubuntu 22.04 (テンプレートVM)
- open-vm-tools 11.3.5
- cloud-init 22.2
- Kubespray
- kubernetes v1.25.5
- MetalLB v0.12.1
- ingress-nginx v1.5.1
- CoreDNS
- EdgeRouter X
秘密鍵とサーバー証明書の作成
homelabで利用する目的のため、認証局は作成せずに、CSRなしで、秘密鍵から自己署名のサーバー証明書を作成しています。
以下のように秘密鍵とサーバー証明書を作成します。Chrome58以降は、証明書のCommonNameフィールドを評価せず、「X509v3 extensions: X509v3 Subject Alternative Name」を評価するようになったため、subjectAltNameを指定しておきます。
$ export KEY_FILE="nginx-tls.key" $ export CERT_FILE="nginx-tls.crt" $ export HOST="nginx.kube.home.lab" $ export CERT_NAME="nginx-tls" $ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE} -out ${CERT_FILE} -subj "/CN=${HOST}/O=${HOST}" -addext "subjectAltName = DNS:${HOST}"
証明書の登録
Secretリソースに証明書を登録します。
$ kubectl create secret tls ${CERT_NAME} --key ${KEY_FILE} --cert ${CERT_FILE}
動作確認
nginxサーバーをデプロイし、 nginx.kube.home.lab
というホスト名と先ほど作成したSecretリソースを指定しIngressを作成します。
kubectl create deployment nginx --image=nginx --port=80 kubectl expose deployment nginx kubectl create ingress nginx --class=nginx --rule ${HOST}/=nginx:80,tls=${CERT_NAME}
curlでアクセスし、証明書が利用されていることを確認します。
$ curl -k -v https://nginx.kube.home.lab : * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use h2 * Server certificate: * subject: CN=nginx.kube.home.lab; O=nginx.kube.home.lab :
ブラウザから https://nginx.kube.home.lab
にアクセスし、ブラウザで信頼されない証明書の警告が表示されます。Chromeの場合は、ブラウザからサーバー証明書をダウンロードし、Chromeの設定のデバイス証明書の管理から、インポートをクリックし、証明書をすべて次のストアに配置するで信頼されたルート証明機関を選択し、サーバー証明書を登録します。
ブラウザを再起動するか、シークレットモードで再度 https://nginx.kube.home.lab
にアクセスし、ブラウザで信頼されない証明書の警告が表示されないことを確認します。
ワイルドカード証明書の作成
ワイルドカード証明書でも動作するか確認してみます。
$ export KEY_FILE="ingress-tls.key" $ export CERT_FILE="ingress-tls.crt" $ export HOST="*.kube.home.lab" $ export CERT_NAME="ingress-tls" $ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE} -out ${CERT_FILE} -subj "/CN=${HOST}/O=${HOST}" -addext "subjectAltName = DNS:${HOST}"
Secretリソースに証明書を登録します。
$ kubectl create secret tls ${CERT_NAME} --key ${KEY_FILE} --cert ${CERT_FILE}
nginxサーバーをデプロイし、 nginx.kube.home.lab
というホスト名と先ほど作成したSecretリソースを指定しIngressを作成します。
kubectl create deployment nginx --image=nginx --port=80 kubectl expose deployment nginx kubectl create ingress nginx --class=nginx --rule nginx.kube.home.lab/=nginx:80,tls=${CERT_NAME}
curlでアクセスし、証明書が利用されていることを確認します。
$ curl -k -v https://nginx.kube.home.lab : * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use h2 * Server certificate: * subject: CN=*.kube.home.lab; O=*.kube.home.lab :
上記と同様に、ブラウザからサーバー証明書をダウンロードし、Chromeの設定のデバイス証明書の管理から、インポートをクリックし、証明書をすべて次のストアに配置するで信頼されたルート証明機関を選択し、サーバー証明書を登録します。
ブラウザを再起動するか、シークレットモードで再度 https://nginx.kube.home.lab
にアクセスし、ブラウザで信頼されない証明書の警告が表示されないことを確認します。
nginxサーバー以外のサーバーをデプロイし、サブドメインでブラウザで信頼されない証明書の警告が表示されないか確認してみます。
httpdサーバーをデプロイし、 httpd.kube.home.lab
というホスト名と先ほど作成したSecretリソースを指定しIngressを作成します。
kubectl create deployment httpd --image=httpd --port=80 kubectl expose deployment httpd kubectl create ingress httpd --class=nginx --rule httpd.kube.home.lab/=httpd:80,tls=${CERT_NAME}
ブラウザから https://httpd.kube.home.lab
にアクセスし、ブラウザで信頼されない証明書の警告が表示されないことを確認します。Ingressを作成する際に、ブラウザに証明書を登録せずに警告なしでアクセスすることができるようになりました。
おわりに
一度証明書を指定してIngressを作成すると、Ingressを削除後に再度Ingressを作成する際に、明示的に証明書を指定しなくてもSSL/TLSが有効になるように見えていました。ホスト名から証明書が自動選択されているように見えています。
また、一度ワイルドカード証明書でIngressを作成すると、明示的に証明書を指定せずにIngressを作成すると、ワイルドカード証明書が利用されているように見えていました。Secretリソースからワイルドカード証明書を削除しても、Ingressでワイルドカード証明書が利用されているように見えており、おそらくPod内に証明書が残存してしまうのではと考えています。
そのため、Ingressで証明書を指定する場合は明示的に行ったほうがよさそうに見えています。