Aikido

脆弱性を気にする開発者のための、BSなしのDockerセキュリティ・チェックリスト

マッケンジー・ジャクソン
マッケンジー・ジャクソン
|
#
#

なぜここに?

Dockerのセキュリティに関する2つの質問に対する本当の答えを知りたい:

Dockerは本番環境でも安全か?

はい、違います。Dockerは名前空間とリソースの分離に依存するセキュリティモデルを使用しており、クラウドVMやベアメタルシステムから直接アプリケーションを実行するよりも、特定の攻撃からコンテナ内のプロセスをよりセキュアにします。

Dockerのセキュリティを(ひどく苦痛を伴わない方法で)向上させるにはどうすればよいでしょうか?

公式イメージの使用やホストを最新の状態に保つといった、Googleのあちこちにあるような基本的な推奨事項を飛ばして、最も一般的で深刻なDockerの脆弱性について説明します。代わりに、新しいデフォルトのDockerコンテナのデプロイメントをこれまでよりもはるかに安全にする、新しいdockerオプションやDockerfileの行を直接紹介します。

ノーBSのDockerセキュリティ・チェックリスト

コンテナ内ファイルシステムを読み取り専用にする

何が得られるのか?

攻撃者がDockerコンテナの実行環境を編集できないようにすることで、インフラに関する有益な情報を収集したり、ユーザーデータを収集したり、DOSやランサムウェア攻撃を直接行ったりできるようになります。

どのように設定するのですか?

実行時またはDocker Composeの設定内で、2つのオプションがあります。

実行時に: docker run --read-only your-app:v1.0.1

Docker Composeファイルに

サービス
webapp:
image: your-app:v1.0.1read_only: true
...

ロック権限の昇格

何が得られるのか?

setuidやsetgidを使うことで、Dockerコンテナや、コンテナ内部で悪さをする攻撃者が、新しい特権(rootレベルでも)を有効にできないようにすることができます。コンテナへのアクセスがより許可されるようになると、攻撃者はパスワードやデータベースなど、デプロイの接続部分へのキーの形で認証情報にアクセスできるようになります。

どのように設定するのですか?

もう一度、実行時またはDocker Composeの設定内で。

実行時に: docker run --security-opt=no-new-privileges your-app:v1.0.1

Docker Composeファイルに

サービスを提供する: 
	webapp:    
		image: your-app:v1.0.1    
		security_opt
			-no-new-privileges:true    
...

コンテナ間ネットワークの分離

何が得られるのか?

デフォルトでは、Dockerはすべてのコンテナをdocker0ネットワーク経由で通信させるため、攻撃者は侵害されたコンテナから別のコンテナへと横方向に移動できる可能性がある。個別のサービス A そして B 容器入り Y そして ZDockerのセキュリティを向上させるために横方向の移動を防止しながら、ネットワークを分離することで、同じエンドユーザー・エクスペリエンスを提供します。

どのように設定するのですか?

Dockerネットワークは、実行時またはDocker Compose設定内で指定することができます。ただし、最初にネットワークを作成する必要があります:

docker network create your-isolated-network

実行時に --ネットワークオプションn: docker run --network your-isolated-network your-app:v1.0.1

または、Docker Composeファイルの同等のオプション:

サービスを提供する: 
	webapp:    
    	 image: your-app:v1.0.1    
        networks     
        	- 分離されたネットワーク    
		...

適切な非 root ユーザーを設定する

何が得られるのか?

コンテナ内のデフォルトユーザーは ルートuidは 0. 別個のユーザを指定することで、攻撃者がrootのような制限なしにアクションを実行できる別のユーザに権限をエスカレートさせることを防ぎます。

どのように設定するのですか?

ビルド・プロセス中またはランタイム中にユーザーを作成します。実行時に、初めてユーザーを作成するか、あるいは ユーザー はビルド時に設定済みである。

ビルドの過程で ドッカーファイル:

...
RUN groupadd -r your-user
RUN useradd -r -g your-user your-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の場合:

サービス
	webapp:
    	 image: your-app:v1.0.1
        cap_drop
        	- すべて
        cap_add
        	- CHOWN
        ...

フォーク爆弾を防ぐ

何が得られるのか?

フォークボムは、既存のプロセスを無限に複製するDoS攻撃の一種である。まずパフォーマンスを低下させリソースを制限するため、必然的にコストが上昇し、最終的にはコンテナやホストシステムをクラッシュさせる可能性がある。いったんフォークボムが始まると、コンテナやホストを再起動する以外に止める方法はない。

どのように設定するのですか?

