Sitemap

Building a Secure Two-Tier Network on AWS — The Bastion Host Approach

4 min readOct 25, 2026

--

Press enter or click to view image in full size

A bastion host — also called a jump box — is a special virtual server placed in your public network that acts as a secure gateway to your private servers. Think of it like the reception desk in an office building: visitors can see and speak to the receptionist, but they cannot walk directly into the inner offices.

In cloud computing, we keep our databases and backend servers in a “private subnet” — meaning they have no public internet address and cannot be reached directly from outside. This is excellent for security, but it creates a problem: how do we access those private servers when we need to? That is exactly what a bastion host solves. It sits in the public subnet, acts as the only entry point, and you log into the private servers through it. Best of all, we can lock the bastion down so that only trusted people — like you, from your own IP address — can even reach it. This reduces your “attack surface”: hackers can’t see or target your private systems at all.

How I Built My Two-Tier Network

I started by creating a Virtual Private Cloud (VPC) — my own isolated private network on AWS — with the address range 10.0.0.0/16 . Inside this VPC, I created two subnets in the same availability zone: a Public Subnet using 10.0.16.0/24 and a Private Subnet using 10.0.17.0/24 .

Press enter or click to view image in full size
SC OF VPC WITH PUBLIC AND PRIVATE SUBNET IN SAME AZ
Press enter or click to view image in full size
SC OF SECURITY GROUP INBOUND RULES FOR MY PRIVATE VM THROUGH THE BASTION HOST SECURITY GROUP

Next, I created and attached an Internet Gateway to the VPC. I updated the public subnet’s route table to send all internet-bound traffic ( 0.0.0.0/0 ) through that gateway, so public servers could connect to the web. The private subnet stayed with its default route only — no internet access at all.

Get Olatunde Peter’s stories in your inbox

Join Medium for free to get updates from this writer.

Then I launched two EC2 instances:

  • Bastion Host: In the Public Subnet, with a public IP. Its security group allowed SSH (port 22) only from my personal IP address.
Press enter or click to view image in full size
SC OF SUCCESSFUL SSH INTO MY BASTION HOST WITH MY PUBLIC KEY

​

- Private Server: In the Private Subnet, with NO public IP address. Its security group allowed SSH traffic — not from an IP address, but directly from the Bastion’s security group. This means only traffic coming from the bastion is permitted.

To connect securely, I used SSH Agent Forwarding. Instead of copying my private key onto the bastion — which would be unsafe — I ran ssh -A from my local machine. This kept my key right where it belonged: on my own computer. The bastion simply forwarded my authentication request through to the private server, and I was logged in securely without ever exposing my key.

Press enter or click to view image in full size
SC OF SUCCESSFUL SSH INTO MY PRIVATE VM FROM MY BASTION HOST THROUGH THE SSH AGENT FORWARDING

Challenges I Faced and How I Fixed Them

Press enter or click to view image in full size
SCREENSHOT OF CIDR ERROR WITH SUBNET-NAME AND AVAILABILITY ZONE

The first major issue was CIDR overlap. When creating my subnets, AWS gave an error saying the address range was already in use. I learned that subnets cannot overlap with any existing addresses in your VPC. I resolved this by choosing completely separate ranges: 10.0.16.0/24 for public and 10.0.17.0/24 for private.

The second challenge was SSH connection errors. Initially, I tried connecting to the private server using its private IP from my local computer — which failed, because private IPs are not reachable over the internet. I also struggled with file permissions on my key file until I learned SSH strictly rejects keys that are readable by anyone else; running chmod 400 fixed that. The biggest lesson was understanding the correct order: local machine → bastion (public address) → private server (private address), and using agent forwarding so my key never had to leave my own device.

This project taught me that good security isn’t about making things complicated — it’s about designing networks where each component only has exactly the access it needs, and nothing more.

--

--