From 21d4bfc55e940cdf4805cfd9d19d681fa3f0b827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arturo=20Filast=C3=B2?= Date: Tue, 23 Apr 2024 14:59:44 +0200 Subject: [PATCH] Add support for CloudHSM codesigning machine (#51) * Create cloud HSM code signing cluster * Setup separate private network for communicating with the cloud HSM * Setup EC2 machine that has access to the cloud HSM module via the private network --- tf/environments/prod/main.tf | 13 ++++++ tf/modules/adm_iam_roles/main.tf | 3 +- tf/modules/cloudhsm/main.tf | 78 ++++++++++++++++++++++++++++++++ tf/modules/cloudhsm/outputs.tf | 3 ++ tf/modules/cloudhsm/variables.tf | 28 ++++++++++++ tf/modules/network/main.tf | 42 ++++++++++++++++- tf/modules/network/outputs.tf | 9 +++- tf/modules/network/variables.tf | 5 ++ 8 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 tf/modules/cloudhsm/main.tf create mode 100644 tf/modules/cloudhsm/outputs.tf create mode 100644 tf/modules/cloudhsm/variables.tf diff --git a/tf/environments/prod/main.tf b/tf/environments/prod/main.tf index 7374dae0..f572f467 100644 --- a/tf/environments/prod/main.tf +++ b/tf/environments/prod/main.tf @@ -122,6 +122,8 @@ module "network" { aws_availability_zones_available = data.aws_availability_zones.available + enable_codesign_network = true + depends_on = [module.adm_iam_roles] } @@ -563,3 +565,14 @@ module "oonith_oohelperd" { { Name = "ooni-tier0-oohelperd" } ) } + +## Code signing setup + +module "codesigning" { + source = "../../modules/cloudhsm" + + vpc_id = module.network.vpc_id + subnet_id = module.network.vpc_subnet_cloudhsm[0].id + subnet_cidr_block = module.network.vpc_subnet_cloudhsm[0].cidr_block + key_name = module.adm_iam_roles.oonidevops_key_name +} diff --git a/tf/modules/adm_iam_roles/main.tf b/tf/modules/adm_iam_roles/main.tf index 12ef9fb7..78504275 100644 --- a/tf/modules/adm_iam_roles/main.tf +++ b/tf/modules/adm_iam_roles/main.tf @@ -49,7 +49,8 @@ resource "aws_iam_policy" "oonidevops" { "dynamodb:*", "states:*", "organizations:*", - "secretsmanager:*" + "secretsmanager:*", + "cloudhsm:*" ], "Resource": "*" } diff --git a/tf/modules/cloudhsm/main.tf b/tf/modules/cloudhsm/main.tf new file mode 100644 index 00000000..2caa49d9 --- /dev/null +++ b/tf/modules/cloudhsm/main.tf @@ -0,0 +1,78 @@ +resource "aws_cloudhsm_v2_cluster" "hsm" { + hsm_type = "hsm1.medium" + subnet_ids = [var.subnet_id] + + tags = var.tags +} + +resource "aws_security_group" "hsm" { + vpc_id = var.vpc_id + + ingress { + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + from_port = 2223 # Port for CloudHSM + to_port = 2225 + protocol = "tcp" + cidr_blocks = [var.subnet_cidr_block] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +data "aws_ami" "amazon_linux" { + most_recent = true + owners = ["amazon"] + + filter { + name = "name" + values = ["al2023-ami-*"] + } + + filter { + name = "architecture" + values = ["x86_64"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + +} + +resource "aws_instance" "codesign_box" { + ami = data.aws_ami.amazon_linux.id + + key_name = var.key_name + instance_type = "t3.micro" + + subnet_id = var.subnet_id + vpc_security_group_ids = [aws_security_group.hsm.id] + + associate_public_ip_address = true + + user_data = <<-EOF + #!/bin/bash + sudo yum update -y + curl -o cloudhsm.rpm https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/Amzn2023/cloudhsm-cli-latest.amzn2023.x86_64.rpm + sudo yum install -y ./cloudhsm-cli.rpm + rm cloudhsm-cli.rpm + + curl -o cloudhsm-pkcs11.rpm https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/Amzn2023/cloudhsm-pkcs11-latest.amzn2023.x86_64.rpm + sudo yum install -y ./cloudhsm-pkcs11.rpm + rm cloudhsm-pkcs11.rpm + EOF + + tags = merge(var.tags, { Name = "codesign-box" }) +} diff --git a/tf/modules/cloudhsm/outputs.tf b/tf/modules/cloudhsm/outputs.tf new file mode 100644 index 00000000..31b57097 --- /dev/null +++ b/tf/modules/cloudhsm/outputs.tf @@ -0,0 +1,3 @@ +output "cloudhsm_cluster_id" { + value = aws_cloudhsm_v2_cluster.hsm.id +} diff --git a/tf/modules/cloudhsm/variables.tf b/tf/modules/cloudhsm/variables.tf new file mode 100644 index 00000000..4939d3bc --- /dev/null +++ b/tf/modules/cloudhsm/variables.tf @@ -0,0 +1,28 @@ +variable "aws_region" { + description = "The AWS region to create things in." + default = "eu-central-1" +} + +variable "key_name" { + description = "Name of AWS key pair" +} + +variable "vpc_id" { + description = "the id of the VPC to deploy the instance into" +} + +variable "subnet_id" { + description = "the id of the subnet for the HSM" + type = string +} + +variable "subnet_cidr_block" { + description = "the ids of the subnet of the subnets to deploy the instance into" + type = string +} + +variable "tags" { + description = "tags to apply to the resources" + default = {} + type = map(string) +} diff --git a/tf/modules/network/main.tf b/tf/modules/network/main.tf index 450ef7e7..4e60e031 100644 --- a/tf/modules/network/main.tf +++ b/tf/modules/network/main.tf @@ -1,5 +1,6 @@ locals { - private_net_offset = 100 + private_net_offset = 100 + cloudhsm_net_offset = 200 } resource "aws_vpc" "main" { @@ -58,6 +59,7 @@ resource "aws_subnet" "private" { } } + resource "aws_eip" "nat" { count = var.az_count domain = "vpc" @@ -144,3 +146,41 @@ resource "aws_route_table_association" "private" { create_before_destroy = true } } + +resource "aws_subnet" "cloudhsm" { + count = var.enable_codesign_network ? 1 : 0 + cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, local.cloudhsm_net_offset) + + availability_zone = var.aws_availability_zones_available.names[0] + vpc_id = aws_vpc.main.id + map_public_ip_on_launch = false + + depends_on = [aws_internet_gateway.gw] + + lifecycle { + create_before_destroy = true + } + + tags = { + Name = "ooni-cloudhsm-subnet-0" + } +} + +resource "aws_route_table" "cloudhsm" { + vpc_id = aws_vpc.main.id + + route { + cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.gw.id + } + + tags = { + Name = "ooni-cloudhsm-route-table" + } +} + +resource "aws_route_table_association" "cloudhsm" { + count = var.enable_codesign_network ? 1 : 0 + subnet_id = element(aws_subnet.cloudhsm[*].id, count.index) + route_table_id = aws_route_table.cloudhsm.id +} diff --git a/tf/modules/network/outputs.tf b/tf/modules/network/outputs.tf index 5f1844a3..555991dd 100644 --- a/tf/modules/network/outputs.tf +++ b/tf/modules/network/outputs.tf @@ -4,11 +4,16 @@ output "vpc_id" { } output "vpc_subnet_public" { - description = "The value of the subnet associated to the VPC" + description = "The value of the public subnet associated to the VPC" value = aws_subnet.public } output "vpc_subnet_private" { - description = "The value of the subnet associated to the VPC" + description = "The value of the private subnet associated to the VPC" value = aws_subnet.private } + +output "vpc_subnet_cloudhsm" { + description = "The value of the cloudhsm subnet associated to the VPC" + value = aws_subnet.cloudhsm +} diff --git a/tf/modules/network/variables.tf b/tf/modules/network/variables.tf index 4410ab13..1416be87 100644 --- a/tf/modules/network/variables.tf +++ b/tf/modules/network/variables.tf @@ -19,3 +19,8 @@ variable "tags" { type = map(string) } +variable "enable_codesign_network" { + description = "Enable codesign network" + default = false + type = bool +}