deploy init: verify your POC first, then harden when you decide to keep it.
Overview
This runbook applies security best practices to production VMs:- SSH hardening
- Fail2ban for brute-force protection
- Unattended security updates
Where is the firewall? Owned by your groundβs Terraform (infra/): the DO cloud firewall or AWS security groups. There is no host firewall (UFW) by design: Dockerβs iptables rules bypass UFW for published ports, so a host firewall protects nothing. The cloud firewall sits in front of the box, where traffic structurally cannot bypass it. SSH and Dozzle are admin-IP-only (admin_cidrin terraform.tfvars); app ports accept the load balancer.
Prerequisites
- Core services deployed (01-core.md)
- Database configured (02-database.md)
- Services verified working before hardening
Steps
1. Run Hardening
2. Verify Access Still Works
What Gets Configured
SSH Hardening
- Disable password authentication (keys only)
- Disable root password login
- SSH stays on port 22, reachable only from
admin_cidr(cloud firewall)
Fail2ban
- Bans IPs after repeated failed SSH attempts
- 1 hour ban duration (3600 seconds)
- Protects against brute-force attacks
Troubleshooting
Next Steps
- 06-test.md - Verify connectivity

