Amazon Q Developer CLIにAWSアカウントを調査・操作させてみた

Amazon Q Developer CLIにAWSアカウントを調査・操作させてみた

Clock Icon2025.07.11

大阪オフィスの小倉です。

今回はAmazon Q Developer CLIを使って、普段使用しているAWSアカウントを調査・操作してみました。

今回やってみたのは、

  • CloudFormationスタックからAWS構成図の作成
  • CloudFrontアクセスログからWAFルールの作成

の2つです。

準備

実行環境はAmazon Q Developer CLIがインストールされていればどこでも良いのですが、
今回は以下のブログのVisual Studio Code Server環境で動かしてみました。

私は普段、手元のMacから一時クレデンシャルでAWSアカウントにアクセスしていて、
一定時間経過するとクレデンシャルが期限切れになりますが、Code Server環境ではその心配がありません。

https://dev.classmethod.jp/articles/aws-vscode-server-workshop-setup-review/

Amazon Q Developer CLIのインストール

作成したCode Server環境で使われるAMIはubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-20250627だったので、
以下のページの手順に従ってインストールしました。

https://docs.aws.amazon.com/ja_jp/amazonq/latest/qdeveloper-ug/command-line-installing.html#command-line-installing-ubuntu

Code Serverのターミナルで、以下のコマンドを順に実行するだけです。

# ダウンロード
wget https://desktop-release.q.us-east-1.amazonaws.com/latest/amazon-q.deb
# インストール
sudo apt-get install -f
sudo dpkg -i amazon-q.deb

今回インストールされたバージョンは1.12.4でした。

q を実行して You are not logged inが返ってくれば、インストールは成功しています。

ubuntu@dev:~/environment$ q
error: You are not logged in, please log in with q login

AWS Builders IDの作成

AWS Builders IDを作成していれば無料でAmazon Q Developer CLIは利用できるので、
もし作成していなければ、https://profile.aws.amazon.com/ でメールアドレスを登録し作成してください。

https://docs.aws.amazon.com/ja_jp/signin/latest/userguide/create-aws_builder_id.html

ログイン

Code Serverのターミナルでq loginを入力すると、Select methodを問われます。
Use for Free with Builder IDを選択すると、認証用のURLが表示されます。

ubuntu@dev:~/environment$ q login
✔ Select login method · Use for Free with Builder ID

Confirm the following code in the browser
Code: XXXX-XXXX

Open this URL: https://view.awsapps.com/start/#/device?user_code=XXXX-XXXX
▰▱▱▱▱▱▱ Logging in...

手元のマシンのブラウザでURLにアクセスし、作成したBuilders IDでログインし、画面の指示に従って進めます。

Code Server側のターミナルの表示が変われば完了です。

Open this URL: https://view.awsapps.com/start/#/device?user_code=XXXX-XXXX
Device authorized
Logged in successfully

AWS構成図の作成

まず、実行中のCode Server環境について調査させてみます。

q chatで対話モードになり、以下の指示を入力しました。

東京リージョンのCodeServerスタックの内容を調べ、drawio形式でAWS構成図を作成してください

Q CLIが回答を作成する中で、

Allow this action? Use 't' to trust (always allow) this tool for the session. [y/n/t]:

の形式で実行許可を求められる場合がありますが、今回は全てy(yes)を入力して進めていきます。

今回の最終回答は以下のようなものでした。出力された値はXでマスクしています。

> 東京リージョンのVSCodeServerスタックの構成を調査し、draw.io形式のAWS構成図を作成しました。

## 構成の概要

VSCodeServerスタックは以下の主要コンポーネントで構成されています:

### ネットワーク構成
• **VPC**: vpc-XXXXXXXXXXXXXXXXX (10.0.0.0/16)
• **Internet Gateway**: igw-XXXXXXXXXXXXXXXXX
• **パブリックサブネット**: 
  • AZ 1a: subnet-XXXXXXXXXXXXXXXXX (10.0.1.0/24)
  • AZ 1c: subnet-XXXXXXXXXXXXXXXXX (10.0.2.0/24)
• **プライベートサブネット**:
  • AZ 1a: subnet-XXXXXXXXXXXXXXXXX (10.0.3.0/24)
  • AZ 1c: subnet-XXXXXXXXXXXXXXXXX (10.0.4.0/24)

