To prevent a Linux server from routing all traffic through a VPN, you must remove the default route that points to the VPN interface and ensure your primary network interface retains the default gateway. This is typically achieved by adjusting routing metrics or explicitly deleting the incorrect route using the
ip route command. For WireGuard users, this often involves modifying the configuration file to disable
AllowedIPs = 0.0.0.0/0 or managing routes manually via systemd-networkd or NetworkManager.
Understanding Default Routes and VPNs
When you connect to a VPN, especially one configured with
AllowedIPs = 0.0.0.0/0 in WireGuard or
redirect-gateway def1 in OpenVPN, the client adds a new default route to the kernel’s routing table. This new route has a lower metric (higher priority) than your existing internet connection’s default route. Consequently, all outbound traffic, including web browsing and package updates, is tunneled through the VPN server.
For many server applications, this behavior is undesirable. You may need your server to communicate directly with local services, access public APIs without leaking identity, or simply reduce latency by avoiding the VPN tunnel for general internet traffic. The goal is to keep the VPN tunnel active for specific subnets while ensuring the system’s default gateway remains your physical or virtual network interface.
Method 1: Configuring WireGuard Split Tunneling
The most robust solution for WireGuard is to configure split tunneling at the source level. By specifying only the remote networks that should traverse the VPN, you prevent the creation of a global default route. Edit your WireGuard configuration file, typically located at
/etc/wireguard/wg0.conf.
Locate the
[Peer] section for the server you are connecting to. Change the
AllowedIPs directive from
0.0.0.0/0, ::/0 to the specific CIDR blocks required. For example, if you only need to access a private corporate network at
192.168.50.0/24, set it as follows:
[Peer]
PublicKey = ...
AllowedIPs = 192.168.50.0/24
Endpoint = vpn.example.com:51820
After saving the file, restart the WireGuard service using
systemctl restart wg-quick@wg0. The system will now only route traffic destined for
192.168.50.0/24 through the VPN. All other traffic, including the default route, will continue to use your primary network interface. If you need to manage complex routing policies, consider reviewing
configure split tunneling with wireguard on linux for advanced scenarios involving multiple peers.
Method 2: Manually Adjusting Routing Metrics
If you cannot modify the VPN configuration or are using a client that forces a default route, you can adjust the routing table manually. First, identify your current routes using
ip route show. You will likely see two default routes: one pointing to your gateway (e.g.,
via 192.168.1.1 dev eth0) and one pointing to the VPN interface (e.g.,
dev wg0).
To prioritize your physical interface, you can change the metric of the default route. Lower metrics have higher priority. Check the current metrics:
ip route show default
Suppose the VPN route has a metric of 0 and your primary route has a metric of 100. You can increase the VPN route's metric to make it less preferred, or decrease the primary route's metric. However, a safer approach is to delete the unwanted default route entirely if it was added dynamically. Use the
replace keyword rather than
add to avoid errors if the route already exists:
sudo ip route replace default via 192.168.1.1 dev eth0 metric 100
This command ensures the primary gateway is set with a specific metric. If the VPN route persists, you may need to delete it specifically:
sudo ip route del default dev wg0
Be cautious when manipulating routes manually, as mistakes can disconnect your server from the network. Always verify connectivity after making changes. For deeper insights into why routes might fail to update correctly, refer to
troubleshooting wireguard no access to remote.
Method 3: Using Policy Routing for Specific Traffic
In some cases, you want to keep the VPN as the default for certain applications but not others. Linux supports policy routing, which allows you to create separate routing tables based on source IP, firewall marks, or packet properties.
Create a new routing table entry in
/etc/iproute2/rt_tables:
echo "200 vpn_table" >> /etc/iproute2/rt_tables
Then, add a rule that directs traffic from a specific source IP or mark to this table. For example, to route traffic from a specific application through the VPN while keeping the system default intact, you would mark packets using iptables or nftables and then add a rule in the custom table. This method is powerful but complex; for most users, Method 1 is sufficient. If you find that your VPN connection drops frequently or causes timeouts, check
implement pmtu discovery on udp connection for vpn tunnel to resolve fragmentation issues that often accompany complex routing setups.
Verifying Your Configuration
After applying any of these methods, verify that your default gateway is correct. Run
ip route get 8.8.8.8. The output should show the path through your physical interface (e.g.,
dev eth0) rather than the VPN interface (
dev wg0). Additionally, test access to both internal resources (which should still go through the VPN if configured correctly) and external websites. If internal resources are unreachable, ensure their specific routes are present in the main routing table or the WireGuard peer configuration.
Frequently Asked Questions
Why does my VPN automatically become the default gateway?
Most VPN clients, including WireGuard with
AllowedIPs = 0.0.0.0/0, are designed to route all traffic through the tunnel for privacy. This is done by adding a default route with a high priority (low metric). To stop this, you must either restrict the
AllowedIPs to specific subnets or manually delete the default route added by the VPN client.
Can I use NetworkManager to control VPN routing?
Yes. In NetworkManager’s VPN settings, there is usually a checkbox labeled "Use this connection only for resources on its network" or "Disable IPv6 routing." Enabling these options prevents NetworkManager from setting the VPN as the system-wide default gateway. This is the easiest non-command-line solution for desktop and server environments using NM.
What happens if I delete the wrong default route?
If you delete the only default route pointing to your internet provider, your server will lose external connectivity. You will only be able to communicate with local network devices. To restore connectivity, you must re-add the default route via your gateway IP, such as
sudo ip route add default via 192.168.1.1. Always keep a console session open or have out-of-band access when modifying routing tables remotely.
How do I troubleshoot if split tunneling doesn't work?
Check the output of
ip route show to ensure the specific subnet routes are present and pointing to the VPN interface. Also, verify that the VPN peer’s
AllowedIPs includes those subnets. If traffic still leaks, check for overlapping routes or conflicting rules in policy routing. Reviewing
troubleshooting wireguard client-to-client communication issues can help isolate routing conflicts between peers.
Is it safe to leave the VPN route in the table with a high metric?
It is generally safe if you understand how Linux routing precedence works. The kernel selects the route with the lowest metric. If your primary internet route has a metric of 100 and the VPN default route has a metric of 200, traffic will prefer the internet. However, if the VPN route has a lower metric, it will be used. Explicitly removing the unwanted default route is cleaner than relying on metric manipulation alone.