[AWS](WA)WAF 保護を備えた CloudFront

AWS

元ネタ

AWSのWell-Architected Frameworkを改めて整理。せっかくなんでハンズオン形式で学べるAWS Well-Architected Labsをやってみよう!ということで、備忘も兼ねて実践&記録をしてみました。

Workshop Studio
Discover and participate in AWS workshops and GameDays

前提条件

  • AWSアカウントがあること

ハンズオン開始

0. 概要

このハンズオンでは、Amazon CloudFront と AWS ウェブ アプリケーション ファイアウォール (WAF) を使用してネットワーク ベースの攻撃からワークロードを保護する手順を実施します。 AWS マネジメントコンソールと AWS CloudFormation を使用して、WAF 統合を備えた CloudFront をデプロイして多層防御方法を適用する方法を実施します。

1. EC2インスタンスの作成

WebアプリケーションとなるEC2インスタンスを作成します。

EC2インスタンス作成手順

  1. EC2コンソールより「インスタンスの起動」を選択する。
  1. 「名前とタグ」の「名前」に適切な名前を入力する。
  1. 「Application and OS Images」は「Amazon Linux 2023 AMI」を選択する。(デフォルト)
  1. 「インスタンスタイプ」は「t2.micro」を選択する。(デフォルト)
  1. 「キーペア(ログイン)」には、あれば既存のキーペアを選択。なければ「新しいキーペアの作成」を選択する。
  1. 「キーペアを作成」では、「キーペア名」を入力、「キーペアのタイプ」に「ED25519」を選択、「プライベートキーファイル形式」は使用しているツールによって選択し、「キーペアを作成」を選択する。
  1. 「ネットワーク設定」では「Allow SSH traffic from」に「自分のIP」を選択し、「インターネットからのHTTPトラフィックを許可」のチェックボックスをオンにする。
  1. 「ストレージを設定」はデフォルトのまま。
  1. 「高度な詳細」を開く。
  1. 「IAMインスタンスプロフィール」で「新しいIAMプロファイルの作成」を選択する。(ブラウザに別タブが開く。
  1. 「ロールを作成」を選択する。
  1. 「信頼されたエンティティタイプ」に「AWSのサービス」を、「ユースケース」の「サービスまたはユースケース」に「EC2」を選択した上で、ユースケースは「EC2」を選択し、「次へ」を選択する。
  1. 「許可ポリシー」の検索入力ボックスに「s3」を入力する。ポリシーの一覧から「AmazonS3ReadOnlyAccess」の右のチェックボックスをオンにし、「次へ」を選択する。
  1. 「ロールの詳細」の「ロール名」に「ec2-s3-read-only-role」を入力する。
  1. 「ロールを作成」を選択する。
  1. 作成完了のメッセージを確認する。
  1. 元タブのEC2インスタンス作成にて「IAMインスタンスプロフィール」に作成したロール「ec2-s3-read-only-role」を選択する。
  1. 「ユーザーデータ」に以下を入力する。
#!/bin/bash
yum update -y
yum install -y httpd
service httpd start
chkconfig httpd on
groupadd www
usermod -a -G www ec2-user
chown -R root\:www /var/www
chmod 2775 /var/www
find /var/www -type d -exec chmod 2775 {} +
find /var/www -type f -exec chmod 0664 {} +
  1. 「インスタンスを起動」を選択する。
  1. 開始のメッセージを確認する。
  1. インスタンス一覧より作成したインスタンスのステータスチェックが完了するのを確認する。
  1. 作成したインスタンスの詳細を開き、概要の右側にある「パブリック IPv4 DNS」のドメイン名を予めコピーする。

2. AWS WAFを設定する

CloudFormationを使ってWAFを構成します。

CloudFormationによるWAF作成手順

  1. CloudFormationコンソールを開き、「スタックの作成」より「新しいリソースを使用(標準)」を選択する。
  1. 「前提条件ーテンプレートの準備」の「テンプレートの準備」では「テンプレートの準備完了」、「テンプレートの指定」の「テンプレートソース」に「Amazon S3 URL」を選択の上、「Amazon S3 URL」に以下を貼り付け、「次へ」を選択する。
https://s3-us-west-2.amazonaws.com/aws-well-architected-labs/Security/Code/waf-global.yaml
  1. 「スタック名」に「waf」を入力する。
  1. 「パラメータ」は以下の表を参考に入力する。(全てデフォルトのままでOK)
項目名説明入力値(デフォルト)
WAFNameこのスタックのリソースとエクスポート名に使用するベース名を入力します。たとえば、WAF は Lab1-ManualBlacklistIPRule1 などのベース名と組み合わせたエクスポート名を作成します。Lab1
WAFCloudWatchPrefix各ルールに使用する CloudWatch プレフィックスの名前を入力します (英数字のみ)Lab1
WAFManualBlacklistIPRule1Name作成された WAFManualBlacklistIPRule1 リソースの CloudFormation リソース名ManualBlacklistIPRule1
WAFManualBlacklistIPSet1Name作成された WAFManualBlacklistIPSet1 リソースの CloudFormation リソース名ManualBlacklistIPSet1
WAFUserAgentBlacklistRule1Name作成された WAFUserAgentBlacklistRule1 リソースの CloudFormation リソース名UserAgentBlacklistRule1
WAFUserAgentByteSet1Tuple1Stringユーザー エージェント ブラックリスト ルールに含める文字列を入力し、必要に応じてパディングの例の名前を変更し、カンマ区切りの値が合計 10 個あることを確認します。長いため割愛
WAFUserAgentBlacklistSet1Name作成された WAFUserAgentBlacklistSet1 リソースの CloudFormation リソース名UserAgentBlacklistSet1
WAFManualBlacklistIPRule1NameインポートするManualBlacklistIPRuleの名前を入力してください。値が空の場合はルールは作成されません。ManualBlacklistIPRule1
WAFManualBlacklistIPRule1ActionCOUNTか、BLOCKCOUNT
WAFManualBlacklistUserAgentRule1NameインポートするManualBlacklistUserAgentRuleの名前を入力してください。値が空の場合はルールは作成されません。UserAgentBlacklistRule1
WAFManualBlacklistUserAgentRule1ActionCOUNTか、BLOCKCOUNT
WAFSqlInjectionProtectionParam一般的な SQL インジェクション攻撃をブロックするように設計されたコンポーネントを有効にするには、「Yes」を選択します。Yes
WAFSqlInjectionExceptionByteSet1ParamYesか、NoYes
WAFSqlInjectionProtectionActionCOUNTか、BLOCKCOUNT
WAFSqlInjectionExceptionByteSet1Tuple1TypeHEADER、METHOD、QUERY_STRING、URI、BODYのいずれかURI
WAFSqlInjectionExceptionByteSet1Tuple1StringSQL インジェクション ルールから除外する文字列を入力し、必要に応じてパディングの例の名前を変更し、カンマ区切りの値が合計 10 個あることを確認します。長いため割愛
WAFSqlInjectionExceptionByteSet1Tuple1TransformCMD_LINE、COMPRESS_WHITE_SPACE、HTML_ENTITY_DECODE、LOWERCASE、URL_DECODE、NONEのいずれかNONE
WAFSqlInjectionExceptionByteSet1Tuple1PositionCONTAINS、CONTAINS_WORD、EXACTLY、STARTS_WITH、ENDS_WITHのいずれかCONTAINS
WAFSqlInjectionExceptionByteSet1Tuple1DataHEADER に設定されている場合のバイト一致タイプの値User-Agent
WAFXssProtectionParam一般的な XSS 攻撃をブロックするように設計されたコンポーネントを有効にするには、[Yes] を選択します。Yes
WAFXssExceptionByteSet1ParamYesか、NoYes
WAFXssProtectionActionCOUNTか、BLOCKCOUNT
WAFXssExceptionByteSet1Tuple1TypeHEADER、METHOD、QUERY_STRING、URI、BODYのいずれかURI
WAFXssExceptionByteSet1Tuple1StringXss ルールから除外する文字列を入力し、必要に応じてパディングの例の名前を変更し、カンマ区切りの値が合計 10 個あることを確認します。長いため割愛
WAFXssExceptionByteSet1Tuple1TransformCMD_LINE、COMPRESS_WHITE_SPACE、HTML_ENTITY_DECODE、LOWERCASE、URL_DECODE、NONEのいずれかNONE
WAFXssExceptionByteSet1Tuple1PositionCONTAINS、CONTAINS_WORD、EXACTLY、STARTS_WITH、ENDS_WITHのいずれかCONTAINS
WAFXssExceptionByteSet1Tuple1DataHEADER に設定されている場合のバイト一致タイプの値User-Agent
WAFSizeProtectionParamURI およびクエリ文字列における一般的なオーバーフロー攻撃をブロックするように設計されたコンポーネントを有効にするには、[Yes] を選択します。Yes
WAFSizeExceptionByteSet1ParamYesか、NoYes
WAFSizeProtectionActionCOUNTか、BLOCKCOUNT
WAFSizeURI1URI の最大サイズ (バイト単位) (最大 8192)512
WAFSizeQuery1クエリ文字列の最大サイズ (バイト単位) (最大 8192)512
WAFSizeCookie1Cookie ヘッダーの最大サイズ (バイト単位) (最大 4096)。 サイズは、Web アプリケーションが Cookie に保存する情報の量によって決まります。 セッション トークンを Cookie 経由でのみ渡す場合は、サイズをセッション トークンと Cookie メタデータのシリアル化されたサイズ以下に設定します。4096
WAFSizeExceptionByteSet1Tuple1TypeHEADER、METHOD、QUERY_STRING、URI、BODYのいずれかURI
WAFSizeExceptionByteSet1Tuple1Stringサイズ制限ルールから除外する文字列を入力し、必要に応じてパディングの例の名前を変更し、カンマ区切りの値が合計 10 個あることを確認します。長いため割愛
WAFSizeExceptionByteSet1Tuple1TransformCMD_LINE、COMPRESS_WHITE_SPACE、HTML_ENTITY_DECODE、LOWERCASE、URL_DECODE、NONEのいずれかNONE
WAFSizeExceptionByteSet1Tuple1PositionCONTAINS、CONTAINS_WORD、EXACTLY、STARTS_WITH、ENDS_WITHのいずれかCONTAINS
WAFSizeExceptionByteSet1Tuple1DataHEADER に設定されている場合のバイト一致タイプの値User-Agent
WAFBlacklistByteSet1ProtectionParam[Yes] を選択すると、コンポーネントが汎用バイト一致文字列をブロックできるようになります。Yes
WAFBlacklistByteSet1ProtectionActionCOUNTか、BLOCKCOUNT
WAFBlacklistByteSet1Tuple1TypeHEADER、METHOD、QUERY_STRING、URI、BODYのいずれかHEADER
WAFBlacklistByteSet1Tuple1Stringバイト セット 1 ルールで拒否される文字列を入力します。追加には関連するバイト セットを更新する必要があります。必要に応じてサンプル パディングの名前を変更し、カンマ区切りの値が合計 10 個あることを確認します。長いため割愛
WAFBlacklistByteSet1Tuple1TransformCMD_LINE、COMPRESS_WHITE_SPACE、HTML_ENTITY_DECODE、LOWERCASE、URL_DECODE、NONEのいずれかLOWERCASE
WAFBlacklistByteSet1Tuple1PositionCONTAINS、CONTAINS_WORD、EXACTLY、STARTS_WITH、ENDS_WITHのいずれかCONTAINS
WAFBlacklistByteSet1Tuple1DataHEADER に設定されている場合のバイト一致タイプの値User-Agent
  1. 「次へ」を選択する。
  2. 「スタックオプションの設定」もデフォルトのままで「次へ」を選択する。
  1. 「レビュー」にて内容を確認する。
  1. 「送信」を選択する。
  1. 「ステータス」が「CREATE_IN_PROGRESS」から「CREATE_COMPLETE」に変わるまで待つ。

3. CloudFrontを構成する

作成したEC2、WAFを元にCloudFrontを構成します。

CloudFront構成手順

  1. CloudFrontコンソールより「CloudFrontディストリビューションを作成」選択する。
  1. 「オリジン」の「オリジンドメイン」に作成したEC2の詳細でコピーした「パブリック IPv4 DNS」を貼り付け、「プロトコル」に「HTTPのみ」を選択する。
  1. 「キャッシュキーとオリジンリクエスト」の「キャッシュポリシー」で「CachingOptimized」を選択する。
  1. 「ウェブアプリケーションファイアウォール(WAF)」で「セキュリティ保護を有効にする」を選択し、「既存のWAF設定」にチェックを入れ、「ウェブACLを選択」にて作成したWAFを選択する。
  1. 「ディストリビューションを作成」を選択する。
  1. 作成のメッセージを確認する。
  1. 作成したディストリビューションの詳細を確認し、「最終変更日」が「デプロイ」から日時に変わるのを待つ。
  1. 「ディストリビューションドメイン名」をコピーし、ブラウザのURLに貼り付け、WEBアプリケーションが応答することを確認する。

Appendix. クリーンアップ手順

作成したリソースのクリーンアップ手順です。

CloudFrontの削除手順

  1. CloudFrontコンソールより「ディストリビューション」を開き、対象のディストリビューションをオンにした上で「無効」を選択する。
  1. 「ディストリビューションを無効にしますか?」にて「無効」を選択する。
  1. 「ステータス」が「無効」であることを確認し、最終変更日が「デプロイ」から日時に変わるまで待つ。
  1. 対象のディストリビューションをオンにした上で「削除」を選択する。
  2. 「ディストリビューションを削除しますか?」にて「削除」を選択する。
  1. 削除メッセージを確認する。

WAF(CloudFormation)の削除手順

  1. CloudFormationコンソールよりスタックを開き、対象スタックをオンにした上で「削除」を選択する。
  1. 「スタックを削除しますか?」にて「削除」を選択する。
  1. 削除開始のメッセージを確認する。
  1. リストから削除されるまで待つ。

EC2インスタンスの削除手順

  1. EC2コンソールよりインスタンスを開き、対象のインスタンスをオンにした上で、「インスタンスの状態」から「インスタンスの終了」を選択する。
  1. 「終了インスタンス?」にて「終了」を選択する。
  1. 終了メッセージを確認する。
  1. 「終了済み」になるまで待つ。

不要になったインスタンスは削除できます。これは、インスタンスの終了 と呼ばれます。インスタンスの状態が shutting-down または terminated に変わったら、そのインスタンスへの課金は停止します。

インスタンスを削除した後に、接続または起動することはできません。ただし、同じ AMI から別のインスタンスを起動することができます。

インスタンスの削除後、インスタンスはしばらくの間コンソールに表示されたままですが、エントリは自動的に削除されます。終了したインスタンスのエントリを自分で削除することはできません。インスタンスを削除すると、タグやボリュームなどのリソースはインスタンスから徐々に関連付けが解除され、しばらくすると削除されたインスタンスでこれらのリソースが表示されなくなる可能性があります。

インスタンスが終了すると、そのインスタンスに関連付けられたすべてのインスタンスストアボリュームのデータが削除されます。

デフォルトでは、インスタンスの削除時に Amazon EBS のルートデバイスボリュームが自動的に削除されます。ただし、起動時にアタッチした追加の EBS ボリューム、または既存のインスタンスにアタッチした EBS ボリュームがある場合、デフォルトでは、インスタンスの削除後もそれらのボリュームは保持されます。この動作はボリュームの DeleteOnTermination 属性によって制御されますが、変更できます。

タイトルとURLをコピーしました