Take the 2-minute tour ×
Server Fault is a question and answer site for professional 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 192.168.1.101 and gets VPN IP 192.168.2.3.

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 192.168.2.0/24 -o eth0 -j MASQUERADE

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

ip rule add fwmark 0x50 table 200
ip route add table 200 default via 192.168.2.1
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 google.com), 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 192.168.1.101.34941 > 74.125.67.100.80: S 4254520618:4254520618(0) win 5840 <mss 1334,sackOK,timestamp 558838 0,nop,wscale 5>
05:39:10.751921 IP 192.168.1.101.34941 > 74.125.67.100.80: S 4254520618:4254520618(0) win 5840 <mss 1334,sackOK,timestamp 559588 0,nop,wscale 5>

Where 74.125.67.100 is the IP it gets for google.com .

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

Edit: Some routes [from the client]

$ ip route show table main
192.168.2.0/24 dev tap0  proto kernel  scope link  src 192.168.2.4
192.168.1.0/24 dev wlan0  proto kernel  scope link  src 192.168.1.101  metric 2
169.254.0.0/16 dev wlan0  scope link  metric 1000
default via 192.168.1.1 dev wlan0  proto static

$ ip route show table 200
default via 192.168.2.1 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
add comment

3 Answers

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 192.168.2.0/24 dev tap0  proto kernel  scope link  src 192.168.2.4 table 200
ip route add 192.168.1.0/24 dev wlan0  proto kernel  scope link  src 192.168.1.101  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.

#!/bin/bash
IFACE=wlan0
RT=200
/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}
done


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 192.168.2.0/24 -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
add comment

Try on the server:

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

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

net.ipv4.conf.default.forwarding=1

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

share|improve this answer
    
Already enabled –  Mikeage May 17 '09 at 17:49
add comment
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
add comment

Your Answer

 
discard

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.