“Zero trust” is a buzzword in many vendor brochures, but the core idea is simple and useful even for a two-person team with a few VPSes: don’t trust anything because of where it is on the network. Every access, whether to SSH, a database or an admin panel, should be authenticated, authorised and encrypted, whether it comes from the office, a home network or another server.

The old model vs zero trust

Perimeter model: a firewall protects the “inside”. Anything inside, such as the office network or a VPN, is trusted. Once an attacker gets in (a phished laptop, a compromised VPN account), they can move freely.

Zero trust:

  • Verify identity for every request: users and devices, not IP addresses.
  • Least privilege: access to specific applications, not whole networks. See least privilege.
  • Assume breach: segment, log and limit how far any single compromise spreads.
  • Encrypt everywhere, including “internal” traffic.

What this means for your servers

1. No admin interfaces on the public internet

Databases, Redis, phpMyAdmin, Portainer, Grafana, Proxmox, router UIs: none of these should be reachable from the internet. Bind them to localhost or a private interface, and reach them through an authenticated layer:

sudo ss -tlnp | grep -v '127.0.0.1\|::1'     # what's listening publicly?

See check open ports and nmap.

2. Identity-based private access: mesh VPNs

Tools like Tailscale, Netbird, Headscale (a self-hosted Tailscale control server) or ZeroTier connect devices and servers into a private WireGuard mesh:

  • each device authenticates with your identity provider (Google, Microsoft, GitHub, OIDC);
  • ACLs define who may reach which server and port (“developers → app servers :22; ops → all”);
  • no inbound ports need to be open on servers;
  • removing a person in the identity provider removes their access everywhere.

See Tailscale on a VPS and WireGuard.

3. Identity-aware proxies for web apps

For internal web tools, put an authenticating proxy in front:

  • Cloudflare Access / Tunnel — the app has no open ports. Users log in via SSO at Cloudflare’s edge. See Cloudflare Tunnel.
  • Authelia, Authentik, oauth2-proxy — self-hosted SSO in front of Nginx or Traefik, with 2FA.
  • Pomerium — an open-source identity-aware proxy.

Every request is checked against the user’s identity and group, not their IP.

4. Strong, short-lived credentials

  • SSH keys, preferably hardware-backed or short-lived certificates. See YubiKey SSH and SSH certificates.
  • MFA everywhere: the identity provider, the hosting control panel, registrar, Git hosting and DNS.
  • Per-service credentials with minimal scope. See secrets management.

5. Encrypt service-to-service traffic

Even on a private network: TLS for database connections across hosts, WireGuard between servers in different locations, HTTPS between proxy and app when they’re on different machines.

6. Log and review access

Central logs for SSH, sudo and proxy access, plus alerts on unusual logins. See sudo logging, SSH login alerts and rsyslog.

A realistic setup for a small team

Team laptops ──(Tailscale / Netbird, SSO + MFA)──▶ servers' private addresses
                                                    ├─ SSH (keys, per-role ACL)
                                                    ├─ Grafana, Portainer (no public port)
                                                    └─ databases (private only)

Public internet ──▶ Nginx :443 only ──▶ apps
                    (+ WAF / rate limits)
Internal web tools ──▶ Authelia/oauth2-proxy SSO ──▶ app

Public firewall: only 80/443 open, plus SSH restricted or closed entirely when you use the mesh. See UFW.

Common misconceptions

  • “Zero trust means no VPN.” Mesh VPNs with identity-based ACLs are a common zero-trust building block. What’s dropped is the idea that being on the VPN means trusted for everything.
  • “It’s a product you buy.” It’s an approach. Many pieces are free and open source.
  • “It’s only for big companies.” Small teams benefit the most: fewer exposed services, easier onboarding and offboarding, and less damage when a laptop is lost.

Getting started

  1. Inventory every service on your servers that listens publicly. Close or privatise everything that isn’t meant for the public.
  2. Put team access behind a mesh VPN with SSO and MFA.
  3. Add SSO in front of internal web tools.
  4. Move to short-lived or hardware-backed SSH credentials.
  5. Centralise logs and review access quarterly.

Related: VPN vs proxy and Linux server hardening.

  • Security
  • Networking
  • Best Practices