-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #37 from Crown-Commercial-Service/ithc-ingress-wit…
…hout-rds Creating ITHC Ingress without RDS module
- Loading branch information
Showing
7 changed files
with
335 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# ITHC Ingress - Caution! | ||
|
||
This module introduces resources which deliberately bypass and / or reduce the efficacy of existing security measures. | ||
|
||
It's intended for use during an IT Health Check / Penetration Test situation. | ||
|
||
> You are **STRONGLY** advised never to use this module in production. | ||
## Adding Ingress in your project | ||
|
||
This module is designed to be reusable and temporary. To optimise on both these attributes it's advised to implement it as follows: | ||
|
||
### Locate the module invocation separately | ||
|
||
Invoke the module using the typical Terraform `module` construct. | ||
|
||
It's advised to put this block into the top-level of your environment folder, as a separate file with a name such as `ithc_ingress.tf` (so, for example, `environments/staging/ithc_ingress.tf`). There are a few reasons for this approach: | ||
|
||
1. It shows with a glance of the folder that this environment has ITHC ingress set up | ||
2. It stops the `main.tf` becoming cluttered | ||
3. When you are finished testing, each of the resources and components can be removed from your platform by simply deleting this file and re-applying the Terraform. | ||
|
||
## What gets created | ||
|
||
This module adds the following: | ||
|
||
* An IAM user for ITHC audit (the ARN for this is in the module outputs) | ||
* An IAM group for ITHC audit - the audit user is placed into this group and the group has policies: | ||
* ReadOnlyAccess | ||
* SecurityAudit | ||
* A custom policy as defined in [this file](ithc_iam_user.tf) which allows key management, MFA management, etc and blocks SSM access (among other things) | ||
* An EC2 instance for VPC Scanning (the public DNS name for this is in the module outputs, and the username to use for ssh connection is `kali`) | ||
|
||
## Origins | ||
|
||
Adopted from: | ||
|
||
* https://github.com/Crown-Commercial-Service/ccs-corporate-website-terraform/tree/main/cgi_ithc | ||
* https://github.com/Crown-Commercial-Service/ccs-digital-foundation-terraform/tree/main/cgi_ithc |
108 changes: 108 additions & 0 deletions
108
modules/ithc-ingress-without-rds-caution/ithc_iam_user.tf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
resource "aws_iam_user" "ithc_audit" { | ||
name = "${var.resource_name_prefixes.hyphens_lower}-ithc-audit" | ||
} | ||
|
||
resource "aws_iam_group" "ithc_audit" { | ||
name = "${var.resource_name_prefixes.hyphens_lower}-ithc-audit" | ||
} | ||
|
||
resource "aws_iam_user_group_membership" "ithc_audit" { | ||
groups = [ | ||
aws_iam_group.ithc_audit.name | ||
] | ||
user = aws_iam_user.ithc_audit.name | ||
} | ||
|
||
resource "aws_iam_group_policy_attachment" "ithc_audit__read_only_access" { | ||
group = aws_iam_group.ithc_audit.name | ||
policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess" | ||
} | ||
|
||
resource "aws_iam_group_policy_attachment" "ithc_audit__security_audit" { | ||
group = aws_iam_group.ithc_audit.name | ||
policy_arn = "arn:aws:iam::aws:policy/SecurityAudit" | ||
} | ||
|
||
data "aws_iam_policy_document" "custom_ithc_access_rules" { | ||
statement { | ||
sid = "AllowAccessKeyManagement" | ||
effect = "Allow" | ||
actions = [ | ||
"iam:DeleteAccessKey", | ||
"iam:UpdateAccessKey", | ||
"iam:CreateAccessKey", | ||
"iam:ListAccessKeys" | ||
] | ||
resources = [ | ||
"arn:aws:iam::*:user/$${aws:username}" | ||
] | ||
} | ||
|
||
statement { | ||
sid = "AllowManageOwnVirtualMFADevice" | ||
effect = "Allow" | ||
actions = [ | ||
"iam:DeleteVirtualMFADevice", | ||
"iam:CreateVirtualMFADevice", | ||
] | ||
resources = [ | ||
"arn:aws:iam::*:mfa/$${aws:username}" | ||
] | ||
} | ||
|
||
statement { | ||
sid = "AllowManageOwnUserMFA" | ||
effect = "Allow" | ||
actions = [ | ||
"iam:ResyncMFADevice", | ||
"iam:ListMFADevices", | ||
"iam:EnableMFADevice", | ||
"iam:DeactivateMFADevice", | ||
] | ||
resources = [ | ||
"arn:aws:iam::*:user/$${aws:username}" | ||
] | ||
} | ||
|
||
statement { | ||
sid = "BlockMostAccessUnlessSignedInWithMFA" | ||
effect = "Deny" | ||
condition { | ||
test = "Bool" | ||
values = [false] | ||
variable = "aws:MultiFactorAuthPresent" | ||
} | ||
not_actions = [ | ||
"sts:GetSessionToken", | ||
"iam:ResyncMFADevice", | ||
"iam:ListVirtualMFADevices", | ||
"iam:ListUsers", | ||
"iam:ListServiceSpecificCredentials", | ||
"iam:ListSSHPublicKeys", | ||
"iam:ListMFADevices", | ||
"iam:ListAccountAliases", | ||
"iam:ListAccessKeys", | ||
"iam:GetAccountSummary", | ||
"iam:EnableMFADevice", | ||
"iam:DeleteVirtualMFADevice", | ||
"iam:CreateVirtualMFADevice", | ||
] | ||
resources = ["*"] | ||
} | ||
|
||
statement { | ||
sid = "DenyAllSSMAccess" | ||
effect = "Deny" | ||
actions = [ | ||
"ssm:GetParameter*" | ||
] | ||
resources = [ | ||
"arn:aws:ssm:*:*:*" | ||
] | ||
} | ||
} | ||
|
||
resource "aws_iam_group_policy" "ithc_audit__custom_rules" { | ||
group = aws_iam_group.ithc_audit.name | ||
policy = data.aws_iam_policy_document.custom_ithc_access_rules.json | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Override existing NACL - For rules on overriding see: | ||
# https://github.com/Crown-Commercial-Service/ccs-migration-alpha-tools/tree/main/modules/four-tier-vpc#network-acls-and-customisation-of | ||
# | ||
resource "aws_network_acl_rule" "public__allow_ssh_everywhere_in" { | ||
for_each = toset(var.ithc_operative_cidr_safelist) | ||
cidr_block = each.value | ||
egress = false | ||
from_port = 22 | ||
network_acl_id = var.public_subnets_nacl_id | ||
protocol = "tcp" | ||
rule_action = "allow" | ||
rule_number = index(var.ithc_operative_cidr_safelist, each.value) + 1 | ||
to_port = 22 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
output "ithc_audit_iam_user_arn" { | ||
description = "ARN of the IAM user created for ITHC audit" | ||
value = aws_iam_user.ithc_audit.arn | ||
} | ||
|
||
output "vpc_scanner_public_dns" { | ||
description = "Public DNS name of the VPC Scanner instance" | ||
value = aws_instance.vpc_scanner.public_dns | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
terraform { | ||
required_providers { | ||
aws = { | ||
source = "hashicorp/aws" | ||
version = ">=5.26.0" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# See naming convention doc: | ||
# https://crowncommercialservice.atlassian.net/wiki/spaces/GPaaS/pages/3561685032/AWS+3+Tier+Reference+Architecture | ||
variable "ithc_operative_cidr_safelist" { | ||
type = list(string) | ||
description = "List of CIDR ranges to be allowed to access the EC2 instances" | ||
} | ||
|
||
variable "public_subnets_nacl_id" { | ||
type = string | ||
description = "The ID of the existing NACL for public subnets" | ||
} | ||
|
||
variable "resource_name_prefixes" { | ||
type = object({ | ||
normal = string, | ||
hyphens = string, | ||
hyphens_lower = string, | ||
}) | ||
description = "Prefix to apply to resources in AWS; options provided to satisfy divergent naming requirements across AWS" | ||
} | ||
|
||
variable "vpc_cidr_block" { | ||
type = string | ||
description = "CIDR block of the VPC" | ||
} | ||
|
||
variable "vpc_id" { | ||
type = string | ||
description = "The ID of the VPC" | ||
} | ||
|
||
variable "vpc_scanner_instance_public_key" { | ||
type = string | ||
description = "Single-line public key (e.g. 'ssh-ed25519 AAAAver3rbrbr')" | ||
} | ||
|
||
variable "vpc_scanner_instance_root_device_size_gb" { | ||
type = number | ||
description = "Required size in GB of the root device for the VPC Scanner instance" | ||
} | ||
|
||
variable "vpc_scanner_instance_subnet_id" { | ||
type = string | ||
description = "ID of the subnet for the VPC Scanner instance - probably a public one" | ||
} | ||
|
||
variable "vpc_scanner_instance_type" { | ||
type = string | ||
description = "Instance type for the VPC Scanner instance" | ||
} |
107 changes: 107 additions & 0 deletions
107
modules/ithc-ingress-without-rds-caution/vpc_scanner_instance.tf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# Instance used to scan for vulnerabilities from inside the VPC. | ||
# | ||
resource "aws_key_pair" "vpc_scanner" { | ||
key_name = "${var.resource_name_prefixes.hyphens_lower}-vpc-scanner" | ||
public_key = var.vpc_scanner_instance_public_key | ||
} | ||
|
||
data "aws_ami" "kali_pinned_ami" { | ||
most_recent = true | ||
|
||
filter { | ||
name = "name" | ||
values = ["kali-last-snapshot-amd64-2023.3.0-804fcc46-63fc-4eb6-85a1-50e66d6c7215"] | ||
} | ||
|
||
owners = [ | ||
"aws-marketplace" | ||
] | ||
} | ||
|
||
resource "aws_instance" "vpc_scanner" { | ||
associate_public_ip_address = true | ||
ami = data.aws_ami.kali_pinned_ami.id | ||
instance_type = var.vpc_scanner_instance_type | ||
key_name = aws_key_pair.vpc_scanner.key_name | ||
subnet_id = var.vpc_scanner_instance_subnet_id | ||
vpc_security_group_ids = [ | ||
aws_security_group.vpc_scanner_instance.id, | ||
] | ||
|
||
root_block_device { | ||
encrypted = true | ||
volume_size = var.vpc_scanner_instance_root_device_size_gb | ||
} | ||
|
||
tags = { | ||
"Name" = "${var.resource_name_prefixes.normal}:EC2:VPCSCAN" | ||
} | ||
} | ||
|
||
resource "aws_security_group" "vpc_scanner_instance" { | ||
name = "${var.resource_name_prefixes.normal}:EC2:VPCSCAN" | ||
description = "EC2 instance for VPC scanning" | ||
vpc_id = var.vpc_id | ||
|
||
tags = { | ||
Name = "${var.resource_name_prefixes.normal}:EC2:VPCSCAN" | ||
} | ||
} | ||
|
||
resource "aws_security_group_rule" "vpc_scanner_instance_ssh_in" { | ||
cidr_blocks = var.ithc_operative_cidr_safelist | ||
description = "Allow SSH from approved ranges into the VPC Scanner instance" | ||
from_port = 22 | ||
protocol = "tcp" | ||
security_group_id = aws_security_group.vpc_scanner_instance.id | ||
to_port = 22 | ||
type = "ingress" | ||
} | ||
|
||
resource "aws_security_group_rule" "vpc_scanner_http_anywhere_out" { | ||
cidr_blocks = [ | ||
"0.0.0.0/0", | ||
] | ||
description = "Allows HTTP to anywhere" | ||
from_port = 80 | ||
to_port = 80 | ||
protocol = "tcp" | ||
security_group_id = aws_security_group.vpc_scanner_instance.id | ||
type = "egress" | ||
} | ||
|
||
resource "aws_security_group_rule" "vpc_scanner_https_anywhere_out" { | ||
cidr_blocks = [ | ||
"0.0.0.0/0", | ||
] | ||
description = "Allows HTTPS to anywhere" | ||
from_port = 443 | ||
to_port = 443 | ||
protocol = "tcp" | ||
security_group_id = aws_security_group.vpc_scanner_instance.id | ||
type = "egress" | ||
} | ||
|
||
resource "aws_security_group_rule" "vpc_scanner_all_tcp_vpc_out" { | ||
cidr_blocks = [ | ||
var.vpc_cidr_block | ||
] | ||
description = "Any TCP within VPC" | ||
from_port = 0 | ||
to_port = 65535 | ||
protocol = "tcp" | ||
security_group_id = aws_security_group.vpc_scanner_instance.id | ||
type = "egress" | ||
} | ||
|
||
resource "aws_security_group_rule" "vpc_scanner_all_udp_vpc_out" { | ||
cidr_blocks = [ | ||
var.vpc_cidr_block | ||
] | ||
description = "Any UDP within VPC" | ||
from_port = 0 | ||
to_port = 65535 | ||
protocol = "udp" | ||
security_group_id = aws_security_group.vpc_scanner_instance.id | ||
type = "egress" | ||
} |