AWS WAF 特定ドメイン IP制限 Basic認証 Cloudfront

Terraform

↓ WAFルール

Basic認証のユーザは bar-user パスワードは bar-pass

echo -n bar-user:bar-pass | base64
YmFyLXVzZXI6YmFyLXBhc3M=

terraform

resource "aws_wafv2_ip_set" "foo" {
  provider = aws.us-east-1
  name               = "foo"
  description        = "foo IP set"
  scope              = "CLOUDFRONT"
  ip_address_version = "IPV4"
  addresses          = ["1.2.3.4/32", "5.6.7.8/32"]
}

resource "aws_wafv2_web_acl" "waf" {
  provider = aws.us-east-1
  name     = "waf"
  scope    = "CLOUDFRONT"

  default_action {
    allow {}
  }

  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name                = "waf"
    sampled_requests_enabled   = true
  }

  rule {
    name     = "foo-block-ip"
    priority = 1

    action {
      block {}
    }

    statement {
      and_statement {

        statement {
          byte_match_statement {
            field_to_match {
              single_header {
                name = "host"
              }
            }
            positional_constraint = "EXACTLY"
            search_string         = "foo.example.com"
            text_transformation {
              priority = 0
              type     = "LOWERCASE"
            }
          }
        }

        statement {
          not_statement {
            statement {
              ip_set_reference_statement {
                arn = aws_wafv2_ip_set.foo.arn
              }
            }
          }
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "foo-block-ip"
      sampled_requests_enabled   = true
    }
  }

  rule {
    name     = "bar-basic-auth"
    priority = 0

    action {
      block {
        custom_response {
          response_code = 401
          response_header {
            name  = "www-authenticate"
            value = "Basic"
          }
        }
      }
    }

    statement {
      and_statement {

        statement {
          byte_match_statement {
            field_to_match {
              single_header {
                name = "host"
              }
            }
            positional_constraint = "EXACTLY"
            search_string         = "bar.example.com"
            text_transformation {
              priority = 0
              type     = "LOWERCASE"
            }
          }
        }

        statement {
          not_statement {
            statement {
              byte_match_statement {
                positional_constraint = "EXACTLY"
                search_string         = "Basic YmFyLXVzZXI6YmFyLXBhc3M="
                field_to_match {
                  single_header {
                    name = "authorization"
                  }
                }
                text_transformation {
                  priority = 0
                  type     = "NONE"
                }
              }
            }
          }
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "bar-basic-auth"
      sampled_requests_enabled   = true
    }
  }
}

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_ip_set
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl

参考

IP制限、Basic認証Apache等の設定でも実装可能ですが、本記事では下記を考慮しWAFでの実装とします。

  • AWS のセキュリティベストプラクティスに記載のある「全レイヤーでセキュリティを適⽤する」に則り、WAFによるセキュリティをCloudfrontに適⽤します。
  • Webページをホストしているサーバーにトラフィックが届かないため、サーバーの負荷軽減が期待できます。

...
「許可IPセットで指定したIP以外が指定のパスにアクセスした場合ブロックする」
...
「指定のパスにアクセスがあった場合、Basic認証を要求し認証失敗したものはブロックする」

AWS WAF で特定のパスに対してIP制限と Basic認証を実装する | iret.media 2023

↑とても参考になる

CloudfrontのIP制限をAWS/WAFで行う 2023

TerraformでAWS WAFを構築するサンプルコードを書いてみた #AWS - Qiita 2022

WAFで特定ドメインのIP制限をする(Terraform) #AWS - Qiita 2022