# ~$ Hardening checklist This is the non-negotiable baseline before real company data touches the box. Every item is copy-paste ready for Debian/Ubuntu. ## 1. SSH: keys only, no root ```bash adduser ops && usermod -aG sudo,docker ops mkdir -p /home/ops/.ssh && cp ~/.ssh/authorized_keys /home/ops/.ssh/ \ && chown -R ops:ops /home/ops/.ssh && chmod 700 /home/ops/.ssh ``` `/etc/ssh/sshd_config.d/hardening.conf`: ``` PermitRootLogin no PasswordAuthentication no KbdInteractiveAuthentication no ``` ```bash systemctl restart ssh # TEST A NEW SSH SESSION BEFORE CLOSING THIS ONE. ``` ## 2. Firewall — four ports, nothing else ```bash apt install -y ufw ufw default deny incoming ufw allow 80/tcp 443/tcp 443/udp # caddy (http/https/h3) ufw allow 2222/tcp # git ssh ufw allow 51820/udp # wireguard (only if using --profile vpn) ufw allow 22/tcp # your ssh (move it if you want) ufw enable ``` Note: Docker's published ports bypass ufw INPUT rules — that's exactly why this compose file publishes only caddy, git-ssh and wireguard, and keeps postgres/redis on the `internal` network with no ports at all. Don't add `ports:` to internal services "for debugging" and forget them. ## 3. Automatic security updates ```bash apt install -y unattended-upgrades dpkg-reconfigure -plow unattended-upgrades ``` ## 4. fail2ban (ssh brute force) ```bash apt install -y fail2ban # default ssh jail is enough to start ``` ## 5. Vaultwarden specifics - `VAULTWARDEN_SIGNUPS_ALLOWED=false` the moment your team is on board. - Use an argon2 `ADMIN_TOKEN` (`vaultwarden hash` / see wiki), not a plain string. - The admin panel (`/admin`) is for setup — consider blocking it in Caddy afterwards: ``` vault.{$DOMAIN} { @admin path /admin* respond @admin 404 reverse_proxy vaultwarden:80 } ``` ## 6. Pin your images `latest` is fine on day one, dangerous on day 300. Pin majors at minimum (`caddy:2-alpine`, `forgejo:11`, `uptime-kuma:1` already are). Watchtower blindly auto-updating a password manager at 3 a.m. is how you get incidents — update deliberately: `docker compose pull && docker compose up -d` after reading release notes. n8n and Outline move fast; Vaultwarden occasionally has breaking web-vault pairs. ## 7. Backups (minimum viable, today) ```bash # stop, snapshot volumes, start — cron it nightly until Episode 10 (borgmatic offsite) docker compose stop tar czf /backup/stack-$(date +%F).tgz -C /var/lib/docker/volumes . docker compose start ``` Plus: enable your provider's server snapshots. Two clicks, saves your company. ## 8. What this list is NOT Not covered here, on purpose (own episodes): SSO everywhere, 2FA enforcement per service, Netbird zero-trust mesh, central logging, CrowdSec, offsite borg. Baseline first. Perfect later.