### コンピューティング
• **EC2インスタンス**: i-XXXXXXXXXXXXXXXXX (c7i.large)
  • VSCode Server (code-server) が動作
  • プライベートIP: 10.0.1.175
  • パブリックIP: XX.XXX.XX.XXX (Elastic IP)

### セキュリティ
• **セキュリティグループ**: CloudFrontからのHTTPアクセスのみ許可
• **IAMロール**: EC2インスタンス用のプロファイル
• **キーペア**: ws-default-keypair

### その他のサービス
• **CloudFront**: グローバル配信とセキュリティ強化
• **Secrets Manager**: VSCode Serverのパスワード管理
• **S3バケット**: SSMセッションログの保存
• **SSM Document**: インスタンスのブートストラップ
• **Lambda関数**: S3バケットクリーンアップ用カスタムリソース

### アクセスフロー
1. ユーザーがCloudFrontディストリビューション経由でアクセス
2. CloudFrontがEC2インスタンスのパブリックIPにHTTPリクエストを転送
3. EC2インスタンス上のVSCode Serverがリクエストを処理

この構成により、セキュアで高可用性なVSCode Server環境が提供されています。作成したdraw.ioファイル(vscode-server-architecture.drawio)をdraw.ioで開いて、詳細な構成図を確
認できます。

作成されたdrawioのファイルを開くと、以下のような構成図になっていました。

vscode-drop-1752212919589-gl8lyfkhvid.png

アイコンの配置により若干見づらい部分もありますが、細かい部分は手動で修正すればよいですし、 一つの指示でこれだけ作ってくれるのは便利ですね。

CloudFrontアクセスログからWAFルールの作成

CloudFrontのアクセスログを分析し、不正なリクエストをブロックするWAFルールを作成させてみました。

下準備

対象となるCloudFrontの環境は、以下のテンプレートで作成しました。

  • CloudFront + S3 + OAC
  • CloudFrontアクセスログをS3バケットに出力
  • HTTPステータスコード403,404用にカスタムエラーレスポンスを設定
準備用CloudFormationテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'S3 + CloudFront Static Website Hosting with S3 Access Logs'

Parameters:
  BucketNamePrefix:
    Type: String
    Description: 'S3 bucket name prefix for hosting website'
    Default: 'static-website'

Resources:
  # S3 Bucket for static website content
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub '${BucketNamePrefix}-${AWS::AccountId}-${AWS::Region}'
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true

  # S3 Bucket for CloudFront access logs
  LogBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub '${BucketNamePrefix}-logs-${AWS::AccountId}-${AWS::Region}'
      OwnershipControls:
        Rules:
          - ObjectOwnership: BucketOwnerPreferred
      PublicAccessBlockConfiguration:
        BlockPublicAcls: false
        BlockPublicPolicy: true
        IgnorePublicAcls: false
        RestrictPublicBuckets: true
      LifecycleConfiguration:
        Rules:
          - Id: DeleteOldLogs
            Status: Enabled
            ExpirationInDays: 90

  # S3 Bucket Policy for CloudFront
  S3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref S3Bucket
      PolicyDocument:
        Statement:
          - Sid: AllowCloudFrontServicePrincipalReadOnly
            Effect: Allow
            Principal:
              Service: cloudfront.amazonaws.com
            Action: 's3:GetObject'
            Resource: !Sub '${S3Bucket.Arn}/*'
            Condition:
              StringEquals:
                'AWS:SourceArn': !Sub 'arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}'

  # CloudFront Origin Access Control
  CloudFrontOriginAccessControl:
    Type: AWS::CloudFront::OriginAccessControl
    Properties:
      OriginAccessControlConfig:
        Name: !Sub '${BucketNamePrefix}-${AWS::AccountId}-OAC'
        OriginAccessControlOriginType: s3
        SigningBehavior: always
        SigningProtocol: sigv4

  # CloudFront Distribution
  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Origins:
          - Id: S3Origin
            DomainName: !GetAtt S3Bucket.RegionalDomainName
            S3OriginConfig:
              OriginAccessIdentity: ''
            OriginAccessControlId: !GetAtt CloudFrontOriginAccessControl.Id
        Enabled: true
        DefaultRootObject: index.html
        DefaultCacheBehavior:
          TargetOriginId: S3Origin
          ViewerProtocolPolicy: redirect-to-https
          AllowedMethods:
            - GET
            - HEAD
          CachedMethods:
            - GET
            - HEAD
          Compress: true
          ForwardedValues:
            QueryString: false
            Cookies:
              Forward: none
        CustomErrorResponses:
          - ErrorCode: 403
            ResponseCode: 403
            ResponsePagePath: /403.html
            ErrorCachingMinTTL: 300
          - ErrorCode: 404
            ResponseCode: 404
            ResponsePagePath: /404.html
            ErrorCachingMinTTL: 300
        PriceClass: PriceClass_100
        HttpVersion: http2
        Logging:
          Bucket: !GetAtt LogBucket.DomainName
          Prefix: cloudfront-logs/
          IncludeCookies: false

