Dockerコンテナ内でGCPの証明書エラーと戦ってみた - Qiitaという記事を以前書きました。
この記事ではホスト(Mac OSX)の証明書をコンテナにコピーすることで、コンテナの証明書エラーを解消していました。
この時の手順では、Macにインストールされた証明書をGUI操作でエクスポートしていたのですが、この辺のエラーは割とよく起こるので、もうちょっと手軽に使いたい!
ということでコマンド一発でできないのか調べてみました。
結論
インストールされている全ての証明書をエクスポートする場合
$ security find-certificate -p -a > cert.pem
証明書の名前を指定する場合
$ security find-certificate -p -c CertName > cert.pem
securityコマンド
キーチェーンアクセス
と同じ情報を見えるコマンドがないか調べたところ、以下の質問が見つかりました。
今やりたいことにマッチするのは
$ security find-certificate -a -p /System/Library/Keychains/SystemCACertificates.keychain > allcerts.pem
か
$ security find-certificate -a -p >certs.pem
ですかね
このコマンドで生成されたpem
ファイルの中身を見ると以下のようになってました。このファイルをコンテナに持っていけば良さそうですね。
解決しました
$ security find-certificate -a -p -c "Apple World"
-----BEGIN CERTIFICATE-----
************************
************************
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
************************
************************
-----END CERTIFICATE-----
ちなみに、この2つの違いは全ての証明書を指定するか、システムの証明書のみ
か、という違いです。
以下のコマンドでキーチェーンの一覧が表示されるので、ここから指定すれば良いみたいです。
$ security list-keychains
"/Users/${username}/Library/Keychains/login.keychain-db"
"/Library/Keychains/System.keychain"
securityコマンドの使い方
一応コマンドの使い方も確認しておこう、ということでman security
で確認してみました。
この中で今回使うのは以下3つですかね
-
-a
- 全証明書を一括でエクスポートしたい場合はつける。これをつけない場合は先頭1つのみエクスポートされる
-
-p
- pem形式でエクスポートする。今回は必須
-
-c
- 名前で絞り込みする。任意
find-certificate [-h] [-a] [-c name] [-e emailAddress] [-m] [-p] [-Z] [keychain...]
Find a certificate item. If no keychain arguments are provided, the default search list is used.
Options:
-a Find all matching certificates, not just the first one
-c name Match on name when searching (optional)
-e emailAddress
Match on emailAddress when searching (optional)
-m Show the email addresses in the certificate
-p Output certificate in pem format. Default is to dump the attributes and keychain the cert is in.
-Z Print SHA-1 hash of the certificate
Examples
security> find-certificate -a -p > allcerts.pem
Exports all certificates from all keychains into a pem file called allcerts.pem.
security> find-certificate -a -e me@foo.com -p > certs.pem
Exports all certificates from all keychains with the email address me@foo.com into a pem file called certs.pem.
security> find-certificate -a -c MyName -Z login.keychain | grep ^SHA-1
Print the SHA-1 hash of every certificate in 'login.keychain' whose common name includes 'MyName'
-c
オプション
-c
をつけると、証明書の名前が指定できます
例えばApple Worldwide Developer Relations Certification Authority
の証明書をエクスポートしたい場合は以下のようになります
部分一致なので、-c
のあとには、他と被らない程度のキーワードを入れれば良いです。
-a
をつけると一致した全ての証明書が吐かれるので、ここで出力される証明書が1つになるまで探しました
$ security find-certificate -a -p -c "Apple World"
-----BEGIN CERTIFICATE-----
************************
************************
-----END CERTIFICATE-----
動作確認
確認のために前回と同様のGCPの動作確認をしてみました
最後2行を追加して証明書インストール済みイメージを作ります
FROM ubuntu:18.04
RUN apt update && apt install -y lsb-release
RUN apt install -y curl gnupg
RUN export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)" && \
echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && \
curl -k https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \
apt-get update -y && apt-get install google-cloud-sdk -y
# 追加
COPY root.pem /certificates/root.pem
RUN gcloud config set core/custom_ca_certs_file /certificates/root.pem
ビルドして、実行していきます
# root.pemに証明書を出力
$ security find-certificate -a -p > root.pem
# この証明書を含んだDockerfileをビルド
$ docker build -t certificate_test .
これで無事にログインできるか確認します
$ docker run --rm -it certificate_test gcloud auth login
Go to the following link in your browser:
https://accounts.google.com/o/oauth2/auth?code_challenge=****
Enter verification code: **********
WARNING: `gcloud auth login` no longer writes application default credentials.
If you need to use ADC, see:
gcloud auth application-default --help
You are now logged in as [***].
Your current project is [None]. You can change this setting by running:
OKです
WarningはGCPのプロジェクトを設定しろよ、という警告なので関係ないです
おわりに
どうしても証明書周りで結構ハマるので、コマンドで証明書を吐き出せるのは助かります。コマンドなら手順的にも入れやすいので。