How to Configure OpenVPN for Selective Routing: Route Specific IPs Through VPN While Using eth0 for Other Traffic


3 views

Many developers working with VPNs encounter a common scenario: needing to access certain internal resources through a VPN while maintaining regular internet connectivity for other traffic. The current setup shows VPN connectivity working for internal IPs (10.132.x.x) but breaking regular internet access.

From the ip r output, we can see the core issue:

default via 10.8.0.5 dev tun0  proto static  metric 50 
default via 10.0.2.2 dev eth0  proto static  metric 100

The VPN client is pushing a default route (10.8.0.5 via tun0) with a lower metric (50) than the regular gateway (metric 100), causing all traffic to route through the VPN.

We need to modify the OpenVPN configuration to only route specific subnets through the VPN. Here's how to implement this:

1. Server Configuration Modifications

Edit your server.conf to stop pushing default routes:

# Remove or comment out any 'push "redirect-gateway"' lines
# Keep your specific route push
push "route 10.132.0.0 255.255.0.0"

2. Client Configuration Adjustments

Modify your .ovpn client configuration:

client
dev tun
proto udp
remote my.vpn.server.com 1194
nobind
user nobody
group nogroup
persist-key
persist-tun
remote-cert-tls server
comp-lzo
verb 3
route-nopull
route 10.132.0.0 255.255.0.0
....
...
...

3. Network Manager Settings

Ensure your Network Manager settings for the VPN connection are configured to "Use this connection only for resources on its network" (or equivalent in your GUI).

After applying these changes:

$ ip r
# Should show default route via eth0
# Should show specific route to 10.132.0.0/16 via tun0

For more complex scenarios, consider using multiple routing tables:

# Create a new routing table
echo "200 vpn" >> /etc/iproute2/rt_tables

# Add route to VPN table
ip route add 10.132.0.0/16 dev tun0 table vpn
ip route add default via 10.8.0.5 dev tun0 table vpn

# Add rule to use VPN table for marked packets
ip rule add fwmark 1 table vpn

# Mark packets destined for VPN subnet
iptables -t mangle -A OUTPUT -d 10.132.0.0/16 -j MARK --set-mark 1

The traceroute error suggests DNS issues. Ensure your resolv.conf isn't being overwritten:

# Add to client .ovpn file
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

From your configuration and diagnostic outputs, I can see you've established a working OpenVPN connection with the following characteristics:

# Server pushing route for internal network
push "route 10.132.0.0 255.255.0.0"

# Client showing dual default routes
default via 10.8.0.5 dev tun0  proto static  metric 50 
default via 10.0.2.2 dev eth0  proto static  metric 100

The problem stems from having multiple default routes with different metrics. While you have route specificity for your 10.132.0.0/16 network, all other traffic is being routed through tun0 because:

  • The VPN client automatically adds a default route
  • Your network manager is not properly ignoring non-VPN traffic
  • The metric values aren't effectively prioritizing eth0 for non-VPN traffic

Here's the definitive solution to achieve true split-tunneling:

# Modified client.ovpn configuration
client
dev tun
proto udp
remote my.vpn.server.com 1194
nobind
user nobody
group nogroup
persist-key
persist-tun
remote-cert-tls server
comp-lzo
verb 3
route-nopull
route 10.132.0.0 255.255.0.0
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf
<ca>....</ca>
<cert>...</cert>
<key>...</key>

Your server.conf needs these modifications to support proper split-tunneling:

# Disable default route pushing
push "route 10.132.0.0 255.255.0.0"
push "redirect-gateway def1 bypass-dhcp"  # REMOVE or comment this line
push "dhcp-option DNS 8.8.8.8"  # Optional: specify DNS if needed

After implementing these changes, your routing table should look like this:

$ ip route show
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 
10.8.0.1 via 10.8.0.5 dev tun0 
10.8.0.5 dev tun0 proto kernel scope link src 10.8.0.6 
10.132.0.0/16 via 10.8.0.5 dev tun0 
default via 10.0.2.2 dev eth0

If you encounter DNS resolution issues after implementing split-tunneling, consider these solutions:

# Option 1: Configure resolv.conf directly
nameserver 8.8.8.8
nameserver 1.1.1.1

# Option 2: Use NetworkManager settings
nmcli con mod "Your Ethernet Connection" ipv4.dns "8.8.8.8,1.1.1.1"
nmcli con up "Your Ethernet Connection"

For more complex scenarios where you need to route multiple subnets through VPN:

# In client.ovpn
route 10.132.0.0 255.255.0.0
route 192.168.1.0 255.255.255.0
route 172.16.0.0 255.240.0.0

# Optional: Exclude specific IPs from VPN routing
route 10.132.5.100 255.255.255.255 net_gateway