Security measures for your homelab setup
I keep my homelab because it scratches a technical itch and gives me somewhere safe to test things. The sensible answer is not paranoia. It is basic security, repeatable automation, and a few checks that stop a small mistake turning into a proper headache.
These are the steps I use. Nothing clever. Just the sort of thing that keeps services contained, recoverable, and less likely to bite when I am not looking.
Lock the doors: basic security practices that actually work
Security is a stack of small choices. Pick a few and stick with them.
- Inventory and reduce your attack surface.
- List exposed services with
sudo ss -tulpenorsudo lsof -i -P -n. Remove anything you do not need. - Put lab gear on a separate VLAN or guest SSID. On OpenWrt or pfsense, tag ports so homelab traffic stays away from personal devices.
- Use SSH keys and limit access.
- Disable password SSH for servers: in
/etc/ssh/sshd_configsetPasswordAuthentication noandPermitRootLogin no, then restart SSH:
systemctl restart sshd
- Store private keys in a hardware token or an encrypted file with a strong passphrase. Add an SSH config entry per host to avoid typing mistakes.
- Use multi-factor where the service supports it.
- Use a YubiKey or TOTP for services that support 2FA. For web UIs, I prefer hardware keys where they are available.
- If a self-hosted app does not support MFA, put it behind an authenticated reverse proxy.
- Harden services and defaults.
- Use unattended-upgrades on Debian or Ubuntu:
apt install unattended-upgrades && dpkg-reconfigure --priority=low unattended-upgrades
- Check
/var/log/unattended-upgradesfor activity. - Keep admin panels on localhost or a VPN. Do not expose management ports like 8080 or 8000 directly to the internet.
- Tidy up privacy settings and logging.
- Review app privacy settings before you add a new service. Turn off telemetry at install time where possible.
- Keep logs for a reasonable window. Use logrotate and push critical logs to a separate machine so they are still there when something breaks.
Verify it from outside your LAN:
- Run
nmap -sT -p- <external-ip>to check only the ports you expect are open. - Test SSH key-only login from a clean client. Try a failed login too, then check that bans or rate limits trigger.
That cuts the chance of a silly break-in and keeps the lab less exposed than it needs to be.
Automate the boring and the dangerous
Automation cuts human error and means I spend less time babysitting services.
- Backups that run automatically and can be checked.
- Run scheduled backups with restic or Borg. Example restic cron job:
0 3 * * * /usr/local/bin/restic-backup.sh
- Include a verification step:
restic snapshots && restic check
- I run a restore test monthly to a throwaway VM.
- Infrastructure as code for repeatability.
- Use Ansible for configuration. Keep playbooks small and idempotent. Store secrets in an encrypted vault or secret manager.
- A playbook that installs Docker, sets UFW rules, and deploys a reverse proxy means a dead server is more annoying than disastrous.
- Automated certificate renewals.
- Use certbot with Nginx and a non-interactive renewal path:
certbot --nginx --non-interactive --agree-tos -m you@example.com
certbot renew --dry-run
- Check
/var/log/letsencryptfor failures. If you use Traefik, configure ACME there instead of running separate renewals.
- Service supervision and restarts.
- Use systemd for services or a process manager like supervisord. Add
Restart=on-failureandRestartSec=10to unit files.
- Observability that tells you something useful.
- Run Prometheus and Grafana for CPU, memory, disk I/O, certificate expiry, and backup success.
- Alert only on things you can act on: failed backups, full disks, or certificates that expire within seven days.
- Use a private push service, an encrypted message to your phone, or another low-noise channel. Alert fatigue is pointless.
- Small, safe automation wins.
- Auto-update containers with something like watchtower only for non-critical apps. For important services, automate build and test pipelines rather than pushing straight to production.
- Automate security scans with Lynis or OpenVAS, but run them at sensible times so the noise stays manageable.
Verify the automation before you trust it:
- Break one component in a safe environment and watch the playbook or restore run.
- Check alerts for false positives for two weeks, then tighten thresholds.
Practical privacy settings
- For any self-hosted app, look for telemetry and disable it. If there is no switch, block the domains at Pi-hole or your DNS resolver.
- For shared machines, create unprivileged accounts and limit sudo access with
visudorules.
Why it matters
- Automation makes recovery predictable. Predictable recovery takes some of the fear out of running the lab.
- When rebuilds and restores are documented and automated, a breakage is an operational task rather than a crisis.
- That is the part that matters when you want to tinker without worrying about every small mistake.



