Guide to Securely Exposing Self-Hosted Services: From Tailscale to Defense in Depth

A layered security guide for safely exposing self-hosted services like Immich to remote family members.
This guide covers the full spectrum of self-hosted service security: using Tailscale for zero public exposure, configuring reverse proxies with automatic HTTPS, adding authentication gateways like Authelia or Cloudflare Tunnel + Access, hardening the server with SSH keys and Fail2ban, implementing network isolation via VLANs, and establishing 3-2-1 backups for irreplaceable data.
The Security Anxiety of Starting from Scratch with Self-Hosting
In Reddit's self-hosting community, a newcomer who had been self-hosting for just three weeks posed a question many of us have faced: "How do I properly secure my server?" His setup was fairly typical—Proxmox VE as the virtualization foundation, Tailscale running in an LXC container, Docker deployed in a virtual machine, and Arcane for container management. The base OS was Debian 13.
Proxmox VE (Virtual Environment) is an open-source server virtualization management platform based on Debian that supports both KVM full virtualization and LXC container virtualization. KVM provides complete hardware virtualization where each VM has its own independent kernel and full operating system environment, while LXC offers OS-level containerization that shares the host kernel—lighter on resources but slightly weaker in isolation. Proxmox manages all VMs and containers through a web interface (default port 8006), supporting enterprise features like clustering, high availability, and backups. It's one of the most popular virtualization platforms in the self-hosting community.
His goal was clear: let family members in other countries access self-hosted applications like Immich (photo management), Mealie (recipe management), and Kavita (e-book reading). But before exposing the server to the public internet, security became an unavoidable hurdle. He even locked himself out of the Proxmox web management interface while configuring its firewall—a rite of passage nearly every self-hosting newcomer experiences.
This question touches on an entire set of self-hosting security best practices. This article will systematically outline the key steps you need to consider before exposing services to remote users.
Preferred Approach: Don't Expose If You Don't Have To
Many self-hosting newcomers instinctively think, "I need to buy a domain and set up port forwarding." But in reality, for scenarios like "family-only access," the most secure approach is often not exposing services to the public internet at all.
Leveraging Tailscale for Zero Public Exposure
This user was already running Tailscale in an LXC container—which happens to be the most elegant solution. Tailscale is a zero-configuration mesh VPN built on WireGuard, and its core advantages include:
- Zero public exposure: The server doesn't need to open any inbound ports, reducing the attack surface to virtually zero.
- End-to-end encryption: All traffic travels through WireGuard encrypted tunnels.
- Cross-border friendly: Family members in other countries simply install the Tailscale client on their devices, join the same Tailnet, and can access Immich, Mealie, and other services as if they were on the same local network.
WireGuard is a modern VPN protocol that, compared to traditional OpenVPN and IPSec, has only about 4,000 lines of code (OpenVPN exceeds 100,000 lines), meaning a smaller attack surface and easier security auditing. WireGuard uses the Noise protocol framework for key exchange, employing ChaCha20 symmetric encryption and Curve25519 elliptic curve key exchange, delivering exceptional performance with minimal latency. Tailscale builds a mesh topology on top of WireGuard—each node establishes direct encrypted connections rather than routing through a central server. This means even if Tailscale's coordination server goes down, established connections continue to work. When direct connections aren't feasible (e.g., behind strict NAT), Tailscale relays traffic through its DERP (Designated Encrypted Relay for Packets) relay servers, but data remains end-to-end encrypted.
For the family remote access scenario, having everyone install the Tailscale client offers the best balance of security and usability. If you're worried that family members might struggle with setup, Tailscale's Funnel feature can temporarily expose specific services to the public internet when needed—but this should be a fallback, not the primary approach.
Tailscale Funnel works by proxying traffic through Tailscale's edge nodes, so your server's IP address is never directly exposed to visitors. Funnel automatically provides HTTPS certificates, and visitors access your service through a domain like machine-name.tailnet-name.ts.net. However, note that using Funnel means traffic passes through Tailscale's infrastructure, throughput is limited, and you can't use custom domains—making it more suitable for temporary sharing or lightweight access scenarios rather than long-term, high-traffic production environments.
When Public Exposure Is Necessary: Building Defense in Depth
If you genuinely need public internet exposure (e.g., certain applications don't support VPN scenarios, or family members' devices can't install clients), then you must establish a layered defense system.
A Reverse Proxy Is Non-Negotiable
Never directly port-forward Docker container ports to the public internet. The correct approach is to place a reverse proxy in front, with common choices including:
- Nginx Proxy Manager: GUI-based, beginner-friendly, with automatic Let's Encrypt certificate provisioning and renewal.
- Traefik: Deep Docker integration, ideal for containerized environments, but has a steeper learning curve.
- Caddy: Extremely simple configuration, automatic HTTPS, suitable for small to medium deployments.
A reverse proxy sits between clients and backend servers, receiving requests from the internet and forwarding them to internal backend services based on rules. Unlike a forward proxy (which makes requests on behalf of clients), a reverse proxy receives requests on behalf of servers. In self-hosting scenarios, the reverse proxy acts as a security gateway: external users can only see the reverse proxy's IP and ports (typically only 80/443) and have no knowledge of which ports the backend Docker containers run on. Additionally, reverse proxies enable domain-based or path-based routing (one public IP serving multiple services), SSL/TLS termination (centralized certificate management while backends communicate via HTTP to reduce overhead), request rate limiting, caching, and load balancing.
Let's Encrypt is a free, automated certificate authority (CA) operated by the Internet Security Research Group (ISRG) that fundamentally lowered the barrier to HTTPS deployment—before it, SSL certificates typically cost tens to hundreds of dollars per year. Let's Encrypt uses the ACME (Automatic Certificate Management Environment) protocol for automated certificate issuance and renewal, with certificates valid for 90 days, encouraging automated renewal over manual processes. Domain ownership verification primarily uses two methods: HTTP-01 challenge (placing a specific file in the website's root directory) and DNS-01 challenge (adding a specific TXT record to DNS records). Nginx Proxy Manager, Caddy, and Traefik all have built-in ACME clients that can automatically handle the entire certificate lifecycle.
The core value of a reverse proxy lies in: unified entry point, enforced HTTPS encryption, hiding real backend ports, and centralizing access control at this layer.
Layer an Authentication Gateway for Enhanced Security
A reverse proxy alone isn't enough. Applications like Immich have built-in login systems, but exposing the login page directly to the entire internet still carries risk. It's recommended to add an authentication layer in front of the reverse proxy:
- Authelia or Authentik: Provide single sign-on (SSO) and two-factor authentication (2FA), requiring all access to pass through this verification layer first.
- Cloudflare Tunnel + Access: No need to open ports; establish a tunnel through Cloudflare and configure email-based access policies so family members can log in with their Google accounts in one click.
Authelia is an open-source authentication and authorization server designed specifically for reverse proxy environments. Its mechanism leverages the reverse proxy's auth_request module (Nginx) or forwardAuth middleware (Traefik)—whenever a request arrives, the reverse proxy first sends a sub-request to Authelia to verify user identity, only forwarding the original request to the backend service after authentication passes. Authelia supports multi-factor authentication (TOTP time-based tokens, WebAuthn hardware keys, push notifications), single sign-on (SSO—one login for all services), and fine-grained access control (different policies based on user groups, subdomains, or paths). Authentik is a more feature-rich alternative supporting enterprise protocols like SAML, OAuth2/OIDC, but with higher resource consumption and configuration complexity.
Cloudflare Tunnel (formerly Argo Tunnel) works by running a daemon called cloudflared on your server, which initiates outbound connections to Cloudflare's edge network (using HTTP/2 and QUIC protocols) to establish persistent tunnels. Since the connection direction is from your server to Cloudflare (outbound), the server doesn't need to open any inbound ports, nor does it require a public IP or port forwarding. When external users access your configured domain, requests first hit Cloudflare's edge nodes, pass through its WAF (Web Application Firewall) and DDoS protection, then get forwarded to your server through the established tunnel. Cloudflare Access is a Zero Trust Network Access (ZTNA) layer supporting identity-based access control—you can specify that only Google/GitHub accounts with specific email domains can access your services, achieving fine-grained permissions without a traditional VPN.
Cloudflare Tunnel is particularly well-suited for family remote access scenarios—it avoids port forwarding and public IP exposure, enables precise control over who can access through Access policies, and provides free DDoS protection.
Hardening the Server Itself
Regardless of which exposure method you choose, underlying server hardening cannot be skipped.
The Right Way to Avoid Firewall "Self-Lockout"
The user mentioned locking himself out of the Proxmox web interface while configuring its firewall—this reminds us to always allow SSH and management ports before enabling restrictive firewall rules. When enabling the firewall on Proxmox, a good practice is to first add allow rules at the datacenter level (e.g., allowing your current IP to access port 8006), then gradually tighten restrictions, rather than defaulting to deny-all from the start.
Server Hardening Checklist
Here's the baseline security work you should complete before exposing any services:
- SSH hardening: Disable root login, switch to key-based authentication, disable password login, and consider changing the default port.
- Automatic security updates: Configure
unattended-upgradesfor Debian to promptly patch known vulnerabilities. - Fail2ban for brute-force protection: Automatically ban IP addresses that attempt brute-force attacks.
- Principle of least privilege: Run Docker containers as non-root users whenever possible, and don't carelessly mount sensitive directories.
- Network isolation: Place public-facing VMs/containers in a separate VLAN or network segment, isolated from other internal devices.
Fail2ban is an intrusion prevention framework that works by monitoring system log files (such as /var/log/auth.log) for failed authentication records. It uses regular expressions to match failed login patterns in logs, and when a specific IP address exceeds the failure threshold within a defined time window, Fail2ban calls firewall tools (like iptables or nftables) to add rules temporarily or permanently banning that IP. Beyond SSH brute-force protection, Fail2ban can be configured with filter rules for Nginx, Apache, Postfix, and other services. In self-hosting scenarios, if you've exposed a reverse proxy's login page, configuring Fail2ban to monitor Authelia or Nginx authentication failure logs is equally important for effectively defending against credential stuffing attacks.
VLAN (Virtual Local Area Network) is a technology for implementing logical network isolation on Layer 2 switches. By adding 802.1Q tags to network frames, ports on the same physical switch can be divided into different broadcast domains—devices in different VLANs cannot communicate directly even if physically connected, and must route through Layer 3 devices controlled by firewall rules. In self-hosting security practice, a typical VLAN segmentation strategy places the management network (Proxmox management interface and SSH), DMZ network (public-facing services), internal network (NAS, databases, and other sensitive services), and IoT network in separate VLANs. This way, even if a public-facing container is compromised, attackers cannot laterally move directly to the network segment containing your storage NAS or management interface.
Backups: The Last Line of Defense
When discussing security, people often overlook backups. But for irreplaceable data like family photos stored in Immich, the importance of backups may even exceed access security.
Follow the 3-2-1 backup principle: at least 3 copies, on 2 different media types, with 1 stored offsite. Proxmox natively supports scheduled VM/LXC backups, and combined with Proxmox Backup Server or syncing snapshots to external storage, you can recover from ransomware or accidental mistakes.
The 3-2-1 backup principle was originally proposed by photographer Peter Krogh and later widely adopted in information security. In modern self-hosting environments, this principle might look like: Proxmox local snapshots (first backup), Proxmox Backup Server storing to a separate physical machine (second backup, second location), and encrypted sync to cloud object storage like Backblaze B2 or Wasabi via tools like rclone (offsite backup). For photo applications like Immich, pay special attention to consistent backups of both the database and media files—backing up only image files while losing the database means all album structures and metadata are gone.
Action Roadmap for Self-Hosting Newcomers
Taking everything into account, for all self-hosting newcomers in similar scenarios, here's the recommended implementation priority:
- Make the most of Tailscale first: Have family members install the client and join your Tailnet. This offers the best return on investment.
- Complete basic server hardening: SSH key authentication, firewall configuration (remember to keep management ports open), automatic updates, Fail2ban.
- When public access is truly needed, use Cloudflare Tunnel or reverse proxy + Authelia—never expose raw port forwarding.
- Establish automated backup mechanisms, especially for irreplaceable data like photos.
The joy of self-hosting lies in having complete control over your data, but that control is predicated on security. From "no exposure" to "layered exposure," building your defense system incrementally is how you give family members convenient access while still sleeping soundly at night.
Related articles

VICE Platform: An AI Security Scanning Tool Review for Indie Developers
VICE Platform scans web app vulnerabilities from an attacker's perspective, with open-source CLI and GitHub Action integration. Covers leaked secrets, Supabase RLS misconfigs, and exposed APIs for indie developers.

ScreenMark: A Mac Screen Annotation Tool with iPhone Remote Control for Freer Presentations
ScreenMark is a macOS menu bar screen annotation tool with live drawing, zoom, whiteboard overlay, recording, and a free iPhone remote app for teachers, presenters, and developers.

Switchy: One-Click Switching of Magic Keyboard, Mouse, and Trackpad Between Multiple Macs
Switchy is a macOS menu bar tool that lets you switch Magic Keyboard, Trackpad, and Mouse between multiple Macs with one click—no manual Bluetooth re-pairing needed.