For about a year, I have been treating Tailscale as an easy button for secure remote access. It worked, it was reliable, and it ran quietly in the background without any issues. But there is a difference between owning infrastructure and using a managed solution. About a month ago, I decided to replace Tailscale with raw WireGuard as an experiment to understand what I was missing.
I didn’t want to replace Tailscale entirely, and my motive wasn’t to prove one better than the other. My goal was to understand what actually changed when I moved from a managed overlay to raw tunnels. Tailscale already runs on top of WireGuard, so I was curious to see what happens when I remove Tailscale from the equation.
Is Tailscale the safest way to access your home network remotely?
Tailscale is easy to set up, but is that trading off your security?
Why I tried replacing Tailscale
I wanted full control instead of relying on a managed overlay
My initial assumption was, "Tailscale already uses WireGuard, and I already have experience running and managing my own router configuration and VPS for connectivity. So removing Tailscale from the equation wouldn't be difficult."
I wanted to manage the backend of the process, like keys, peers, and routing decisions; I believed it would give me more control over the environment. Tailscale made the process so seamless, as all these were handled in the background without nudging me.
Since the tunneling itself was not changing and the protocol was the same, I assumed the process in between was simple enough to take control of and the heavy lifting was happening at the protocol level.
WireGuard is simple — but not automatic
No discovery, no control plane — just keys and endpoints
WireGuard itself is extremely clean and minimal to operate. But there is no orchestration. Most of the tasks are manually handled by me. There is no central coordination layer unless I decide to build one.
It only does what it is instructed to do. For example, each device (peer) will need its own private and public keys, endpoints, and allowed IPs. I had to manually add the peer info to the central hub (a VPS in my case; I will explain later why) and then the hub’s key back to the peer to establish a handshake and connectivity. Only those two defined devices/interfaces will talk to each other. No one else.
That’s when the difference became clear: we are replacing convenience with configuration. Tailscale has a simple flow. I add a device to the account, and it automatically appears in the admin console. It can then automatically communicate with other devices under that account. But with WireGuard, I had to manually add each peer and then restart the service and verify the handshake. WireGuard assumes I am the control plane.
Another thing I understood is that WireGuard is a protocol and not a platform, so I need to treat it that way.
CGNAT and firewalls made the difference clear
When your home network isn’t publicly reachable
Residing in the countryside in India has its own pros and cons, and one of the cons is we don’t have many options for home internet connection. I have a fiber connection from a local ISP as my primary internet connection, and unfortunately, they only provide a connection behind CGNAT. This might not be an issue for a normal user, but for a home lab user, it becomes a serious limitation.
That limitation became obvious when I tried setting up WireGuard on my primary internet connection. WireGuard needs at least one publicly reachable endpoint to start with. I do have a secondary AirFiber connection. However, it uses dynamic IP allocation, so that didn’t help either. I use a TP-Link ER605 gateway as well, but due to CGNAT from the ISP and dynamic IP addresses, port forwarding was ineffective.
This wasn’t a WireGuard misconfiguration. It was my network topology that was a big wall to the configuration. This was never the case with Tailscale. Once I added a device to Tailscale, it automatically handled the NAT traversal and coordination. I didn’t have to think about public reachability of my home IP.
To cope with the issue, I had to introduce an intermediary in the process. I have already been using a Hetzner VPS for my self-hosted services and apps. As the VPS comes with a public IPv4, I could easily configure WireGuard on it by opening the UDP 51820 port. The one additional step was that I had to manually add peer info to the VPS via SSH each time.
After that, WireGuard worked perfectly. But now I was responsible for firewall rules, VPS uptime, endpoint configuration, and security hardening. In the end, the protocol worked. The topology didn’t.
WireGuard expects precision
Silent failures and configuration responsibility
During these configuration attempts, I observed two things: first, you need a reachable network topology, and second, WireGuard will behave the way you configure it. It doesn’t validate the intent of whether the connection is successfully established or not. It doesn’t even warn you of any logic errors. It is not fragile or unreliable. Just precise.
I faced a couple of similar issues. One frustrating issue was that SaveConfig was set to true in the /etc/wireguard/wg0.conf file. Whenever I added a new peer and restarted the service, it was wiping the peer info each time, which prevented the handshake from occurring.
Another issue I faced was that I unknowingly set an incorrect PublicKey for the hub in my MacBook’s WireGuard config. The peer appeared in the hub’s configuration, but the handshake never occurred. The only way to debug these issues was with wg show and logs.
What this explains is that you are the control plane. There is no dashboard, no error banners, and no connection failed notifications; if the configuration doesn’t match, it won’t work. WireGuard simply does what you tell it to do; nothing more, nothing less. There is no abstraction layer correcting your mistakes.
Setting up a local DNS was one of the easiest improvements I made to my home network
Having local control opens up so many possibilities
So did I actually replace Tailscale?
This experiment wasn’t meant to prove one better than the other, nor was my motive to replace Tailscale permanently. After a month of using raw WireGuard, I understood that it gave me full ownership and control over keys, routing, firewall rules, and reachability. It behaved exactly the way I configured it, but that precision also meant additional responsibility.
Tailscale, on the other hand, removes that responsibility by design. It abstracts the orchestration layer that most users don’t want to manage. Once I added a device to the account, it automatically handled the NAT traversal, coordination, and device discovery without additional configuration.
In the end, I appreciate both: one for its minimalist design and the other for its orchestration. For someone who is comfortable managing infrastructure on a daily basis, raw WireGuard is empowering. For someone who prefers the convenience of the operational complexity being handled in the background, Tailscale becomes a frictionless choice. They solve the same problem at different layers.
