Skip to content

Commit

Permalink
add baseline security rules (#2)
Browse files Browse the repository at this point in the history
* version upgrades

* add sanctioned countries rule

* switch var type to map object

* add more vars

* add more rules

* add logic to calculate capacity

* multiple changes

* remove unsupported rules

* add tf plan workflow

* upgrade action version

* update job name

* transform text to lowercase for domain rule

* fix vars

* update header file

* update title

* update repo name

* switch to different release action

* delete unwanted params for release action
  • Loading branch information
paliwalvimal authored May 5, 2024
1 parent f9654a6 commit a954286
Show file tree
Hide file tree
Showing 14 changed files with 340 additions and 52 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/checkov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.9
uses: actions/setup-python@v4
- uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.9
python-version: 3.11
- name: Scan with Checkov
id: checkov
uses: bridgecrewio/checkov-action@v12
Expand Down
19 changes: 8 additions & 11 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Terraform
uses: hashicorp/setup-terraform@v2
uses: hashicorp/setup-terraform@v3
- name: Terraform Init
id: init
run: terraform init
Expand All @@ -19,11 +19,11 @@ jobs:
checkov:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.9
uses: actions/setup-python@v4
- uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.9
python-version: 3.11
- name: Scan with Checkov
id: checkov
uses: bridgecrewio/checkov-action@v12
Expand All @@ -39,8 +39,5 @@ jobs:
runs-on: ubuntu-latest
needs: [test, checkov]
steps:
- uses: actions/checkout@v3
- uses: "marvinpinto/action-automatic-releases@919008cf3f741b179569b7a6fb4d8860689ab7f0" # v1.2.1
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
prerelease: false
- uses: actions/checkout@v4
- uses: softprops/action-gh-release@v2
19 changes: 0 additions & 19 deletions .github/workflows/tests.yml

This file was deleted.

29 changes: 29 additions & 0 deletions .github/workflows/tf-plan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: tf-plan
on:
push:
branches:
- main
pull_request:

permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout

jobs:
plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.TF_READ_ONLY_GITHUB_OIDC_ROLE_ARN }}
aws-region: eu-west-1
- name: Set up Terraform
uses: hashicorp/setup-terraform@v3
- name: Terraform Init
id: init
run: terraform init
- name: Terraform Plan
id: plan
run: terraform plan -var 'name=baseline-waf-rule-group' -var 'scope=REGIONAL'
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand All @@ -10,11 +10,11 @@ repos:
- id: detect-private-key
- id: no-commit-to-branch
- repo: https://github.com/gitleaks/gitleaks
rev: v8.16.1
rev: v8.18.2
hooks:
- id: gitleaks
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.81.0
rev: v1.89.1
hooks:
- id: terraform_fmt
- id: terraform_validate
Expand All @@ -24,12 +24,12 @@ repos:
args:
- --args=--config=__GIT_WORKING_DIR__/.tflint.hcl --fix
- repo: https://github.com/bridgecrewio/checkov.git
rev: "2.3.314"
rev: "3.2.74"
hooks:
- id: checkov
args: ["--quiet", "--compact", "--framework", "terraform", "--download-external-modules", "false", "--skip-path", "examples"]
- repo: https://github.com/terraform-docs/terraform-docs
rev: v0.16.0
rev: v0.17.0
hooks:
- id: terraform-docs-go
args: ["."]
5 changes: 3 additions & 2 deletions .tf-header.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Title
# Create a baseline security rule group for WAF

