EC2ユーザーデータのAWS認証情報漏えいの可能性

実際のAWSシークレットアクセスキーをEC2ユーザーデータに保存せず、インスタンスロールと一時的な認証情報を使用してください。

説明

EC2のuser_dataに実際のAWSシークレットを入れると、プレイブックやユーザーデータを参照できる人に漏えいする可能性があります。長期アクセスキーの代わりに、必要な権限だけを持つインスタンスロールと一時的な認証情報を使用してください。

アクセスキーIDだけではAWSリクエストを認証できません。シークレットアクセスキーも必要で、一時的な認証情報にはセッショントークンも必要です。疑わしい値が文書の例か、実際の認証情報かを確認してください。実際のシークレットが漏えいした場合、現在のファイルから削除するだけでは十分ではありません。

想定される影響

  • 有効な認証情報一式が漏えいすると、その権限の範囲内で意図しないAWSリクエストに使われる可能性があります。
  • リポジトリの履歴、ユーザーデータ、デプロイ記録にコピーが残る場合があります。共有キーを交換する際は、それを使う処理も変更する必要があります。

対処方法

  • 実際のシークレットをuser_dataから削除し、インスタンスプロファイルを通じて最小権限のIAMロールを関連付けてください。アプリケーションは、対応するSDKのデフォルト認証情報プロバイダーで一時的な認証情報を使用するように構成してください。
  • 有効なキーが漏えいした場合は、依存する処理を確認しながら速やかに無効化または失効させ、交換してください。現在のファイルだけでなく、リポジトリの履歴や既存ユーザーデータのコピーも確認してください。
  • 関連するアクセス記録を調査し、新しい認証方式で必要な処理が引き続き動くことを確認してください。

例

キーの文字列は公開文書の例であり、実際の認証情報ではありません。AMI、インスタンスタイプ、サブネットは環境に合わせて指定してください。変更後の例には、必要なロールを含むインスタンスプロファイルと、それを関連付けるデプロイ主体の権限が必要です。

変更前

yaml
- name: start an instance
  community.aws.ec2_instance:
    name: credential-example
    image_id: "{{ ami_id }}"
    instance_type: "{{ instance_type }}"
    vpc_subnet_id: "{{ subnet_id }}"
    user_data: |
      #!/bin/bash
      export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
      export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

初期化スクリプトにキーの組を直接記述しています。実際のキーをこのように保存すると、ユーザーデータとプレイブックにシークレットが残ります。

変更後

yaml
- name: start an instance
  community.aws.ec2_instance:
    name: credential-example
    image_id: "{{ ami_id }}"
    instance_type: "{{ instance_type }}"
    vpc_subnet_id: "{{ subnet_id }}"
    iam_instance_profile: "{{ instance_profile_name }}"

キーを埋め込む代わりにインスタンスプロファイルを関連付けます。アプリケーションが一時的な認証情報を使用し、必要な権限だけを持つことを確認してください。この変更だけで漏えい済みのキーが失効するわけではありません。

参考資料