ここに来た目的は何ですか?
Dockerセキュリティに関する2つの質問について、真の答えを知りたいとお考えでしょう。
Dockerは本番環境での使用において安全ですか?
はい、でもいいえ、です。Dockerは、名前空間とリソース分離に依存するセキュリティモデルを使用しており、クラウドVMやベアメタルシステムから直接アプリケーションを実行するよりも、内部のプロセスを特定の攻撃からより安全にしています。この層があるにもかかわらず、攻撃者がコンテナにアクセスし、機密情報を読み取ったり、サービス拒否(DoS)攻撃を実行したり、さらにはホストシステムへのrootアクセスを取得したりする多くの方法が依然として存在します。
Dockerのセキュリティを(それほど苦痛なく)改善するにはどうすればよいですか?
ここでは、最も一般的で深刻なDockerの脆弱性についてご説明します。公式イメージの使用やホストの最新状態の維持といった、Googleでよく見かける基本的な推奨事項は割愛します。代わりに、新しいDockerオプションとDockerfileの記述に直接ご案内し、新しいデフォルトのDockerコンテナデプロイメントをこれまで以上に安全にします。

本質を突いたDockerセキュリティチェックリスト
コンテナ内のファイルシステムを読み取り専用にする
どのようなメリットがありますか?
攻撃者がDockerコンテナのランタイム環境を編集するのを防ぎます。これにより、攻撃者がインフラストラクチャに関する有用な情報を収集したり、ユーザーデータを取得したり、DoS攻撃やランサムウェア攻撃を直接実行したりするのを防ぐことができます。
どのように設定しますか?
設定には2つのオプションがあります。ランタイム時、またはDocker Composeの設定内です。
ランタイム時: docker run --read-only your-app:v1.0.1
Docker Composeファイル内:
services:
webapp:
image: your-app:v1.0.1read_only: true
...権限昇格のロック
どのようなメリットがありますか?
Dockerコンテナ、またはそのコンテナ内で不正な操作を行う攻撃者が、setuidやsetgidを使用してrootレベルを含む新しい権限を有効にすることを防ぎます。コンテナへのアクセス権がより緩い場合、攻撃者はデータベースなど、デプロイメントの接続部分へのパスワードやキーといった形式の資格情報にアクセスする可能性があります。
どのように設定しますか?
これもまた、ランタイム時、またはDocker Composeの設定内で指定できます。
ランタイム時: docker run --security-opt=no-new-privileges your-app:v1.0.1
Docker Composeファイル内:
services:
webapp:
image: your-app:v1.0.1
security_opt:
- no-new-privileges:true
...コンテナ間のネットワークを分離する
どのようなメリットがありますか?
デフォルトでは、Dockerはすべてのコンテナがdocker0ネットワークを介して通信することを許可しており、これにより攻撃者が侵害されたコンテナから別のコンテナへ水平移動する可能性があります。個別のサービスを運用している場合、 A そして B コンテナ内で Y そして Z、そしてそれらが直接通信する必要がない場合、それらのネットワークを分離することで、同じエンドユーザーエクスペリエンスを提供しつつ、Dockerセキュリティを向上させるための水平移動を防ぐことができます。
どのように設定しますか?
ランタイム時、またはDocker Composeの設定内でDockerネットワークを指定できます。ただし、まずネットワークを作成する必要があります。
docker network create your-isolated-networkランタイム時に、次のものを追加します --network オプション: docker run --network your-isolated-network your-app:v1.0.1
または、Docker Composeファイル内の同等のオプション:
services:
webapp:
image: your-app:v1.0.1
networks:
- your-isolated-network
...適切な非rootユーザーを設定する
どのようなメリットがありますか?
コンテナ内のデフォルトユーザーは root、UIDは 0. 個別のユーザーを指定することで、攻撃者がrootのような制限なくアクションを実行できる別のユーザーに権限を昇格させることを防ぎます。これは、苦労して実装した他のDockerセキュリティ対策を無効にしてしまう可能性があります。
どのように設定しますか?
ビルドプロセス中またはランタイム時にユーザーを作成します。ランタイム時には、ユーザーを初めて作成するか、または ユーザー ビルド時に既に設定したものを上書きできます。
ビルドプロセス中に、 Dockerfile:
...
RUN groupadd -r your-user
RUN useradd -r -g your-user your-user
USER myuser
...ランタイム時: docker run -u your-user your-app:v1.0.1
Linuxカーネルのケーパビリティを削除する
どのようなメリットがありますか?
デフォルトでは、Dockerコンテナは制限されたLinuxカーネルのケーパビリティセットを使用できます。Dockerの担当者がその制限されたセットを完全にセキュアにするために作成したと考えるかもしれませんが、多くのケーパビリティは互換性とシンプルさのために存在します。例えば、デフォルトのコンテナは、ファイルの所有権を任意に変更したり、ルートディレクトリを変更したり、プロセスのUIDを操作したり、ソケットを読み取ったりすることができます。これらのケーパビリティの一部またはすべてを削除することで、攻撃ベクトルの数を最小限に抑えられます。
どのように設定しますか?
ランタイム時にケーパビリティを削除し、新しいものを設定できます。例えば、すべてのカーネルケーパビリティを削除し、既存ファイルの所有権を変更するケーパビリティのみをコンテナに許可することができます。
docker run --cap-drop ALL --cap-add CHOWN your-app:v1.0.1またはDocker Composeの場合:
services:
webapp:
image: your-app:v1.0.1
cap_drop:
- ALL
cap_add:
- CHOWN
...フォークボムを防止する
どのようなメリットがありますか?
フォークボムは、既存のプロセスを無限に複製するタイプのDoS攻撃です。まず、パフォーマンスを低下させ、リソースを制限し、それが必然的にコストを増加させ、最終的にはコンテナまたはホストシステムをクラッシュさせる可能性があります。フォークボムが一度開始されると、コンテナまたはホストを再起動する以外に停止する方法はありません。
どのように設定しますか?
ランタイム時に、コンテナが作成できるプロセス(PID)の数を制限できます。
docker run --pids-limit 99 your-app:v1.0.1またはDocker Composeの場合:
services:
webapp:
image: your-app:v1.0.1
deploy
limits:
pids: 99オープンソースの依存関係を監視することで、Dockerのセキュリティを向上させます
どのようなメリットがありますか?
Dockerでデプロイするためにコンテナ化したアプリケーションは、多くの依存関係を持つ可能性が高いです。
どのように設定しますか?
最も「無駄のない」方法は、Aikidoのオープンソースの依存関係スキャンです。当社の継続的な監視は、アプリケーション内のロックファイルの存在に基づいて、12以上の言語で書かれたプロジェクトをスキャンし、脆弱性とマルウェアの即時概要を提供します。誤検知を除外する自動トリアージにより、Aikidoは、他の多くの参考資料やGitHubのIssueを読んだ後だけでなく、すぐに作業を開始できる修正アドバイスを提供します。
Aikidoでは、Trivy、Syft、Grypeのような定評のあるオープンソースプロジェクトを高く評価しています。また、それらを単独で使用することは、特に優れた開発者体験ではないことを経験から知っています。内部では、Aikidoはこれらのプロジェクトをカスタムルールで強化し、ギャップを埋め、そうでなければ見つけられないセキュリティ上の欠陥を明らかにします。様々なオープンソースツールを連携させるのとは異なり、Aikidoはスキャン用のスクリプトを構築したり、CI/CDでカスタムジョブを作成したりする手間から解放します。

