# VPS Setup Checklist for setting up a fresh VPS. ## Initial Access and User Setup Create a regular user, add them to `sudo`, and disable root login over SSH: ```bash adduser deploy usermod -aG sudo deploy ``` Set up SSH key authentication for the new user before disabling password auth. Copy your public key into `~/.ssh/authorized_keys` (or use `ssh-copy-id`). Then in `/etc/ssh/sshd_config`: ```text PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes ``` Restart `sshd` — but keep your current session open until you've confirmed you can log in with the new user in a second terminal. Locking yourself out of a VPS is not fun. ## Firewall Set up `ufw` (or `nftables`/`iptables` directly) early: ```bash ufw default deny incoming ufw default allow outgoing ufw allow ssh ufw enable ``` Only open ports you actually need (80, 443, etc.) as you go. ## SSH Hardening Beyond disabling passwords and root login, consider: - Changing the default SSH port (minor but reduces log noise from bots) - Setting `MaxAuthTries 3` - Using `AllowUsers deploy` to explicitly whitelist who can log in - Installing `fail2ban` to auto-ban IPs after repeated failed attempts See also: [[SSH]] ## System Updates ```bash apt update && apt upgrade -y ``` Enable unattended security updates (`unattended-upgrades` on Debian/Ubuntu) so critical patches get applied automatically. Configure it to only auto-apply security updates and notify you about the rest. ## Other Security Considerations - **Disable unused services** — check what's listening with `ss -tlnp` and stop/remove anything you don't need - **Set up a swap file** if your VPS has limited RAM, otherwise OOM kills can take down your services unexpectedly - **Configure timezone and locale** — `timedatectl set-timezone Europe/Zurich` (or wherever makes sense), keeps logs readable - **Log monitoring** — at minimum, know where your logs are. `journalctl` for systemd services, `/var/log/auth.log` for login attempts. Tools like `logwatch` can send you daily summaries - **Automatic reboots** after kernel updates — `needrestart` helps you see what needs restarting, or set up automatic reboot via cron ## Running Web Services - Use a reverse proxy (nginx/Caddy) — Caddy is especially nice because it handles TLS certificates automatically - Don't run application processes as root. Create dedicated service users with minimal permissions - Use [[Docker]] if it fits your workflow, but be aware that Docker by default punches through `ufw` rules. Configure Docker's iptables behavior or use `docker-compose` network settings carefully ## Backups Set up automated backups from day one, even if it's just a cron job rsyncing to another location or using your provider's snapshot feature. Test restoring at least once. ## Optional - **2FA for SSH** via `libpam-google-authenticator` - **AppArmor or SELinux** profiles for services you expose publicly - **Monitoring** — `htop`/`btop` for interactive use, Prometheus + node_exporter or a simple uptime check (UptimeRobot, etc.) for ongoing visibility The general principle: minimal attack surface, least privilege, and assume someone will try to break in — automated scanners hit new VPS IPs within minutes. --- See also: [[Linux]], [[SSH]], [[Docker]]