Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kaalpanikh/bastion-host
Secure AWS bastion host setup with Terraform automation, fail2ban, and SSH hardening for private infrastructure access
https://github.com/kaalpanikh/bastion-host
aws aws-ec2 bastion-host cloud-security devops fail2ban iac infra-automation infrastructure-as-code network-security security ssh-hardening terraform vpc
Last synced: 4 days ago
JSON representation
Secure AWS bastion host setup with Terraform automation, fail2ban, and SSH hardening for private infrastructure access
- Host: GitHub
- URL: https://github.com/kaalpanikh/bastion-host
- Owner: kaalpanikh
- Created: 2025-02-13T07:32:59.000Z (8 days ago)
- Default Branch: main
- Last Pushed: 2025-02-13T13:06:34.000Z (7 days ago)
- Last Synced: 2025-02-13T14:23:41.329Z (7 days ago)
- Topics: aws, aws-ec2, bastion-host, cloud-security, devops, fail2ban, iac, infra-automation, infrastructure-as-code, network-security, security, ssh-hardening, terraform, vpc
- Language: HCL
- Homepage:
- Size: 14.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Bastion Host Implementation Project
Project URL: [roadmap.sh/projects/bastion-host](https://roadmap.sh/projects/bastion-host)
## Project Overview
This project implements a secure bastion host architecture in AWS, providing a secure way to access private infrastructure. The implementation includes VPC setup, security configurations, and SSH hardening measures.## Architecture
```mermaid
graph LR
Internet((Internet))
subgraph VPC [VPC 10.0.0.0/16]
subgraph Public [Public Subnet 10.0.1.0/24]
BH[Bastion Host\nt2.micro]
end
subgraph Private [Private Subnet 10.0.2.0/24]
PS[Private Server\nt2.micro]
end
IGW[Internet Gateway]
end
Internet --> IGW
IGW --> BH
BH --> PS
style VPC fill:#f5f5f5,stroke:#333,stroke-width:2px
style Public fill:#e1f5fe,stroke:#333,stroke-width:1px
style Private fill:#ffebee,stroke:#333,stroke-width:1px
style BH fill:#b3e5fc,stroke:#333,stroke-width:1px
style PS fill:#ffcdd2,stroke:#333,stroke-width:1px
style IGW fill:#e8f5e9,stroke:#333,stroke-width:1px
```### Components Created
1. **VPC (10.0.0.0/16)**
- Public Subnet: 10.0.1.0/24
- Private Subnet: 10.0.2.0/24
- Internet Gateway
- Route Tables for public and private subnets2. **EC2 Instances**
- Bastion Host (Public)
- Instance Type: t2.micro
- AMI: Amazon Linux 2
- Private Server
- Instance Type: t2.micro
- AMI: Amazon Linux 23. **Security Groups**
```json
Bastion Security Group:
- Inbound: SSH (22) from 0.0.0.0/0
- Outbound: All trafficPrivate Server Security Group:
- Inbound: SSH (22) from Bastion SG
- Outbound: All traffic
```## Implementation Steps
### 1. VPC Setup
```bash
# Create VPC
aws ec2 create-vpc --cidr-block 10.0.0.0/16# Create Subnets
aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block 10.0.1.0/24
aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block 10.0.2.0/24# Create and Attach Internet Gateway
aws ec2 create-internet-gateway
aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID
```### 2. Security Group Configuration
```bash
# Bastion Security Group
aws ec2 create-security-group --group-name bastion-sg \
--description "Security group for bastion host" --vpc-id $VPC_ID# Private Server Security Group
aws ec2 create-security-group --group-name private-sg \
--description "Security group for private instance" --vpc-id $VPC_ID
```### 3. Instance Launch
```bash
# Launch Bastion Host
aws ec2 run-instances --image-id $AMI_ID --instance-type t2.micro \
--key-name your-key-name --security-group-ids $BASTION_SG_ID \
--subnet-id $PUBLIC_SUBNET_ID# Launch Private Server
aws ec2 run-instances --image-id $AMI_ID --instance-type t2.micro \
--key-name your-key-name --security-group-ids $PRIVATE_SG_ID \
--subnet-id $PRIVATE_SUBNET_ID
```### 4. SSH Configuration
Example SSH config:
```
Host bastion
HostName
User ec2-user
IdentityFile ~/.ssh/your-key.pemHost private-server
HostName
User ec2-user
ProxyJump bastion
IdentityFile ~/.ssh/your-key.pem
```## Infrastructure Automation with Terraform
### Directory Structure
```
terraform/
├── main.tf # Main Terraform configuration
├── variables.tf # Variable definitions
├── outputs.tf # Output definitions
├── terraform.tfvars.example # Example variables file
└── scripts/
└── bastion_setup.sh # Bastion host setup script
```### Prerequisites
1. [Terraform](https://www.terraform.io/downloads.html) installed (v1.0.0 or newer)
2. AWS credentials configured
3. SSH key pair created in AWS### Quick Start
1. Clone this repository
2. Navigate to the terraform directory:
```bash
cd terraform
```3. Copy and configure variables:
```bash
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars with your values
```4. Initialize Terraform:
```bash
terraform init
```5. Review the execution plan:
```bash
terraform plan
```6. Apply the configuration:
```bash
terraform apply
```### What Gets Created
- VPC with public and private subnets
- Internet Gateway
- Route tables
- Security groups for bastion and private instances
- EC2 instances (bastion host and private server)
- Automatic security configurations:
- fail2ban installation and configuration
- SSH hardening
- Security group rules### Customization
You can customize the deployment by modifying:
- `terraform.tfvars`: Change region, CIDR blocks, instance types
- `scripts/bastion_setup.sh`: Modify security configurations
- `main.tf`: Adjust resource configurations### Cleanup
To destroy all created resources:
```bash
terraform destroy
```## Cleanup Process
When you're done with the bastion host setup, follow these steps to clean up all AWS resources in the correct order to avoid dependency conflicts:### 1. Terminate EC2 Instances
```bash
# Terminate the bastion host
aws ec2 terminate-instances --instance-ids# Wait for instance to fully terminate
aws ec2 describe-instances --instance-ids
# Check that state is "terminated"
```### 2. Delete Network Components
Delete components in this specific order to handle dependencies:1. Detach and Delete Internet Gateway:
```bash
# Detach from VPC
aws ec2 detach-internet-gateway \
--internet-gateway-id \
--vpc-id# Delete the internet gateway
aws ec2 delete-internet-gateway --internet-gateway-id
```2. Delete Security Groups:
```bash
# Delete private server security group
aws ec2 delete-security-group --group-id# Delete bastion host security group
aws ec2 delete-security-group --group-id
```3. Delete Subnets:
```bash
# Delete public subnet
aws ec2 delete-subnet --subnet-id# Delete private subnet
aws ec2 delete-subnet --subnet-id
```4. Delete Route Tables:
```bash
# Delete custom route tables
aws ec2 delete-route-table --route-table-id
```5. Delete VPC:
```bash
# Finally, delete the VPC
aws ec2 delete-vpc --vpc-id
```### Verification Steps
After deletion, verify that all resources are removed:```bash
# Check VPC
aws ec2 describe-vpcs --vpc-id
# Should return: InvalidVpcID.NotFound# Check Security Groups
aws ec2 describe-security-groups --group-ids
# Should return: InvalidGroup.NotFound# Check Subnets
aws ec2 describe-subnets --subnet-ids
# Should return: InvalidSubnetID.NotFound# Check Internet Gateway
aws ec2 describe-internet-gateways --internet-gateway-ids
# Should return: InvalidInternetGatewayID.NotFound
```### Common Issues During Cleanup
1. **Dependency Violations**: If you receive a dependency violation error, it means you're trying to delete a resource that other resources still depend on. Follow the order specified above.2. **Resource Still in Use**: Sometimes AWS needs a few minutes to fully process the termination of resources. Wait a few minutes and try again.
3. **Main Route Table**: The main route table associated with the VPC will be automatically deleted when the VPC is deleted.
### Cost Implications
- Terminating resources stops any ongoing charges
- Check your AWS billing dashboard to confirm no unexpected charges
- Some resources like EBS volumes might need separate deletion if not set to auto-delete## Proof of Implementation
### 1. VPC and Subnet Creation
```bash
$ aws ec2 describe-vpcs
{
"Vpcs": [
{
"CidrBlock": "10.0.0.0/16",
"State": "available",
"VpcId": "vpc-xxxxx",
"InstanceTenancy": "default",
"CidrBlockAssociationSet": [
{
"CidrBlock": "10.0.0.0/16",
"CidrBlockState": {
"State": "associated"
}
}
],
"Tags": [
{
"Key": "Name",
"Value": "bastion-vpc"
}
]
}
]
}
```### 2. Security Groups Configuration
```bash
$ aws ec2 describe-security-groups
{
"SecurityGroups": [
{
"GroupName": "bastion-sg",
"Description": "Security group for bastion host",
"IpPermissions": [
{
"FromPort": 22,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"ToPort": 22
}
]
},
{
"GroupName": "private-sg",
"Description": "Security group for private instance",
"IpPermissions": [
{
"FromPort": 22,
"IpProtocol": "tcp",
"UserIdGroupPairs": [
{
"GroupId": ""
}
],
"ToPort": 22
}
]
}
]
}
```### 3. EC2 Instances
```bash
$ aws ec2 describe-instances --query "Reservations[*].Instances[*].[Tags[?Key=='Name'].Value|[0],State.Name]" --output table
---------------------------------
| DescribeInstances |
+---------------+---------------+
| bastion-host | running |
| private-server| running |
+---------------+---------------+
```### 4. SSH Configuration File
```bash
$ cat ~/.ssh/config
Host bastion
HostName
User ec2-user
IdentityFile ~/.ssh/your-key.pemHost private-server
HostName
User ec2-user
ProxyJump bastion
IdentityFile ~/.ssh/your-key.pem
```### 5. fail2ban Installation and Configuration
```bash
$ ssh bastion "systemctl status fail2ban"
● fail2ban.service - Fail2Ban Service
Loaded: loaded
Active: active (running)
```### 6. SSH Hardening Verification
```bash
$ ssh bastion "sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|x11forwarding'"
permitrootlogin no
passwordauthentication no
x11forwarding no
```### 7. Connection Tests
```bash
$ ssh bastion "echo 'Connection to bastion host successful!'"
Connection to bastion host successful!$ ssh private-server "echo 'Connection to private server successful!'"
Connection to private server successful!
```## Security Features
1. **Network Security**
- Private server accessible only through bastion host
- Public subnet with Internet Gateway for bastion
- Private subnet for secure server2. **Access Control**
- Key-based authentication only
- fail2ban for brute force protection
- No root login allowed
- SSH hardening configurations3. **Monitoring**
- SSH session logging
- fail2ban logs for access attempts## Challenges Faced
1. **SSH Access Issues**
- Problem: Lost SSH access after implementing strict security measures
- Solution Attempted: Created temporary security group for recovery
- Status: Access recovery in progress2. **Security Implementation**
- MFA implementation pending
- iptables configuration pending## Future Improvements
1. Implement Multi-Factor Authentication (MFA)
2. Configure iptables for granular traffic filtering
3. Set up CloudWatch monitoring
4. Implement automatic security patches
5. Add backup and disaster recovery procedures## Resources Used
1. [AWS VPC Documentation](https://docs.aws.amazon.com/vpc/)
2. [AWS EC2 Documentation](https://docs.aws.amazon.com/ec2/)
3. [OpenSSH Documentation](https://www.openssh.com/manual.html)
4. [fail2ban Documentation](https://www.fail2ban.org/wiki/index.php/Main_Page)## Project Status
- Core infrastructure: Complete
- Basic security measures: Complete
- Advanced security (MFA, iptables): Pending
- Documentation: Complete