Outputs:
  CloudFrontDomainName:
    Description: 'CloudFront Distribution Domain Name'
    Value: !GetAtt CloudFrontDistribution.DomainName
  CloudFrontDistributionId:
    Description: 'CloudFront Distribution ID'
    Value: !Ref CloudFrontDistribution
  S3BucketName:
    Description: 'S3 Bucket Name for website content'
    Value: !Ref S3Bucket
  LogBucketName:
    Description: 'S3 Bucket Name for access logs'
    Value: !Ref LogBucket

s3-cloudfront-static-website.yamlという名前でファイルに保存し、Code Server環境にアップロードした後、
以下のコマンドを使って自分で東京リージョンにデプロイしておきます。

※ S3バケット名がユニークになるように、BucketNamePrefixの値は任意のもので差し替えてください。

aws cloudformation deploy \
  --template-file s3-cloudfront-static-website.yaml \
  --stack-name my-static-website-stack \
  --parameter-overrides BucketNamePrefix=cm-ogura \
  --capabilities CAPABILITY_IAM \
  --region ap-northeast-1

CloudFrontを作成するので、デプロイに10分程かかります。

コンテンツの作成と表示確認

CloudFrontで公開するHTMLファイルを作成してもらいます。

まず、デプロイ済みのスタックのことをQ CLIに把握してもらうため、q chatで以下の指示を入力しました。

東京リージョンのs3-cloudfront-static-websiteスタックを確認してください。このスタックはローカルにあるs3-cloudfront-static-website.yamlから作成されています。

Q CLIの応答末尾は以下でした。

> ## スタック確認結果

東京リージョン(ap-northeast-1)のmy-static-website-stackスタックの状況は以下の通りです:

### スタック基本情報
• **ステータス**: CREATE_COMPLETE(正常に作成完了)
• **作成日時**: 2025-07-11 01:21:02 UTC
• **最終更新**: 2025-07-11 01:21:08 UTC
• **パラメータ**: BucketNamePrefix = "cm-ogura"

### 作成されたリソース
1. S3バケット(メインコンテンツ)
   • バケット名: cm-ogura-XXXXXXXXXXXX-ap-northeast-1
   • 静的ウェブサイトのコンテンツを格納

2. S3バケット(ログ用)
   • バケット名: cm-ogura-logs-XXXXXXXXXXXX-ap-northeast-1
   • CloudFrontのアクセスログを格納

3. CloudFront Distribution
   • Distribution ID: XXXXXXXXXXXXXX
   • ドメイン名: XXXXXXXXXXXXX.cloudfront.net

4. CloudFront Origin Access Control
   • ID: XXXXXXXXXXXXXX
   • S3バケットへの安全なアクセスを制御

5. S3バケットポリシー
   • CloudFrontからのアクセスのみを許可

### 主要な出力値
• **CloudFrontドメイン**: XXXXXXXXXXXXX.cloudfront.net
• **メインS3バケット**: cm-ogura-XXXXXXXXXXXX-ap-northeast-1
• **ログS3バケット**: cm-ogura-logs-XXXXXXXXXXXX-ap-northeast-1

すべてのリソースが正常に作成されており、静的ウェブサイトホスティングの準備が完了しています。CloudFrontのドメイン名を使用してウェブサイトにアクセスできます。

スタックの内容を読めていそうですね。

引き続き、HTMLファイルを作成してもらいます。
Q CLIがCloudFormationテンプレートの内容を把握していれば、テンプレートに記述のあるindex.html403.htmlを勝手に作ってくれると期待しています。

