Linux – Only tunnel certain applications via OpenVPN

debianirclinuxopenvpnvpn

I've purchased a VPN solution, it works correctly when I have "redirect-gateway def1" in the configuration file (routing all traffic through the VPN).

However when I remove that line from the configuration file, I am still able to ping-out of the machine (ping -I tap0), however I cannot ping the IP assigned to the machine (it's a public ip), i get the error: Destination Host Unreachable.

I only want to have certain applications sending traffic through the VPN tunnel (eg: ZNC, irssi), all of which i can select which IP they use. However they can't recieve any data, making the tunnel essentially useless to me when disabling redirect-gateway.

Any ideas on how to allow specific applications use the tunnel, without of forcing everything to go through it?

My configuration file is as follows:

dev tap
remote #.#.#.#
float #.#.#.#
port 5129
comp-lzo
ifconfig #.#.#.# 255.255.255.128
route-gateway #.#.#.#
#redirect-gateway def1
secret key.txt
cipher AES-128-CBC

The output of ifconfig -a when the tunnel is connected:

tap0      Link encap:Ethernet  HWaddr 00:ff:47:d3:6d:f3  
          inet addr:#.#.#.#  Bcast:#.#.#.#  Mask:255.255.255.255
          inet6 addr: <snip> Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:612 errors:0 dropped:0 overruns:0 frame:0
          TX packets:35 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:25704 (25.1 KiB)  TX bytes:6427 (6.2 KiB)

EDIT: the Bcast:#.#.#.# (ifconfig) is different from route-gateway #.#.#.# (openvpn) if that makes any difference.

Best Answer

I think u can do that using iptables:

#!/bin/bash
# Create new routing table
echo 200 vpn >> /etc/iproute2/rt_tables

# assign iptables mark "1" to this table
ip rule add fwmark 1 table vpn

#next hop for the new routing table will be trough openvpn
ip route add table vpn eql nexthop via <remotevpnip> dev tap0

#with iptables, add mark "1" to the traffic that must be sent trough the vpn
# Sample using the -m owner iptables module
iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner <user> -j MARK --set-mark 0x01

This works for udp & tcp traffic, not icmp.