Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 7 Jan 2000 16:31:00 -0800 (PST)
From:      "Rodney W. Grimes" <freebsd@gndrsh.dnsmgr.net>
To:        luigi@info.iet.unipi.it (Luigi Rizzo)
Cc:        patrick@mindstep.com (Patrick Bihan-Faou), logix@foobar.franken.de (Harold Gutch), freebsd-current@FreeBSD.ORG, nate@mt.sri.com (Nate Williams)
Subject:   Re: ipfw optimizations
Message-ID:  <200001080031.QAA13581@gndrsh.dnsmgr.net>
In-Reply-To: <200001072340.AAA06578@info.iet.unipi.it> from Luigi Rizzo at "Jan 8, 2000 00:40:53 am"

next in thread | previous in thread | raw e-mail | index | archive | help
> > No, this is completly reasonable now that I understand what it is your
> > proposing.  Even the memory footprint is minimal if pointers to the
> > actual rules is all we store in the per interface list, my largest set
> > duplicated over 8 interfaces would only be 3200 rules.  Stored as
> 
> I'd be curious to know what your 400-rule set looks like, what is
> the longest search path through that ruleset, and whether that
> ruleset could be made more efficient to run by implementing some
> kind of switch() statement (eg. for selecting based on interfaces),
> or hash tables (e.g. you want to allow/deny to a list of random
> addresses...).

If you search the archives you'll find a function I wrote in /bin/sh
called clnsrv is what creates 90% of the rules.  Ahh.. hech.. here...

# clnsrv(action, proto, sport, dport, clients, servers)
clnsrv() {
        action=$1;      shift
        proto=$1;       shift
        sport=$1;       shift
        dport=$1;       shift
        clients=$1;     shift
        servers=$1;     shift


        if [ X"${proto}" = X"tcp" ]; then
                setup="setup"
                base=10000
        else
                setup=""
                base=40000
        fi
        if [ X"${dport}" = X"" ]; then
                ruleoffset=${sport}
        else
                ruleoffset=${dport}
        fi
        if [ ${ruleoffset} -gt 1899 ]; then
                ruleoffset=1900
        fi
        rule=`expr ${base} + \( ${ruleoffset} \* 10 \)`
        for cln in ${clients} ; do
                for srv in ${servers} ; do
                        ${fadd} ${rule} ${action} ${proto} \
                                from ${cln} ${sport} to ${srv} ${dport} ${setup}
                done
        done

        rule=`expr ${rule} + 9`
        ${fadd} ${rule} ${CLASS} log ${proto} from any ${sport} to any ${dport}
}

Then this is called like so:
clnsrv "allow    " tcp   20   "" "${tcp_ftpdata_c}"    "${tcp_ftpdata_s}"
clnsrv "allow    " tcp   ""   21 "${tcp_ftp_c}"                "${tcp_ftp_s}"  
clnsrv "allow    " tcp   ""   22 "${tcp_ssh_c}"                "${tcp_ssh_s}"
clnsrv "allow    " tcp   ""   23 "${tcp_telnet_c}"     "${tcp_telnet_s}"
clnsrv "allow    " tcp   ""   25 "${tcp_smtp_c}"       "${tcp_smtp_s}"
clnsrv "allow    " tcp   ""   43 "${tcp_nicname_c}"    "${tcp_nicname_s}"
clnsrv "allow    " tcp   ""   53 "${tcp_domain_c}"     "${tcp_domain_s}"
clnsrv "allow    " tcp   ""   79 "${tcp_finger_c}"     "${tcp_finger_s}"
clnsrv "allow    " tcp   ""   80 "${tcp_http_c}"       "${tcp_http_s}"
clnsrv "allow    " tcp   ""  110 "${tcp_pop3_c}"       "${tcp_pop3_s}"
clnsrv "allow    " tcp   ""  111 "${tcp_sunrpc_c}"     "${tcp_sunrpc_s}"
clnsrv "allow    " tcp   ""  113 "${tcp_ident_c}"      "${tcp_ident_s}"
... on and on up to the 1024 and then a few splattered after that.

Note that those variables ``tcp_ftp_c'' are often long lists of IP
prefixes, and tcp_ftp_s is a single IP or ``any'', dependent on where
this firewall is in the network topology, so these calls can quickly
build into fairly long ipfw lists.  Often the _c and _s will be lists,
causing the double nested loop to product a few not so meaningful rules,
but that has been fairly rare, bgp being the big exception :-).

Also this same routine is called again for a whole pile of udp ports.

The single largest optimization would probably be a dispatch based on
source or destination port, the latter being more prevelent.

I can't easily send out the actual IP firewall list, it may expose
what ever router I grabbed it off of to an attack :-)

-- 
Rod Grimes - KD7CAX @ CN85sl - (RWG25)               rgrimes@gndrsh.dnsmgr.net


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




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