Auth logs show 50,000 SSH attempts on a small staging VPS this weekend. Nothing compromised — root password disabled. But noise hides real alerts, and fail2ban banned monitoring IP.
A bastion concentrates admin: one hardened, logged entry point — instead of N servers with public :22.
Bastion model
Architecture: admin → bastion (public or VPN-only) → private targets without public SSH.
Harden bastion: minimal OS, security auto-update, 2FA, AllowUsers, no agent forwarding unless needed.
ProxyJump and ergonomics
Example ~/.ssh/config with Host bastion + ProxyJump + ControlMaster.
Document one-liner for newcomers — or they bypass with ad hoc tunnels.
Keys and rotation
One key per human, not shared on Slack. authorized_keys via IaC. Revoke on departure.
Bastion knows human keys; targets know bastion key or SSH certs.
Audit and recording
Session recording for regulated prod. Minimum: centralize auth.log to SIEM. Alert off-hours + improbable geo logins.
Modern alternatives
| Tool | Strength | Weakness |
|---|---|---|
| WireGuard mesh | No perceived jump | Key governance |
| SSM | Zero inbound | AWS lock-in |
| Tailscale SSH | SMB simplicity | ACL discipline |
Choose by cloud vs bare metal.
Typical bastion week
Monday: review weekend bastion auth.log anomalies. Tuesday: sync authorized_keys from IaC. Wednesday: ProxyJump test for new hire. Thursday: bastion OS patch check. Friday: export session logs to SIEM.
Monthly: human key rotation review. Quarterly: exercise "access without bastion must fail" on server sample.
Annual: DR test — rebuild bastion from Ansible, restore access <1h.
Bastion helps only if team uses it without friction — measure "SSH timeout" tickets before adding extra hops.
Progressive hardening
Week 1: bastion up, parallel direct access still for rollback. Week 2: firewall closes direct 22 except bastion. Week 3: audit log review. Week 4: remove parallel access.
Measure "SSH impossible" tickets — if >2× rise, ProxyJump ergonomics insufficient, not team resistance.
Backup bastion config off prod; quarterly rebuild test.
External contractors: temporary bastion account with automatic expiry, not permanent key on your infra.
Agent forwarding off by default on bastion — enable case by case if absolutely needed.
Correlate bastion fail2ban + SIEM: bastion brute force = P1 alert, not silent jail.
Attack surface complement
Every server removed from public SSH but reachable via IPMI or host panel remains a door — harden panel credentials with MFA and IP allowlist as much as the bastion itself.
Automate weekly inventory: internal nmap or cloud API script listing instances with public :22. One forgotten terraform deploy = instant regression.
For Windows Admin, Linux bastion + RDP jump through tunnel equivalent — same concentrate-and-log logic.
Operational summary
SSH bastion concentrates admin access — ProxyJump ergonomics, key rotation, session logging. Close direct public 22 after bastion proven. Alternatives: SSM, Tailscale, WireGuard mesh.
Production readiness
Load test concurrent ProxyJump sessions. Verify session recording if required compliance. Disaster rebuild bastion from IaC under 1h tested.
Bastion in hybrid teams
Remote-first teams often skip bastion because VPN is « enough » until a contractor needs one server for one day. Temporary bastion accounts with expiry beat permanent VPN full tunnel access — narrower blast radius.
Automate bastion patching separately from app fleet — it is the highest value target. One CVE on jump host equals keys to kingdom if every prod server trusts its key.
Measure mean time to revoke access on departure. If >1 hour, your bastion authorized_keys pipeline is manual debt.
Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.
Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.
Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.
Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.
Keep a dated runbook, before/after metrics, post-incident review — cumulative discipline beats Friday night panic.
Patch bastion
Jump host CVE = kingdom keys. Quarterly Ansible rebuild <1h.
Decide and move forward without blind spots
- Close direct SSH on prod servers — keys allowed only via bastion or ProxyJump.
- Sync authorized_keys from IaC — weekly auth.log review, export session logs to SIEM.
- Test ProxyJump for each new hire — measure « SSH timeout » tickets before adding hops.
- Patch bastion first — highest-value target; DR exercise Ansible rebuild under one hour.
- Quarterly exercise — access without bastion must fail on a server sample.
Pick VPS or dedicated for the bastion via our comparison tool and directory.
Frequently asked questions
Bastion vs VPN?
Bastion = single audited SSH point. VPN = broad private network. Often combined: VPN for ops, bastion for limited contractors.
Passwords on bastion?
Not in prod: Ed25519 keys, optional MFA, fail2ban or rate limit as complement.
Speed up ProxyJump?
~/.ssh/config with Host bastion + ProxyJump + ControlMaster for multiplexing.
Without bastion?
AWS SSM Session Manager, Tailscale SSH, or mTLS admin — same idea: no public 22 on every node.
Count servers with public SSH today — if more than one, bastion is not optional, it is overdue.
