Link to home
Start Free TrialLog in
Avatar of gsx1022
gsx1022Flag for Hungary

asked on

Access MS W2K8 VPN from Ubuntu

Hi Experts,

I have a scenario where I have VPN access to a corporate server running W2K8, say 192.168.1.2. The default gateway to the internet on that network is 192.168.1.1 (another W2K8). I am on a home lan with my computer's ip being 192.168.1.100 and the default gateway to the internet being 192.168.1.1 here too. The two tunnel endpoints are 192.168.150.8 (workstation) and 192.168.150.10 (server).
When I connect to the VPN from Windows 7, routing is automatically set up, so that the 192.168.1.0/24 subnet corresponds to the remote 192.168.1.0/24, so therefore I can use all services on the corporate lan, and access the internet through the corporate internet gateway.
On Ubuntu however, this is not done automatically (which is good, since I want something else). I would like to achieve, that the 192.168.111.0/24 subnet on my workstation corresponds to the corporate 192.168.1.0/24 subnet. I think this could be done with a little iptables/ip rule/ip route magic. However, I am not sure how exactly, though. I think the following would probably work:
- add a rule to mangle/prerouting in iptables to mark all packages heading to 192.168.111.0/24
- add an ip rule to put packages with the mark to a table (say 'vpn')
- add an ip route to route packages from the 'vpn' table through the vpn network interface ('ppp0')
- add a postrouting rule to iptables that changes the destination ip of any packet heading to the 192.168.111.0/24 subnet to head to the 192.168.1.0/24 subnet.
- add a rule to input (or maybe somewhere else?) in iptables to change any packet's source ip from 192.168.1.0/24 to 192.168.111.0/24 if it came from ppp0.

However, currently (with none of the above implemented)
ping -I ppp0 192.168.1.1

Open in new window

times out. Is that expected to happen?

Also, would my steps above do what I expect them to? If yes, what would the exact rules be? If no, how could I do what I would like to?

Thanks in advance,
gsx1022
Avatar of HawyLem
HawyLem

I'm not sure but, have you got firewalls/routers between the two endpoints?

Something that may block your calls stealthing the gateway
Avatar of gsx1022

ASKER

I've got a router (my home LAN's router) in between the two endpoints but that shouldn't really matter, since Windows works fine.
You have 2 questions:

1) I want a fancy setup , can I have that?
2) Why is the simple setup not working?

What you want to achieve in 1 is not possible by the method you mention here. Mostly because the DNAT target is restricted to PREROUTE/OUTPUT table in linux-iptables (meaning that AFTER you change the destination ip a routing decision is made) You would have to mark the packets, change the dest ip and then route them based on the mark.

as for question 2, you gave no information on configuration, routing tables, remote config etc... I would advise you to start by having a tcpdump run on the ppp0 interface to see what is happening with your echo requests..
Avatar of gsx1022

ASKER

Well, you are right de2Zotjes.

However, I think the two questions are closely related, because currently the problems might be caused by the fact that the fancy set up is not done yet, and therefore the two subnets collide.

Currently, ping to 192.168.1.7 for instance (which I am sure only exists on the remote subnet) times out, BUT in tcpdump I see that there is a reply in fact.
Also, my HTTP connections are tunneled through the VPN! But trying to use RDP to connect to 192.168.1.7 also times out (and tcpdump doesn't show anything).

I suspect that the problem might be that Ubuntu is trying to route through both ppp0 and wlan0 (my lan network card).

Here is the local routing table with the VPN beaing inactive:
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     *               255.255.255.0   U     2      0        0 wlan0
link-local      *               255.255.0.0     U     1000   0        0 wlan0
default         192.168.1.1     0.0.0.0         UG    0      0        0 wlan0

Open in new window


And when the VPN is active:
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.150.10  *               255.255.255.255 UH    0      0        0 ppp0
12.34.56.78     192.168.1.1     255.255.255.255 UGH   0      0        0 wlan0
12.34.56.78     192.168.1.1     255.255.255.255 UGH   0      0        0 wlan0
192.168.1.1     *               255.255.255.0   U     2      0        0 wlan0
link-local      *               255.255.0.0     U     1000   0        0 wlan0
default         *               0.0.0.0         U     0      0        0 ppp0

Open in new window

where 12.34.56.78 is the external IP of the corporate gateway (and yes, there is a duplicate entry, it's not a mistake).

So, maybe if I could implement the advanced setup, all my problems would go away. Could you please give some exact details on setting up the fancy config?

Thanks,
gsx1022
It is good to hear that the non responsive ping is in the kernel routing layer and that a reply is visible to tcpdump. The ppp-link is functional, one less problem :)

Under these circumstances there is a good chance that  the advanced setup is indeed what the doctor prescribes..

Rough guide to the commands:

iptables -t mangle -A PREROUTING --dest 192.168.111.0/24 -j MARK --set-mark 0x0111
iptables -t nat -A PREROUTING --dest 192.168.111.0/24 -j DNAT --to-destination 192.168.1.0/24

ip route add 192.168.1.0 via ppp0 dev ppp0 table corpnet
ip rule add fwmark 0x0111 table corpnet

I have not tested this specific setup, but the ingredients for this recipe I have used quite often. It should work.
First iptables command adds the rule to mark all packetsdestined to the 111.0 network. This happens in the mangle table, the first one traversed when packets enter the routing subsytem.
Second iptables command adds the rule to translate the destination ip. This is the one I have hesitation over, I am not sure it will leave the last octet alone. If it doesn't you will have to add 256 rules.. one for each possible address (some scripting adviced) The translation happens in the nat table, traversed after the mangle table, so by the time the address is altered the mark is already in place.
After this the packet gets to the routing code. First order of of business is to select the appropriate routing table, that was setup with the second ip command (ip rule add fwmark 0x0111 table corpnet). Almost there, all that is left is to make sure the packets are pumped out of the ppp0 interface, the first ip command set that up for us.

There is one key ingredient missing from all this, the source ip of the packets you pump out onto the ppp0 might very well be coming from 192.168.1.0/24... that will not fly. I do not know what type of vpn is in place (network or host at the remote side) but you will need to fix that as well ( an SNAT or MASQUERADE in the POSTROUTING for ppp0 comes to mind)


Avatar of gsx1022

ASKER

Hi,

It sounds great, but there's a bit of trouble.
root@netbook:/# iptables -t mangle -L PREROUTING -n -v
Chain PREROUTING (policy ACCEPT 670 packets, 348K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MARK       all  --  *      *       0.0.0.0/0            192.168.111.0/24    MARK xset 0x111/0xffffffff 
root@netbook:/# ping -c 2 192.168.111.7
PING 192.168.111.7 (192.168.111.7) 56(84) bytes of data.
^C
--- 192.168.111.7 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1006ms
root@netbook:/# iptables -t mangle -L PREROUTING -n -v
Chain PREROUTING (policy ACCEPT 672 packets, 348K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MARK       all  --  *      *       0.0.0.0/0            192.168.111.0/24    MARK xset 0x111/0xffffffff 

Open in new window


I've taken a look at it with Wireshark. The packets are sent out with the 192.168.111.0/24 destination address.

According to table 3-2. at http://www.faqs.org/docs/iptables/traversingoftables.html, the mangle/prerouting table isn't even involved here. Are you sure that is the right place for the rule?

gsx1022
Avatar of gsx1022

ASKER

Okay, I have greatly simplified the setup, but it's still not working properly.
Now I only have two rules:
ip route add 192.168.111.0/24 via 192.168.150.8 dev ppp0
iptables -t nat -A OUTPUT -o ppp0 -d 192.168.111.7 -j DNAT --to-destination 192.168.1.7

However, this doesn't solve the problem, that the packets coming from the hosts on the corporate lan don't have their source address rewritten to 192.168.111.0/24, but that doesn't matter at the moment, I would be satisfied if packets would go out to the corporate lan on ppp0. However, at the moment ping fails with destination host unreachable.

Any ideas?

gsx1022
Avatar of gsx1022

ASKER

If I remove the iptables rule, the icmp echo requests to 192.168.111.7 go out to the corporate network with the 192.168.111.0/24 IP fine. However, when I add the DNAT rule to iptables, I get destination host unreachable, because the ARP queries about 192.168.1.7 (please note that it's not 111 anymore) are sent on the local lan. This makes me worried that maybe what I am trying to achieve is impossible. Please tell me if it is. Or maybe I'll have to convince the corporate sysadmin to set up the DNAT for me on the remote side of the tunnel? I really wouldn't like to do that.
You must realize that what you want to accomplish needs some advanced magic. You need the marking of packets. I did not realize that you would want to send packets from the box that has the vpn endpoint. Indeed packets generated locally will not traverse the mangle prerouting, the traverse mangle output, so you would need to add a marking rule in the mangle output table:

iptables -t mangle -A OUTPUT --dest 192.168.111.0/24 -j MARK --set-mark 0x0111

as for the ping failing, I did mention that you would probably need to do a masquerade...

iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE


I attach the file I use for reference when looking at table traversal in iptables subsystem netfilterflow.pdf
Avatar of gsx1022

ASKER

In fact, I only want to send packets from the machine with the endpoint.
I am not sure, why would I need marking packets, but I don't mind as long as it works. However, your previous solution to changing the IPs from 1 to 111 (iptables -t nat -A PREROUTING --dest 192.168.111.0/24 -j DNAT --to-destination 192.168.1.0/24) also has to be changed. I assume iptables -t nat -A OUTPUT --dest 192.168.111.7 -j DNAT --to-destination 192.168.1.7 would be ok for that. But I don't see how would that solve my ARP problem. And also, based on the faqs.com link I posted above, the OUTPUT chains are traversed after the routing decision, while your source shows them before routing. What is the thruth?

Anyway, I tried the following, based on your post:
iptables -t mangle -A OUTPUT --dest 192.168.111.0/24 -j MARK --set-mark 0x0111
iptables -t nat -A OUTPUT --dest 192.168.111.7 -j DNAT --to-destination 192.168.1.7
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

ip route add 192.168.111.0/24 via 192.168.150.10 dev ppp0 table corpnet
ip rule add fwmark 0x0111 table corpnet

Open in new window


And the result is, that telnet says no route to host for 192.168.111.7, and ping fails with destination host unreachable. I've confirmed that the arp queries are only sent on wlan0 and are like this:
21:33:49.693585 ARP, Request who-has 192.168.1.7 tell 192.168.150.8, length 28

Open in new window

The problem is that the address is already translated to the 192.168.1.0/24 subnet, when the arp queries are sent, so they are sent on the wlan0 card. I've explicitly enabled arp on ppp0 with ifconfig ppp0 arp, but arp queries are still not sent out. If I could configure the system to send arp queries on both interfaces, I could use arptables to filter so queries for the corporate lan are only sent out on ppp0, not wlan0 and vice versa.

Thanks for your help,
gsx1022
I see 1 error in the setup you tried out.
line 5 of the commands you add a route to 192.168.111.0/24, that should be 192.168.1.0/24

That change should also make clear why the marking is needed. There are now 2 different instructions in the kernel for forwarding packets for the 192.168.1.0 net. One set in the main routing table, and one set in the corpnet routing table. Packets that were originally destined for the 111 subnet have a mark and are handled via the corpnet routing table because of that mark.
Avatar of gsx1022

ASKER

All right, thanks, that's logical. I misunderstood the whole concept at first. The ping replies are coming back now! But sadly ping still doesn't work, since the echo replies coming back are from hosts in the 192.168.1.0/24 subnet, and ping knows it sent out requests to a host in 192.168.111.0/24. The problem is however, that the nat table cannot be used in the INPUT chain, and the SNAT target cannot be used in the PREROUTING chain. How would I overcome that?

Thank you very much for your help!
gsx1022
We will repeat the trick in reverse direction:

# label all packets that come in on ppp0 and have a source address in the network we "hide":
iptables -t mangle -A PREROUTING -i ppp0 --source 192.168.1.0/24 -j MARK --set-mark 0x0999

# do a source address translation on packets with specific source AND mark:
iptables -t nat -A POSTROUTING --source 192.168.1.7 -m mark --mark 0x0999 -j SNAT --to-source 192.168.111.7
Avatar of gsx1022

ASKER

Thanks, I'll try when I get home. (No sense in messing with the vpn from the corporate lan :))

Although, I don't understand why is that supposed to work. Based on the netfilterflow.pdf you attached earlier, incoming packets don't reach the POSTROUTING chain. But we'll see.
Oh damn, i keep forgetting you are doing this on the endpoint. No choice then but to rely on the proper statekeeping of the DNAT target. These nat-targets (SNAT,DNAT, MASQUERADE) all keep state information to provide 2 way translations with 1 rule.

I am nearing the point where I am going to build this in virtual machines :) Just to find out for sure what flies and what fails.
Avatar of gsx1022

ASKER

Sadly, statekeeping isn't solving problems for me :( Both ping, and TCP handshake fail.
I don't see why, though. Maybe because DNAT is intended for incoming packets, and would work if I weren't using it on outgoing packets?
Also, (I can't find the link again, but) I've read on a mailing list, in a thread similar to this, that someone advised the asker, that it might worth a try using iproute2 to do the SNAT, because theoretically it could do it. I don't know if that is true or not, but I'll keep looking.

Actually I'm getting so annoyed that I was thinking of patching iptables to provide SNAT in the PREROUTING/NAT table. It can't be that hard, can it? They say iptables is easily extendable.

gsx1022
iproute2: there has been a nat implementation in the routing tables of the linux kernel in the 2.4 kernels. It was taken out in the 2.6 kernels afaik. There is a warning along those lines in the man page of ip

extending nat targets: netfilter is intended to be extensible. You would be mucking around in the kernel code though and that is never an undertaking to be taken lightheartedly.

There is always the cowards way out, if the 192.168.1.0 network on the local side of the vpn-link is under your control, why not change that? ( I have been using the house number as third octet for networks I put up for people at private locations, has helped a lot in preventing this type of clash :) )
Avatar of gsx1022

ASKER

Allright, iproute2 is out then. I might consider taking a look at iptables code (I hope I don't have to touch netfilter, only iptables).

Oh, yes my co-workers are sporting me since I started to mess with this kind of setup :) This is a matter of honour now, so changing the local subnet is the last thing I'd do :)
iptables is only a userspace interface to netfilter. iptables in not capable of doing anything. Extending functionality happens in netfilter :(

There is always the possibility of creating a virtual machine inside your regular machine. Make the virtual the endpoint of the vpn tunnel. Set up the packet mangling and routing tricks. Tell your desktop that it should route packets for ...111/24 via the virtual. That way the stateful settings for DNAT can kick in ( the fact that it will not work for locally delivered packets is caused by the non existence of nat table on input)

Then there is yet another target for the nat tables: NETMAP. I can't find any decent documentation on what and how it maps, but it is referenced by the shorewall people as one ot the components to solve exactly the problem you are facing (http://www.shorewall.net/netmap.html)

Time to install some virtuals and start playing around..
Avatar of gsx1022

ASKER

Allright, I was hoping that the functionality for SNAT in PREROUTING is in netfilter, it's just not accessible from iptables. If not, then it's a bit more tough. :(

Yes, well, probably I'll have to use a virtual machine on my desktop. Problem is my netbook with its 1.6GHz processor...

I've seen NETMAP, but the problem is, that it decides which address to rewrite this way: if this rule is in a chain that is for outgoing packets -> do SNAT, otherwise do DNAT.

I'll try to take a look at the iptables/netfilter code in a few days.

Thanks a lot for your effort,
gsx1022
Avatar of gsx1022

ASKER

Okay, I've read something that might be the one. Maybe I could redirect all the vpn traffic through lo in both directions, and then the packets would go through the interfaces we need. Do you think that could be done?
ASKER CERTIFIED SOLUTION
Avatar of de2Zotjes
de2Zotjes
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gsx1022

ASKER

It's a shame. I'm sure I saw this kind of trick somewhere. But I guess I'll just set up a vm. I'm tired of iptables. Thanks!