From owner-freebsd-net@FreeBSD.ORG Mon Jan 31 19:34:54 2005 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3D40516A4CE for ; Mon, 31 Jan 2005 19:34:54 +0000 (GMT) Received: from cheer.mahoroba.org (gw4.mahoroba.org [218.45.22.175]) by mx1.FreeBSD.org (Postfix) with ESMTP id 079D243D46 for ; Mon, 31 Jan 2005 19:34:53 +0000 (GMT) (envelope-from ume@mahoroba.org) Received: from lyrics.mahoroba.org (IDENT:zUXZsNGHGNlu4zrFoJzY0TZ+8M1niPv/9tp5rbhTjrXOdKJO25PD52COCdK+42f0@lyrics.mahoroba.org [IPv6:3ffe:501:185b:8010:280:88ff:fe03:4841]) (user=ume mech=CRAM-MD5 bits=0)j0VJYesN059824 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 1 Feb 2005 04:34:41 +0900 (JST) (envelope-from ume@mahoroba.org) Date: Tue, 01 Feb 2005 04:34:40 +0900 Message-ID: From: Hajimu UMEMOTO To: Lukasz Stelmach In-Reply-To: <20050130235357.GA72888@tygrys.k.telmark.waw.pl> References: <20050130235357.GA72888@tygrys.k.telmark.waw.pl> User-Agent: xcite1.38> Wanderlust/2.13.1 (You Oughta Know) SEMI/1.14.6 (Maruoka) FLIM/1.14.7 (=?ISO-8859-4?Q?Sanj=F2?=) APEL/10.6 Emacs/21.3.50 (i386-unknown-freebsd5.3) MULE/5.0 (SAKAKI) X-Operating-System: FreeBSD 5.3-RELEASE-p3 MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-Virus-Scanned: by amavisd-new X-Virus-Status: Clean X-Spam-Status: No, score=-5.6 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 autolearn=ham version=3.0.2 X-Spam-Checker-Version: SpamAssassin 3.0.2 (2004-11-16) on cheer.mahoroba.org cc: freebsd-net@freebsd.org Subject: Re: if_stf and rfc1918 X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 31 Jan 2005 19:34:54 -0000 Hi, >>>>> On Mon, 31 Jan 2005 00:53:57 +0100 >>>>> Lukasz Stelmach said: Lukasz> Once I've discussed this matter with Hajimu UMEMOTO and he posted a patch Lukasz> that made it possible to run 6to4 router behind a nat (FreeBSD 4.x). Soon Lukasz> I will probably be upgrading my old system to 5.x release so I checked Lukasz> if newer stf code allows such operation and to my disapointment I've Lukasz> found out that it doesn't (or at least it seems so). The comment in the Lukasz> code says that it is a requirement of RFC3056. I've check it and in fact Lukasz> it says that RFC1918 addresses MUST NOT be used as NLAs in 6to4 addresses. Lukasz> But IMHO it does not mean that I can't run my 6to4 router behind a NAT Lukasz> at all. In such a situation the IPv6 address contains valid public IPv4 Lukasz> address and the private one in the IPv4 header is substitutet by NAT. So Lukasz> after the packets leave my site they are completly valid 6to4 packets. Lukasz> Also when 6to4 packets come to me they are handeled properly. Lukasz> My question now is why FreeBSD is so restrictive about it. Oops, I completely forget this issue. If there is no objection, I'll commit following patch into HEAD then MFC to RELENG_5. Index: share/man/man4/stf.4 diff -u share/man/man4/stf.4.orig share/man/man4/stf.4 --- share/man/man4/stf.4.orig Sat Jan 4 14:15:26 2003 +++ share/man/man4/stf.4 Tue Feb 1 02:05:05 2005 @@ -178,6 +178,17 @@ Note, however, there are other security risks exist. If you wish to use the configuration, you must not advertise your 6to4 address to others. +.Pp +You can configure to use 6to4 from behind NAT by setting the +.Xr sysctl 8 +variable +.Va net.link.stf.no_addr4check +to 1 with support of your NAT box. In this case, make sure to use a +6to4 address which is worked out from an IPv4 global address of your +NAT box. If you are directly connected to the Internet, you shouldn't +chenge the value of +.Va net.link.stf.no_addr4check . +This is only hack to use 6to4 from within a NAT. .\" .Sh EXAMPLES Note that Index: sys/net/if_stf.c diff -u -p sys/net/if_stf.c.orig sys/net/if_stf.c --- sys/net/if_stf.c.orig Thu Jan 13 00:47:31 2005 +++ sys/net/if_stf.c Tue Feb 1 04:00:34 2005 @@ -89,6 +89,7 @@ #include #include #include +#include #include #include @@ -183,6 +184,13 @@ static int stf_clone_destroy(struct if_c struct if_clone stf_cloner = IFC_CLONE_INITIALIZER(STFNAME, NULL, 0, NULL, stf_clone_match, stf_clone_create, stf_clone_destroy); +SYSCTL_DECL(_net_link); +SYSCTL_NODE(_net_link, IFT_STF, stf, CTLFLAG_RW, 0, "6to4 Interface"); + +static int no_addr4check = 0; +SYSCTL_INT(_net_link_stf, OID_AUTO, no_addr4check, CTLFLAG_RW, + &no_addr4check, 0, "Skip checking outer IPv4 address"); + static int stf_clone_match(struct if_clone *ifc, const char *name) { @@ -357,9 +365,17 @@ stf_encapcheck(m, off, proto, arg) * local 6to4 address. * success on: dst = 10.1.1.1, ia6->ia_addr = 2002:0a01:0101:... */ - if (bcmp(GET_V4(&ia6->ia_addr.sin6_addr), &ip.ip_dst, - sizeof(ip.ip_dst)) != 0) - return 0; + if (no_addr4check) { + struct ifnet *tif; + + INADDR_TO_IFP(ip.ip_dst, tif); + if (!tif) + return 0; + } else { + if (bcmp(GET_V4(&ia6->ia_addr.sin6_addr), &ip.ip_dst, + sizeof(ip.ip_dst)) != 0) + return 0; + } /* * check if IPv4 src matches the IPv4 address derived from the @@ -401,12 +417,14 @@ stf_getsrcifa6(ifp) if (!IN6_IS_ADDR_6TO4(&sin6->sin6_addr)) continue; - bcopy(GET_V4(&sin6->sin6_addr), &in, sizeof(in)); - LIST_FOREACH(ia4, INADDR_HASH(in.s_addr), ia_hash) - if (ia4->ia_addr.sin_addr.s_addr == in.s_addr) - break; - if (ia4 == NULL) - continue; + if (!no_addr4check) { + bcopy(GET_V4(&sin6->sin6_addr), &in, sizeof(in)); + LIST_FOREACH(ia4, INADDR_HASH(in.s_addr), ia_hash) + if (ia4->ia_addr.sin_addr.s_addr == in.s_addr) + break; + if (ia4 == NULL) + continue; + } return (struct in6_ifaddr *)ia; } @@ -511,8 +529,10 @@ stf_output(ifp, m, dst, rt) bzero(ip, sizeof(*ip)); - bcopy(GET_V4(&((struct sockaddr_in6 *)&ia6->ia_addr)->sin6_addr), - &ip->ip_src, sizeof(ip->ip_src)); + if (!no_addr4check) + bcopy(GET_V4( + &((struct sockaddr_in6 *)&ia6->ia_addr)->sin6_addr), + &ip->ip_src, sizeof(ip->ip_src)); bcopy(&in4, &ip->ip_dst, sizeof(ip->ip_dst)); ip->ip_p = IPPROTO_IPV6; ip->ip_ttl = ip_stf_ttl; @@ -587,13 +607,6 @@ stf_checkaddr4(sc, in, inifp) } /* - * reject packets with private address range. - * (requirement from RFC3056 section 2 1st paragraph) - */ - if (isrfc1918addr(in)) - return -1; - - /* * reject packets with broadcast */ for (ia4 = TAILQ_FIRST(&in_ifaddrhead); @@ -645,7 +658,16 @@ stf_checkaddr6(sc, in6, inifp) */ if (IN6_IS_ADDR_6TO4(in6)) { struct in_addr in4; + bcopy(GET_V4(in6), &in4, sizeof(in4)); + + /* + * reject packets with private address range. + * (requirement from RFC3056 section 2 1st paragraph) + */ + if (isrfc1918addr(&in4)) + return -1; + return stf_checkaddr4(sc, &in4, inifp); } @@ -694,6 +716,18 @@ in_stf_input(m, off) #ifdef MAC mac_create_mbuf_from_ifnet(ifp, m); #endif + + /* + * Skip RFC1918 check against dest address to allow incoming + * packets with private address for dest. Though it may + * breasks the requirement from RFC3056 section 2 1st + * paragraph, it helps for 6to4 over NAT. + */ + if ((!no_addr4check && isrfc1918addr(&ip->ip_dst)) || + isrfc1918addr(&ip->ip_src)) { + m_freem(m); + return; + } /* * perform sanity check against outer src/dst. Sincerely, -- Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan ume@mahoroba.org ume@{,jp.}FreeBSD.org http://www.imasy.org/~ume/