What setups/softwares do you use to secure your server?
All I do is run the process as user with no login shell.
The topic came to mind after reading this post Is Authelia enough without fail2ban or crowdsec?
My stuff is only accessible from my LAN (because I haven’t figured out how to set up a tunnel or reverse proxy yet).
Tailscale is your friend.
I’ve tried to use ZeroTier because Tailscale still has centralized servers for starting the connection, but had trouble getting it to work. Maybe I should stop letting the perfect be the enemy of the good.
Screw Tailscale, ZeroTier and specially cloudflare, all centralized, all with changable terms.
Use a VPS, lowest spec but good bandwidth, and use Wireguard VPN for your VPS and homeserver, and nginx or caddy to make a Reverse Proxy
All agreed but not every homelabber can spend money for something that is not the main job or contributed to work. Tailscale for now works well enough for free.
Cloudflare agreed is not something I would trust.
I’m so close to doing this. Cloudflare makes me nervous. Have you heard of Rathole? That was recommended to basically do what my cloudflared tunnel is already doing. The only trouble I could see was I was going to have to keep the cloudflared access controls.
I’m in this boat too, my security is awful, bad practices everywhere, my solution: don’t let it go out in public…
it’s so secure not even I, the owner can get in
(I forgot the password to truenas scale)They’d be helping you out by cracking your password, log us both in 😂
My setup is airgapped (everything is wireless).
Can’t tell if joke.
It’s more difficult to steal my data when it’s only stored in a single place without backups.
Brilliant!
- Begins project to print out all essential data and move it into three ring binders, then format hard drive.
deleted by creator
User process makes sense, but login shell is probably limited value. If your service gets pwn’d the attacker will spin up a reverse shell, and that isn’t protected by the login shell. You ideally want to use selinux/apparmor to prevent execution, or containers to limit the available execution environment.
I operate SSH, nginx, and uvicorn like this:
SSH
- pubkey auth only
- not on default port
- AllowUsers var in sshd.conf is set
nginx
- runs as its own user
- serves static files or forwards to uvicorn
- rate limits are set
- returns 444 on requests that aren’t in sitemap.xml (nonsense and probing)
uvicorn
- runs as its own user
and a firewall runs on top of everything in a hardened kernel. I’m self taught, so I could be missing something obvious and this setup has been reliable for me for a few years.
Do you have any sort of access limiting, either by whitelist (e.g. Tailscale), or blacklist (e.g. Crowd-Sec)?
Nope, I’m accessible on the WAN and the webserver is intentionally public facing.
Edit: AllowUsers in sshd.conf is my access control
Secure enough I suppose.
f2b at the FW, auth with MFA for anything exposed, anything local only has restricted access at the FW level, with exposed (via proxy) and local-only (separate proxy) on different vlans. Each service is (typically, with some exceptions) an LXC, with additional rules and templated out based on use case. The few cases where docker is involved is local-only and that has its own vlan with additional rules.
Reverse proxy for services for friends and family
Tailscale for my remote services
Basically everything is in docker containers.
Any middlemen between the proxy and services?
I’m a little paranoid, so this is my security set up.
SSH, blocked at firewall level, only allowing specific local IP to access port 22. Also authentication is done by key, with password disabled.
Most services are local only and I access them through wireguard VPN when I’m outside my home.
For services that need a domain name and be public facing, I use a reverse proxy, with the following protections:
- Very restrictive geoIP block, only my country can access.
- Restrictive rate limiting.
- Crodwsec, with community lists, a pluging for open lists, community rules and my own very restrictive set of rules for banning attackers. (For instance as soon as the requested path contains “.env” that’s an instant ban, no second chances).
- Monitoring through grafana.
- Some complex services that need a valid tls handshake but I only want to use them myself have a setup when they are technically open to the net, to get let’s encrypt, but the server rejects every IP request but mine.
Recently I also reduced some noise, surface attack, deleting the A register from my second level domain and using an obscured target for the CNAME records. I also want to delete the www subdomain as it gets a lot of uneeded noise.
Secrets
- Encrypted secrets file. All repo-managed credentials live in secrets/secrets.yaml, encrypted with SOPS/age.
- Encrypted OpenTofu state. State and plans are encrypted client-side (PBKDF2 + AES-GCM) with a passphrase from TF_VAR_state_passphrase.
Network perimeter
- Default-drop firewall on the router. I use a hand-written nftables ruleset with policy drop on both input and forward. Only lo, lan0 and wg0 are trusted. WAN accepts only established traffic, WireGuard UDP and HTTP/HTTPS.
- No SSH from the WAN. sshd on the router is not exposed to the internet at all.
- WireGuard for remote access.
- Forced DNS. NAT redirects all LAN and VPN port-53 traffic to the router’s AdGuard. AdGuard uses Quad9 over DoT upstream, with blocklists and safe search.
- Second-level ACL in nginx. Private .home vhosts and Grafana carry
allow LAN; allow VPN; deny all;. - TLS everywhere. Every public vhost sets forceSSL with recommendedTlsSettings. Certificates come from ACME DNS-01, so issuance needs no inbound port 80. Cloudflare is DNS-only with no proxy, so no third party sees plaintext.
Host access
- SSH hardening. Password and keyboard-interactive auth are off, PermitRootLogin = “no”, and logins are key-only.
- Dedicated deployer system user. It uses a CI-only keypair, separate from the interactive keys. Everything it does through sudo is logged with LOG_INPUT/LOG_OUTPUT to /var/log/sudo-deployer.log.
Walking to the setup you would stub your small toe a few times, that alarm is enough.
I don’t have anyone to share it with, so it’s not open.
your NSA agent is very upset you haven’t thought about their feelings on the subject.
I tend to go overboard on security, or so I’ve been told.
For my server, secure enough. Just the basic recommendations, non-standard ssh port, default deny on firewall, fail2ban, etc. It doesn’t need a lot of security because its just a static website. For most projects this is enough.
I will say, a honeypot can be useful and I’m getting one set up but its a low priority for me.










