DEV Community

Cover image for AWS Networking with Terraform: Bastion Hosts to restrict access to Private Hosts
Chinmay Tonape
Chinmay Tonape

Posted on • Updated on

AWS Networking with Terraform: Bastion Hosts to restrict access to Private Hosts

In our previous post, we explored how to enhance storage resiliency by attaching EFS volumes to multiple EC2 instances.

Now, let's delve into AWS networking concepts, starting with the pivotal role of Bastion hosts. We'll employ Terraform to create modular components, ensuring a seamless and reproducible setup.

A bastion host is a server whose purpose is to provide access to a private network from an external network, such as the Internet. Because of its exposure to potential attack, a bastion host must minimize the chances of penetration. For example, you can use a bastion host to mitigate the risk of allowing SSH connections from an external network to the Linux instances launched in a private subnet of your Amazon Virtual Private Cloud (VPC).

Architecture Overview:

Before diving into implementation, let's understand the architecture we'll be building:

Bastion Host Architecture Diagram

Step 1: Creating the VPC and Network Components

Create VPC with IGW, 1 Public and 1 private subnet with route table associations. Please refer to my github repo in resources section below.

Step 2: Deploying a Bastion Host in the Public Subnet and a Private Host in the Private Subnet

Deploy Linux EC2 instances one in each subnet.



####################################################
# Create EC2 Server Instances
####################################################

module "vpc_a_bastion_host" {
  source           = "./modules/web"
  instance_type    = var.instance_type
  instance_key     = var.instance_key
  subnet_id        = module.vpc_a.public_subnets[0]
  vpc_id           = module.vpc_a.vpc_id
  ec2_name         = "Bastion Host A"
  sg_ingress_ports = var.sg_ingress_public
  common_tags      = local.common_tags
  naming_prefix    = local.naming_prefix
}

module "vpc_a_private_host" {
  source           = "./modules/web"
  instance_type    = var.instance_type
  instance_key     = var.instance_key
  subnet_id        = module.vpc_a.private_subnets[0]
  vpc_id           = module.vpc_a.vpc_id
  ec2_name         = "Private Host A"
  sg_ingress_ports = var.sg_ingress_private
  common_tags      = local.common_tags
  naming_prefix    = local.naming_prefix
}


Enter fullscreen mode Exit fullscreen mode

Step 3: Implementing Access Restriction using Security Groups

Amend private subnet security group to allow traffic only from public subnet.



####################################################
# Amend Private Host SG to allow traffic from Bastion Host SG
####################################################
resource "aws_security_group_rule" "public_in_ssh" {
  type                     = "ingress"
  from_port                = 22
  to_port                  = 22
  protocol                 = "tcp"
  security_group_id        = module.vpc_a_private_host.security_group_id
  source_security_group_id = module.vpc_a_bastion_host.security_group_id
}


Enter fullscreen mode Exit fullscreen mode

Steps to Run Terraform

Follow these steps to execute the Terraform configuration:



terraform init
terraform plan 
terraform apply -auto-approve


Enter fullscreen mode Exit fullscreen mode

Upon successful completion, Terraform will provide relevant outputs.



Apply complete! Resources: 12 added, 0 changed, 0 destroyed.


Enter fullscreen mode Exit fullscreen mode

Testing the outcome

Bastion Host with Public IP in Public Subnet:
Bastion Host

Private Host without Public IP in Private Subnet:
Private Host

Private Host Security group with only inbound from Bastion Host Security Group:
Private Host Security Group

Connecting to Private Host from Bastion Host.
You will need to create key pair with correct permissions on bastion host before connecting to Private Host



chmod 0400 WorkshopKeyPair.pem
ssh ec2-user@10.1.2.71 -i WorkshopKeyPair.pem


Enter fullscreen mode Exit fullscreen mode

Connecting Private Host via Bastion Host

Cleanup:

Remember to stop AWS components to avoid large bills.



terraform destroy -auto-approve


Enter fullscreen mode Exit fullscreen mode

With the Bastion host setup accomplished, our next module will delve deeper into AWS networking. We'll explore setting up peer-to-peer VPC connections to further enhance our network architecture.

Resources:

Github Link: https://github.com/chinmayto/terraform-aws-networking-bastion-host
Bastion Host Concept: https://www.knowledgehut.com/tutorials/aws/aws-bastion-host

Top comments (0)