[Openl2tp-users] Multiple clients behind the same NAT problem
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 (192.168.0.21)
. +-- (192.168.0.1) NAT Device (220.127.116.11) -- Internet --
(18.104.22.168) L2TP/IPsec server
Client n (192.168.0.20+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, ...
ComSTAR, spol. s r. o.
More information about the Openl2tp-users