Hi all,
I believe this is one of those i think the answer is no, but need to ask
situations.
Weve built out an L2TP/IPSEC environment whose goal is to provide VDI access
to
subsidiaries and support client connections from MacOS, Windows, Unix,
Linux,
et all.
For MacOS and *nix, client connections happening as expected with multiple
concurrent VPN sessions behind a single shared NAT device.
However Windows clients are limited to only one connection at a time.
Subsequent
connections cause the current session to die and be replaced by the new one.
Our environment details are below.
For the sake of siplicity, below are the configs for the PSK variant of our
RAS
environment.
Here's what I think is happening: Windows clients used a fixed source port
for
their outbound L2TP connections to VPN servers. And since L2TP is encypted
inside ESP, the NAT device cant translate the connection to some other
ephemeral port. So the connection looks like this:
[client]<clientIP:UDP/1701> --> [office firewall]<OfficeIP:UDP/1701> -->
[Ras]<SerivceIP:UDP/1701>
Isakmpd reports this when multiple windows clients connect at once:
IPSEC Connections:
FLOWS:
flow esp in proto udp from OFFICE_IP port l2tp to RAS_IP port l2tp
peer OFFICE_IP srcid ras.rakuten-it.com type use
flow esp out proto udp from RAS_IP port l2tp to OFFICE_IP port l2tp
peer OFFICE_IP srcid ras.rakuten-it.com type require
SAD:
esp transport from OFFICE_IP to RAS_IP spi 0x2aa4e054 auth hmac-sha1
enc aes
esp transport from RAS_IP to OFFICE_IP spi 0x636b2bdd auth hmac-sha1
enc aes
esp transport from RAS_IP to OFFICE_IP spi 0xc38a28d8 auth hmac-sha1
enc aes
esp transport from OFFICE_IP to RAS_IP spi 0xc6612448 auth hmac-sha1
enc aes
esp transport from RAS_IP to OFFICE_IP spi 0xc83c49d6 auth hmac-sha1
enc aes
esp transport from OFFICE_IP to RAS_IP spi 0xea3ad136 auth hmac-sha1
enc aes
In short, many security associations (for each windows client) but only one
actual flow.
Isakmpd doesnt have a way to distinguish between the connections as it
renegotiates
their keys.
As a result, when the ipsec session renegotiates it's keys, these sessions die
one by one until only a single session remains.
I've seen a number of discussions here and other places that describe just
this
problem: Windows Clients may have only one session at a time. Other OS types
are
fine.
One particular one that caught my attention was by Yasuoka Masahik three
years
ago:
http://openbsd.7691.n7.nabble.com/NPPPD-L2TP-IPsec-problems-td79729.html#a797
32
The thing I haven't found yet is what's a good approach to solving the
problem.
Is there a way to keep the L2TP/IPSEC vpn and also support windows?
Some configuration that I've overlooked?
Does iked handle NAT-T better than isakmpd for this scenario?
Thank you in advance for any advice offered. It's deeply deeply appreciated.
James McGoodwin
[email protected] | www.kobo.com
135 Liberty St. Suite 101, Toronto ON, M6K 1Y7
-------------Environment Configurations --------------
Platform:
$ uname -a
OpenBSD mras1.rakuten-it.com 5.6 GENERIC#0 i386
isakmpd:
$ sudo cat /etc/ipsec.conf
ext_carp_ip="<PUBLIC_IP_ADDRESS_OF_RAS_SERVICE>"
ike passive esp transport proto udp from $ext_carp_ip to any port 1701 \
main auth "hmac-sha1" enc "3des" group modp1024 \
quick auth "hmac-sha1" enc "aes" \
psk "<redacted>"
npppd:
$ sudo cat /etc/npppd/npppd.conf
set user-max-session 5
authentication LOCAL_B type local {
users-file "/etc/npppd/npppd-users"
}
tunnel L2TP_ipv4 protocol l2tp {
listen on <PUBLIC_IP_ADDRESS_OF_RAS_SERVICE>
}
ipcp IPCP_B {
pool-address 192.168.128.2-192.168.191.254
dns-servers <server1_ip> <server2_ip>
}
interface tun0 address 192.168.128.1 ipcp IPCP_B
interface pppx0 address 192.168.128.1 ipcp IPCP_B
bind tunnel from L2TP_ipv4 authenticated by LOCAL_B to tun0
pf <<(fragments below)>> :
$ sudo cat /etc/pf.conf
nclude "/etc/pf/macros.conf"
set skip on { lo enc0 }
set limit states 100000
set block-policy return
EXT_IF="bnx0"
TUN0_IF="tun0"
l2tp_port="1701"
ipsec_ports="{ 500, 4500 }"
ipsec_isakmp_port="500"
ipsec_nat_port="4500"
ext_carp_ip="<PUBLIC_IP_ADDRESS_OF_RAS_SERVICE>"
int_carp_ip="10.0.70.10"
intra_net="10.0.0.0/8"
VDI="10.90.0.0/19"
l2tp_intra_net="192.168.64.0/18"
l2tp_vdi_net="192.168.128.0/18"
match in on enc0 all scrub (no-df max-mss 1326)
match out on enc0 all scrub (no-df max-mss 1326)
match out log on $EXT_IF inet from !$EXT_IF to any nat-to $ext_carp_ip
match out log on $INT_IF inet from { $l2tp_intra_net $l2tp_vdi_net }
to $intra_net nat-to $int_carp_ip
# ISAKMP and IPSEC-NAT-T
pass in quick log on $EXT_IF inet proto udp to (self) port
{ 500 4500 }
pass out quick log on $EXT_IF inet proto udp from (self) port
{ 500 4500 }
# L2TP
pass in quick log on $EXT_IF inet proto { tcp udp } to (self) port
$l2tp_port
pass out quick log on $EXT_IF inet proto { tcp udp } from (self) port
$l2tp_port
# ESP
pass in quick log on $EXT_IF inet proto { esp ah } to (self)
pass out quick log on $EXT_IF inet proto { esp ah } from (self)
# ENC
pass in quick log on enc0 inet proto tcp to (self) port ssh keep state
(if-bound)
pass in quick log on enc0 inet proto ipencap to (self) keep state
(if-bound)
# ENC
pass out quick log on enc0 inet proto tcp from (self) port ssh keep
state (if-bound)
pass out quick log on enc0 inet proto ipencap from (self) keep state
(if-bound)
# for npppd
pass log quick on $TUN0_IF
# allow L2TP clients to connect to $VDI but nothing else on intra_net
pass in log quick on { pppx $TUN0_IF } from { $l2tp_intra_net
$l2tp_vdi_net } to { $VDI }
block in log quick on { pppx $TUN0_IF } from { $l2tp_intra_net
$l2tp_vdi_net } to $intra_net
[demime 1.01d removed an attachment of type application/pgp-signature which had
a name of signature.asc]