Bastion Server
Your database server should never be one misconfigured security group away from the public internet.
Yet in many infrastructure setups — especially early-stage ones — that's exactly what happens. Private servers get assigned public IPs. SSH ports get opened to 0.0.0.0/0. Engineers take shortcuts to move fast, and the exposure quietly accumulates.
A Bastion Server is one of the simplest, most effective patterns to prevent this.
The Problem It Solves
Imagine you have a fleet of EC2 instances sitting in a private subnet — application servers, databases, internal tooling. None of them should be reachable from the public internet. That's the whole point of a private subnet.
But you still need to access them. You need to SSH in, debug a process, check logs, run a migration.
The naive solution: give each instance a public IP and open port 22 to the world.
The problem: you've just handed attackers a direct line to your most sensitive infrastructure. Every instance becomes an attack surface. Credentials get brute-forced. Keys get leaked. A single compromised server cascades into a full breach.
The better approach is to control the entry point.
What Is a Bastion Server?
A Bastion Server — also called a Jump Server or Jump Box — is a single, hardened server that acts as the sole entry point into your private network.
It sits in a public subnet, facing the internet. Everything else sits in private subnets, invisible to the outside world. The only way in is through the bastion.
You (Internet)
│
▼
┌─────────────┐ Public Subnet
│ Bastion Host│
└─────────────┘
│
▼
┌─────────────────────────────────┐ Private Subnet
│ App Server │ DB Server │ ... │
└─────────────────────────────────┘
You SSH into the bastion first. From there, you hop to any private server. Your private instances never receive a connection from the open internet — only from the bastion's private IP.
This is called a two-hop architecture.
How the Connection Works
Hop 1 — Into the Bastion
ssh -i ~/.ssh/my-key.pem ec2-user@<bastion-public-ip>
You're now inside the bastion. It has visibility into the private subnet.
Hop 2 — Into the Private Server
ssh -i ~/.ssh/my-key.pem ec2-user@<private-server-ip>
Because the bastion and your private instances are in the same VPC, this works using private IPs — no public exposure needed.
The Cleaner Way: SSH ProxyJump
Doing this in two steps every time gets tedious. The -J flag (ProxyJump) collapses both hops into a single command:
ssh -J ec2-user@<bastion-public-ip> ec2-user@<private-server-ip>
Even better — set it up in your ~/.ssh/config so you never have to think about it:
Host bastion
HostName <bastion-public-ip>
User ec2-user
IdentityFile ~/.ssh/my-key.pem
Host private-server
HostName <private-server-ip>
User ec2-user
IdentityFile ~/.ssh/my-key.pem
ProxyJump bastion
Now you just run:
ssh private-server
One command. Two hops. No mental overhead.
Why This Works as a Security Pattern
The power of the bastion model comes down to attack surface reduction.
Without a bastion, every private server is a potential door. You're defending dozens of entry points simultaneously. A single weak key, a single misconfigured security group, and an attacker is inside.
With a bastion, there is exactly one door. It's the only server with a public IP. It's the only server with port 22 open to the internet. All your hardening effort is concentrated in one place.
If an attacker wants to reach your database, they have to get through the bastion first. And the bastion is purpose-built to resist that.
Hardening the Bastion
A bastion is only as strong as how it's configured. Exposing it to the internet and calling it a day defeats the purpose.
Restrict inbound SSH by IP
Don't open port 22 to 0.0.0.0/0. Lock it down to your office IP range or your team's known IPs.
Inbound Rule: SSH (port 22) — Source: <your-office-ip>/32
Disable password authentication
Only SSH key pairs. No exceptions.
# /etc/ssh/sshd_config
PasswordAuthentication no
PermitRootLogin no
Enable MFA
Add a second factor using tools like Google Authenticator with libpam-google-authenticator. Even if a key leaks, access isn't automatic.
Keep it minimal
The bastion should do one thing: act as a jump point. No web servers. No databases. No application code. Every extra service is another attack vector.
Log everything
Every session through the bastion should be audited. Use tools like auditd or cloud-native solutions (AWS CloudTrail, for example) to capture who connected, when, and what commands they ran.
Bastions in the Cloud
In AWS, the pattern maps directly to VPC architecture:
| Component | Where It Lives |
|---|---|
| Bastion Host (EC2) | Public Subnet |
| App Servers (EC2) | Private Subnet |
| Databases (RDS) | Private Subnet |
| Internet Gateway | Attached to VPC |
The bastion sits in the public subnet, reachable via the Internet Gateway. The private subnet has no route to the internet — traffic in or out flows only through the bastion.
The same pattern applies in GCP (using a bastion inside a VPC with no external IPs on other instances) and Azure (using Azure Bastion or a jump VM in a subnet with restricted NSG rules).
Modern Alternatives
Bastions work well, but they're not the only option. As cloud tooling has matured, a few alternatives have emerged:
AWS Systems Manager Session Manager — access private EC2 instances without any open SSH ports, no bastion needed. All sessions go through the SSM agent. No keys to manage, no port 22, full audit trail in CloudTrail.
VPNs — connect your machine to the private network as if you were on the same LAN. Suitable when you need broad internal access rather than server-to-server hops.
Zero Trust / Identity-Aware Proxies — tools like Tailscale, Cloudflare Access, or HashiCorp Boundary verify identity at the application layer, not the network layer.
Each has tradeoffs. Bastions remain common because they're simple, infrastructure-agnostic, and don't require buy-in from every engineer on the team to work.
When to Use a Bastion
A bastion is a good fit when:
- You have servers in private subnets that engineers need SSH access to
- You want a single, auditable choke point for all administrative access
- You're in a regulated environment (HIPAA, PCI-DSS) that requires access logging
- You're not yet ready to adopt full zero-trust tooling
It starts to show its limits when your team scales significantly — managing SSH keys across many engineers becomes painful, and the bastion can become a bottleneck. At that stage, tools like SSM Session Manager or Teleport are worth evaluating.
Summary
A Bastion Server is a deceptively simple idea with real security impact.
Rather than exposing every private server to the internet, you expose exactly one — purpose-built, hardened, and monitored. Engineers access the private network through it. Attackers face a single, well-guarded chokepoint instead of a sprawling surface.
The pattern is decades old and still relevant because it maps cleanly to how networks work. One door. One lock. All the attention on that one lock.