実行時に、コンテナが作成できるプロセス(PID)の数を制限できる。

docker run --pids-limit 99あなたのアプリ:v1.0.1

あるいはDocker Composeを使う:

サービス
	webapp:
		image: your-app:v1.0.1
デプロイ
			制限
				pids: 99

オープンソースの依存関係を監視してDockerのセキュリティを向上させる

何が得られるのか?

Dockerでデプロイするためにコンテナ化したアプリケーションは、おそらく幅広い依存関係のツリーを持っている。

どのように設定するのですか?

最も "非BS的 "な方法は、Aikido オープンソース依存性スキャンです。私たちの継続的なモニタリングは、アプリケーション内のロックファイルの存在に基づいて、12以上の言語で書かれたプロジェクトをスキャンし、脆弱性とマルウェアの概要を即座に提供します。偽陽性をフィルタリングする自動トリアージにより、Aikido 、あなたが他の多くの参考文書やGitHubの問題を読んだ後だけでなく...すぐに作業を開始できる修復アドバイスを提供します。

Aikido、TrivySyftGrypeのような確立されたオープンソース・プロジェクトが大好きです。また、これらのプロジェクトを単独で使用することは、開発者にとって特に良い経験にはならないことも経験から知っています。Aikido 、これらのプロジェクトをカスタム・ルールで強化することで、ギャップを埋め、他の方法では見つけられないようなセキュリティ上の欠陥を明らかにします。様々なオープンソースのツールを連結して使うのとは異なり、Aikido 、スキャンスクリプトを構築したり、CI/CDでカスタムジョブを作成したりする必要から解放します。

より完全なDockerセキュリティのためのAikidioのオープンソース依存性スキャン。
タイプキャプション(オプション)

Dockerのセキュリティのために信頼できるイメージのみを使用する

何が得られるのか?

Docker Content Trust (DCT)は、Docker HubのようなDockerレジストリから取り出した公式イメージに署名し、その内容と完全性を検証するシステムです。作者によって署名されたイメージのみをプルすることで、デプロイに脆弱性を生じさせるような改ざんがされていないことをより確実にすることができます。

どのように設定するのですか?

最も簡単な方法は、シェルに環境変数を設定することで、あなたや他の人が信頼できないイメージで作業するのを防ぐことができる。

exportDOCKER_CONTENT_TRUST=1
docker run ...

あるいは、Dockerを実行するたびに環境変数を設定することもできる:

docker_content_trust=1docker run ...

製造終了(EOL)ランタイムの更新

何が得られるのか?

Dockerコンテナのセキュリティに関する一般的な推奨事項の1つは、イメージと依存関係を特定のバージョンに固定することです。 最新.理論的には、改ざんされたものであっても、新たな脆弱性をもたらす新しい画像を無意識のうちに使用することを防ぐことができる。

どのように設定するのですか?

EOLを発見し、最善の準備をするのに役立つオープンソースのプロジェクトがいくつかある。endoflife.dateプロジェクト(GitHubリポジトリ)は、複数のソースからのデータを集約し、公開APIを介して利用できるようにすることで、300以上の製品を追跡している。endoflife.dateや同様のプロジェクトにはいくつかの選択肢がある:

  • アプリケーションが依存している依存関係のアップデートがないかプロジェクトを手動でチェックし、必要なアップデートのチケットや課題を作成します。
  • APIから依存関係のEOL日を取得するスクリプト(Bash、Pythonなど)を書き、cronジョブのように定期的に実行する。
  • 公開API、またはカスタムスクリプトをCIプラットフォームに組み込んで、EOLに近い、またはEOLに達したプロジェクトを使用するビルドを失敗させる。

開発者として、あなたの時間は貴重であり、しばしば限られていることを理解しています。そこでAikido EOLスキャン機能は、Node.jsやNginxウェブサーバのように、最も影響と露出のあるランタイムを優先的に、コードとコンテナを追跡します。いつものように、Aikidoは情報収集を自動化するだけでなく、適切な重要度を持つアラートを配信することで、ユーザを圧倒するのではなく、情報を提供します。

使用済みの依存関係をスキャンすることで、Dockerのセキュリティを向上させる例。
アン

コンテナ・リソースの使用を制限する

何が得られるのか?

デフォルトでは、コンテナにはリソース制約がなく、ホストのスケジューラと同じだけのメモリやCPUを使用する。特定のコンテナの リソース使用量を制限することで、DoS攻撃の影響を最小限に抑えることができます。Out of Memory Exceptionによってコンテナやホストシステムがクラッシュする代わりに、進行中のDoS攻撃はエンドユーザーエクスペリエンスに悪影響を与える「だけ」になります。

