ESP transport and udpencap/nat-t (on OpenBSD v4.3)

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <ipv6@...>
Date: Thursday, June 25, 2009 - 4:37 pm

Dear list,

I'm currently working on setting an OpenBSD server (running on v "4.3
GENERIC#698 i386") to accept incoming ESP traffic (ipv4) encapsulating
UDP packets. More precisely, the OpenBSD machine as a server process
listening on a UDP port but the I've made sure that only enc0
originating packets can reach the server socket (see PF rules, after
this paragraphs of summary).

The server has a public IP address, the IPSec authentication is based
on public key infrastructure (x509 certificates).

The client is a MacOS machine (10.5, IKE based on racoon). It is
establishing a ESP-transport "connection" to the server (my OpenBSD
machine) and then starts, within this channel, some UDP based protocol
(l2tp precisely). The client os a 'road-warrior', changing address
from one time to the other.

When the client has a public IP address, all goes well, IKE/ISAKMP
enable the exchange of key (udp 500), the ESP channel is properly
established and the UDP 'connection' is taking place as expected.

-> When the client is behind a NAT, IKE/ISAKMP starts at 500 then hops
to 4500 (nat-traversal), and the ESP channel is established using
nat-traversal/udpencap. But then the server side sockets see's the
caller IP address to be the one of the NAT rather than the "private"
address of the client, while the SA of the kernel is established
between client's private address and server address, hence when the
server tries to answer the packet is send UNencripted, and to the NAT
(but still with the port of the client and NOT the port used by the
NAT -4500, nat-traversal-).

In this example, client is 'CLIENT', NAT is 'NAT-GATEWAY' and
server 'SERVER' . Here's how I would expect the traffic to be :


ESP traffic (ie. as seen on enc0 on the server)  :
CLIENT:3456 <----> SERVER:6543
udpencap/nat-traversal (right part seen on sis0) :
CLIENT:4500 <---> NAT-GATEWAY:4500 <---> SERVER:4500

Hence I don't get how the servers sees the UNencrypted traffic as
originating from address of gateway but port of the client.
Finally when trying to "return the call" the traffic is NOT send
through "enc0" since it's directed the gateway rather than the
client.

Note, finally, that when using ESP-tunnel all goes as expected...
(I guess udpencap has then no chances to mess things up, since all
the info is also inside the ESP part).

Thank you in advance for any hint to where to look.

Serge.


