証明書をリポジトリのクライアント認証に使用

Docker を HTTPS で動かす 方法を学びました。デフォルトでは Docker はネットワークで使えない Unix ソケットと、Docker クライアントとデーモンがで安全に通信できるよう HTTPS 上で TLS を有効化すべきという内容でした。TLS はレジストリのエンドポイントにおける認証を確実なものとし、かつ、レジストリからあるいはレジストリへの通信を暗号化します。

このページでは、Docker レジストリ(例:サーバ)と Docker デーモン(例:クライアント)間でのトラフィックを暗号化する方法と、証明書をベースとしたクライアント・サーバ認証の仕方を扱います。

認証局(CA; Certificate Authority)のルート証明書をレジストリに設定する方法と、クライアント側で TLS 証明書を使って認証する方法を紹介します。

設定の理解

任意の証明書を使うように設定するには、 /etc/docker/certs.d ディレクトリの下に、レジストリのホスト名と同じ名前のディレクトリ(例: localhost )を作成します。このディレクトリを CA ルートとして、全ての *.crt ファイルを追加します。

注釈

認証に関する root 証明書が足りなければ、Docker はシステムのデフォルトを使います(例: ホスト側のルート CA セット)。

任意のリポジトリにアクセスするには、Docker が1つ以上の <ファイル名>.key/cert のセットを認識する必要があります。

注釈

複数の証明書があれば、アルファベット順で処理を行います。もし、認証エラー(例: 403、404、5xx、等)があれば、次の証明書で処理を試みます。

以下は、複数の証明書がある場合の設定です。

/etc/docker/certs.d/        <-- 証明書のディレクトリ
└── localhost               <-- ホスト名
   ├── client.cert          <-- クライアントの証明書(certificate)
   ├── client.key           <-- クライアント鍵
   └── localhost.crt        <-- 認証局によるレジストリ証明書への署名

なお、この例は典型的なオペレーティング・システム上で使う場合を想定したものです。OS が提供する証明書チェーン作成に関するドキュメントを確認すべきでしょう。

クライアント証明書の作成

まず、OpenSSL の genrsareq コマンドを使って RSA 鍵を生成し、それを証明書の作成に使います。

$ openssl genrsa -out client.key 4096
$ openssl req -new -x509 -text -key client.key -out client.cert

注釈

これらの TLS コマンドが生成する証明書は、Linux 上で動作するものです。Mac OS X に含まれている OpenSSL のバージョンでは、Docker が必要とする証明書のタイプとの互換性はありません。

上手くいかない場合の確認点

Docker デーモンは .crt ファイルを CA 証明書として認識し、 .cert ファイルをクライアント証明書として認識します。CA 証明書が正しい .crt 拡張子ではなく .cert 拡張子になってしまうと、Docker デーモンは次のようなエラーメッセージをログに残します。

Missing key KEY_NAME for client certificate CERT_NAME. Note that CA certificates should use the extension .crt.