[BUG] ip_nat_ftp fails for some ftp servers (fwd)

Xuan Baldauf xuan--lkml@baldauf.org
Sun, 07 Oct 2001 16:42:05 +0200


This is a multi-part message in MIME format.
--------------BA02322DF90F239C54949711
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

Hello Mr Reissner,

Sascha Reissner wrote:

> From: "Xuan Baldauf" <xuan--lkml@baldauf.org>
>
> Hello Mr. Baldauf,
>
> [...]
>
> > so the problem is that netfilter creates a "matcher" like this:
> >
> > protocol              tcp
> > source-ip-address     <server ip-address>
> > source-port           any
> > destination-ip-adress <router ip-address>
> > destination-port      <router masquerading-port>
> >
> > is that right? If so, is it possible to change this too-restrictive
> behaviour
> > to something like
> >
> > protocol              tcp
> > source-ip-address     any
> > source-port           any
> > destination-ip-adress <router ip-address>
> > destination-port      <router masquerading-port>
> >
> > I know that this may be a security problem, so this should only be
> optional.
> > But on the other
> > side, does the ftp server do anything wrong?
>
> well if you would change the ftp nat helper from its designed state to =
the
> one
> described by you, every computer in the world would essentially be able=
 to
> access <router ip-address> at <router masquerading-port> and you could
> forget any packetfilter rules you implemented just because they wouldnt=

> filter
> anymore.
>
> with accessing only one ftp server it would be bad. but after you acces=
sed
> some servers in a row you would allow any host to connect to many many
> open ports on your side. building a great security risk.

But the port is only needed to be open as long as nobody already has conn=
ected
to it. Is it closed after the first connect in the current implementation=
? If
so, there is only a race between an eavesdropper and the ftp-server (who
connects first to that port). But this race is always given within the no=
rmal
ftp-protocol. Normally, clients should decide wether connections from
different ip-adresses should be regarded as safe. The server-ip-adress is=
 not
modified for active-mode data-connections from the ftp-server to the
ftp-client, so even when enabling the connection to the client at the
router|firewall side, the client still will have the opportunity to decid=
e.

I've created a patch which changes the behaviour to accept active-mode
connections to masqueraded ftp-clients from any ip-adress. It is attached=
=2E

If a firewall administrator only wants masquerading, but no additional
restrictions by masquerading, the patch might be of use.

Xu=E2n.



--------------BA02322DF90F239C54949711
Content-Type: text/plain; charset=us-ascii;
 name="linux-2.4.10.netfilter-nat-allow-multihomed-ftp-servers.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="linux-2.4.10.netfilter-nat-allow-multihomed-ftp-servers.patch"

--- linux/net/ipv4/netfilter/ip_conntrack_ftp.c.orig	Sun Oct  7 15:36:40 2001
+++ linux/net/ipv4/netfilter/ip_conntrack_ftp.c	Sun Oct  7 15:56:16 2001
@@ -356,16 +356,32 @@
 		if (!loose) goto out;
 	}
 
-	t = ((struct ip_conntrack_tuple)
-		{ { ct->tuplehash[!dir].tuple.src.ip,
-		    { 0 } },
-		  { htonl((array[0] << 24) | (array[1] << 16)
-			  | (array[2] << 8) | array[3]),
-		    { htons(array[4] << 8 | array[5]) },
-		    IPPROTO_TCP }});
-	mask = ((struct ip_conntrack_tuple)
-		{ { 0xFFFFFFFF, { 0 } },
-		  { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
+	if (0) {
+		// match the server ip-address exactly
+		// connections from multihomed servers may fail.
+		t = ((struct ip_conntrack_tuple)
+			{ { ct->tuplehash[!dir].tuple.src.ip,
+			    { 0 } },
+			  { htonl((array[0] << 24) | (array[1] << 16)
+				  | (array[2] << 8) | array[3]),
+			    { htons(array[4] << 8 | array[5]) },
+			    IPPROTO_TCP }});
+		mask = ((struct ip_conntrack_tuple)
+			{ { 0xFFFFFFFF, { 0 } },
+			  { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
+	} else {
+		// allow the server to be multihomed (data connection from other source-ip-address than control-connection)
+		t = ((struct ip_conntrack_tuple)
+			{ { 0,
+			    { 0 } },
+			  { htonl((array[0] << 24) | (array[1] << 16)
+				  | (array[2] << 8) | array[3]),
+			    { htons(array[4] << 8 | array[5]) },
+			    IPPROTO_TCP }});
+		mask = ((struct ip_conntrack_tuple)
+			{ { 0x00000000, { 0 } },
+			  { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
+	}
 	/* Ignore failure; should only happen with NAT */
 	ip_conntrack_expect_related(ct, &t, &mask, NULL);
  out:

--------------BA02322DF90F239C54949711--