[Openswan Users] Connection against a Lucent FW success!!!! but may be there's still room for improvement

Paul Wouters paul at xelerance.com
Mon Apr 6 21:27:42 EDT 2009


On Sun, 5 Apr 2009, Rolando Zappacosta wrote:

>   I could finally manage to get OSW to work against a Lucen VPN Gateway even through NAT. So, in case someone else needs such connection, compile below code and then run this:
>   modprobe ip_queue
>   UDP501encap &
>   iptables -A OUTPUT -d 135.244.223.254 -j QUEUE
>   iptables -A INPUT -s 135.244.223.254 -j QUEUE
> before launching OSW as usual.

Is that IP the local IP or the remote IP?

> is there a way to add this short&simple piece of code into OSW? I heard other commercial products do this same thing (changing the UDP to other than 501 though, but this could be done user-configurable).

Can you provide a README for this explaining the problem and the solution?
Then I'll add it to the contrib/ directory.

Is this a portforward from 501 to 500? If so, why does it need to go through userland?

Paul

>   The code is:
> RJZ-LNX UDP501 # cat UDP501encap.c
> /*
> * This code is GPL.
> */
>
> /*
> To compile:
>        gcc UDP501encap.c -o UDP501encap -lipq
> */
>
> #include <netinet/in.h>
> #include <arpa/inet.h>
> #include <linux/netfilter.h>
> #include <libipq.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> #define BUFSIZE 2048
> #define BOOL int
>
> #define DstPort 501
>        #define DstPortHi DstPort >> 8
>        #define DstPortLo DstPort & 0x00FF
> #define SrcPort 501
>        #define SrcPortHi SrcPort >> 8
>        #define SrcPortLo SrcPort & 0x00FF
>
>
> typedef unsigned short u16;
> typedef unsigned long u32;
>
> u16 ip_sum_calc(u16 len_ip_header, unsigned char buff[])
> {
>        u16 word16;
>        u32 sum=0;
>        u16 i;
>
>        // make 16 bit words out of every two adjacent 8 bit words in the packet
>        // and add them up
>        for (i=0;i<len_ip_header;i=i+2){
>                word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
>                sum = sum + (u32) word16;
>        }
>
>        // take only 16 bits out of the 32 bit sum and add up the carries
>        while (sum>>16)
>          sum = (sum & 0xFFFF)+(sum >> 16);
>
>        // one's complement the result
>        sum = ~sum;
>
> return ((u16) sum);
> }
>
> static void die(struct ipq_handle *h)
> {
>        ipq_perror("passer");
>        ipq_destroy_handle(h);
>        exit(1);
> }
>
> int main(int argc, char **argv)
> {
>        int status;
>        unsigned char buf[BUFSIZE];
>        struct ipq_handle *h;
>        unsigned char *newPayload;
>        u16 srcaddr[4], dstaddr[4];
>        u16 newCS;
>        int ip_header_len;
>        u16 udp_len;
>        int i;
>
>        h = ipq_create_handle(0, PF_INET);
>        if (!h)
>                die(h);
>
>        status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
>        if (status < 0)
>                die(h);
>
>        do {
>                status = ipq_read(h, buf, BUFSIZE, 0);
>                if (status < 0)
>                        die(h);
>
>                switch (ipq_message_type(buf))
>                {
>                        case NLMSG_ERROR:
>                                fprintf(stderr, "Received error message %d\n", ipq_get_msgerr(buf));
>                                break;
>
>                        case IPQM_PACKET:
>                        {
>                                ipq_packet_msg_t *m = ipq_get_packet(buf);
>                                //Enable this to debug the incoming/outgoing packets:
>                                //printf("0x%02x %s -> %s (%d)\n",  m->payload[9], m->indev_name, m->outdev_name, m->data_len);
>
>                                if(m->outdev_name[0] == 0x0)
>                                {
>                                        // INPUT
>                                        ip_header_len = (m->payload[0] & 0xF) * 4;
>                                        u16 new_ip_len = m->data_len - ip_header_len - 8;
>                                        newPayload = malloc(new_ip_len);
>                                        memcpy(newPayload, m->payload + ip_header_len + 8, new_ip_len);
>                                        status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, new_ip_len, newPayload);
>                                        free(newPayload);
>                                }
>                                else
>                                {
>                                        u16 ip_len = (m->payload[2] << 8 & 0xff00) + (m->payload[3] & 0xff);
>                                        ip_header_len = (m->payload[0] & 0xF) * 4;
>                                        u16 new_ip_len = ip_len + ip_header_len + 8;
>                                        newPayload = malloc(new_ip_len);
>                                        // Copy prev packet
>                                        char *dst = newPayload;
>                                        char *org = m->payload;
>                                        // Copy IP header
>                                        memcpy(dst, org, ip_header_len);
>                                        dst += ip_header_len;
>                                        // Update IP length field
>                                        newPayload[2] = new_ip_len >> 8;
>                                        newPayload[3] = new_ip_len & 0x00ff;
>                                        // Set IP protocol field to UDP
>                                        newPayload[9] = 0x11;
>                                        // Calculate and update IP cksum
>                                        newPayload[10] = newPayload[11] = 0x00;
>                                        newCS = ip_sum_calc(ip_header_len, newPayload);
>                                        newPayload[10] = newCS >> 8;
>                                        newPayload[11] = newCS & 0x00FF;
>                                        // Create UDP header
>                                        dst[0] = SrcPortHi; // src port
>                                        dst[1] = SrcPortLo; // src port
>                                        dst[2] = DstPortHi; // dst port
>                                        dst[3] = DstPortLo; // dst port
>                                        u16 new_udp_len = new_ip_len - ip_header_len;
>                                        dst[4] = new_udp_len >> 8; // total len
>                                        dst[5] = new_udp_len & 0x00ff; // total len
>                                        dst[6] = 0x00; // Cksum
>                                        dst[7] = 0x00; // Cksum
>                                        dst += 8;
>                                        // Clone the rest of the packet
>                                        memcpy(dst, org, ip_len);
>                                        status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, new_ip_len, newPayload);
>                                        free(newPayload);
>                                }
>                                if (status < 0)
>                                        die(h);
>                                break;
>                        }
>
>                        default:
>                                fprintf(stderr, "Unknown message type!\n");
>                                break;
>                }
>        } while (1);
>
>        ipq_destroy_handle(h);
>        return 0;
> }
>
> RJZ-LNX UDP501 #
>
>
>
>
>
>
> --- On Wed, 9/10/08, Paul Wouters <paul at xelerance.com> wrote:
>
>> From: Paul Wouters <paul at xelerance.com>
>> Subject: Re: [Openswan Users] Connection against a Lucent FW success!!!! but may be there's still room for improvement
>> To: "Rolando J. Zappacosta" <zappacor at yahoo.com.ar>
>> Cc: users at openswan.org
>> Date: Wednesday, September 10, 2008, 6:39 AM
>> On Tue, 9 Sep 2008, Rolando J. Zappacosta wrote:
>>
>>>> If you have the logs from the lucent side, to see
>> what vendorid is logged
>>>> on their side, I'd be interested so we can
>> add it to our own recognised
>>>> vendor list (and possible take action based on
>> it)
>>> I discussed this subject here:
>>>
>> http://lists.openswan.org/pipermail/users/2008-February/014030.html
>> based on
>>> what I could capture under Windows, the relevant part
>> of it is:
>>> "I'm trying to connect OpenSwan to a Lucent
>> VPN Gateway, which according to
>>> its ASCII interpretation of its Vendor ID payload is:
>>>
>> 4C5647392E312E3235353A425249434B3A392E312E323535="LVG9.1.255:BRICK:9.1.255".
>> I
>>> can connect to it by means of the Lucent VPN Client
>> V7.1.2 on a Windows XP
>>> computer (Vendor ID=
>> 4C5643372E312E323A5850="LVC7.1.2:XP")."
>>
>> Thanks. Normally vendorids are md5sum's of some text,
>> though in this case
>> that does not seem to be the case. I added them as-is to
>> vendor.c for now.
>>
>>> Seems one can know the running version of the client
>> and server just looking
>>> on the vendor id part of an ASCII capture dump.
>>> Interesting thing is, as explained to you privatelly,
>> the way the PSK gets
>>> handled here. Under the LVC (windows) I had to
>> configure a PSK like:
>>> <MyCompanysPSK> where the real PSK is 9 ASCII
>> characters long. However, I
>>> could find that in order to have OSW establishing
>> phase 1 succesfully I had to
>>> add the string "01234567890" as a trailer,
>> i.e. my ipsec.secrets looks like:
>>> !@#$% <MyCompanysGWipAddress> : PSK
>> "<MyCompanysPSK>01234567890"
>>>
>>> what gives a PSK of lenght 20. Not sure on how they
>> handle it but my guess is
>>> they just take the PSK the user configures, add the
>> string
>>> "01234567890123456789" and take the first 20
>> bytes of it. Easy way to hook you
>>> on their client while still keeping it simply to
>> develop.
>>>
>>> And I'm not sure if the user !@#$% is the one the
>> GW admin configured on it or
>>> if it's the way they handle it but whatever else I
>> configure, the GW just
>>> don't respond anything back to me.
>>
>> Thanks! I put a note of this in docs/lucent-client.txt, and
>> it will end up
>> in the new wiki once we have it online.
>>
>>>> Looks like a resend, you can ignore it.
>>> Strangely, I *always* do receive the duplicate packet
>> warning. Another
>>> interesting thing is Lucent's VPN client
>> doesn't exchange any CFG at all...
>>> I'm wondering now if I need it indeed. The server
>> sends it to me but seems
>>> like OSW only configures the local IP address based on
>> it. I supossed it was
>>> going to be able to configure something else, such as
>> DNS or things like that.
>>
>> Openswan does support DNS/WINS via XAUTH/ModeConfig. Though
>> as a client, we
>> might be ignoring it, since we have no structured way of
>> modifying resolv.conf
>> in any modern way (eg dbus/networkmanager). I believe we
>> might only pass it
>> as env variables to the updown script.
>>
>>> The LVC do more things with no CFG at all, configures
>> the DNS and WINS servers
>>> for instance, something I'll need to do manually
>> via a script (or can it be
>>> made automatically somehow by OSW?)
>>
>> You can copy the stock _updown script and add resolv.conf
>> rewriting to it,
>> and configure the new script using leftupdown=
>>
>>>>> and this one from pluto's debug:
>>>>>  3) "Intranet" #1: XAUTH:
>> Unsupported attribute: INTERNAL_ADDRESS_EXPIRY
>>>> You can also ignore this. Openswan does not
>> support INTERNAL_ADDRESS_EXPIRY,
>>>> so it wont drop the IP address or ask for a new
>> one.
>>> Same for "ignoring informational payload, type
>> IPSEC_RESPONDER_LIFETIME"
>>> above?
>>
>> Yes. the remote is telling us how long they will keep the
>> SA around. Openswan
>> does not really care what the remote does. If the remote
>> wants to rekey, it
>> will and can do it anytime. We do enforce our own SA life
>> similarly.
>>
>> Paul
>
>
>
>


More information about the Users mailing list