このテンプレートに必要なサンプルHTMLファイルを作成してください。アップロードは後で行います。
(省略)

> ## 作成完了!

CloudFormationテンプレートに対応したサンプルHTMLファイルを作成しました:

### 📁 作成されたファイル一覧

1. index.html - メインページ
   • ウェブサイトのホームページ
   • 使用技術やアーキテクチャの紹介
   • レスポンシブデザイン対応

2. 403.html - アクセス拒否エラーページ
   • 権限エラー時に表示
   • ユーザーフレンドリーなエラー説明
   • ホームへの誘導リンク

3. 404.html - ページ未発見エラーページ
   • 存在しないページアクセス時に表示
   • 検索ボックス付き
   • サイト内ナビゲーション提案

4. about.html - サイト概要ページ
   • アーキテクチャの詳細説明
   • 技術仕様とセキュリティ機能
   • パフォーマンス統計

5. contact.html - お問い合わせページ
   • 複数の連絡方法を提示
   • お問い合わせフォーム(デモ用)
   • FAQ セクション

### 🎨 デザインの特徴

• **統一されたデザイン**: 全ページで一貫したカラーテーマとレイアウト
• **レスポンシブ対応**: モバイルデバイスでも適切に表示
• **アクセシビリティ**: 読みやすいフォントとコントラスト
• **モダンなUI**: グラデーション背景とカードレイアウト

### 📤 次のステップ

これらのファイルをS3バケット(cm-ogura-XXXXXXXXXXXX-ap-northeast-1)にアップロードすれば、CloudFrontドメイン(XXXXXXXXXXXXX.cloudfront.net)でウェブサイトが表示されます
。

アップロードの際は、以下のコマンドが使用できます:
bash
aws s3 sync . s3://cm-ogura-XXXXXXXXXXXX-ap-northeast-1 --exclude "*.yaml" --exclude "*.deb"

index.html403.htmlの他にも勝手にHTMLを作ってくれました。

アップロードもしてもらいます。

作成したHTMLをアップロードしてください
> ## ✅ アップロード完了!

HTMLファイルのアップロードが正常に完了しました。

### 📤 アップロードされたファイル
• **index.html** (4,523 bytes) - メインページ
• **403.html** (3,952 bytes) - アクセス拒否エラーページ
• **404.html** (5,666 bytes) - ページ未発見エラーページ
• **about.html** (8,353 bytes) - サイト概要ページ
• **contact.html** (10,855 bytes) - お問い合わせページ

### 🌐 ウェブサイトへのアクセス

ウェブサイトは以下のURLでアクセスできます:
• **メインサイト**: https://XXXXXXXXXXXXX.cloudfront.net
• **サイト概要**: https://XXXXXXXXXXXXX.cloudfront.net/about.html
• **お問い合わせ**: https://XXXXXXXXXXXXX.cloudfront.net/contact.html

### 🔄 キャッシュ無効化

