【Security Hub修復手順】[ECS.20] ECSタスク定義では、Linux コンテナ定義で非ルートユーザーを設定する必要があります
こんにちは!クラウド事業本部コンサルティング部の浅野です。
皆さん、お使いのAWS環境のセキュリティチェックはしていますか?
本記事では、AWS Security HubによるAWS環境のセキュリティ状況スコアリングに該当する項目についての修復手順をご紹介します。
本記事の対象コントロール
[ECS.20] ECS タスク定義では、Linux コンテナ定義で非ルートユーザーを設定する必要があります
[ECS.20] ECS task definitions should configure non-root users in Linux container definitions
前提条件
本記事はAWS Security Hubで「AWS基礎セキュリティのベストプラクティススタンダード」を利用されている方向けの内容となります。
AWS Security Hubの詳細についてはこちらのブログをご覧ください。
対象コントロールの説明
このコントロールは、ECSタスク定義の最新のアクティブなリビジョンで、Linuxコンテナが非rootユーザーとして実行されるよう設定されているかチェックします。
コンテナ定義の user パラメータに非rootユーザー(root または UID 0 以外)が設定されていると、このコントロールは成功します。
本コントロールはLinuxコンテナを対象とします。タスク定義の operatingSystemFamily が LINUX または未設定のものが評価対象です。
非rootユーザーで動かす設定は2か所ある
コンテナを非rootユーザーで動かすための設定は、実は2か所に存在します。
本コントロールへの対応を考えるうえで、まずこの整理が重要です。
| 設定箇所 | 役割 | 上書き優先順 |
|---|---|---|
Dockerfile の USER 命令 |
イメージ自体のデフォルトユーザーを指定 | 下位(タスク定義に上書きされる) |
タスク定義の user パラメータ |
起動時のユーザーを指定(docker run --user 相当) |
上位(Dockerfileを上書き) |
両方とも、最終的に「コンテナを非rootで動かす」結果は同じになります。
タスク定義の user パラメータはDockerfileの USER 命令を上書きするため、タスク定義側で指定すれば、Dockerfileが何であっても起動時のユーザーは上書きされます。
本コントロールが見ているのは「タスク定義の user」のみ
ここが落とし穴です。
本コントロールが評価対象とするのは タスク定義の user パラメータのみ であり、Dockerfileの USER 命令は評価されません。
つまり、Dockerfile側で USER 1000 を指定していてコンテナが非rootで動作していても、タスク定義の user が未設定であれば、本コントロールは FAILED と検知します。
| Dockerfile USER | タスク定義 user | コンテナの実際の動作 | ECS.20 判定 |
|---|---|---|---|
| 未設定 | 未設定 | rootで動く | 🔴 FAILED |
USER 1000 |
未設定 | 1000で動く(イメージのデフォルト) | 🔴 FAILED(落とし穴) |
| 未設定 | "user": "1000" |
1000で動く | 🟢 PASSED |
USER 1000 |
"user": "1000" |
1000で動く | 🟢 PASSED(推奨) |
つまり、ECS.20への対応自体は タスク定義の user パラメータを明示的に設定するだけ で完了します。
ただし、本質的なセキュリティ強化としては、Dockerfile側でも USER 命令を入れる多層防御の構成が推奨されます(記事末尾で補足します)。
対応しないとどうなるか
コンテナがroot権限で動作する場合、コンテナ内の脆弱性を起点とした攻撃が成立した際に、ホスト側へ影響が及ぶ範囲が広がる可能性があります。特権コンテナの利用やコンテナエスケープと組み合わさると、ホストOSへの侵害につながる懸念もあります。
AWS公式のAmazon ECSのタスクとコンテナのセキュリティに関するベストプラクティスでも、コンテナを非rootユーザーで実行することが推奨されています。
最小権限の原則に従い、コンテナを非rootで動かすことは本番環境では必須の対応です。
修復手順
コントロールの確認方法
- AWSマネジメントコンソールからSecurity Hub CSPMを開く
- 左メニューから「検出結果」を選択
- フィルターで
コンプライアンスセキュリティコントロールIDにECS.20を指定し、コンプライアンスのステータスがFAILEDの検出結果を確認する

- 該当の検出結果を選択し、詳細パネルから対象リソース(タスク定義)のARNを確認する

ARNの形式例: arn:aws:ecs:<region>:<account-id>:task-definition/<family-name>:<revision>
ステークホルダーに確認
修復を行う前に、以下の点をステークホルダーに確認してください。
- 対象タスク定義を利用しているECSサービス・ECSタスクの稼働状況
- コンテナアプリケーションが非rootユーザーで動作するか(特権を要する処理や、root権限が必要なポート番号を使用していないか)
- コンテナイメージ側で利用可能な非rootユーザーがあるか(既存のユーザー名/UID、または新規UIDで動かしてよいか)
- 新しいタスク定義リビジョンへの切り替えタイミング(メンテナンスウィンドウ)
修復手順
既存のタスク定義のリビジョンは編集できないため、user パラメータを設定した新しいリビジョンを作成し、サービスやタスクを新しいリビジョンで再デプロイします。
1. 現状の確認
ECSコンソールを開き、左メニューから「タスク定義」を選択し、対象のタスク定義ファミリーを開きます。

