Secure remote access to my linux home server using a VPN (Tailscale)
If you run a home server, you’ll eventually want to log in from somewhere else than your home network.
I looked at a few options and ended up setting up a VPN using Tailscale. In this post I explain why I went with a VPN, why I run it directly on the host, and how you can set up a similar setup yourself.
📑 Table of Contents
- Why a VPN? 🔐
- Why I run Tailscale on the host 🖥️
- Installing Tailscale on a Linux server ⚙️
- Connecting from another device 💻
- Final thoughts ✅
Why a VPN? 🔐
When accessing a home server from outside your network, there are a few common options. The simplest is opening a port on your router, such as exposing SSH directly to the internet. While this works, it also means the server is always reachable from anywhere, which quickly raises security concerns around hardening and monitoring.
Another approach is using tunnels or reverse proxies. This works well for specific services, especially public web applications, and I already use it for my blog. The downside is that access is still handled per service, meaning each dashboard or UI needs to be exposed and managed separately.
A VPN takes a different approach. Instead of exposing services, it connects your device to the home network first. Once connected, everything works exactly as it does at home: SSH, dashboards, and internal tools are all available without exposing them individually.
What surprised me most was how easy this turned out to be. As soon as the VPN was active, all existing services just worked, without extra configuration or new access patterns. With Tailscale, secure remote access was up and running in minutes, which made the VPN approach an easy choice for my home server.
Why I run Tailscale on the host 🖥️
If you’ve read some of my other posts, you’ll know that I like working with Docker and usually run most services in containers. I did consider running Tailscale in Docker as well, but in the end I decided to install it directly on the host.
The main reason is that a VPN is not just another service. It creates network interfaces and affects how the entire system is accessed. Running it on the host makes this behavior more visible and easier to reason about, without adding an extra networking layer on top of Docker.
By installing Tailscale on the host, I also get immediate access to everything the server offers, including SSH and internal dashboards, without any additional configuration. For me, the VPN felt more like infrastructure than an application, which is why I chose a host-native setup in this case.
Installing Tailscale on a Linux server ⚙️
My server runs Ubuntu Server 24.04, so the installation is straightforward. Tailscale provides an install script that adds the correct package repository and installs everything that’s needed.
On the server, run:
curl -fsSL https://tailscale.com/install.sh | sh
After the installation finishes, Tailscale runs as a system service but is not yet connected to any network. To activate it, run:
sudo tailscale up
This command prints a login URL. Opening that link in a browser allows you to authenticate and approve the server. Once that’s done, the VPN connection is active.
At this point, the server gets a private IP address in the Tailscale network and a new network interface (tailscale0) appears. From here on, the server is reachable through the VPN without opening any ports on the router.
You can verify the connection by checking the assigned IP:
tailscale ip -4
This is the address that will be used to connect to the server from other devices.
Connecting from another device 💻
To actually make use of the VPN, you need to connect another device to the same Tailscale network. In my case, this is my laptop.
First, install Tailscale on the laptop from the official website and log in using the same account:
https://tailscale.com/download
Once logged in, the laptop automatically joins the Tailscale network and receives its own private IP address.
With both the server and the laptop connected, you can now access the server using the Tailscale IP. For example, connecting via SSH looks like this:
ssh user@<tailscale-server-ip>
At this point, the connection behaves exactly the same as if you were on your home network. There is no need for port forwarding, proxies, or exposed services. As long as the VPN is active, the server is reachable in a completely natural way.
Final thoughts ✅
Setting up a VPN for my home server turned out to be much simpler than I expected. Instead of exposing individual services or adding more layers of configuration, the VPN approach made remote access feel natural and predictable.
By running Tailscale directly on the host, I ended up with a setup that is easy to understand, easy to maintain, and flexible enough to grow over time. Once connected, the server behaves exactly as if I were on my home network, which is hard to beat in terms of simplicity.
For me, this struck a good balance between security and convenience. Public services remain public, private services stay private, and remote access no longer feels like a workaround but a normal part of the setup.