Skip to content

MdAkbar123/bastion-host-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bastion Host Setup on AWS (Terraform)

Purpose

This Terraform project creates a secure bastion host in AWS to manage SSH access to a private EC2 instance. The bastion is the only public entry point; private instances remain inaccessible from the internet.

Architecture

  • VPC with a public subnet (10.0.1.0/24) and a private subnet (10.0.2.0/24)
  • Bastion Host: public EC2 with Elastic IP, SSH access restricted to your IP, Fail2Ban installed
  • Private Server: EC2 in private subnet, no public IP, SSH allowed only from the Bastion
  • SSH keys are generated automatically by Terraform and stored locally

Repository Layout

bastion-host-setup/

  • main.tf # VPC, subnets, IGW, NAT, routing
  • bastion.tf # Bastion EC2, SG, EIP, user_data (Fail2Ban)
  • private-server.tf # Private EC2 and SG
  • keys.tf # Automatic SSH key generation
  • iam.tf # Optional: IAM roles/policies (e.g., CloudWatch)
  • variables.tf # Configurable variables
  • outputs.tf # Useful outputs (bastion IP, private IPs, key paths)
  • terraform.tfvars # Environment-specific values

Prerequisites

  • Terraform (>= 0.12 recommended)
  • AWS account and credentials configured (AWS CLI or env vars)
  • Internet access to download providers and AMIs

Quickstart

  1. Initialize Terraform terraform init

  2. Validate config terraform validate

  3. Preview plan terraform plan -out infra.plan

  4. Apply terraform apply infra.plan

What Terraform will create

  • VPC, public and private subnets, IGW and NAT
  • Security groups:
    • Bastion SG: SSH (22) from your local IP only
    • Private SG: SSH (22) from Bastion private IP only
  • Bastion EC2 (public) with Elastic IP and Fail2Ban via user_data
  • Private EC2 (no public IP)
  • Two PEM key files generated locally:
    • bastion_key.pem
    • private_server_key.pem

SSH Usage

  1. Protect generated keys: chmod 400 bastion_key.pem private_server_key.pem

  2. SSH to bastion: ssh -i bastion_key.pem ubuntu@<bastion_public_ip>

  3. From bastion, SSH to private instance: ssh -i ~/.ssh/private-server.pem ubuntu@<private_server_private_ip>

Recommended: copy the private-server key to the bastion first: scp -i bastion_key.pem private_server_key.pem ubuntu@<bastion_public_ip>:/home/ubuntu/.ssh/private-server.pem ssh -i bastion_key.pem ubuntu@<bastion_public_ip> chmod 400 ~/.ssh/private-server.pem ssh -i ~/.ssh/private-server.pem ubuntu@10.0.2.x

Fail2Ban

Fail2Ban is installed automatically on the bastion using instance user_data. To check status:

  • sudo fail2ban-client status
  • sudo systemctl status fail2ban
  • sudo tail -f /var/log/fail2ban.log

Security Notes

  • Bastion SSH ingress is limited to your IP (configure in terraform.tfvars)
  • Private server SSH is limited to the Bastion private IP
  • Keys are generated locally and not stored in the repository or AWS
  • Rotate keys and restrict who has access to PEM files
  • Consider additional hardening: MFA for AWS console, session logging (CloudWatch), and OS-level hardening

Outputs

Expected useful outputs (from outputs.tf):

  • bastion_public_ip
  • bastion_private_ip
  • private_server_private_ip
  • local paths to generated PEM files

Cleanup

To destroy everything created by Terraform: terraform destroy

Troubleshooting

  • If SSH times out, check security group rules and routing
  • If instances fail to boot services, view cloud-init logs: sudo journalctl -u cloud-init -b /var/log/cloud-init-output.log

Notes

  • Adjust AMI, instance type, and region in variables.tf
  • This project is a starting point; adapt IAM, monitoring, and logging for production

https://roadmap.sh/projects/bastion-host

License

MIT (or specify your preferred license)

About

Setup a bastion host for managing access to private infrastructure.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages