Re: if_stf and rfc1918

From: Hajimu UMEMOTO (ume_at_freebsd.org)
Date: 01/31/05

  • Next message: Ryan Sommers: "RFC3442 & dhclient"
    Date: Tue, 01 Feb 2005 04:34:40 +0900
    To: Lukasz Stelmach <Lukasz.Stelmach@k.telmark.waw.pl>
    
    

    Hi,

    >>>>> On Mon, 31 Jan 2005 00:53:57 +0100
    >>>>> Lukasz Stelmach <Lukasz.Stelmach@telmark.waw.pl> 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 <sys/module.h>
     #include <sys/protosw.h>
     #include <sys/queue.h>
    +#include <sys/sysctl.h>
     #include <machine/cpu.h>
     
     #include <sys/malloc.h>
    @@ -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/
    _______________________________________________
    freebsd-net@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-net
    To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"
    

  • Next message: Ryan Sommers: "RFC3442 & dhclient"

    Relevant Pages

    • Re: if_stf bug/feature
      ... Lukasz>> a single machine. ... > certain checks enablea us to use 6to4 even behind NAT. ... I've just made a patch against ...
      (freebsd-net)
    • Re: IP alias + NAT through a single NIC?
      ... > the router between the logical nets? ... have to do it for each client machine, not just on this FreeBSD box itself. ... routing and NAT for the machines on net 2. ...
      (freebsd-questions)
    • if_stf and rfc1918
      ... But IMHO it does not mean that I can't run my 6to4 router behind a NAT ... after the packets leave my site they are completly valid 6to4 packets. ... My question now is why FreeBSD is so restrictive about it. ...
      (freebsd-net)
    • Re: Seemingly obvious Linux / BSD firewall question
      ... FreeBSD has a number of firewall options, each if which as far as I know ... I had much more trouble getting NAT ... >> which is in turn connected to another router which is where we get our ...
      (Security-Basics)
    • NAT question.
      ... I wanna remove NAT from router. ... i use FreeBSD 4.5 ... with "unsubscribe freebsd-security" in the body of the message ...
      (FreeBSD-Security)