# Server Security Guided Checklist

Use this when SSH access to the server is not available. Answer each item based
on documentation, deployment runbooks, infrastructure-as-code (Terraform,
Ansible, cloud-init), or knowledge from the team member who set up the server.

For each item:
- ✅ = Confirmed in place
- ❌ = Known to be missing
- ❓ = Unknown / not checked

---

## Network & Firewall

- [ ] UFW enabled with `default deny incoming`? _____
- [ ] `default allow outgoing` set? _____
- [ ] Only ports 80 and 443 are open to the public internet? _____
- [ ] Port 22 (SSH) is blocked from `0.0.0.0/0` (i.e. no unrestricted SSH)? _____
- [ ] SSH is accessible only from a Tailscale interface, office CIDR, or other restricted source? _____
- [ ] No database ports (e.g. 5432, 3306, 27017) are exposed to the public internet? _____
- [ ] Cloud-provider security group / firewall rules match the UFW ruleset (not more permissive)? _____

**Notes / findings:**

---

## SSH Hardening

- [ ] `PasswordAuthentication no` is set in `/etc/ssh/sshd_config`? _____
- [ ] `PermitRootLogin no` is set? _____
- [ ] `AuthenticationMethods publickey` is set (key-only login)? _____
- [ ] `PermitEmptyPasswords no` is set? _____
- [ ] `AllowGroups` directive is configured (e.g. `AllowGroups sshusers`)? _____
- [ ] Service accounts (deploy, appuser) are excluded from the SSH-allowed group? _____
- [ ] `LoginGraceTime 30` is set (reduces slow-connect attack window)? _____
- [ ] `MaxAuthTries 3` is set? _____
- [ ] `X11Forwarding no` is set? _____
- [ ] `AllowTcpForwarding no` is set? _____
- [ ] `PermitUserEnvironment no` is set? _____
- [ ] `LogLevel VERBOSE` is set (captures key fingerprints in auth log)? _____
- [ ] `ClientAliveInterval` and `ClientAliveCountMax` are set to drop idle sessions? _____
- [ ] Modern key exchange algorithms are configured (Mozilla guidelines)? _____

**Notes / findings:**

---

## OS User Accounts

- [ ] Each engineer has their own individual OS account (no shared `ubuntu` / `admin` / `devops` logins)? _____
- [ ] Each person's account has their own unique SSH key? _____
- [ ] Service accounts (deploy, appuser) cannot log in interactively (`/usr/sbin/nologin` shell)? _____
- [ ] An offboarding procedure exists for removing SSH keys and OS accounts? _____
- [ ] Accounts for people who have left the team have been removed or locked? _____

**Notes / findings:**

---

## Sudo Permissions

- [ ] No user or group has `NOPASSWD: ALL` in sudoers? _____
- [ ] The deploy/CI user's sudo access (if any) is scoped to specific commands only (e.g. `docker compose`)? _____
- [ ] Sudo rules are defined in `/etc/sudoers.d/` drop-in files (not directly in `/etc/sudoers`)? _____
- [ ] Sudo logging is enabled (`Defaults logfile="/var/log/sudo.log"`)? _____

**Notes / findings:**

---

## CI/CD Deploy User

- [ ] The deploy user's `authorized_keys` entry uses `command="..."` (ForceCommand) to restrict execution to a single deploy script? _____
- [ ] `no-port-forwarding,no-X11-forwarding,no-agent-forwarding` restrictions are present in the `authorized_keys` entry? _____
- [ ] The CI/CD SSH private key is stored only as a GitHub Actions secret (not in any file or repo)? _____
- [ ] The VPS host key fingerprint is pre-captured and stored as a secret (to prevent MITM at scan time)? _____

**Notes / findings:**

---

## Automatic Security Patches

- [ ] `unattended-upgrades` is installed and running? _____
- [ ] The `${distro_id}:${distro_codename}-security` origin is enabled? _____
- [ ] Database packages (e.g. `postgresql-*`) are pinned / blacklisted to prevent uncontrolled upgrades? _____
- [ ] `Automatic-Reboot "false"` is set (reboots are handled manually)? _____
- [ ] Email notifications for upgrades are configured? _____

**Notes / findings:**

---

## Brute-Force Protection

- [ ] `fail2ban` (or CrowdSec) is installed and running? _____
- [ ] The `sshd` jail is active in fail2ban? _____
- [ ] Ban thresholds are configured (`maxretry`, `bantime`, `findtime`)? _____

**Notes / findings:**

---

## Overall Assessment

**Completed by:** _______________
**Date:** _______________
**Server / environment:** _______________

| Area | Status | Blocker items |
|---|---|---|
| Network & Firewall | ✅ / ❌ / ❓ | |
| SSH Hardening | ✅ / ❌ / ❓ | |
| OS User Accounts | ✅ / ❌ / ❓ | |
| Sudo Permissions | ✅ / ❌ / ❓ | |
| CI/CD Deploy User | ✅ / ❌ / ❓ | |
| Automatic Patches | ✅ / ❌ / ❓ | |
| Brute-Force Protection | ✅ / ❌ / ❓ | |

**Summary of items to fix:**

1.
2.
3.