どのように設定するのですか?

実行時に --メモリ そして --CPU オプションを使用して、それぞれメモリと CPU の使用量の上限を設定する。メモリ・オプションは、g がギガバイト、m がメガバイトの数値をとり、CPU オプションは、コンテナとそのプロセスで使用可能な専用 CPU の上限を反映する。

docker run --memory="1g"--cpus="2"あなたのアプリ:v1.0.1

これはDocker Composeでも使える:

サービス
	webapp:
    	 image: your-app:v1.0.1
        deploy
            limits:
            	 cpus: '2'
                memory: 1G
         ...

Dockerセキュリティのための最後のコマンドとComposeオプション

今までに、あなたはかなりの数のDockerセキュリティのヒントと、それらに関連するCLIオプションや設定を見てきました。以下では、より安全なDockerコンテナのデプロイをすぐに始められるように、推奨事項を1つのコマンドや設定テンプレートにまとめました。

もちろん、非rootユーザー名、カーネル機能、リソース制限などのオプションのいくつかは、アプリケーションのニーズに応じて変更したい。

exportDOCKER_CONTENT_TRUST=1
docker run  \ 
    --read-only  
    --read-only--security-opt=no-new-privileges 
    --network your-isolated-network ¦ --cap-drop ALL  
    --cap-drop ALL 
    --cap-add CHOWN  
    --pids-limit 99 
    --memory="1g" --cpus="2" ୧--user=your-user 
    --ユーザー=ユーザー  
    ...                 # その他のオプションはこちら  
    your-app:v1.0.1

ホストのシェルでdrunエイリアスを作成し、詳細を覚えていなくても呼び出せるようにするのもいいだろう。

関数 drun  { 
docker run   
    	--読み取り専用    
       --security-opt=no-new-privileges \
        --network your-isolated-network ˶ --cap-drop ALL   
        --cap-drop ALL 
        --cap-add CHOWN    
        --pids-limit 99 
        --memory="1g" --cpus="2" ୧--user=your-user   
        -user=your-user ୧-͈ᴗ-͈ᴗ    
        $1\ 
       $2
}.

次に、オプションとイメージ名を指定して、エイリアスを次のように実行する。

もしあなたがDocker Composeを使う人であれば、同じオプションをすべて、今後作業できる新しいベースラインDocker Composeテンプレートに適応させることができます:

サービス
	webapp:
    	 image: your-app:v1.0.1
        read_only: true
        security_opt
           -no-new-privileges:true
        networks
           - 分離されたネットワーク
        cap_drop
           - すべて
        cap_add
           - CHOWN
        デプロイ
        	limits:
        		 pids: 9
        		 cpus: '2'
        		memory: 1G
        ...               # その他のオプションはこちら

おまけ:ルートレスコンテナでDockerを動かす

Dockerを任意のシステムにインストールすると、そのデーモンはrootレベルの特権で動作します。上記のオプションをすべて有効にし、Dockerコンテナ内での権限昇格を防いだとしても、ホストシステム上のコンテナランタイムの残りの部分は依然としてルート権限を持っています。そのため、必然的に攻撃対象が広がってしまいます

その解決策がルートレス・コンテナであり、非特権ユーザーが作成・管理できる。root権限が必要ないということは、ホスト・システムのセキュリティ問題がはるかに少ないことを意味する。

1つのオプションやコマンドでルートレス・コンテナを使う手助けができればいいのだが、そう簡単にはいかない。ルートレス・コンテナのウェブサイトには、Docker用のハウツー・ガイドを含む詳細な手順が掲載されている。

Dockerセキュリティの次は?

この経験から何かを学んだとしたら、それはコンテナ・セキュリティは長丁場の作業だということだ。Dockerやその古く、誤解されがちな従兄弟であるKubernetesのコンテナをロックダウンするための堅牢化チェックリストや深く掘り下げた記事は、いつでも読むことができる。多忙な開発スケジュールの中にセキュリティに取り組む時間を作り、影響度と重大性に基づいて段階的に改善することで、長い時間をかけて長い道のりを歩むことができます。

このような継続的なプロセスを最大限に活用し、アプリケーションのセキュリティを有意義に改善するための修正に優先順位をつけるために、次のようなものがあります。 Aikido.私たちは、"ノー・BS "開発者セキュリティ・プラットフォームのために、1,700万ドルのシリーズAを調達したばかりです。

無料で安全を確保

コード、クラウド、ランタイムを1つの中央システムでセキュアに。
脆弱性を迅速に発見し、自動的に修正。

クレジットカードは不要。