Re: IPSEC problems with pf

From: Peter Jeremy <>
Date: Sun, 26 Sep 2021 03:12:05 UTC
Thanks for all the responses, they provided useful pointers.  I've
discovered that the problem was at least partially my misunderstanding
of the way iked works (and my failure to mention some important
differences between my working and non-working configurations).

Note that I'm trying to configure IPSEC in transport, not tunnel mode.
I think some of the responses assumed that I was using tunnel mode.

In the following:
Host ---- firewall ====(internet)==== VPS
'==' indicates the path I want as an IPSEC (esp) transport - I expect
that VPS thinks it's talking to "firewall" and is unaware of the (NAT'd)
connection between firewall and Host.

My firewall is running 12.2, whereas the other systems I was testing
with were 13 or 14.  12.x doesn't support extended sequence numbers.
I had assumed the message:
iked[3516]: pfkey_sa: kernel has no support for extended sequence numbers (ESN)
was a warning and it would negotiate down.  I've worked out that iked
doesn't actually negotiate but instead initiates a SA based solely on
its local configuration so that's actually a fatal error that prevented
the SA being setup in one direction.  Once I added "childsa noesn" at
the remote (13.x) end, I got bidirectional IPSEC transport setup.

On 2021-Sep-25 16:06:55 +0300, "Andrey V. Elsukov" <> wrote:
>25.09.2021 03:31, Eugene Grosbein пишет:
>> I know three main reasons that may prevent firewall+IPSec from working as expected:
>> 1) for incoming packets: kernel could drop incoming packet withing ipsec code
>> incrementing one of counters shown with "netstat -sp ipsec" command,
>> so you should check it out first;

And "netstat -sp esp".  I also found /usr/src/tools/tools/crypto/ipsecstats.c
dumps all the ipsec-related counters from the kernel.

>> 2) for both outgoing and incoming packets there could be processing order problem:
>> packets processed first by pfil(9) framework (so pf/ipfw have a chance to do NAT etc.)
>> and only then sent to ipsec(4) to transform (in FreeBSD 11 at least), not vice versa.
>AFAIK, pf does not send packets to IPsec processing after NAT. You need
>to make translation after IPsec processing using the if_enc interface.

I'm reasonably confident that this is my remaining problem and am working
on better understanding the interactions between IPSEC and pfil(9).

>> 3) also read if_enc(4) manual page to make familiar with net.enc.out.* and* sysctl family,
>> as it may affect, too. If you do not use enc(4) pseudo-interface, make sure you changed defaults to:
>> net.enc.out.ipsec_filter_mask=0

I wasn't using enc(4) and don't have it loaded.  enc(4) reads like it
is intended for ESP tunnel mode, rather than transport mode.  On the
offchance that it would help, I tried loading it and experimenteng with
the various filter mask options but it didn't help.

>Another important variable that needs an attention is

I discovered that but, unfortunately, it seems to only apply to inbound
(from the Internet) packets.

At this point:
* I can exchange encrypted packets locally between firewall and VPS
* Encrypted packets sent from VPS will arrive at Host (once
  net.inet.ipsec.filtertunnel is set).
* Packets sent from Host to VPS get sent unencrypted over the Internet.

I'm confident that the last point is because the IPSEC processing preceeds
the pfil processing on outbound packets, so they aren't seen as eligible
because IPSEC is seeing the internal, rather than external, address.

Peter Jeremy