最新のアクティブリビジョンを選択し、リビジョン詳細画面の「コンテナ: <コンテナ名>」セクションを展開して「ランタイムの設定」を確認します。
本コントロールが FAILED と検知される状態には、次の2パターンがあります。
パターンA: 「ユーザー」が未設定(空欄)の場合
タスク定義の作成時に user パラメータを指定しなかった場合、コンテナはイメージのデフォルトユーザー(多くの場合 root)で実行されます。コンソール上は「ユーザー」欄が空欄になります。

パターンB: 「ユーザー」に root または 0 が指定されている場合
タスク定義の user パラメータに明示的に root あるいは UID 0 が指定されているケースです。コンソール上は「ユーザー」欄に root が表示されます。

いずれのパターンも、user パラメータに非rootユーザー(root および UID 0 以外)を設定することで PASSED に変わります。
2. JSONエディタで新しいリビジョンを作成し、user パラメータを設定
ECSの新コンソール(v2)では、コンテナ定義の user パラメータは標準のGUIフォーム上に入力欄が用意されていません。修正にはJSONエディタを使用します。
タスク定義ファミリーのリビジョン一覧で最新リビジョンにチェックを入れ、「新しいリビジョンを作成」を選択します。
新リビジョンの編集画面の下部「コンテナ: <コンテナ名>」セクションで「JSON」タブに切り替え、コンテナ定義のJSON内に "user": "1000" を追加します(UID 1000 は一般的な非rootユーザーのUIDの例で、実際にはアプリケーションで動作確認済みのUIDを指定してください)。

画面下部の「作成」を選択し、新しいリビジョンを作成します。
作成後、新リビジョン詳細の「コンテナ: <コンテナ名>」セクションを展開し、「ランタイムの設定」で「ユーザー」が 1000 になっていることを確認します。

3. (サービスで利用している場合)サービスを新しいリビジョンに更新
ECSサービスでタスク定義を利用している場合は、新しいリビジョンを利用するようサービスを更新します。
- ECSコンソールの「クラスター」から対象クラスターを開く
- 「サービス」タブから対象サービスを選択し、「サービスを更新」を選択する
- 「タスク定義のリビジョン」のドロップダウンから、先ほど作成した新しいリビジョンを選択する
- 「更新」を選択してサービスをデプロイする
スタンドアロンタスクとして実行している場合は、新しいリビジョンでタスクを再実行してください。
修復確認
本コントロールは タスク定義の登録時点で評価される ため、新しいリビジョンを作成した時点でPASSEDに切り替わります。サービスの更新は実際の稼働タスクを新リビジョンに切り替えるためのものであり、Security Hubの判定自体はサービス更新を待たずに反映されます。
数分後、Security Hubで検出結果が「PASSED」になることを確認します。

詳細を見ると、コンプライアンスが「PASSED」になっていることが確認できます。

履歴を見ると、コンプライアンスステータスが「FAILED」から「PASSED」に変わったことが記録されています。

注意: Security Hubの検出結果は更新までに時間がかかる場合があります(最大12時間程度)。
補足:Dockerfile側にも USER 命令を入れる多層防御
本コントロールへの対応はタスク定義の user パラメータを設定するだけで完了しますが、AWS公式のAmazon ECSのタスクとコンテナのセキュリティに関するベストプラクティスでは、Dockerfile側にも USER 命令を入れることが推奨されています。CI/CDパイプラインでDockerfileをlintし、USER 命令が無ければビルドを失敗させる運用も示されています。
Dockerfile側にも USER 命令を入れておくと、タスク定義側で user の指定漏れが発生した場合でもイメージ自体は非rootで起動するため、多層防御として有効です。コンテナイメージ単体の安全性や、別環境(ローカル開発、Kubernetes等)での動作にも一貫性が生まれます。
既存イメージにユーザーが用意されている場合の例:
FROM public.ecr.aws/nginx/nginx:latest
USER 1000
新規でユーザーを作成する場合の例:
FROM alpine:latest
RUN addgroup -g 1000 app && \
adduser -u 1000 -G app -D app
USER 1000
タスク定義側だけ修正してもECS.20はPASSEDになりますが、本質的なリスクヘッジを行う場合は、Dockerfile側にも USER 命令を入れる構成を検討してみてください。
最後に
今回は、AWS Security HubによるAWS環境のセキュリティ状況スコアリングに該当する項目についての修正手順をご紹介しました。
コントロールを修正して、お使いのAWS環境のセキュリティをパワーアップさせましょう!
最後までお読みいただきありがとうございました!どなたかのお役に立てれば幸いです。
今回は以上です。





