Logo

Wireguard Locked Me Out of My Own Server, and I'm Not Even Mad

So you spun up a shiny new server, slapped Wireguard on it for ALL the privacy, and then... silence. Yeah. Let's talk about that.

Published: November 11, 2025

Okay, so picture this. It’s late, I’m on my third cup of coffee, and I’ve just finished setting up a brand new little Linux box in the cloud. It’s beautiful. Pristine. Has that new server smell. The plan was simple: turn this baby into my own private corner of the internet, and the first step is to route all its traffic through a VPN. Because privacy, right?

I chose Wireguard because I’m not a monster. It’s clean, it’s fast, and it’s so much less of a headache than OpenVPN. The config is like, five lines long. I copy my little config file over, run wg-quick up wg0, and hold my breath.

[#] ip link set wg0 up [#] wg setconf wg0 /dev/fd/63 …and a bunch of other happy-looking lines.

Success! I check the server’s IP from its own command line. It’s the VPN’s IP. Perfect. I am a genius. A master of networking. A digital ghost.

Feeling very pleased with myself, I type exit in my SSH terminal, ready to log back in and continue my conquest.

ssh josh@<my_server_ip>

…Connection timed out.

Wait, what? I try again. Connection timed out. My heart does that little thump thing. You know the one. The “oh-no-what-did-I-just-break” thump.

I’ve been here before. This is the digital equivalent of locking your keys in the car, only the car is a thousand miles away and the only way to open it is with a key that is… well, inside the car.

The culprit, of course, was this one beautiful, terrible line in my Wireguard config: AllowedIPs = 0.0.0.0/0. This line tells the server, “Hey, every single packet of data, no matter where it’s going, send it through this VPN tunnel.” And it’s a very obedient little server. It did exactly what I told it to. Including my own SSH connection. It was trying to route my attempt to connect to it… back through the tunnel… which I wasn’t in. It’s a classic Catch-22.

So I had to use the web console my provider offers (which feels like performing surgery with oven mitts) to get back in and turn the VPN off.

The fix? It turns out you need to do some fancy footwork with routing rules. You basically have to tell the server, “Look, I know I said everything goes through the tunnel, but I’m making a tiny exception for SSH traffic coming from the outside world. That stuff gets to cut the line.”

And the way to do that is with PostUp and PostDown scripts right in your wg0.conf file. This is the magic sauce.

Under your [Interface] section, you add these two lines:

PostUp = ip rule add from <your_server_ip> table 123; ip route add default via <your_gateway_ip> dev eth0 table 123 PostDown = ip rule del from <your_server_ip> table 123

Okay, let’s break that down because it looks like someone sneezed on their keyboard.

PostUp is the stuff that runs after the VPN connection is made.

  • ip rule add from <your_server_ip> table 123: This says “Hey, any traffic that originates from my server’s own public IP address? Don’t use the main routing table. Use this special one I’m calling ‘123’.” You can call it whatever you want, I just mashed the keyboard.
  • ip route add default via <your_gateway_ip> dev eth0 table 123: This is the second part. It says “And for everything in that special ‘123’ table, send it out the normal way, through your default gateway on the main network interface (probably eth0).” You can find your gateway IP by typing ip route before you start the VPN.

PostDown is just the cleanup crew. It runs when the VPN disconnects and just deletes the special rule you made. Tidy.

The result? The AllowedIPs = 0.0.0.0/0 line still shoves all the server’s outgoing traffic from its services through the VPN, like it should. But this new rule creates a special VIP lane. When you try to SSH into the server’s public IP, teh server sees the connection, recognizes its own IP, consults the special “123” table, and responds directly back to you over the normal internet instead of trying to stuff the response packet into the Wireguard tunnel.

It’s such a simple fix for such a pants-wettingly scary problem. I swear, half of being a software engineer is just learning how to elegantly undo the problems you created for yourself five minutes earlier.

Anyway, that’s my two cents. Hope this saves someone else from that 1 AM cold-pizza-fueled panic.

💡 Need a Developer Who Gets It Done?

If this post helped solve your problem, imagine what we could build together! I'm a full-stack developer with expertise in Python, Django, Typescript, and modern web technologies. I specialize in turning complex ideas into clean, efficient solutions.