[Openswan dev] KLIPS: Source IP of the L2TP packet (1701) in NATed environment

hiren joshi joshihirenn at gmail.com
Wed May 25 12:58:47 EDT 2011


Hello,

I am reporting this again, now against the latest release:
openswan-2.6.33, xl2tpd-1.2.8

Problem:
L2TP (over IPSec) connection attempt fails when server uses KLIPS and
client is NATed.

Setup:
Client - WinXP (fixed with http://support.microsoft.com/kb/818043)
Server - Openswan-2.6.33 with KLIPS, xl2tpd-1.2.8
NAT - Yes, WinXP is NATed (for Openswan, peer is NATed)
Mode - Transport

Description:
With the following network schema -

Openswan ---             NAT  box           --- WindowsXP
172.16.1.2  --- 172.16.1.1 | 171.16.3.1 --- 172.16.3.3

IPSec connection gets established and below eroute is installed.
[root at fc14 ~]# ipsec eroute
0          172.16.1.2/32:1701 -> 172.16.1.1/32:1701 =>
esp0x3c3ee757 at 172.16.1.1:17

First L2TP connection request packet (port 1701) appears from ipsec0
02:41:56.742217 IP 172.16.3.3.1701 > 172.16.1.2.1701:
l2tp:[TLS](0/0)Ns=0,Nr=0 *MSGTYPE(SCCRQ) *PROTO_VER(1.0)
*FRAMING_CAP(S) *BEARER_CAP() FIRM_VER(1280) *HOST_NAME(qawinxp)
VENDOR_NAME(Microsoft) *ASSND_TUN_ID(35) *RECV_WIN_SIZE(8)

Source IP of this  packet is the original IP of the L2TP client.
This is because
ipsec_rcv_cleanup (linux/net/ipsec/ipsec_rcv.c::1765), resets the
original source IP of the incoming packet using NATT-OA payload.
        if ((irs->natt_type) && (irs->proto != IPPROTO_IPIP)) {
               /*
                * NAT-Traversal and Transport Mode:
                *   we need to correct TCP/UDP checksum
                * If we've got NAT-OA, we can fix checksum without
recalculation.
                */
                __u32 natt_oa = (irs->ipsp && irs->ipsp->ips_natt_oa) ?
                        ((struct
sockaddr_in*)(irs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0;

                if (natt_oa != 0) {
                        /* reset source address to what it was before NAT */
                        osw_ip4_hdr(irs)->saddr = natt_oa;

Now the reply packet from xl2tpd is
02:41:58.744197 IP 172.16.1.2.1701 > 172.16.3.3.1701:
l2tp:[TLS](35/0)Ns=0,Nr=1 *MSGTYPE(SCCRP) *PROTO_VER(1.0)
*FRAMING_CAP(AS) *BEARER_CAP() *FIRM_VER(1680)
*HOST_NAME(fc14.localdomain) *VENDOR_NAME(xelerance.com)
*ASSND_TUN_ID(20733) *RECV_WIN_SIZE(4)

which doesn't match the route installed by _updown script
[root at fc14 ~]# ip ro
172.16.1.1 dev ipsec0  scope link

So it never gets injected into KLIPS and L2TP client never receives it
(encrypted). Default route may send it unencrypted.

Even if I try to inject it in KLIPS via inserting a route
ip ro add 172.16.3.3 dev ipsec0

KLIPS rejects the packet as eroute doesn't match the destination IP.
ipsec_tunnel_start_xmit: STARTING
klips_debug:ipsec_xmit_strip_hard_header: >>> skb->len=155
hard_header_len:14 00:0c:29:93:6e:04:00:0c:29:93:6e:04:08:00
klips_debug:   IP: ihl:20 ver:4 tos:0 tlen:141 id:0 DF frag_off:0
ttl:64 proto:17 (UDP) chk:56890 saddr:172.16.1.2:1701
daddr:172.16.3.3:1701
klips_debug:ipsec_xmit_strip_hard_header: Original head,tailroom: 2,35
klips_debug:ipsec_findroute: 172.16.1.2:1701->172.16.3.3:1701 17
klips_debug:rj_match: * See if we match exactly as a host destination
klips_debug:rj_match: ** try to match a leaf, t=0pcfb37800
klips_debug:rj_match: *** start searching up the tree, t=0pcfb37800
klips_debug:rj_match: **** t=0pcfb37818
klips_debug:rj_match: **** t=0pcfb5f740
klips_debug:rj_match: ***** cp2=0pcd332d18 cp3=0pcdbf3690
klips_debug:rj_match: ***** not found.
klips_debug:udp port check: version: 4 nexthdroff: 34 udphdr: cea80824
klips_debug:ipsec_xmit_SAlookup: checking for local udp/500 IKE,
udp/4500 NAT-T, ESP or AH packets saddr=172.16.1.2, er=0p(null),
daddr=172.16.3.3, er_dst=0, proto=17 sport=1701 dport=1701
klips_debug:ipsec_xmit_encap_bundle: shunt SA of DROP or no eroute: dropping.
klips_debug:ipsec_xsm: processing completed due to IPSEC_XMIT_STOLEN.
klips_debug:ipsec_tunnel_start_xmit: encap_bundle failed: 2

An earlier version (openswan-2.6.24) I am using is having the same problem.
I have patched it with the following and it is working fine since long.
--- net/ipsec/ipsec_rcv.c.orig	2010-04-29 20:10:57.000000000 +0530
+++ net/ipsec/ipsec_rcv.c	2010-04-29 20:25:27.000000000 +0530
@@ -1626,11 +1626,12 @@ ipsec_rcv_cleanup(struct ipsec_rcv_state
 			((struct sockaddr_in*)(irs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0;

 		if (natt_oa != 0) {
-			/* reset source address to what it was before NAT */
-			ipp->saddr = natt_oa;
-			ipp->check = 0;
-			ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);
-			KLIPS_PRINT(debug_rcv, "csum: %04x\n", ipp->check);
+			/* Let the packet appear with its NATed source IP
+			 * so that the reply packet matches the eroute installed.
+			 * As a side effect, turned UDP checksum protection off temporarily.
+			 * Will add recalculation code soon.
+			*/
+			((struct udphdr *)((__u32 *)ipp+ipp->ihl))->check = 0;
 		}
 	}
 #endif

I wonder if other L2TP users using KLIPS have working NAT-T.

Thanks for your time.

Regards,
Hiren


On Fri, May 7, 2010 at 4:04 AM, David McCullough
<david_mccullough at mcafee.com> wrote:
>
> Jivin hiren joshi lays it down ...
>> Hello,
>>
>> This is related to L2TP in NATed environment (NAT_TRAVERSAL & TRANSPORT MODE).
>>
>> New KLIPS (openswan-2.6.24/linux/net/ipsec/ipsec_rcv.c::ipsec_rcv_cleanup
>>  at line#1618)
>> overwrites source address with NATT-OA (and recalculates IP checksum).
>>
>> As a result, decrypted packet (from ipsecX device) appears with
>> original IP of the L2TP client
>> as its  source IP. Ans so its reply packet is destined to the original
>> IP of the L2TP client.
>>
>> However the eroute installed for the connection requires the NATed IP
>> as packet's destination.
>>
>> Network:
>> x' (leftsubnet)  --- x (left) === y (NATbox) --- z (L2TP client)
>>
>> eroute installed:
>> x'  -->  y   =>  y
>>
>> packet's source - destination:
>> x' -> z
>>
>> The packet gets dropped as it gets injected into the tunnel.
>>
>> Old KLIPS (openswan-2.4.9/linux/net/ipsec/ipsec_rcv.c::ipsec_rcv_decap
>>  at line#868)
>> was using NATT-OA only to fix udp/tcp checksum. It was modifying the
>> source IP of the packet.
>>
>> I don't have configurations and logs with me right now.
>> I don't know if I am the only one to observe this. I am running old
>> (2.4.9) pluto with new (2.6.24) KLIPS.
>> Request L2TP users to share their input on this.
>
> If you can,  I think the latest 2.6.26 (git) should have that fixed.
> I can't remember whether it was kernel or user or a bit of both but IIRC
> L2TP/klips/NAT is all fairly happy in the latest git code at the moment.
>
> Cheers,
> Davidm
>
> --
> David McCullough,      david_mccullough at mcafee.com,  Ph:+61 734352815
> McAfee - SnapGear      http://www.mcafee.com         http://www.uCdot.org
>


More information about the Dev mailing list