OpenVPN – Configure Multiple Clients on the Same Host

openvpnroutingubuntu-10.04

I'm trying to run two openvpn clients on the same host (let's call this the dual client box), connecting to two different openvpn servers. My dual client box is running Ubuntu 10.04, and I've got two ethernet aliases set up in my interfaces file.

I want to set up the dual client box such that a computer whose gateway is set to eth0:0 gets all their traffic routed through one OpenVPN tunnel, and a computer whose gateway is set to eth0:1 gets all their traffic routed through a different OpenVPN tunnel. Eventually, I want to be able to have multiple computers connecting to my dual client box, sharing that OpenVPN tunnel (but unaware of each other).

Excerpt from my /etc/network/interface file:

iface eth0:0 inet static
address 192.168.1.242
netmask 255.255.255.0
broadcast 192.168.1.255
network 192.168.1.1

iface eth0:1 inet static
address 192.168.1.243
netmask 255.255.255.0
broadcast 192.168.1.255
network 192.168.1.1

I want to configure one client to route through one alias and the other client to route through the other. So far, I've created the client configuration files and told OpenVPN to call an up & down script when it's started/stopped.

OpenVPN is able to start and stop properly, but I'm running into problems with the routing, probably due to my own ignorance. I have a test box that I'm using to connect to my dual client box, and I've set the gateway on the test box to the ethernet alias's IP. I'm able to ping stuff through the dual client box, but my pings get routed oddly – through the main gateway on the dual box as opposed to through the OpenVPN tunnel.

root@test-box:~# ping yahoo.com
PING yahoo.com (98.137.149.56) 56(84) bytes of data.
64 bytes from ir1.fp.vip.sp2.yahoo.com (98.137.149.56): icmp_seq=1 ttl=49 time=413 ms
From 192.168.1.133: icmp_seq=2 Redirect Host(New nexthop: 192.168.1.1)

Furthermore, my server doesn't seem to configure the tun0 device properly – according to OpenVPN's log file, ifconfig gets called to set the tun0 address, but when I run ifconfig to check tun0 settings, there's no IP address assigned. I've checked the logs, and they don't indicate any problem.

Client configuration file looks like this:

client
dev tun0
proto tcp
remote xxx.xxx.xxx.xxx 1000
resolv-retry infinite
nobind
persist-key
tls-client
tls-remote server
ns-cert-type server
tls-auth ta.key 1
cert acertificate.crt
key akey.key
ca ca.crt
comp-lzo
verb 3
auth-user-pass afile
log-append /var/log/openvpn/openvpn.log
script-security 3 system
up "/etc/openvpn/tun-up-us.sh"
down "/etc/openvpn/tun-down-us.sh"

My up script looks like this:

# OpenVPN up script for US
#!/bin/bash
. /usr/local/common/copy-routing-table.sh

# following are the shared variables passed by openvpn
# tun1 1500 1544 10.26.0.2 255.255.255.0 init

# Grab the IP address for the eth0:0 alias
IP_ETH00=$(ifconfig eth0:0 | grep 'inet addr' | sed -e 's/:/ /' | awk '{print $3}')

# Set up routing
copy_routing_table "us_table"
ip route add 10.26.0.0/16 dev eth0:0 src $IP_ETH00 table us_table
ip route add default via $4 table us_table
ip route add 10.26.0.0/16 dev eth0:0 src $IP_ETH00
ip rule add from $IP_ETH00/32 table us_table
ip rule add to $IP_ETH00/32 table us_table
ip route flush cache
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

copy-routing-table.sh copies the main routing table entries to the us_table. Is copying the main routing table undesirable in case of conflict?

Best Answer

You would need to elaborate somewhat further what it is you are trying to do. A rough sketch with IP addresses of the hosts involved and a listing of your routing table(s) would help a lot understanding your problem.

my server doesn't seem to configure the tun0 device properly

It is possible for an ifconfig command to fail - maybe you should check the logs for that and post the relevant excerpts.

I want to set up the dual client box such that a computer whose gateway is set to eth0:0 gets all their traffic routed through one OpenVPN tunnel, and a computer whose gateway is set to eth0:1 gets all their traffic routed through a different OpenVPN tunnel

ip rule add from $IP_ETH00 table us_table

That's probably not the best way to achieve what you really want - which seems to be different routes for different clients. While it is possible to add iptables -t mangle rules to mark packets for different criteria, there would be no set of criteria being able to distinguish between eth0:0 and eth0:1 as the input interface (which is due to the way IP aliasing is implemented).

What you can do however is simply set up something like

ip rule add from <ip-of-your-client-for-the-us-table> table us_table

which would eliminate the need for IP aliases in your configuration entirely since the routing decision would be done based on source and destination IP addresses, no matter which interface the packet came in at.

copy_routing_table "us_table"

You've omitted the source of copy_routing_table - if it does what I suspect it does, you would end up with your entire main routing table in us_table. If your main routing table already contains routes potentially conflicting with what you're defining in the script, you might end up using them instead of your newly-added routes. This is especially a concern since you are adding a new default route in your up-script:

 ip route add default via $4 table us_table

As you already have a default route in your "main" table and add another one "via $4" (which is wrong BTW, as $4 would represent a local IP address of the router's own tun interface - you should use "dev $1" instead) without deleting the old route. You should prepend ip route del default table us_table here - and probably something similar for the other routes you add as well.

And this here:

From 192.168.1.133: icmp_seq=2 Redirect Host(New nexthop: 192.168.1.1)

is a message from 192.168.1.133 which is getting the packet for 98.137.149.56 (yahoo.com) and routing it out through 192.168.1.1. Since 192.168.1.133 knows (by evaluation of the interface netmask) that your host is in the same network as 192.168.1.1, you get notified to use 192.168.1.1 directly in the first place.