Skip to content

Commit

Permalink
FUM-3033-waf-module-refactor (#4)
Browse files Browse the repository at this point in the history
* FUM-3033-waf-module-refactor

* FUM-3033 reduce variables, clanup rule priorities

fix priorities

fix ipv6 list

fix-rule-action-override

* allow-only-count-block-managed-rule-groups

* FUM-3033 add challenge and captcha support

* FUM-3033 readme

* FUM-3033 small fix

* Update README.md

Co-authored-by: Demetrio Carrara <[email protected]>

* Update variables.tf

Co-authored-by: Demetrio Carrara <[email protected]>

* Update variables.tf

Co-authored-by: Demetrio Carrara <[email protected]>

* Update waf.tf

Co-authored-by: Demetrio Carrara <[email protected]>

* Update waf.tf

Co-authored-by: Demetrio Carrara <[email protected]>

* FUM-3033 move example in separated folder

Further examples that can be created: regional waf

* FUM-3033 remove hostname whitelisting

* FUM-3033 remove note

* spellchecking

* Update README.md

Co-authored-by: Demetrio Carrara <[email protected]>

---------

Co-authored-by: Demetrio Carrara <[email protected]>
  • Loading branch information
DCamma and sgametrio authored Feb 22, 2024
1 parent 1e90035 commit 532e578
Show file tree
Hide file tree
Showing 8 changed files with 572 additions and 483 deletions.
52 changes: 23 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ This module create the AWS WAF Web ACLs and AWS WAF IP sets necessary to protect

It's designed to propose the following rules:

- Allow all requests comming from own AWS account (IP list)
- Allow all requests comming from list of IPv4 (IP list)
- Allow all requests comming from list of IPv6 (IP list)
- Allow all requests comming from partner (detect "host" header)
- (optionally) allow requests from Oracle Data Cloud Crawler
- (optionally) allow requests from Google bots
- AWS managed rules
- AWS managed count rules
- Limit requests starting with "/search"
- (optionally) limit requests based on uri path
- Block some articles for some coutries
- Limit requests per countries
- Limit not in limited countries (everybody_else)
- Count Swiss requests
|Priority|Rule Name|Notes|
|----------|----------|------|
|0 | whitelisted_ips_v4| Automatically download and whitelist bots IPV4s (see variables) and whitelist any list of IPV4 ranges|
|1 | whitelisted_ips_v6| Automatically download and whitelist bots IPV6s (see variables) and whitelist any list of IPV6 ranges|
|2 | rate_limit_everything_apart_from_CH| This rule is meant to be a failsafe switch in case of attack. Change "count" to "block" in the console if you are under attack and want to rate limit to a low number of requests every country except Switzerland |
|3 | count_requests_from_ch| |
|4-9 | | Free priority range for additional rules |
|10-19 | AWS Managed rule groups | Each group could contain multiple labels, please refer to the [doc](https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-list.html)|
|20-29 | AWS managed rule labels| For a list of labels is possible to define an action: block, captcha or challenge. In all cases is possible to define a rate limit or directly apply the action |
|30-49 | country_rates| Geographical rules|
|50 | everybody_else_limit| The blocking limit for all country_codes which are not covered by the country_rates rule|
|60-69 | AWS managed rule labels| Additional priority range reserved for AWS Managed rule labels |
|70 | limit_search_requests_by_countries| |
|71-89 | block_uri_path_string| |
|90-109 | block_articles| |
|110-129 | block_regex_pattern| |

## Waf logging

Expand All @@ -32,7 +34,7 @@ The module will also deploy several `AWS Athena` resources by default. These inc
* several `Athena queries`
* and an S3 bucket where waf logs will be saved if activated.

To activare waf logs set the `var.enable_logging` to `true` (`false` by default).
To activate waf logs set the `var.enable_logging` to `true` (`false` by default).

### Query WAF logs
In order to be able to query WAF logs saved on the S3 Bucket, we need to use the AWS Athena service:
Expand All @@ -44,7 +46,7 @@ In order to be able to query WAF logs saved on the S3 Bucket, we need to use the
* Set the query parameters as described in the query comments and run it
* Now a partition table is available and queries can be executed against the WAF logs stored on S3

Note: whenever WAF attachment changes, the partition projection table has to be deleted and recreated by updating the correct S3 bucket path. The table is created thorugh the query partition-projection-table-creation
Note: whenever WAF attachment changes, the partition projection table has to be deleted and recreated by updating the correct S3 bucket path. The table is created through the query partition-projection-table-creation

## How do you use this module?

Expand All @@ -54,23 +56,15 @@ INFO: for cloudfront the aws provider should be in us-west-1 region.

```HCL
module "waf" {
source = "tx-pts-dai/waf/aws"
version = "~> 0.x"
providers = {
aws = aws.us
}
self_ips = module.cf_extractor.public_ips # ie. NAT gateways
allowed_ips = var.waf_allowed_ips
allowed_ips_v6 = var.waf_allowed_ips_v6
country_rates = var.waf_country_rates
block_articles = var.waf_block_articles
aws_managed_count_rules = var.waf_aws_managed_rules
allowed_partners = var.waf_allowed_partners
everybody_else_limit = var.waf_everybody_else_limit
search_limitation = var.waf_search_limitation
}
```

For a list of all variables please refer to: [terraform-dock](terraform-docs.md)
For a list of all variables please refer to [the terraform-docs](terraform-docs.md) of the module

### Waf scope: CLOUDFRONT or REGIONAL

Expand Down Expand Up @@ -113,11 +107,11 @@ A rule statement that uses a forwarded IP header for the IP address won’t use
If the oracle data cloud regex throws errors the automatic parsing can be disabled by:
* setting `enable_oracle_crawler_whitelist = false`

If the `data.http.oracle` structure throws errors the url can be overriden by:
If the `data.http.oracle` structure throws errors the url can be overridden by:
* setting the variable `oracle_data_cloud_crawlers_url` to a valid URL

If the google bot jsonecode throws errors it can be disabled by:
* setting `enable_google_bots_whitelist = false`

If the `data.http.googlebot` structure throws errors the url can be overriden by:
If the `data.http.googlebot` structure throws errors the url can be overridden by:
* setting the variable `google_bots_url` to a valid URL
92 changes: 92 additions & 0 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
terraform {
required_version = ">= 1.4.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
alias = "us"
}

module "waf" {
source = "../../"
providers = {
aws = aws.us
}
# Required variables: None
# Non required variables"
waf_name = "cloudfront-waf"
waf_scope = "CLOUDFRONT"
waf_logs_retention = 7
enable_oracle_crawler_whitelist = true
oracle_data_cloud_crawlers_url = "https://www.oracle.com/corporate/acquisitions/grapeshot/crawler.html"
enable_google_bots_whitelist = true
google_bots_url = "https://developers.google.com/search/apis/ipranges/googlebot.json"
enable_parsely_crawlers_whitelist = false
parsely_crawlers_url = "https://www.parse.ly/static/data/crawler-ips.json"
enable_k6_whitelist = false
k6_ip_ranges_url = "https://ip-ranges.amazonaws.com/ip-ranges.json"
whitelisted_ips_v4 = ["1.1.1.1/16", "255.255.255.255/32"]
whitelisted_ips_v6 = []
aws_managed_rule_groups = [
{
name = "AWSManagedRulesAnonymousIpList" # Full list of labels from this group: https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-ip-rep.html
priority = 10
},
{
name = "AWSManagedRulesAmazonIpReputationList" # Full list of labels from this group: https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-ip-rep.html
priority = 11
}
]
aws_managed_rule_labels = [
{
name = "aws_managed_rule_low_limit"
labels = ["awswaf:managed:aws:anonymous-ip-list:AnonymousIPList", "awswaf:managed:aws:amazon-ip-list:AWSManagedIPReputationList", "awswaf:managed:aws:amazon-ip-list:AWSManagedReconnaissanceList", "awswaf:managed:aws:amazon-ip-list:AWSManagedIPDDoSList"]
priority = 20
},
{
name = "aws_managed_rule_high_limit"
labels = ["awswaf:managed:aws:anonymous-ip-list:HostingProviderIPList"]
limit = 750
priority = 21
},
]
count_requests_from_ch = false
country_rates = [
{
name = "Group_1-CH"
limit = 50000
country_codes = ["CH"]
priority = 30
},
{
name = "Group_2-DE_AT_FR"
limit = 4000
country_codes = ["AT", "FR", "DE"]
priority = 31
},
{
name = "Very_slow"
limit = 100
country_codes = ["AR", "BD", "BR", "KH", "CN", "CO", "EC", "IN", "ID", "MX", "NP", "PK", "RU", "SG", "TR", "UA", "AE", "ZM", "VN"]
priority = 35
}
]
everybody_else_limit = 0
limit_search_requests_by_countries = {
limit = 100
country_codes = ["CH"]
}
block_uri_path_string = []
block_articles = []
block_regex_pattern = {}
enable_logging = false
deploy_athena_queries = true
logs_bucket_name_override = null
}
Empty file added examples/complete/outputs.tf
Empty file.
Empty file added examples/complete/variables.tf
Empty file.
2 changes: 1 addition & 1 deletion logs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ resource "aws_athena_named_query" "first_logs_query" {
}

resource "aws_s3_bucket" "logs" {
bucket = coalesce(var.logs_bucket_name, "aws-waf-logs-${var.waf_name}-${data.aws_caller_identity.current.account_id}")
bucket = coalesce(var.logs_bucket_name_override, "aws-waf-logs-${var.waf_name}-${data.aws_caller_identity.current.account_id}")
force_destroy = true
}

Expand Down
Loading

0 comments on commit 532e578

Please sign in to comment.