Secure remote access to your NAS with Tailscale
- Published on
- ·6 min read
The problem: accessing your NAS from outside
I have about twenty services running on my NAS - Jellyfin, Immich, Home Assistant, monitoring dashboards. All accessible locally without issue. But the moment I'm at a client site, on vacation, or just at a coffee shop, everything becomes unreachable.
The classic solution I absolutely don't want: open ports on the router, configure port forwarding, set up dynamic DNS, and hope no bot finds your exposed services. Not doing it.
Traditional VPN vs Tailscale
A self-hosted VPN (OpenVPN, native WireGuard) requires:
- Opening at least one UDP port on the router
- Configuring port forwarding to the VPN server
- Managing dynamic DNS if your IP changes
- Maintaining the VPN server, its certificates, its keys
- Manually configuring each client
Tailscale takes a completely different approach. It's a WireGuard-based mesh VPN that creates encrypted point-to-point tunnels between devices. No central server to maintain and most importantly no ports opened on the router.
Connections happen through NAT traversal (STUN/DERP): Tailscale finds the most direct path between two devices, even behind double NAT. When a direct connection is impossible, traffic goes through relay servers (DERP servers), but remains end-to-end encrypted.
Installation via Ansible
Like everything on the NAS, Tailscale goes through Ansible. Key variables:
# group_vars/nas.yml (Tailscale excerpt)
tailscale_auth_key: 'tskey-auth-xxxxx' # auth key (vault encrypted)
tailscale_subnet_router: true
tailscale_advertised_routes: '192.168.1.0/24'
tailscale_exit_node: true
tailscale_accept_dns: true
The Ansible role handles installation, authentication, and configuration. The actual installation:
# What the Ansible role does
curl -fsSL https://tailscale.com/install.sh | sh
# Activation with options
sudo tailscale up \
--authkey=tskey-auth-xxxxx \
--advertise-routes=192.168.1.0/24 \
--advertise-exit-node \
--accept-dns
Subnet router: exposing your entire LAN
This is the most powerful feature. By enabling subnet routing, the NAS becomes a gateway that exposes your entire local network (192.168.1.0/24) to Tailscale-connected devices.
In practice, from my phone on a mobile connection with Tailscale active, I can access:
- All NAS services via their local IPs (192.168.1.50:8096 for Jellyfin, etc.)
- Other LAN devices: network printer, IP cameras, home automation hub
- Admin interfaces: the internet router, managed switches
It's completely transparent. Applications behave exactly as if I were on the local network. Jellyfin on my phone connects to the same address as at home.
For subnet routing to work, IP forwarding must be enabled on the NAS:
# /etc/sysctl.d/99-tailscale.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
And routes must be approved in the Tailscale admin console (or via tailscale set with appropriate ACLs).
Exit node: secure browsing
Exit node is a complementary feature: when enabled on a client, all internet traffic from that device routes through the NAS. The NAS becomes your outbound proxy.
Particularly useful on untrusted public WiFi - hotels, coffee shops, airports. Instead of trusting the local network, all traffic is encrypted through the WireGuard tunnel to the NAS, then exits via your home connection.
Enabling it on the client is simple: toggle in the Tailscale app, pick the NAS as the exit node, done. You can enable or disable it on demand depending on which network you're on.
Real-world use cases
Since deploying Tailscale:
- Jellyfin on the road: watching my movies and shows from anywhere, without exposing port 8096 to the internet
- Immich from my phone: automatic photo backup and library browsing, even away from home
- Emergency SSH: connecting to the NAS from my laptop at a client site for quick troubleshooting
- Internal dashboards: checking Homepage, Uptime Kuma, Scrutiny without making them public
- Secure public WiFi: enabling exit node at a hotel to browse through my home connection
MagicDNS: names instead of IPs
Tailscale includes a built-in DNS feature called MagicDNS. Instead of remembering that the NAS is at 100.64.x.y on the Tailscale network, you access it by hostname:
ssh nasadmin@nas.tail1234.ts.net
MagicDNS automatically resolves the hostnames of all machines in the tailnet. Combined with subnet routing, you keep local IP access for Docker services while using the Tailscale hostname for SSH and direct machine connections.
Checking status
The tailscale status command gives an overview:
$ tailscale status
100.64.1.1 nas francois@ linux active; direct 192.168.1.50:41641
100.64.1.2 laptop francois@ linux active; direct 82.66.x.x:38412
100.64.1.3 pixel8 francois@ android active; relay "par"
100.64.1.4 macbook-pro francois@ macOS idle; offline
You can immediately see which devices are connected, whether direct or via relay, and their state. The phone here is through a DERP relay in Paris - a direct connection couldn't be established, but traffic remains end-to-end encrypted.
Integration with the existing firewall
Important point: Tailscale uses its own network interface (tailscale0) and is not affected by UFW rules. Tailscale traffic arrives already decrypted on the tailscale0 interface, then accesses services locally. That's why services restricted to the LAN remain accessible through Tailscale - the traffic arrives as local traffic.
No need to modify existing firewall rules. This is a major advantage over classic VPN where you often need to add specific rules for the VPN subnet.
Tailscale vs self-hosted WireGuard
Tailscale is built on WireGuard, but the comparison is enlightening:
| Native WireGuard | Tailscale | |
|---|---|---|
| Open port on router | Yes (UDP) | No |
| Dynamic DNS | Required | Built-in (MagicDNS) |
| Key management | Manual | Automatic |
| NAT traversal | No | Yes |
| Subnet routing | Manual config | Toggle in admin |
| Multi-user + ACLs | Complex | Built-in |
| External dependency | None | Tailscale (SaaS) |
The trade-off with Tailscale is the dependency on the Tailscale service for coordination (not for traffic, which remains point-to-point). It's a compromise I gladly accept given the simplification it provides.
Performance
WireGuard is renowned for exceptional performance - far superior to OpenVPN or IPSec. Overhead is minimal: in practice, you reach near-native throughput. On my fiber connection, I see no perceptible difference between local access and Tailscale access with a direct connection. Only passing through a DERP relay adds latency, and that's rare.
The takeaway
Tailscale has fundamentally changed how I access my NAS. No more open ports, no more dynamic DNS, no more complex VPN maintenance. I install the app on a new device, log in, and I have access to my entire local network as if I were at home. It's the solution I recommend to anyone self-hosting services who wants remote access without compromising security.
Debian NAS from scratch series — This article is part of a complete series on building a Debian NAS.
Previous: Securing SSH with post-quantum algorithms | Next: Building a complete media center with Jellyfin and the *arr stack