AWS WAF delivers web application protection from malicious attacks and intrusions. The service protects applications running on AWS services such as CloudFront, Application Load Balancer, API Gateway, or AWS AppSync. In early November AWS WAF (Web Application Firewall) introduced granular geo-based blocking rules. We can now check new labels, which define the geographical location of the requests. The labels look like this awswaf:clientip:geo:region:DE-HE .

In the AWS WAF console, we need to create a new set of rules. Let's choose an active WAF and navigate to the rules tab. In the end, we will have two additional rules:

As we want to utilize the labels, we need to first create a rule, which identifies the origin of the request. Based on the setup, we need to either choose "source IP address" or "IP address in header". This will get important in the second step and impacts the labels, that will be added to the request. We need to make sure to use a non-intrusive action for the first rule. Otherwise, the second rule will not be validated. Non-intrusive actions are count, captcha, or challenge.

Afterward, we can define the second rule to block requests based on the granular geographic location. For that, we need to inspect the labels of the request that was added by the first rule. We will see two new labels if we investigate the request:

"labels":[
   {
      "name":"awswaf:clientip:geo:country:DE"
   },
   {
      "name":"awswaf:clientip:geo:region:DE-HE"
   }
]

The labels could be different based on the IP address configuration from the first rule.

Source IP address

awswaf:clientip:geo:country:<ISOCountryCode>

awswaf:clientip:geo:region:<ISOCountryCode>-<ISORegionCode>

IP address in header

awswaf:forwardedip:geo:country:<ISOCountryCode>

awswaf:forwardedip:geo:region:<ISOCountryCode>-<ISORegionCode>

The country and region codes are based on ISO 3166-2. You can access a full list at the Online Browsing Platform of ISO (https://www.iso.org/obp/ui). In my case, I have configured "Source IP address" and chose the state of Hessen in Germany. The label would look like this awswaf:clientip:geo:region:DE-HE.

Afterward, we can choose the correct action like blocking. Please make sure both rules are in the correct order.

If you try to connect to the URL from Hessen in Germany (DE-HE) you will get a 403 status response:

$ curl -I -s http://<server>/
HTTP/1.1 403 Forbidden
Server: awselb/2.0

Join our community of cloud security professionals. 🔐

Subscribe to our newsletter

Geo-Based Rule JSON

{
  "Name": "Geo-Count-Rule",
  "Priority": 0,
  "Statement": {
    "GeoMatchStatement": {
      "CountryCodes": [
        "DE"
      ]
    }
  },
  "Action": {
    "Count": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "Geo-Count-Rule"
  }
},
{
  "Name": "Geo-Restriction-Rule",
  "Priority": 1,
  "Statement": {
    "LabelMatchStatement": {
      "Scope": "LABEL",
      "Key": "awswaf:clientip:geo:region:DE-HE"
    }
  },
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "Geo-Restriction-Rule"
  }
}
Share this post