Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Jan 2002 11:10:18 +0200
From:      Barry Irwin <bvi@itouchlabs.com>
To:        Kshitij Gunjikar <kshitijgunjikar@yahoo.com>
Cc:        freebsd-net@freebsd.org
Subject:   Re: Filtering on the IPsec Tunnel
Message-ID:  <20020115111018.K5446@itouchlabs.com>
In-Reply-To: <DJEEIBCKNENADJJIMPLFAEHLCDAA.kshitijgunjikar@yahoo.com>; from kshitijgunjikar@yahoo.com on Tue, Jan 15, 2002 at 02:08:42PM %2B0530
References:  <DJEEIBCKNENADJJIMPLFAEHLCDAA.kshitijgunjikar@yahoo.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi All

I came across this problem a few months ago, and its mpact is actually
greater than expected.  I have ttached a patch below which I have been
running on our production firewalls for 3 months now with no issues to speak
of.  The patch includes a sysctl to turn off the reinjection action.

The problem is caused by rows 401-404 in ip_input.c (the particular version
I am working with is from the RELENG_4_4. By my understanding, is the packet
comming in was previously an IPSEC encapsulated, packet, the pass rule is
hit, rather than the normal action of being re-injected into the stack, and
subject to another pass through the ruleset.

* $FreeBSD: src/sys/netinet/ip_input.c,v 1.130.2.25 2001/08/29 21:41:37
jesper Exp $


#ifdef IPSEC
        if (ipsec_gethist(m, NULL))
                goto pass;
#endif

This action was NOT present in the 4.3 Release code, but ufortunately I have
not had time to tract down exactly when it was introduced.

The case where I came across the problem is that I have a Firewall
performing NAT, and the resultant NAT packets are injected into an IPSEC
tunnel to a business partner.  The problem comes when a packet is received
from the partner, and decapsulated, since it is not being re-injected into
the stack, the ipfw/ipfilter rules cannot pick it up for further processing. 
Thus I was unable to get the packet passed onto the NATD for processing. 
What drew my attention to this (in addition to connections not working) was
the fact that I was getting lots of traffic logged in vain on the firewall
Nat address itself.  The ports corresponded to the port used by the client
system.

The patch below introduces a sysctl net.inet.ip.ipsecinject, which wraps the
offending lines of code with an if conditional.  By default it skips these
and the packet injection continues as normal.  This was instituted so that a
backout could be performed if I experienced problems ( the machines in
question were sitting about 20 000km away :> ) 

I believe that the current implementation is incorrect as it stands.  A
better method in my opinion is to possibly do a comparison of the address in
the packet following decapsulation, if the address is an address local to
the system then it shoudl be re-injected. Although this still doesnt address
the problem of one wanting to do filtering.  Yes it does induce a slight
performance hit, but I certainly do not want to trust the security of my
network to that of my bsiness partners.  How about a sysctl similar to
net.inet.ip.fw.one_pass , which is on by default causing packets to be
passed through the rules prior to, and that an informed administrator can
explicityly turn off if he does not want this function.

This problem is still present in the RELENG_4 branch being used for 4.5.
* $FreeBSD: src/sys/netinet/ip_input.c,v 1.130.2.30 2001/12/14 20:08:22
jlemon Exp $
 
Although I dont think any changes will make it into 4.5 would be nice to get
a commit in soon after release to fix this.

Other thought I had is that the 'correct' place for the sysctl is probably
under the ipsec tree, unfortunately I dont have a box handy to make the
change on and run a test, so here is the patch anyway.

Cheers

Barry

-- 
Barry Irwin
Systems Administrator: Networks and Security
Itouch Labs			bvi@itouchlabs.com

PATCH agains 4.4-SECURITY branch.

bash-2.05# diff -u ip_input.c.orig  ip_input.c
--- ip_input.c.orig     Sun Oct 28 20:25:38 2001
+++ ip_input.c  Sun Oct 28 20:25:12 2001
@@ -129,6 +129,12 @@
        &ip_maxfragpackets, 0,
        "Maximum number of IPv4 fragment reassembly queue entries");
 
+static int      ip_ipsecinject = 1;
+SYSCTL_INT(_net_inet_ip, OID_AUTO, ipsecinject, CTLFLAG_RW,
+        &ip_ipsecinject,  0,
+                "Enable IPSEC reinject to fw stack fixes NAT");
+                
+
 /*
  * XXX - Setting ip_checkinterface mostly implements the receive side of
  * the Strong ES model described in RFC 1122, but since the routing table
@@ -399,8 +405,10 @@
        }
 
 #ifdef IPSEC
-       if (ipsec_gethist(m, NULL))
-               goto pass;
+       if (!ip_ipsecinject) {
+               if (ipsec_gethist(m, NULL))
+                       goto pass;
+       }
 #endif
 
        /*
bash-2.05# 


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




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