swarm セキュリティを公開鍵暗号基盤 [PKI] で管理

swarm モードの公開鍵暗号基盤(PKI)システムは Docker に組み込まれおり、コンテナのオーケストレーション・システムの安全なデプロイを簡単にします。swarm 内のノードは共通の TLS (トランスポート・レイヤー・セキュリティ)を使い、認証、権限付与、他のノートとの暗号化通信を行います。

docker swarm init を実行して swarm を作成すると、 Docker は自分自身を manager ノードに指定します。デフォルトでは、 manager ノードは新しいルート認証局(CA)をキーペア(key pair)と共に作成します。これらは swarm に参加する他のノード間で安全に通信するために使います。もしも希望するのであれば、外部で生成した自身のルート CA を指定するためい、 docker swarm init--external-ca フラグを使います。

また、manager ノードは swarm にノードが参加するために使う2つのトークンを作成します。1つは woker トークン で、もう1つは manager トークン です。各トークンには root CA 証明書の digest とランダムに生成したシークレット(secret)を含みます。swarm にノードが参加する時、参加するノードはリモートの manager からの root CA 証明書を確認するために digest を使います。リモートの manager はシークレットを使い、参加を試みているノードに対して、ノードとしての承認を与えます。

swarm に新しいノードが参加するたびに、 manager はノードに対して証明書を発行します。この証明書には、認証コモン・ネーム(CN)と organization unit(ON)の下に、役割を識別するためのランダムに生成した ノード ID を含みます。このノード ID の役目は、現在の swarm において、ノードが生存し続ける限り、暗号化して安全にノードを識別するためです。

下図は manager ノードと worker ノードが最小の TLS 1.2 を使ってどのように暗号化通信するかを示します。

tls の図

以下の例は worker ノードにおける証明書の情報を表示したものです。

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            3b:1c:06:91:73:fb:16:ff:69:c3:f7:a2:fe:96:c1:73:e2:80:97:3b
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: CN=swarm-ca
        Validity
            Not Before: Aug 30 02:39:00 2016 GMT
            Not After : Nov 28 03:39:00 2016 GMT
        Subject: O=ec2adilxf4ngv7ev8fwsi61i7, OU=swarm-worker, CN=dw02poa4vqvzxi5c10gm4pq2g
...snip...

デフォルトでは、 swarm 内の各ノードは3ヶ月ごとに証明書を更新します。この期間は docker swarm update --cert-expiry <間隔> のコマンドで調整できます。最小のローテート時間は1時間です。詳細は docker swarm update コマンドライン・リファレンスをご覧ください。

CA 証明書のローテート

クラスタ CA キーや manager ノードで障害が発生する事態になったら、自分で swarm ルート CA をローテートできますので、古いルート CA によって書名された証明書を、一切信頼しないようにできます。

新しい CA 証明書とキーを作成するには、 docker swarm ca --rotate を実行します。希望する場合は、 swarm 外部のルート証明書やルート CA を使うため --ca-cert--external-ca フラグを使えます。あるいは、 --ca-cert--ca-key フラグを使い、swarm で使いたい証明書と鍵を指定できます。

docker swarm ca --rotate コマンドを実行すると、順番に以下の処理が進みます。

  1. Docker はクロス書名証明書(cross-signed certificate)を生成します。これは、新しいルート CA 証明書のバージョンは、古いルート CA 証明書によって書名されているということを意味します。クロス書名証明書は、新しい全てのノード証明書に対する中間証明書として用います。これにより、ノードは古い CA によって確実に信頼されているだけなく、新しい CA によって署名された証明書も有効であるとも確認できます。

  1. Docker 17.06 以降では、 Docker もまた全ノードに対して直ちに更新した TLS 証明書を伝えられます。この処理は swarm 内のノード数に依存し、数分かかる場合があります。

    注釈

    もしも swarm ノードの Docker バージョンが異なる場合は、以下2つのことが真になります。

    • manager のみが leader として稼働し、 かつ 、Docker 17.06 以上で動作中は、ノードに対して更新した TLS 証明書を伝達する

    • ノードのみが Docker 17.06 以上で動作中は、その命令に従う

    最も予想できうる挙動は、全ての swarm ノードを Docker 17.06 以上で確実に稼働することです。

  1. swarm 内の全てのノードが、新しい CA によって書名された新しい TLS 証明書に切り替わり後、Docker は古い CA 証明書とキーの要素を忘れ、全てのノードに対して信頼できる CA 証明書のみを伝えます。

    これにより、 swarm への参加(join)トークンも変更になります。以前の参加トークンは以後一切無効です。

以上の手順で、新しいノード証明書が新しいルート CA によって書名および発行され、あらゆる中間物を含みません。

さらに学ぶ

参考

Manage swarm security with public key infrastructure (PKI)

https://docs.docker.com/engine/swarm/how-swarm-mode-works/pki/