Dockerセキュリティのために、信頼できるイメージのみを使用する
どのようなメリットがありますか?
Docker Content Trust (DCT) は、Docker HubのようなDockerレジストリからプルする公式イメージのコンテンツと整合性を署名および検証するためのシステムです。作成者によって署名されたイメージのみをプルすることで、デプロイメントに脆弱性を作成するために改ざんされていないという確信が高まります。
どのように設定しますか?
最も簡単な方法は、シェルで環境変数を設定することです。これにより、信頼できないイメージの操作を防ぎます。
export DOCKER_CONTENT_TRUST=1
docker run ...または、Dockerを実行するたびに環境変数を設定することもできます。
DOCKER_CONTENT_TRUST=1 docker run …サポート終了 (EOL) ランタイムを更新します。
どのようなメリットがありますか?
Dockerコンテナセキュリティの一般的な推奨事項の1つは、イメージと依存関係を特定のバージョンに固定することです latest理論上、これにより、改ざんされたイメージや新たな脆弱性を導入するイメージなど、新しいイメージを意図せず使用することを防ぎます。
どのように設定しますか?
EOLを発見し、最善の準備をするのに役立つオープンソースプロジェクトがいくつかあります。endoflife.dateプロジェクト(GitHubリポジトリ)は、複数のソースからデータを集約して300以上の製品を追跡し、公開APIを通じて利用可能にしています。endoflife.dateや類似のプロジェクトにはいくつかの選択肢があります。
- アプリケーションが依存するプロジェクトの依存関係の更新を手動で確認し、必要な更新のためにチケットやIssueを作成する。
- APIから依存関係のEOL日付を取得するスクリプト(Bash、Pythonなど)を作成し、cronジョブのように定期的に実行する。
- 公開API、またはそのカスタムスクリプトをCIプラットフォームに組み込み、EOLが近づいている、または到達したプロジェクトを使用するビルドを失敗させる。
開発者の皆様の時間は貴重であり、しばしば限られていることを理解しています。ここでAikidoが安心感を提供できます。当社のEOLスキャン機能は、コードとコンテナを追跡し、Node.jsやNginxウェブサーバーなど、最も影響と露出が大きいランタイムを優先します。通常通り、情報を収集するだけでなく、適切な重大度のアラートを配信し、情報を提供しつつも過負荷にならないようにします。

