I have a server running Debian which has networking like this:

eth0 - has public IP address
eth1 - has public IP address

I'm trying to set up a VPN on the server which I can connect to from my Android phone. I followed the instructions at http://wiki.debian.org/HowTo/AndroidVPNServer to install and configure xl2tpd and racoon. It all works, but I have one last adjustment I want to make: when I connect my phone to the VPN, my public IP address out of which traffic from the phone is routed is the one on eth0, i.e. I'd like VPN traffic to be NATed behind eth1's IP address, that is (ideally, with VPN clients continuing to connect to

My firewall rules look like this:

iptables -A INPUT -p udp --dport 500 -j ACCEPT
iptables -A INPUT -p udp --dport 4500 -j ACCEPT
iptables -A INPUT -p esp -j ACCEPT
iptables -A INPUT -p udp -m policy --dir in --pol ipsec -m udp --dport 1701 -j ACCEPT
# Enable VPN traffic on the ppp+ adapters (only active when a call is established)
# to go through the machine using SNAT/masquerading.
iptables -A FORWARD -i ppp+ -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o ppp+ -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -s $VPN_CLIENT_RANGE -j MASQUERADE

I had hoped that changing eth0 to eth1 in the last three lines would achieve the right effect, but it does not - the VPN client can connect but can no longer see the internet, and the logs show traffic from VPN clients (pppX interfaces on the server) still being sent out of eth0 (which the firewall blocks without those last three lines).

Do I need to configure a source address in pppd somehow? Or change the default route for ppp interfaces?

1 Answer 1


I've worked it out.

When a client connects to the VPN, a PPP connection is established.

Packets flow from the client to the pppN interface on the server. What causes them to flow from there out to the internet via the 'wrong' IP address is the default routing table of the server:

$ ip route show
default dev eth0 scope link

i.e. all outbound traffic goes via eth0.

Assuming we don't want to change the default route, what we need is to create a separate routing table with a default route via eth1, and make the VPN use it.

Add an entry for the new table to /etc/iproute2/rt_tables :

101 vpn

The number can be anything unique in the file; the name is a descriptive one for the job in hand.

Now add a default route via eth1 to this table:

# ip route add table vpn default dev eth1 scope link

Finally, force incoming VPN traffic (on the pppN interfaces) to be routed according to our new table. The simplest way is to use the /etc/ppp/ip-up.d and ip-down.d mechanism to add and delete rules as ppp interfaces are brought up and down.


ip rule add dev $IF table vpn


ip rule delete dev $IF table vpn

To make all this survive a reboot, you need to put the 'ip route add' line in something executed on startup - e.g. your firewall script - or as an 'up' line in /etc/network/interfaces on eth0.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .