Dockerのシークレットを安全に管理する方法(Kubernetesを使っていない場合も)
Marcelo Oliveira
2022年8月24日
0 分で読めます分散コンテナシステムは、アプリケーション、リソース、サービス、データベースなどのコンポーネントで構成されます。これらのコンポーネントが適切に機能するには、ユーザーキー、パスワード、APIキー、証明書などの機密情報が必要になることがよくあります。
シークレット管理は、機密情報を適切に扱ううえで欠かせません。Kubernetes環境では、組み込みのSecretsリソースタイプと関連するRBAC制御がよく利用されます。しかし、Kubernetesにデプロイしない場合はどうでしょうか?Kubernetesの強力な機能が不要な組織や、その複雑さを引き受けたくない組織も少なくありません。それでも、データ漏えいやパスワード紛失のリスクを避ける必要があります。幸い、Dockerに組み込まれたSwarmオーケストレーターがその解決策を提供します。
この記事では、Dockerでシークレットを管理する方法を取り上げ、ベストプラクティスと使用に伴う潜在的なリスクを解説します。また、Dockerシークレットの作成と一覧表示、サービスへの追加と削除を行う簡単な演習も紹介します。読者は、DockerコンテナランタイムとそのSwarmオーケストレーターについて基本的な知識があることを前提としています。
Dockerシークレットを安全に管理する
組織内でシークレットや機密データをやり取りする際には、データ漏えいやパスワード紛失のリスクがあります。パスワード、秘密鍵、トークン、APIキーなどの機密情報を扱うDockerプロジェクトでは、シークレットを安全に保管し、コンテナに渡す方法を定める必要があります。
最も避けるべき方法のひとつは、機密データをソースコードに残すことです。セキュリティ上の懸念に加えて、コードにシークレットをハードコードすると、シークレットを変更するたびにイメージを再ビルドしなければなりません。
もうひとつのよくない方法は、パスワードやSSHキーなどの重要な情報を「手作業」で扱い、ローカルディスクに残しておくことです。権限のないユーザーや悪意のあるプログラムもファイルを読み取る可能性があることを忘れてはいけません。
開発者は機密データの保存に環境変数をよく使います。状況によっては問題ありませんが、Dockerコンテナでは推奨されません。環境変数はファイルよりも安全性が低く、次のようなさまざまな経路から漏れる可能性があります。
docker inspectコマンド
イベントログファイル
たとえば、アプリケーションの例外処理コードがログにcontextを出力すると、環境変数に含まれる機密値までログに記録されるおそれがあります。
シークレットマネージャーを使うと、Docker Swarmでシークレットを一元管理できるため、先ほどの方法よりはるかに優れています。シークレットマネージャーは、シークレットの保存、管理、取得を便利に行えるサービスを提供し、アプリケーション、サービス、ITリソースへのアクセスを保護します。対象となるのは、APIやデータベースの認証情報、キー、パスワード、SSH秘密鍵、SSL証明書など、アプリケーションの実行時に必要な機密データです。
Dockerでのシークレット管理の仕組み

上の図は、Dockerが分散システム内の複製ログを管理するためにRaftという合意アルゴリズムを使用し、Swarm全体とその上で稼働するすべてのサービスでデータの一貫性を保っていることを示しています。Raftアルゴリズムは、シークレットを暗号化してすべてのマネージャーノードに一貫して送信します。
図には、ワーカーノードも示されています。これらは、コンテナの実行に特化したDocker Engineのインスタンスです。マネージャーノードは、キーが割り当てられたサービスに属するコンテナへシークレットを配布します。
Dockerシークレットは、機密データを保管できる金庫のようなものです。金庫の鍵を持っている場合にのみ利用できます。鍵は、その鍵を割り当てたサービスノードから取得する必要があります。
Dockerのシークレット管理サービスは、コンテナオーケストレーションスタックの一部であり、データを安全に保つプロセスを自動化します。
Docker Swarmサービスでは、シークレットは保存時も転送時も暗号化されています。
Dockerシークレットは一元管理でき、アクセスが必要なコンテナに安全に送信できます。各シークレットにアクセスできるのは、明示的に権限を付与されたサービスだけであり、サービスの稼働中に限られます。
サービスがシークレットへのアクセス権を得ると、シークレットを復号して、メモリ内ファイルシステムを介してコンテナと共有します。コンテナタスクが停止すると、利用可能だった復号済みシークレットは直ちに切り離され、ノードのメモリから消去されます。
Docker CLIでシークレットを管理する
Dockerの組み込み機能を使うと、シークレットを登録し、どのサービスがシークレットにアクセスできるか、またどのような状況で使用できるかを細かく制御できます。
この簡単な演習では、rootパスワードを設定したMySQLサービスを作成し、その認証情報をシークレットとして追加します。
DockerシークレットはSwarmサービスでのみ利用できるため、動作を確認するにはDocker Swarmをセットアップする必要があります。まず、Dockerコマンドライン(Docker CLI)がインストールされていることを確認してください。まだの場合は、Swarmを初期化するか、参加します。
次に、Dockerにシークレットを追加します。
シークレットを保存する場所にテキストファイルを作成します。次のコマンドは、this-is-a-mysql-passwordという文字列を含むpassword.txtファイルを作成します。
次に、docker secret createコマンドを使い、前の手順で作成したファイルから新しいシークレットを作成します。
上記のl1m5jvgcox1l96i6bjbz4dvntという文字列はシークレットそのものではなく、シークレットIDです。そのため、実際の環境では異なる値になります。
次に、docker secret createコマンドの別の使い方を見てみましょう。最後の引数(ファイルを表す引数)にマイナス記号(-)を指定して、ファイル名を省略します。
このコマンドを実行すると、次のような出力が表示されます。
この方法ではシークレットを読み取るファイルを指定せず、docker secret createコマンドが標準入力からanother-mysql-passwordを読み取ります。
Dockerシークレットの一覧表示
Docker Swarmで利用可能なシークレットを一覧表示するには、docker secret lsコマンドを実行します。
Docker Swarmで作成したシークレットの一覧が出力されます。
シークレットを使ってサービスを作成する
上で作成したシークレットを使ってサービスを作成できます。
mysql-serviceサービスを作成し、--secretフラグを使って、コンテナにanother-mysql-secretへのアクセス権を付与します。
既存のサービスへのシークレットの追加・削除
既存のサービスからシークレットを削除できます。
または、稼働中のサービスにシークレットを追加できます。
シークレットをサービスに紐付けると、Dockerはシークレットと同じ名前のテキストファイルを作成します。このファイルにはシークレットを表す文字列が含まれ、デフォルトでは、コンテナ内にマウントされた/run/secretsディレクトリにある一時ファイルシステム(TMPFS)に配置されます。この例では、ファイルのパスは/run/secrets/mysql-password-secretです。作成すると、そのサービスのすべてのコンテナでシークレットを利用できます。
外部シークレット管理の選択肢
Dockerシークレットは優れたソリューションですが、このタスクを外部のサードパーティ製シークレットストレージに委ねることも検討しましょう。特定のプラットフォームに関する知見や投資がすでにある組織では、特に有効です。
たとえば、すでにHashicorp Vaultを利用していて、アプリケーションが統合されているなら、プラットフォームに組み込まれているという理由だけでDockerシークレット(またはKubernetesシークレット)に切り替える必要はほとんどありません。そのソリューションに関する既存のプロセス、ライブラリ、知見をサービスで活用しましょう。
シークレット管理の代表的な選択肢には、次のようなものがあります。
クラウドプロバイダーのソリューション(AWS Secrets Manager、GCP Secret Managerなど)
シークレットを安全に保つ
この記事では、Docker Swarmにおけるシークレットとシークレット管理の概念を紹介し、Dockerがシークレットを管理する仕組みを解説しました。また、機密データをハードコードしたり、環境変数を使ったり、手作業で管理したりするより、シークレットマネージャーを利用するほうがはるかに優れていることを示しました。
データセキュリティは、効果的な企業統治を支える柱のひとつです。CLIコマンドと、シークレットデータを細かく制御してデプロイできるインメモリーアーキテクチャにより、Dockerは堅牢なシークレット管理ツールを提供し、組織の情報セキュリティの適切な実装を支援します。
シークレットをのぞき見から守ることは、安全なコンテナを構築するための第一歩です。Snyk Codeはハードコードされたシークレットの検出を支援し、Snyk ContainerとSnyk Open Sourceは、コンテナに最適な安全性の高いベースイメージやパッケージを見つける手助けをします。本番環境への移行準備が整ったら、Snyk IaCでデプロイ前後のリスクを低減できます。今すぐ無料で始めて、コード、オープンソース依存関係、コンテナ、クラウドインフラストラクチャの脆弱性を検出し、自動的に修正しましょう。
開発者ファーストのコンテナセキュリティ
Snykは、コンテナイメージとKubernetesワークロードの脆弱性を検出し、自動的に修正します。



