[Openl2tp-users] Multiple clients behind the same NAT problem

Michal Růžička michal.ruzicka at comstar.cz
Tue Sep 26 16:23:12 BST 2006


I've been running an L2TP/IPSec server on Linux (using OpenL2TP for the L2TP 
part and native IPSec of Linux kernel 2.6 with ipsec-tools (racoon) for the 
IPSec part) for quite some time without any serious issues except one:
It is not possible to connect from multiple clients which happen to be 
behind the same NAT device.

I understand that this is a complex problem and that both OpenL2TP and the 
Linux kernel has to be changed in order to make this work.
In fact this post is meant to start a discussion on how to do it right.

Here comes a detailed description of the problem:
Let's suppose the following setup:

Client 1 (
.  \
.  +-- ( NAT Device ( -- Internet --  
( L2TP/IPsec server
.  /
Client n (

The first client behind the NAT device (the "first" client) that tries to 
connect succeeds but as soon as another one (the "second" client) tries to 
connect it fails and what's worse the connection of the client that 
connected first becomes stuck and eventually is disconnected.

The problem is that the connections from both of the clients look absolutely 
the same after IPSec processing at the L2TP/IPsec server (and it is how 
OpenL2TP sees them) - both appear to be comming from:
and destined for
OpenL2TP is confused by this and ignores the connection requests from the 
"second" client (thus its attempt to connect fails).
Further during the IPSec negotiations triggered by the "second" client an SA 
(Security Association) is installed into the Linux kernel SA database (SAD) 
that is from then on used even for the packets destined for the "first" 
client. This is because the packets' destination address (and the source as 
well) is the same for packets destined for either of the clients and thus 
when linux kernel looks for an SA matching the packets it is unable to 
distinguish between the one negotiated with the "first" client and the one 
negotiated with the "second" client and chooses the latter of the two. 
(Probably just because more recent SAs take precedence and the SA negotiated 
with the "second" client is the more recent of the two.) This has the effect 
that packets sent by OpenL2TP to the "first" client are delivered to the 
second client from the moment when the SA with the "second" client is 
negotiated thus the connection with the "first" client becomes stuck. 
(Actually it becomes only half-stuck since the packtes from the "first" 
client to the server can still pass but this doesn't really make a 

My thoughts on solving the problem:
As I see things now there has to be a way for an application (OpenL2TP in 
our case) to be able to get some information regarding IPSec processing 
performed by the kernel on the packets it receives (namely the source IP 
address and port of the original IPSec packet) and on the other hand to 
supply the same sort of information back to the kernel as a hint to the 
IPSec processing of the packets sent out.
I'd suggest the following:
- modify connect(2) socket call in such a way so that we can specify 
(besides the standard server's IP address) also an IPSec address. Only 
packets which have had the specified IPSec address before IPSec processing 
(and of course the standard IP address after the processing) would be 
received through the socket after this call. Further the IPSec address 
specified in the call would be used as a hint to the linux kernel on which 
SA to choose when performing IPSec processing on packets sent out through 
the socket. (Although this would be enough for our purpouse it would be 
resonable to implement analogous functionality for the sendto(2) and 
recvfrom(2) socket calls as well.)
- make OpenL2TP to use this functionality

I'd like to hear your comments, ideas, disagreements, corrections, ...

Michal Růžička
ComSTAR, spol. s r. o. 

More information about the Openl2tp-users mailing list