Here are some details (to abstract from the specific question of l2tp,
I'm here using netcat, port 3456 on client, 6543 on server):


OpenBSD server :

* Firewall settings (limited to relevant ones):
-bash-3.2# pfctl -s rules
scrub in on sis0 all fragment reassemble
scrub in on enc0 all fragment reassemble
block return log on sis0 all
....
pass in log (all, to pflog1) on sis0 proto udp from any to any port =  
isakmp keep state
pass in log (all, to pflog1) on sis0 proto udp from any to any port =  
ipsec-nat-t keep state
...
pass in log (all, to pflog1) on sis0 proto esp all keep state
pass out log (all, to pflog1) on sis0 proto esp all keep state
pass in log (all, to pflog1) on enc0 all flags S/SA keep state (if- 
bound)
pass out log (all, to pflog1) on enc0 all flags S/SA keep state (if- 
bound)
...

* IPSEC settings (while the connection is on):
-bash-3.2# ipsecctl -sa
FLOWS:
flow esp in proto udp from CLIENT port 3456 to SERVER port 6543 peer  
NAT-GATEWAY srcid dedi.chocolatnoir.net type use
flow esp out proto udp from SERVER port 6543 to CLIENT port 3456 peer  
NAT-GATEWAY srcid dedi.chocolatnoir.net type require

SAD:
esp transport from SERVER to NAT-GATEWAY spi 0x053bf47f auth hmac-sha1  
enc aes
esp transport from NAT-GATEWAY to SERVER spi 0x37df7481 auth hmac-sha1  
enc aes

* ESP buildup traffic :
Jun 25 21:43:22.883771 rule 19/(match) pass in on sis0: NAT-GATEWAY. 
500 > SERVER.500: isakmp v0.1 exchange NONE
         cookie: c0cf5fe65ad3434a->ba7f0d0060000000 [|isakmp]
Jun 25 21:43:22.884666 rule 19/(match) pass out on sis0: SERVER.500 >  
NAT-GATEWAY.500: isakmp v0.0 exchange NONE
         cookie: c0cf5fe600000000->0000000000000000 [|isakmp]
Jun 25 21:43:23.303841 rule 19/(match) pass in on sis0: NAT-GATEWAY. 
500 > SERVER.500: isakmp v0.1 exchange NONE
         cookie: c0cf5fe65bd3434a->94d5040060000000 [|isakmp]
Jun 25 21:43:23.316820 rule 19/(match) pass out on sis0: SERVER.500 >  
NAT-GATEWAY.500: isakmp v0.5 exchange NONE
         cookie: c0cf5fe65bd3434a->a5d4060060000000 [|isakmp]
Jun 25 21:43:23.447653 rule 20/(match) pass in on sis0: NAT-GATEWAY. 
4500 > SERVER.4500:udpencap: isakmp v0.0 exchange NONE
         cookie: 5bd3434ade720700->60000000fc040000 [|isakmp]
Jun 25 21:43:23.488158 rule 20/(match) pass out on sis0: SERVER.4500 >  
NAT-GATEWAY.4500:udpencap: isakmp v0.0 exchange 176 (unknown)  
encrypted commit
         cookie: 5bd3434aa1de0800->60000000b4000000 [|isakmp]
Jun 25 21:43:23.581281 rule 20/(match) pass in on sis0: NAT-GATEWAY. 
4500 > SERVER.4500:udpencap: isakmp v0.0 exchange NONE
         cookie: 0000000000000000->0000000000000000 [|isakmp]
Jun 25 21:43:24.591664 rule 20/(match) pass in on sis0: NAT-GATEWAY. 
4500 > SERVER.4500:udpencap: isakmp v0.0 exchange NONE
         cookie: 5cd3434af4210900->600000005c010000 [|isakmp]
Jun 25 21:43:24.598516 rule 20/(match) pass out on sis0: SERVER.4500 >  
NAT-GATEWAY.4500:udpencap: isakmp v0.0 exchange NONE
         cookie: 5cd3434a6b170a00->600000009c000000 [|isakmp]
Jun 25 21:43:24.661355 rule 20/(match) pass in on sis0: NAT-GATEWAY. 
4500 > SERVER.4500:udpencap: isakmp v0.0 exchange NONE
         cookie: 5bd3434ade720700->60000000fc040000 [|isakmp]
Jun 25 21:43:44.783525 rule 20/(match) pass in on sis0: NAT-GATEWAY. 
4500 > SERVER.4500:NAT-T Keepalive

* Some ESP traffic (a single packet coming in) :
Jun 25 21:46:39.749443 rule 20/(match) pass in on sis0: NAT-GATEWAY. 
4500 > SERVER.4500:udpencap: esp NAT-GATEWAY > SERVER spi 0xD0E589AA  
seq 534004554 len 68
Jun 25 21:46:39.749502 rule 30/(match) pass in on enc0: NAT-GATEWAY. 
3456 > SERVER.6543: udp 7

What I fail to understand is how come, for the UNencrypted packet, the
address is the one of the gateway (NAT-GATEWAY), but the UDP port
is the one of the originating machine (3456). This while the ipsecctl
returns both the client's address (CLIENT) and port.
Also, the "server process" (the listening netcat on the server) is
never receiving the packet ... !

For info, here are the settings on the 'client' side :
* IPSEC :
cedar:~ root# setkey -D -P
SERVER[6543] CLIENT[3456] udp
	in ipsec
	esp/transport//require
	spid=33 seq=1 pid=65128
	refcnt=2
CLIENT[3456] SERVER[6543] udp
	out ipsec
	esp/transport//require
	spid=32 seq=0 pid=65128
	refcnt=2

* Firewall traced traffic (rules are basically logging anything that
has to do with ESP, NAT-T...)

Jun 25 21:43:22 cedar Firewall[75]:  2000 Count UDP CLIENT:500 SERVER: 
500 out via en2
Jun 25 21:43:22 cedar Firewall[75]:  2000 Count UDP SERVER:500 CLIENT: 
500 in via en2
Jun 25 21:43:23 cedar Firewall[75]:  2000 Count UDP CLIENT:500 SERVER: 
500 out via en2
Jun 25 21:43:23 cedar Firewall[75]:  2000 Count UDP SERVER:500 CLIENT: 
500 in via en2
Jun 25 21:43:23 cedar Firewall[75]:  1000 Count UDP CLIENT:4500 SERVER: 
4500 out via en2
Jun 25 21:43:23 cedar Firewall[75]:  1000 Count UDP SERVER:4500 CLIENT: 
4500 in via en2
Jun 25 21:43:23 cedar Firewall[75]:  1000 Count UDP CLIENT:4500 SERVER: 
4500 out via en2
Jun 25 21:43:24 cedar Firewall[75]:  1000 Count UDP CLIENT:4500 SERVER: 
4500 out via en2
Jun 25 21:43:24 cedar Firewall[75]:  1000 Count UDP SERVER:4500 CLIENT: 
4500 in via en2
Jun 25 21:43:24 cedar Firewall[75]:  1000 Count UDP CLIENT:4500 SERVER: 
4500 out via en2
Jun 25 21:43:44 cedar Firewall[75]:  1000 Count UDP SERVER:4500 CLIENT: 
4500 out via lo0
Jun 25 21:43:44 cedar Firewall[75]:  1000 Count UDP CLIENT:4500 SERVER: 
4500 out via en2
Jun 25 21:43:44 cedar Firewall[75]:  1000 Count UDP SERVER:4500 CLIENT: 
4500 in via lo0

=> Note that due to an 'inferior design', I've not found a way on the
client machine to trace the UNencrypted packets (gets the traffic info
of the inside of the ESP channel).
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
web site, Lily Zey, (Fri Oct 24, 1:20 pm)
ESP transport and udpencap/nat-t (on OpenBSD v4.3), Serge Cohen, (Thu Jun 25, 4:37 pm)
Re: Default route and laptop suspend, Christian Weisgerber, (Tue May 17, 1:38 pm)
CARP | IPv6, , (Tue Feb 28, 11:58 am)
IPv6 Linklocal address and IPSec bug, , (Mon Sep 15, 9:56 am)
Re: PF dropping fragmented icmp6 packets, Jun-ichiro itojun Hagino, (Thu Jan 15, 11:01 pm)
Re: Default route and laptop suspend, Todd T. Fries, (Tue May 17, 2:49 pm)
Re: Splitting /64 over Multiple Gateway Interfaces in rtadvd, Christopher JS Vance, (Tue Mar 22, 8:42 pm)
Re: Splitting /64 over Multiple Gateway Interfaces in rtadvd, Christopher JS Vance, (Wed Mar 23, 6:00 pm)
Re: trouble with IPv6-in-ipv4 tunnel configuration, Thorsten Glaser, (Mon Mar 22, 3:03 pm)
Re: IPv6 Linklocal address and IPSec bug, Jun-ichiro itojun Hagino, (Mon Sep 15, 5:02 pm)