公開鍵基盤を利用した 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 を用いて、通信を暗号化している様子を示しています。
以下の例では、ワーカーノード上の証明書の情報を示しています。
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
コマンドが実行されると、以下に示す内容が順に発生します。
-
Docker はクロス署名された証明書を生成します。 これはつまり新たなルート CA 証明書が、古いルート CA 証明書によって署名されるということです。 このクロス署名証明書は、新たなノードの証明書に対する中間証明書として利用されます。 こうすることで、古いルート証明書を信頼するノードが、新たな CA によって署名された証明書も有効にできます。
-
Docker は全ノードに対して TLS 証明書をすぐに更新するように指示することになりました。 この処理は Swarm 内のノード数に応じて数分程度かかります。
-
Swarm 内のノードがすべて、新たな CA によって署名された新たな TLS 証明書を受け取った後は、Docker は古い CA 証明書や鍵に関することは一切忘れます。 そしてノードに対しては、新たな CA 証明書だけを信頼するように指示を出します。
その際には Swarm への参加時のトークンも変更されます。 それまでの参加時のトークンはこれ以降は無効になります。
これ以降、新たなノードに発行される証明書は、新たなルート CA によって署名されます。 中間証明書が含まれることはありません。