Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Apr 2001 11:23:58 +0100
From:      Brian Candler <B.Candler@pobox.com>
To:        Lowell Gilbert <lowell@world.std.com>
Cc:        Rasputin <rara.rasputin@virgin.net>, freebsd-security@freebsd.org
Subject:   Re: Interaction between ipfw, IPSEC and natd
Message-ID:  <20010416112358.A13561@linnet.org>

next in thread | raw e-mail | index | archive | help
> Some forms of IPSEC have fundamental problems with packet rewriting,
> which means that NAT is extremely hard to use in an IPSEC environment.
> Notably, end-to-end IPSEC modes are broken, although router-based
> tunnels can be a problem depending on whether the NAT rewriting occurs
> before or after the IPSEC headers are applied.
> 
> Even without NAT, though, firewalls are a little tricky to configure
> for IPSEC packets.  This is because the firewall can't see the
> protocol ports (or even the protocol, for that matter) in the packet,

Ah, it seems I wasn't clear :-) It's actually a very simple scenario, and I
do not need IPSEC packets to be routed through the firewall at all. There
are cleartext sessions which need NAT to be able to browse the outside
Internet, and then cleartext packets which are IPSEC-tunnelled from one
private network to another, like this:

            Internet                       Internet
               ^      . . . . . . . . . .     ^
               |    ,    IPSEC tunnel     `   |
          +----------+                   +----------+
          | Firewall |                   | Firewall |
          +----------+                   +----------+
               |                              |
            ---+---                        ---+---
            Office1                        Office2
            10.0.1.0/24                    10.0.2.0/24

Now, I have done a bit of experimentation and found the following.

1. Packets which are diverted to natd are reinjected into the ipfw ruleset
   at the following rule (actually 'man 8 natd' does say this). The packets
   do retain their 'in via <interface>' tag. 'man 4 divert' documents the
   mechanism which makes this possible.

2. Incoming IPSEC packets pass _twice_ through the ipfw rules: once in
   their encapsulated form (protocol 50), and when decrypted they pass
   through the whole ruleset again, retaining their 'in via <interface>' tag.

The second rule makes things a bit of a mess. For starters, you need two
rules to permit IPSEC traffic through, one in encrypted and one in decrypted
form:

add 1000 allow esp from <tunnel-rem> to <tunnel-local> in via fxp0
add 1010 allow ip from 10.0.1.0/24 to 10.0.2.0/24 in via fxp0

Now, it seems ipfw cannot tell the difference between a packet which came
'in via fxp0' in the clear, or 'in via fxp0' as IPSEC which was successfully
decrypted and authenticated.

It is not clear what happens if someone spoofs a packet with a 10.0.x source
and dest address and injects it into the outside interface of the firewall;
hopefully the IPSEC policy (/require) catches this case and drops the
packet, but I would feel much happier with an explicit ipfw antispoofing
rule.

Then you need to put natd _after_ this so that the IPSEC tunneled traffic is
not subject to NAT:

add 1020 divert 8668 ip from any to any via fxp0

i.e. rule 1010 catches the tunnel-decrypted traffic. Of course, this only
works because we know the IP address space used at each end of the tunnel;
these rules could get complicated in a more complex environment than the one
shown above, and it would be a pain keeping the SPD and ipfw rules in sync.

I have done some poking around, and it seems that NetBSD had the same issue:
http://www.netbsd.org/Documentation/network/ipsec/#ipf-interaction

They made a change in February, and their new behaviour is:
"ipf(4) looks at packets in native wire format only. ipf(4) looks at packets
before IPsec processing on inbound, and after IPsec processing on outbound."

This looks reasonable to me, except that it appears impossible to have an
'untrusted IPSEC tunnel' (that is, a tunnel which you want to filter traffic
from before allowing it in)

Since you might want to have different policies for different tunnels, it
would be very nice for ipfw to be able to test which tunnel traffic came
through (e.g. "in via x.x.x.x" where x.x.x.x is the IP address of the remote
tunnel endpoint). Just a thought.

Anyway, I think my original point still stands - whatever FreeBSD does, all
this needs to be documented properly :-)

Regards,

Brian.

P.S. It appears that all this has been discussed before, so sorry for the
overlap...
http://docs.FreeBSD.org/cgi/getmsg.cgi?fetch=116841+0+/usr/local/www/db/text/2001/freebsd-security/20010325.freebsd-security

P.P.S. OpenBSD appears to pass traffic through the filters twice, but you
can differentiate IPSEC traffic by looking for the 'enc0' interface:
http://www.openbsd.org/cgi-bin/man.cgi?query=vpn&apropos=0&sektion=0&format=html

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010416112358.A13561>