![License](https://img.shields.io/github/license/terrablocks/REPO_NAME?style=for-the-badge) ![Tests](https://img.shields.io/github/actions/workflow/status/terrablocks/REPO_NAME/tests.yml?branch=main&label=Test&style=for-the-badge) ![Checkov](https://img.shields.io/github/actions/workflow/status/terrablocks/REPO_NAME/checkov.yml?branch=main&label=Checkov&style=for-the-badge) ![Commit](https://img.shields.io/github/last-commit/terrablocks/REPO_NAME?style=for-the-badge) ![Release](https://img.shields.io/github/v/release/terrablocks/REPO_NAME?style=for-the-badge)
![License](https://img.shields.io/github/license/terrablocks/aws-wafv2-baseline-rule-group?style=for-the-badge) ![Plan](https://img.shields.io/github/actions/workflow/status/terrablocks/aws-wafv2-baseline-rule-group/tf-plan.yml?branch=main&label=Plan&style=for-the-badge) ![Checkov](https://img.shields.io/github/actions/workflow/status/terrablocks/aws-wafv2-baseline-rule-group/checkov.yml?branch=main&label=Checkov&style=for-the-badge) ![Commit](https://img.shields.io/github/last-commit/terrablocks/aws-wafv2-baseline-rule-group?style=for-the-badge) ![Release](https://img.shields.io/github/v/release/terrablocks/aws-wafv2-baseline-rule-group?style=for-the-badge)

This terraform module will deploy the following services:
- WAFv2 Rule Group
2 changes: 1 addition & 1 deletion .tflint.hcl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugin "aws" {
enabled = true
version = "0.24.3"
version = "0.30.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
}

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2023 terrablocks (by SkildOps)
Copyright (c) 2024 terrablocks (by SkildOps)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
53 changes: 47 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,49 @@
# terraform-base-template

This is a template repository that will serve as a starting point for all the new terraform modules
<!-- BEGIN_TF_DOCS -->
# Create a baseline security rule group for WAF

## Important changes:
- Replace `REPO_NAME` with the actual repository name in examples and .tf-header.md
- Update module name in the examples
- Add title in the .tf-header.tf file
![License](https://img.shields.io/github/license/terrablocks/aws-wafv2-baseline-rule-group?style=for-the-badge) ![Plan](https://img.shields.io/github/actions/workflow/status/terrablocks/aws-wafv2-baseline-rule-group/tf-plan.yml?branch=main&label=Plan&style=for-the-badge) ![Checkov](https://img.shields.io/github/actions/workflow/status/terrablocks/aws-wafv2-baseline-rule-group/checkov.yml?branch=main&label=Checkov&style=for-the-badge) ![Commit](https://img.shields.io/github/last-commit/terrablocks/aws-wafv2-baseline-rule-group?style=for-the-badge) ![Release](https://img.shields.io/github/v/release/terrablocks/aws-wafv2-baseline-rule-group?style=for-the-badge)

This terraform module will deploy the following services:
- WAFv2 Rule Group

# Usage Instructions
## Example
```hcl
module "wafv2_rule_group" {
source = "github.com/terrablocks/aws-wafv2-baseline-rule-group.git?ref=" # Always use `ref` to point module to a specific version or hash
name = "baseline-waf-rule-group"
scope = "REGIONAL"
}
```

## Requirements

| Name | Version |
|------|---------|
| terraform | >= 1.8.0 |
| aws | >= 5.0.0 |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| block_cloudfront_default_domain | Block all incoming traffic if the request host header contains cloudfront domain. This rule prevents bad actors from bypassing the custom domain to which you have mapped cloudfront domain | ```object({ enabled = bool priority = optional(number) enable_cw_metrics = optional(bool) })``` | ```{ "enable_cw_metrics": true, "enabled": true, "priority": 1 }``` | no |
| block_load_balancer_default_domain | Block all incoming traffic if the request host header contains load balancer domain. This rule prevents bad actors from bypassing the custom domain to which you have mapped load balancer domain | ```object({ enabled = bool priority = optional(number) enable_cw_metrics = optional(bool) })``` | ```{ "enable_cw_metrics": true, "enabled": true, "priority": 2 }``` | no |
| block_sanctioned_countries | Blacklist all incoming traffic from the countries sanctioned by the US. Country codes must follow alpha-2 format as per [ISO](https://www.iso.org/obp/ui) 3166 standards | ```object({ enabled = bool priority = optional(number) countries_code = optional(list(string)) enable_cw_metrics = optional(bool) })``` | ```{ "countries_code": [ "CU", "IR", "KP", "RU", "SY" ], "enable_cw_metrics": true, "enabled": true, "priority": 0 }``` | no |
| description | Description for the rule group | `string` | `"Baseline security WAF rule group"` | no |
| enable_cw_metrics | Enable CloudWatch metrics for the rule group | `bool` | `true` | no |
| name | Name of the rule group | `string` | n/a | yes |
| scope | Scope of the rule group. **Note:** Valid value is either **REGIONAL** or **CLOUDFRONT** | `string` | n/a | yes |
| tags | Map of key value pair to associate with the rule group | `map(string)` | `null` | no |

## Outputs

| Name | Description |
|------|-------------|
| arn | ARN of the WAF rule group |
| capacity | WCU (web ACL capacity units) required for the WAF rule group |
| id | ID of the WAF rule group |

<!-- END_TF_DOCS -->
7 changes: 5 additions & 2 deletions examples/default.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
module "name" {
source = "github.com/terrablocks/REPO_NAME.git" # Always use `ref` to point module to a specific version or hash
module "wafv2_rule_group" {
source = "github.com/terrablocks/aws-wafv2-baseline-rule-group.git?ref=" # Always use `ref` to point module to a specific version or hash

name = "baseline-waf-rule-group"
scope = "REGIONAL"
}
137 changes: 137 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
locals {
# Following docs can be referred to calculate capacity required for each rule
# https://docs.aws.amazon.com/cli/latest/reference/wafv2/check-capacity.html
# https://docs.aws.amazon.com/waf/latest/APIReference/API_CheckCapacity.html#API_CheckCapacity_RequestParameters
rule_group_capacity = sum(flatten(
[
# https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-type-geo-match.html
lookup(var.block_sanctioned_countries, "enabled", false) ? [1] : [0],

# https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-type-string-match.html
# https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-transformation.html
# 2 for ENDS_WITH constraint and 10 for text transformations
lookup(var.block_cloudfront_default_domain, "enabled", false) ? [12] : [0],

# https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-type-string-match.html
# https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-transformation.html
# 2 for ENDS_WITH constraint and 10 for text transformations
lookup(var.block_load_balancer_default_domain, "enabled", false) ? [12] : [0]
])
)
}

resource "aws_wafv2_rule_group" "this" {
name = var.name
description = var.description
scope = var.scope
capacity = local.rule_group_capacity

dynamic "rule" {
for_each = lookup(var.block_sanctioned_countries, "enabled", false) ? [0] : []
content {
name = "block-sanctioned-countries"
priority = var.block_sanctioned_countries["priority"]

action {
block {}
}

statement {
geo_match_statement {
country_codes = var.block_sanctioned_countries["countries_code"]
}
}

dynamic "visibility_config" {
for_each = var.block_sanctioned_countries["enable_cw_metrics"] ? [0] : []
content {
cloudwatch_metrics_enabled = true
metric_name = "${var.name}-block-sanctioned-countries-rule-waf"
sampled_requests_enabled = true
}
}
}
}

dynamic "rule" {
for_each = lookup(var.block_cloudfront_default_domain, "enabled", false) ? [0] : []
content {
name = "block-cloudfront-default-domain"
priority = var.block_cloudfront_default_domain["priority"]

action {
block {}
}

statement {
byte_match_statement {
field_to_match {
single_header {
name = "host"
}
}
positional_constraint = "ENDS_WITH"
search_string = ".cloudfront.net"
text_transformation {
type = "LOWERCASE"
priority = 0
}
}
}

dynamic "visibility_config" {
for_each = var.block_cloudfront_default_domain["enable_cw_metrics"] ? [0] : []
content {
cloudwatch_metrics_enabled = true
metric_name = "${var.name}-block-cloudfront-default-domain-rule-waf"
sampled_requests_enabled = true
}
}
}
}

dynamic "rule" {
for_each = lookup(var.block_load_balancer_default_domain, "enabled", false) ? [0] : []
content {
name = "block-load-balancer-default-domain"
priority = var.block_load_balancer_default_domain["priority"]

action {
block {}
}

statement {
byte_match_statement {
field_to_match {
single_header {
name = "host"
}
}
positional_constraint = "ENDS_WITH"
search_string = ".elb.amazonaws.com"
text_transformation {
type = "LOWERCASE"
priority = 0
}
}
}

dynamic "visibility_config" {
for_each = var.block_load_balancer_default_domain["enable_cw_metrics"] ? [0] : []
content {
cloudwatch_metrics_enabled = true
metric_name = "${var.name}-block-load-balancer-default-domain-rule-waf"
sampled_requests_enabled = true
}
}
}
}

visibility_config {
cloudwatch_metrics_enabled = var.enable_cw_metrics
metric_name = "${var.name}-waf-rule-group"
sampled_requests_enabled = var.enable_cw_metrics
}

tags = var.tags
}
14 changes: 14 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
output "arn" {
value = aws_wafv2_rule_group.this.arn
description = "ARN of the WAF rule group"
}

output "id" {
value = aws_wafv2_rule_group.this.id
description = "ID of the WAF rule group"
}

output "capacity" {
value = local.rule_group_capacity
description = "WCU (web ACL capacity units) required for the WAF rule group"
}
2 changes: 1 addition & 1 deletion requirements.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
terraform {
required_version = ">= 1.3.0"
required_version = ">= 1.8.0"
required_providers {
aws = {
source = "hashicorp/aws"
Expand Down
Loading

0 comments on commit a954286

Please sign in to comment.