amazon-web-servicesterraformamazon-wafweb-application-firewall

terraform aws waf rules to allow access to path only for certain ip addreses


I have 2 instances behind a load balancer and I need to secure access to the /admin.php script to be accessible to only certain IP addresses Trying to do this with WAF but if there is a simpler way to do it with ALB that's also fine

The below code currently applies globally

resource "aws_wafv2_ip_set" "allowed_ips" {
  name        = "allowed-ips"
  scope       = "REGIONAL"
  description = "IP set containing allowed IP addresses"
  ip_address_version = "IPV4"
  addresses = var.allowed_ip_addresses
}

resource "aws_wafv2_web_acl" "web_acl" {
  name        = "example-web-acl"
  description = "Example Web ACL"
  scope       = "REGIONAL"
  default_action {
    block {}
  }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "web-acl-metric"
      sampled_requests_enabled   = false
    }

  rule {
    name     = "allow-only-from-allowed-ips"
    priority = 1
      

    statement {
      ip_set_reference_statement {
        arn = aws_wafv2_ip_set.allowed_ips.arn
      }
     

    }

    action {
      allow {}
    }
    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "allow-only-from-allowed-ips-metric"
      sampled_requests_enabled   = false
    }
  }
}



resource "aws_wafv2_web_acl_association" "load_balancer_acl_association" {
  resource_arn = aws_lb.external_alb.arn
  web_acl_arn  = aws_wafv2_web_acl.web_acl.arn
}

Solution

  • You could do this with ALB listener rules if the IP count is less to manage. You can mention up to 4 Source IPs as the total condition count is 5.

    A rough sample of this is below:

    resource "aws_lb_listener_rule" "static" {
        listener_arn = aws_lb_listener.front_end.arn
        priority = 100
        action {
            type = "forward"
            target_group_arn = aws_lb_target_group.static.arn
        }
        condition {
            path_pattern {
                values = ["/admin.php"]
            }
        }
        condition {
            source_ip {
                values = ["1.2.3.4/32"]
            }
        }
    }
    
    resource "aws_lb_listener_rule" "static" {
        listener_arn = aws_lb_listener.front_end.arn
        priority = 101
        action {
            type = "forward"
            target_group_arn = aws_lb_target_group.static.arn
        }
    
        condition {
            path_pattern {
                values = ["/admin.php"]
            }
        }
    
        action {
        type = "fixed-response"
    
        fixed_response {
          content_type = "text/plain"
          message_body = "Access Denies"
          status_code  = "403"
        }
    }
    

    Rule with priority 100 is to allow the list of IPs (i.e Forward to respective target group). Rule 101 will give back a fixed-response of 403 for everyone else.

    Terraform registry link