Understanding the Network Conflict
The core issue arises because a Wireguard client on a router typically routes all internet-bound traffic through the VPN tunnel. When you attempt to SSH from a device behind that router to a server, the SSH packets are encapsulated inside the Wireguard tunnel. If the SSH server is also part of the same VPN mesh or if the return path is misconfigured, the packets may never reach their destination, or they may loop back into the tunnel indefinitely.
To resolve this, we must distinguish between management traffic (SSH) and general internet traffic. The goal is to allow SSH connections to traverse the public internet directly, while keeping other data secure within the encrypted tunnel. This requires precise control over the routing tables on both the client side (your router) and potentially the server side.
Configuring Split Tunneling on the Router
The first step is to modify the Wireguard configuration file on your router. Open the wg0.conf file or the equivalent configuration used by your router’s firmware. Locate the AllowedIPs directive within the peer section representing your Wireguard server.
- Exclude Local Subnets: Ensure that your local LAN subnet (e.g.,
192.168.1.0/24) is NOT included in theAllowedIPs. If it is present, traffic intended for devices on your local network will be forced into the VPN tunnel, causing connectivity issues for local resources. - Define Specific Routes: Instead of using
0.0.0.0/0which captures all traffic, specify only the networks that should go through the VPN. For example, if you want to access a remote office network at10.8.0.0/24, setAllowedIPs = 10.8.0.0/24.
This change ensures that when you type an SSH command, the router checks its main routing table first. Since the SSH target is not in the AllowedIPs list, the packet will be sent out via the default gateway (the public internet) rather than being encapsulated into the Wireguard interface.
Binding SSH to the Correct Interface
On the SSH server side, it is crucial to ensure that the SSH daemon (sshd) is listening on the correct network interface. By default, many servers listen on 0.0.0.0, which binds to all interfaces. While this usually works, it can sometimes lead to ambiguity in complex routing scenarios.
- Edit SSH Configuration: Access the server’s
/etc/ssh/sshd_configfile. - Set ListenAddress: Add or modify the line
ListenAddress 0.0.0.0(or the specific public IP of the server). If the server has multiple IPs, specify the one accessible via the public internet. - Restart Service: Apply changes by running
sudo systemctl restart sshd.
Additionally, verify that the firewall on the SSH server allows incoming connections on port 22 from any source, or specifically from your home IP range if you prefer tighter security. This step ensures that the unencrypted SSH handshake can complete before any potential VPN interference occurs.
Routing Considerations and Troubleshooting
If you still experience timeouts, check the routing table on your router. Use the command ip route get <server_ip> to see which interface the system chooses to reach the SSH server. It should show the default gateway (usually dev eth0 or similar), not the Wireguard interface (dev wg0).
If the output shows the Wireguard interface, you may need to add a static route with a lower metric for the SSH server’s IP address. However, split tunneling as described above usually resolves this automatically. For more complex setups involving multiple peers, consider reviewing how traffic is routed between peers to avoid asymmetric routing issues. You might find relevant insights in our guide on Routing Internet-Bound Traffic Between Two WireGuard Peers, which details how to manage overlapping routes effectively.
Another common pitfall is MTU (Maximum Transmission Unit) mismatches. Wireguard adds overhead to each packet. If your MTU is too high, packets may fragment or drop, leading to slow SSH sessions or dropped connections. Adjust the MTU on the Wireguard interface to 1420 or 1400 to accommodate the additional headers. This adjustment is critical for maintaining stable performance across different network conditions.
Finally, test the connection using verbose mode: ssh -v user@server_ip. Observe where the connection hangs. If it fails during key exchange, it is likely a routing or firewall issue. If it hangs after authentication, it could be an MTU problem or a bandwidth limitation. Monitoring these logs helps isolate the root cause quickly without needing advanced network analysis tools.
Frequently Asked Questions
Why does my SSH connection drop randomly?
This is often caused by MTU mismatches where large SSH packets are fragmented incorrectly. Reducing the Wireguard interface MTU to 1420 bytes usually resolves this instability. Additionally, check if your ISP blocks long-lived TCP connections, though this is rare for standard SSH ports.
Can I use the same Wireguard config for both client and server?
No, the configurations differ significantly. A client needs a PrivateKey and a PublicKey of the server, while a server needs its own PrivateKey and listens for incoming connections. Mixing them up will prevent either endpoint from establishing a valid tunnel.
How do I access local devices while the VPN is active?
You must exclude your local LAN subnet from the AllowedIPs in the Wireguard client configuration. This forces traffic destined for local devices to use the router’s default gateway instead of the VPN tunnel, ensuring seamless local access.
Is it safe to expose SSH over the public internet?
It is generally safe if you use strong passwords, key-based authentication, and fail2ban. Exposing SSH directly is less secure than tunneling it through a VPN, but splitting traffic allows you to keep management channels open even if the VPN disconnects.
What if my ISP blocks UDP port 51820?
If your ISP blocks standard Wireguard ports, you can configure Wireguard to use a different UDP port, such as 443. Update the ListenPort on the server and the Endpoint on the client to reflect this new port number.