公開鍵基盤を利用した Swarm セキュリティ管理

Docker に組み込まれている Swarm モードの公開鍵基盤(public key infrastructure; PKI)は、コンテナーによるオーケストレーションシステムを、簡単かつ安全にデプロイできるものです。 Swarm 内のノードは、他のノードとの認証、承認、通信暗号化のために相互 TLS を利用します。

docker swarm init を実行して Swarm を生成すると、Docker 自体がマネージャーノードとなります。 マネージャーノードは、デフォルトで新たなルート認証局(CA)と鍵ペアを生成します。 これらは Swarm に参加するノードとの間でセキュアな通信を実現するために利用されます。 必要であれば docker swarm init コマンドの --external-ca フラグを用いて、外部に生成した独自のルート CA を指定することができます。

マネージャーノードは、Swarm へのノード追加時に利用される 2 つのトークンも生成します。 その 1 つが ワーカートークン であり、もう 1 つが マネージャートークン です。 それぞれのトークンには、ルート CA 証明書のダイジェスト値と、ランダムに生成された Secret 情報が含まれます。 Swarm へノードが参加する際には、参加するノードがそのダイジェスト値を用いて、リモートマネージャーからのルート CA 証明書を検証します。 リモートマネージャーは Secret 情報を使って、参加ノードが承認されているノードであることを確認します。

新たなノードが Swarm に参加するたびに、マネージャーはノードに対して証明書を発行します。 その証明書には、ランダムに生成されたノード ID が含まれます。 このノード ID によって、証明書のコモンネーム(common name; CN)のもとでのノードと、組織名(organizational unit; OU)のもとでの役割が識別されます。 ノード ID は、現 Swarm 内においてこのノードが存在する間、暗号的に安全なノードとして機能します。

以下の図は、マネージャーノードとワーカーノードが、最低限必要となる TLS 1.2 を用いて、通信を暗号化している様子を示しています。

TLS 図

以下の例では、ワーカーノード上の証明書の情報を示しています。

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
...省略...

デフォルトにおいて Swarm 内の各ノードの証明書は、3 ヶ月ごとに更新されます。 この期間は docker swarm update --cert-expiry <期間> コマンドを使って設定することができます。 ローテーションの最小値は 1 時間です。 詳しくは CLI リファレンスの docker swarm update を参照してください。

CA 証明書のローテート

クラスターの CA 鍵やマネージャーノード自体においてセキュリティ侵害が発生した場合、Swarm のルート CA をローテートすることができます。 これによって古いルート CA により署名された証明書は、どのノードも信頼しないようにすることができます。

docker swarm ca --rotate を実行すれば、新たな CA 証明書と鍵を生成することができます。 必要なら --ca-cert--external-ca フラグを指定して、Swarm の外部にあるルート証明書やルート CA を設定することもできます。 これとは別に --ca-cert--ca-key フラグを用いれば、Swarm で利用したい証明書と鍵を具体的に指定することもできます。

docker swarm ca --rotate コマンドが実行されると、以下に示す内容が順に発生します。

  1. Docker はクロス署名された証明書を生成します。 これはつまり新たなルート CA 証明書が、古いルート CA 証明書によって署名されるということです。 このクロス署名証明書は、新たなノードの証明書に対する中間証明書として利用されます。 こうすることで、古いルート証明書を信頼するノードが、新たな CA によって署名された証明書も有効にできます。

  2. Docker は全ノードに対して TLS 証明書をすぐに更新するように指示することになりました。 この処理は Swarm 内のノード数に応じて数分程度かかります。

  3. Swarm 内のノードがすべて、新たな CA によって署名された新たな TLS 証明書を受け取った後は、Docker は古い CA 証明書や鍵に関することは一切忘れます。 そしてノードに対しては、新たな CA 証明書だけを信頼するように指示を出します。

    その際には Swarm への参加時のトークンも変更されます。 それまでの参加時のトークンはこれ以降は無効になります。

これ以降、新たなノードに発行される証明書は、新たなルート CA によって署名されます。 中間証明書が含まれることはありません。

さらに詳しく

swarm, security, tls, pki