CloudFrontのキャッシュ無効化も実行しました:
• **無効化ID**: XXXXXXXXXXXXXXXXXXXXXXXXXX
• **ステータス**: InProgress
• **対象**: 全ファイル (/*)

キャッシュ無効化は通常数分で完了し、その後新しいコンテンツが世界中のエッジロケーションで利用可能になります。

### 🎉 次のステップ

1. ウェブサイトの確認: 上記URLにアクセスしてサイトが正常に表示されることを確認
2. エラーページのテスト: 存在しないページにアクセスして404ページが表示されることを確認
3. コンテンツの更新: 必要に応じてHTMLファイルを編集し、再度アップロード

静的ウェブサイトの構築とデプロイが完了しました!

CloudFrontのキャッシュも処理してくれたようです。
アップロードが完了したら、手元のPCのブラウザでCloudFrontのURLを開きます。index.htmlが表示されればOKです。

vscode-drop-1752213020080-otq1mbvj6xm.png
実際に表示されたindex.html

攻撃リクエストからWAFの作成

手元のPCのブラウザを使い、以下のURLで数回アクセスしておきます。
これらには不正アクセスとみなされる文字列が含まれています。 後でQ CLIに分析させるため、アクセスログに記録させます。

# search=test' OR 1=1--  を付与している
https://<your-cloudfront-domain>/?search=test'%20OR%201%3D1--

# name=<script>alert('xss')</script>  を付与している
https://<your-cloudfront-domain>/?name=%3Cscript%3Ealert('xss')%3C%2Fscript%3E

# id=1 UNION SELECT username,password FROM users  を付与している
https://<your-cloudfront-domain>/?id=1%20UNION%20SELECT%20username%2Cpassword%20FROM%20users

しばらく待つと、アクセスログ用のS3バケットにログファイルが出力されてきます。
(今回は5分くらいで出力されましたが、もっと時間がかかる場合もあります)

vscode-drop-1752213072314-xk61ppjlb39.png

ログファイルが出力されたことを確認したら、Q CLIに分析を依頼します。

AWS WAFの作成を検討しています。CloudFrontのアクセスログを確認し、不正なリクエストがあれば、その種類を教えて下さい
(省略)
> ## 🚨 CloudFrontアクセスログ分析結果

CloudFrontのアクセスログを分析した結果、**複数の不正なリクエスト**が検出されました。AWS WAFの導入を強く推奨します。

### 🔍 検出された攻撃の種類

#### 1. SQLインジェクション攻撃 (2件)
• **パターン1**: search=test' OR 1=1--
  • 典型的なSQLインジェクション攻撃
  • 認証バイパスを試行

• **パターン2**: id=1 UNION SELECT username,password FROM users
  • UNION-based SQLインジェクション
  • データベースからユーザー情報の抽出を試行

#### 2. クロスサイトスクリプティング (XSS) 攻撃 (1件)
• **パターン**: name=<script>alert('xss')</script>
  • Stored/Reflected XSS攻撃
  • JavaScriptコードの実行を試行

### 📊 攻撃の詳細情報

• **攻撃元IP**: XXX.XX.X.XX
• **攻撃時間**: 2025-07-11 02:25:24 - 02:25:57 UTC (約33秒間)
• **User-Agent**: Chrome 138.0.0.0 (Mac OS X)
• **攻撃回数**: 合計3種類の攻撃パターン、複数回実行
• **レスポンス**: 200/304 (攻撃は成功していないが、リクエストは処理された)

### 🛡️ AWS WAF推奨ルール

以下のAWS WAFルールの実装を推奨します:

#### 1. SQLインジェクション対策
• **AWS Managed Rule**: AWSManagedRulesSQLiRuleSet
• **カスタムルール**: UNION、SELECT、OR、--などのキーワード検出

#### 2. XSS攻撃対策
• **AWS Managed Rule**: AWSManagedRulesCommonRuleSet
• **カスタムルール**: <script>、javascript:、onerrorなどの検出

#### 3. レート制限
• **IP-based Rate Limiting**: 同一IPからの短時間での大量リクエストを制限
• **推奨設定**: 5分間で100リクエスト以上をブロック

#### 4. 地理的制限
• 必要に応じて特定の国・地域からのアクセスを制限

### 🚀 次のステップ

1. AWS WAFの即座の導入を推奨
2. CloudWatch Alarmsの設定で攻撃の早期検出
3. AWS Shield Advancedの検討(DDoS対策)
4. 定期的なログ分析の自動化

この攻撃パターンは一般的なウェブアプリケーション攻撃の典型例であり、AWS WAFによる保護が効果的です。

SQLインジェクションやXSSになるリクエストがあると回答してくれました。

これらを防ぐAWS WAFを作ってもらいましょう。

AWS WAFマネージドルールを作成するCloudFormationテンプレートを新規に作成してください。
検出された攻撃をブロックするマネージドルールを設定した、最小構成のテンプレートを作成してください。
- ログ出力は不要
- IP制限、レート制限への対応は不要
- CloudFrontとの関連付けは後で行うため考慮不要

WAFルールの確認だけしたいので、ログ出力は不要と指示しました。
また、親切にIP制限なども入れてくれることがありますが、一旦不要にしています。

出力末尾は以下になりました

(省略)
> ## ✅ AWS WAF マネージドルール CloudFormationテンプレート作成完了

検出された攻撃(SQLインジェクション、XSS)をブロックするAWS WAFマネージドルールのCloudFormationテンプレートを作成しました。

### 📁 作成されたファイル

1. aws-waf-managed-rules.yaml - メインのCloudFormationテンプレート
2. WAF-README.md - 詳細な説明とデプロイ手順

### 🛡️ 実装されるセキュリティ対策

#### **Priority 1: AWSManagedRulesSQLiRuleSet**
• 検出された攻撃: test' OR 1=1-- と UNION SELECT 攻撃をブロック
• SQLインジェクション全般を防御

#### **Priority 2: AWSManagedRulesCommonRuleSet**
• 検出された攻撃: <script>alert('xss')</script> 攻撃をブロック
• XSS攻撃全般を防御
• 静的サイト用に一部ルールを除外して誤検知を防止

#### **Priority 3: AWSManagedRulesKnownBadInputsRuleSet**
• 既知の悪意のある入力パターンを防御
• 追加のセキュリティ層を提供

### 🚀 デプロイ手順

重要: WAF for CloudFrontは必ず us-east-1 リージョンで作成してください。

bash
# 1. WAFスタックの作成
aws cloudformation create-stack \
  --stack-name my-waf-stack \
  --template-body file://aws-waf-managed-rules.yaml \
  --region us-east-1

# 2. 作成完了の確認
aws cloudformation describe-stacks \
  --stack-name my-waf-stack \
  --region us-east-1

### 📊 期待される効果

• **SQLインジェクション攻撃**: 100%ブロック
• **XSS攻撃**: 100%ブロック
• **既知の悪意のある攻撃**: 大幅に軽減
• **誤検知**: 最小限(静的サイト用に最適化済み)

### 💰 料金概算

• **月額約$2.80** + リクエスト料金
• WebACL: $1.00/月
• ルール3つ: $1.80/月
• リクエスト: $0.60/100万リクエスト

このテンプレートにより、検出された攻撃パターンを効果的にブロックし、ウェブサイトのセキュリティを大幅に向上させることができます。

WAFを作成するCloudFormationテンプレートを作成してくれました。

実際にAmazon Q Developer CLIが作成したCloudFormationテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'AWS WAF with Managed Rules for SQL Injection and XSS Protection'

Parameters:
  WebACLName:
    Type: String
    Description: 'Name for the WAF WebACL'
    Default: 'static-website-waf'

Resources:
  # AWS WAF WebACL
  WebACL:
    Type: AWS::WAFv2::WebACL
    Properties:
      Name: !Ref WebACLName
      Description: 'WAF WebACL for static website protection against SQL injection and XSS attacks'
      Scope: CLOUDFRONT
      DefaultAction:
        Allow: {}
      Rules:
        # AWS Managed Rule - SQL Injection Protection
        - Name: AWSManagedRulesSQLiRuleSet
          Priority: 1
          OverrideAction:
            None: {}
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesSQLiRuleSet
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: AWSManagedRulesSQLiRuleSetMetric

        # AWS Managed Rule - Cross-Site Scripting (XSS) Protection
        - Name: AWSManagedRulesCommonRuleSet
          Priority: 2
          OverrideAction:
            None: {}
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesCommonRuleSet
              ExcludedRules:
                # Exclude rules that might cause false positives for static websites
                - Name: SizeRestrictions_BODY
                - Name: GenericRFI_BODY
                - Name: GenericRFI_QUERYARGUMENTS
                - Name: GenericRFI_URIPATH
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: AWSManagedRulesCommonRuleSetMetric

        # AWS Managed Rule - Known Bad Inputs Protection
        - Name: AWSManagedRulesKnownBadInputsRuleSet
          Priority: 3
          OverrideAction:
            None: {}
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesKnownBadInputsRuleSet
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: AWSManagedRulesKnownBadInputsRuleSetMetric

      VisibilityConfig:
        SampledRequestsEnabled: true
        CloudWatchMetricsEnabled: true
        MetricName: !Sub '${WebACLName}Metric'

Outputs:
  WebACLId:
    Description: 'WAF WebACL ID'
    Value: !GetAtt WebACL.Id
    Export:
      Name: !Sub '${AWS::StackName}-WebACL-Id'

  WebACLArn:
    Description: 'WAF WebACL ARN'
    Value: !GetAtt WebACL.Arn
    Export:
      Name: !Sub '${AWS::StackName}-WebACL-Arn'

  WebACLName:
    Description: 'WAF WebACL Name'
    Value: !Ref WebACL
    Export:
      Name: !Sub '${AWS::StackName}-WebACL-Name'

テンプレートの中身を確認すると、AWSManagedRulesCommonRuleSetAWSManagedRulesSQLiRuleSet等のマネージドルールが設定されています。

そのままデプロイを指示していきます。CloudFrontとWAFの紐付けは、AWS CLIで実施するように指示しました。

作成したWAFのテンプレートをデプロイしてください。デプロイ後、CloudFrontとの関連付けをAWS CLIで実施してください。
(省略)
> ## ✅ AWS WAF デプロイ完了!

AWS WAFマネージドルールのデプロイとCloudFrontとの関連付けが正常に完了しました。

### 🛡️ デプロイ結果サマリー

#### **1. WAF WebACL作成完了**
• **WebACL名**: static-website-waf
• **WebACL ID**: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
• **ARN**: arn:aws:wafv2:us-east-1:XXXXXXXXXXXX:global/webacl/static-website-waf/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
• **容量**: 1,100 WCU (Web ACL Capacity Units)

#### **2. 実装されたマネージドルール**
✅ Priority 1: AWSManagedRulesSQLiRuleSet
• SQLインジェクション攻撃をブロック
• 検出された test' OR 1=1-- と UNION SELECT 攻撃に対応

✅ Priority 2: AWSManagedRulesCommonRuleSet
• XSS攻撃をブロック
• 検出された <script>alert('xss')</script> 攻撃に対応
• 静的サイト用に4つのルールを除外して誤検知を防止

✅ Priority 3: AWSManagedRulesKnownBadInputsRuleSet
• 既知の悪意のある入力パターンをブロック

#### **3. CloudFront関連付け完了**
• **Distribution ID**: XXXXXXXXXXXXXX
• **ステータス**: InProgress(数分で完了予定)
• **WebACL ID**: 正常に関連付け済み

### 📊 セキュリティ強化効果

#### **ブロック対象の攻撃**
1. SQLインジェクション: search=test' OR 1=1--
2. SQLインジェクション: id=1 UNION SELECT username,password FROM users
3. XSS攻撃: name=<script>alert('xss')</script>
4. その他の既知攻撃パターン

### 🔍 監視とメトリクス

#### **CloudWatchメトリクス**
• AWSManagedRulesSQLiRuleSetMetric
• AWSManagedRulesCommonRuleSetMetric
• AWSManagedRulesKnownBadInputsRuleSetMetric
• static-website-wafMetric

### 💰 料金概算
• **WebACL**: $1.00/月
• **ルール3つ**: $1.80/月
• **リクエスト**: $0.60/100万リクエスト
• **月額合計**: 約$2.80 + リクエスト料金

### 🚀 次のステップ

1. CloudFront配信完了の確認 (約5-15分後)
2. 攻撃テストの実施 (同じ攻撃パターンでブロック確認)
3. CloudWatchメトリクスの監視設定
4. 定期的なログ分析の自動化

WAFが有効になると、以前検出された攻撃パターンは全てブロックされ、ウェブサイトのセキュリティが大幅に向上します。

WAFのCloudFormationテンプレートデプロイと、CloudFrontの関連付けを実施してくれました。
記載を省略しましたが、一度CloudFrontの情報をJSONファイルに保存したあと、CLIによる関連付け操作を行ってくれました。

前述の不正アクセスとみなされるURLをつかって、手元のPCのブラウザから再度アクセスすると、
今度は403.htmlが表示されるようになりました。期待どおりですね。

vscode-drop-1752213116658-w2a8gtdzzm.png
実際に表示された403.html

後片付け

自分で作成したCloudFrontのスタックと、Q CLIが作ってくれたWAFのスタックは、確認が終わったら忘れずに削除しましょう。

まとめ

Amazon Q Developer CLIを使って、AWS環境を調査&操作させてみました。

何度か試行して気づいたこととして、
生成AIに対して指示を与える時は、その指示の裏にある背景までしっかり伝えると、人間が期待するレスポンスに近づいていくように感じました。

今回の場合だと、HTML生成時にCloudFormationのテンプレートを予め読ませることで、テンプレート内で使われているHTMLファイル(index.html, 403.html)を生成してくれる、といった感じです。

生成AIが期待通りのレスポンスを返してくれない場合は、
自分が持っているコンテキストを正しく文章にして、生成AIに伝えられているか?を再確認してみるのがよいのかもしれません。

参考

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.