Subject: dhclient and IPsec
To: None <>
From: Michael Richardson <>
List: tech-net
Date: 02/16/2002 14:48:16

  Some of you may know that I spend good portions of my time working
on Linux FreeSWAN. 

  At one of my colleagues place, he as a 802.11 network. His local firewall
policy on that wire is proto 50,51, UDP 500, DNS and DHCP only. i.e. you had
better do IPsec over that wire. No problem, my notebook (running NetBSD/i386)
has what it takes thanks to KAME.

  We make a SA like:

spdadd $myip/32 any -P out ipsec esp/tunnel/${myip}-${gateway}/require;
spdadd $myip/32 any -P in ipsec  esp/tunnel/${gateway}-${myip}/require;

  No problems there. All packets are encrypted to his gateway across the 
wireless LAN. Sure beats WEP.

  The problem is DHCP lease renewals.

  Version info:
  NetBSD 1.5.2 + racoon 20011215 (with one patch from Sakane).
  DHCLIENT V3.0rc10

  Debian Potato (r2.2)
  Linux 2.2.17 + FreeSWAN 1.91
  DHCPd a version that predates having a version in --version.
	seems to be 2.0pl5. Locally compiled.
	We will try 3.0 soon, but I don't think it is a server problem.

  Initially, the firewall/802.11 gateway was not accepting on port 67 in.
Of course, one still gets a lease because dhcpd (also ISC) on the server
listens to raw sockets. (Recall Jim Wise' problems). That is now fixed
for some time. 

  Of course, due to the SA above, the dhclient renewals go via IPsec. On
NetBSD we have no way (that I know of) to tcpdump the decrypted packets, only
the encrypted ones.
  {I would actually like to propose a pseudo-device name for tcpdump to attach
to that would cause packets from esp_input. I may hack something to help
debug this}

  Anyway, the dhclient renewals do not get through. Looking at the tcpdump
from the Linux/FreeSWAN end, we can see the packets going in and out. But,
they apparently never are received by dhclient on my notebook.

Feb 15 16:00:03 marajade dhclient: DHCPREQUEST on wi0 to port 67
Feb 15 16:00:35 marajade last message repeated 2 times
Feb 15 16:00:58 marajade last message repeated 2 times
Feb 15 16:01:15 marajade dhclient: DHCPREQUEST on wi0 to port 67
Feb 15 16:01:48 marajade last message repeated 3 times
Feb 15 16:02:15 marajade last message repeated 2 times
Feb 15 16:02:27 marajade dhclient: Trying medium "-mediaopt adhoc nwid SSW" 0
Feb 15 16:02:28 marajade dhclient: DHCPDISCOVER on wi0 to port 67 interval 3
Feb 15 16:02:31 marajade dhclient: Trying medium "-mediaopt adhoc" 1
Feb 15 16:02:32 marajade dhclient: DHCPDISCOVER on wi0 to port 67 interval 6
... at this point lots of messages arrive from racoon informing me that the 
interface has been ifconfig'ed down, since there is no responding DHCP server 
to renew the lease.

Feb 15 16:02:38 marajade dhclient: Trying medium "mediaopt adhoc" 0
Feb 15 16:02:39 marajade dhclient: DHCPDISCOVER on wi0 to port 67 interval 6
Feb 15 16:02:39 marajade dhclient: DHCPOFFER from
Feb 15 16:02:47 marajade dhclient: DHCPREQUEST on wi0 to port 67
Feb 15 16:02:47 marajade dhclient: DHCPACK from
Feb 15 16:02:47 marajade dhclient: bound to -- renewal in 277 seconds.

Since we got a new lease from the server via broadcasting, my dhclient-up
scripts go recreate SAs, only they actually never got deleted (That in itself
may be a bug)

Feb 15 16:02:47 marajade /netbsd: key_spdadd: a SP entry exists already.

5 minutes later (which is the renewal time), it repeats.

- From the server:

Merged output with interfaces identified.

16:00:53.542497 ipsec3 > xid:0x6501903f secs:259 C: [|bootp]
16:00:53.544218 ipsec3 > xid:0x6501903f secs:259 C: Y: S: [|bootp]

  So, it sees a request to renew and answers it.

  Later, it sees the broadcast:

16:01:10.530797 eth5 > xid:0x6501903f secs:276 C: [|bootp] [tos 0x10]

  but, since there is an SA alive, the reply goes via IPsec. 
  (Yes, FreeSWAN does not provide any alternative for this, and should)

  This continues for awhile.
  Eventaully, my end gives up and attempts a broadcast:

16:01:20.528697 eth5 > xid:0x6501903f secs:286 C: [|bootp] [tos 0x10]

16:01:20.530064 ipsec3 > xid:0x6501903f secs:286 C: Y: S: [|bootp]

  but that doesn't help, since the reply still goes via the SA.

16:02:34.767855 eth5 > xid:0x8eefa81f secs:11 [|bootp] [tos 0x10]
16:02:34.768449 eth5 > xid:0x8eefa81f secs:11 Y: S: [|bootp] [tos 0x10]
16:02:42.682711 eth5 > xid:0x8eefa81f secs:11 [|bootp] [tos 0x10]
16:02:42.683988 eth5 > xid:0x8eefa81f secs:11 Y: S: [|bootp] [tos 0x10]

  Eventually, I give up my address and send a request. The result is not sent
on the SA (in fact, I think that it goes directly out via raw socket), and I
get my previous address again.

16:07:19.977294 ipsec3 > xid:0x8eefa81f C: [|bootp]

  5 minutes later, a repeat.

  So, it seems to me that the reply is making it back to my machine (but I
have no way to prove it unless we setup manual keying, which is a total

  Is dhclient looking for a reply only via BPF?  Examining the source code
does not suggest this, but I'm not certain.

  (Also, we never seem to have figured out what flags stfX should have so
that dhclient will ignore it. We talked once about a "physical" or "logical"
flag that we'd add. It has neither POINTTOPOINT nor BROADCAST. I think that
dhclient should ignore non-BROADCAST, non-MULTICAST interfaces)

]       ON HUMILITY: to err is human. To moo, bovine.           |  firewalls  [
]   Michael Richardson, Sandelman Software Works, Ottawa, ON    |net architect[
] |device driver[
] panic("Just another NetBSD/notebook using, kernel hacking, security guy");  [


Version: 2.6.3ia
Charset: latin1
Comment: Finger me for keys