Sign up ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I'm trying to set up an OpenVPN VPN, which will carry some (but not all) traffic from the clients to the internet via the OpenVPN server.

My OpenVPN server has a public IP on eth0, and is using tap0 to create a local network, 192.168.2.x. I have a client which connects from local IP and gets VPN IP

On the server, I ran:

iptables -A INPUT -i tap+ -j ACCEPT
iptables -A FORWARD -i tap+ -j ACCEPT

iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE

On the client, the default remains to route via In order to point it to for HTTP, I ran

ip rule add fwmark 0x50 table 200
ip route add table 200 default via
iptables -t mangle -A OUTPUT -j MARK -p tcp --dport 80 --set-mark 80

Now, if I try accessing a website on the client (say, wget, it just hangs there. On the server, I can see

$ sudo tcpdump -n -i tap0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tap0, link-type EN10MB (Ethernet), capture size 96 bytes
05:39:07.928358 IP > S 4254520618:4254520618(0) win 5840 <mss 1334,sackOK,timestamp 558838 0,nop,wscale 5>
05:39:10.751921 IP > S 4254520618:4254520618(0) win 5840 <mss 1334,sackOK,timestamp 559588 0,nop,wscale 5>

Where is the IP it gets for .

Why isn't the MASQUERADE working? More precisely, I see that the source showing up as -- shouldn't there be something to indicate that it came from the VPN?

Edit: Some routes [from the client]

$ ip route show table main dev tap0  proto kernel  scope link  src dev wlan0  proto kernel  scope link  src  metric 2 dev wlan0  scope link  metric 1000
default via dev wlan0  proto static

$ ip route show table 200
default via dev tap0
share|improve this question
What's with the marking? I don't see any obvious reason why you need to do any of that. – womble May 17 '09 at 3:52
how else can I direct outgoing packets on port 80 to a different route than my normal default route? – Mikeage May 17 '09 at 7:39

3 Answers 3

Can you post the output of ip route show table main and ip route show table 200? I suspect you are missing a couple routes in your '200' table. Your '200' route table should have pretty much the same routes as the 'main' table the only difference being the default route.

I see that you updated, and I believe my original suggestion was correct. Notice how your main table has the 'scope link' route for both your local network and the vpn link? Those routes have to be added to the '200' table as well.

Try running these commands in addition to the other commands you use.

ip route add dev tap0  proto kernel  scope link  src table 200
ip route add dev wlan0  proto kernel  scope link  src  metric 2 table 200
ip route flush cache

If you want to script the creation of these routes you can use this. It will copy all the 'scope link' routes from the main route table into your other table.

/sbin/ip route list scope link table main proto kernel dev ${IFACE} \
| while read ROUTE ; do
    # and add that route to all the tables mentioned in the rrtables option
    # in the interfaces file
    /sbin/ip route add table ${RT} scope link proto kernel dev ${IFACE} ${ROUTE}

Another update. I just noticed I missed something rather obvious earlier.

Your MASQ statement seems to be working on eth0. From the route tables you posted, your output device isn't eth0. Instead of this.

iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE

You probably should just use a statement like this.

iptables -t nat -A POSTROUTING -o tap0 -j MASQUERADE
share|improve this answer
done [I'm posting this since I don't remember which one notifies you: a comment or an edit] – Mikeage May 17 '09 at 3:24
still not working :( I suspect the problem is on the gateway; after all, I can see the packets there in tcpdump. [OT: I'll be offline for a few hours, but I'll be back soon] – Mikeage May 17 '09 at 3:41
up vote 1 down vote accepted

Two things were wrong:

First, on the client, I needed SNAT the source to the actual IP.

Second, the reverse path filter was blocking the return packets, as it thought they were spoofed. echo 0 > /proc/sys/net/ipv4/conf/tun0/rp_filter fixed that

share|improve this answer
Can you post your iptables rules? Thanks. – Shoan Dec 7 '10 at 18:09

Try on the server:

echo 1 > /proc/sys/net/ipv4/ip_forward

That, I think, will enable it temporarily. If it works add:


to your /etc/sysctl.conf to make it permanent.

share|improve this answer
Already enabled – Mikeage May 17 '09 at 17:49

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.