コンテナのリソース使用量を制限します。
どのようなメリットがありますか?
デフォルトでは、コンテナにはリソース制約がなく、ホストのスケジューラが許す限りメモリやCPUを使用します。特定のコンテナのリソース使用量を制限することで、DoS攻撃の影響を最小限に抑えることができます。メモリ不足例外によりコンテナやホストシステムがクラッシュする代わりに、進行中のDoS攻撃は「単に」エンドユーザーエクスペリエンスに悪影響を与えるだけになります。
どのように設定しますか?
実行時に、 --memory そして --cpus オプションを使用して、メモリとCPUの使用量にそれぞれ制限を設定できます。memoryオプションは、ギガバイトには「g」、メガバイトには「m」を付けた数値を指定し、CPUオプションは、コンテナとそのプロセスに利用可能な専用CPUの制限を反映します。
docker run --memory="1g" --cpus="2" your-app:v1.0.1これはDocker Composeでも機能します。
services:
webapp:
image: your-app:v1.0.1
deploy:
limits:
cpus: '2'
memory: 1G
...Dockerセキュリティのための最終コマンドとComposeオプション
これまでに多くのDockerセキュリティのヒントと、それらに付随する関連CLIオプションや設定をご覧いただきました。これらを実装することに非常に意欲的であるか、それらをすべてまとめる方法に圧倒されているかのどちらかでしょう。以下に、すべての推奨事項を単一のコマンドまたは設定テンプレートにまとめましたので、よりセキュアなDockerコンテナをすぐにデプロイし始めるのに役立ちます。
当然ながら、非rootユーザー名、カーネル機能、リソース制限など、アプリケーションのニーズに基づいていくつかのオプションを変更する必要があるでしょう。
export DOCKER_CONTENT_TRUST=1
docker run \
--read-only \
--security-opt=no-new-privileges \
--network your-isolated-network \
--cap-drop ALL
--cap-add CHOWN \
--pids-limit 99 \
--memory="1g" --cpus="2" \
--user=your-user \
... # OTHER OPTIONS GO HERE
your-app:v1.0.1ホストのシェルでdrunエイリアスを作成し、これらの詳細をすべて記憶することなく呼び出すこともできます。
function drun {
docker run \
--read-only \
--security-opt=no-new-privileges \
--network your-isolated-network \
--cap-drop ALL
--cap-add CHOWN \
--pids-limit 99 \
--memory="1g" --cpus="2" \
--user=your-user \
$1 \
$2
}その後、オプションとイメージ名を指定して、エイリアスを次のように実行します: drun -it your-app:v1.0.1
Docker Composeを使用する方であれば、同じオプションをすべて新しいベースラインDocker Composeテンプレートに適用し、今後使用することができます。
services:
webapp:
image: your-app:v1.0.1
read_only: true
security_opt:
- no-new-privileges:true
networks:
- your-isolated-network
cap_drop:
- ALL
cap_add:
- CHOWN
deploy:
limits:
pids: 9
cpus: '2'
memory: 1G
... # OTHER OPTIONS GO HEREボーナス: ルートレスコンテナでDockerを実行します。
任意のシステムにDockerをインストールすると、そのデーモンはrootレベルの特権で動作します。上記のすべてのオプションを有効にし、Dockerコンテナ内での特権昇格を防いだとしても、ホストシステム上の残りのコンテナランタイムは依然としてroot特権を持っています。それは必然的に攻撃対象領域を拡大します。
このソリューションは、権限のないユーザーが作成および管理できるrootlessコンテナです。root権限が不要であるため、ホストシステムのセキュリティ上の問題が大幅に減少します。
単一のオプションまたはコマンドでrootlessコンテナの使用を支援できればと思いますが、それほど単純ではありません。Rootless Containersのウェブサイトで、Dockerのハウツーガイドを含む詳細な手順をご確認いただけます。
Dockerセキュリティの次なるステップは何でしょうか?
この経験から何かを学んだとすれば、コンテナセキュリティは長期的な運用であるということです。Dockerや、その古くしばしば誤解されがちなKubernetesでコンテナをロックダウンするための、より多くの強化チェックリストや詳細な記事が常に存在します。完璧なコンテナセキュリティを目指すことはできませんが、忙しい開発スケジュールの中でセキュリティに対処する時間を確保し、影響と深刻度に基づいて段階的な改善を行うことは、長期的には大きな成果をもたらします。
その継続的なプロセスを最大限に活用し、アプリケーションセキュリティを大幅に向上させる修正を優先するために、Aikidoがあります。当社は「無駄のない」開発者向けセキュリティプラットフォームのために、1,700万ドルのシリーズA資金調達を完了しました。ぜひご参加ください。

