From owner-freebsd-ipfw@FreeBSD.ORG Tue Feb 3 06:54:19 2015 Return-Path: Delivered-To: freebsd-ipfw@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id ADF2F445; Tue, 3 Feb 2015 06:54:19 +0000 (UTC) Received: from mail-pa0-x22d.google.com (mail-pa0-x22d.google.com [IPv6:2607:f8b0:400e:c03::22d]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 82679B11; Tue, 3 Feb 2015 06:54:19 +0000 (UTC) Received: by mail-pa0-f45.google.com with SMTP id et14so92534913pad.4; Mon, 02 Feb 2015 22:54:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=2X6dA5vpZissLKDr2jLs7L6YuT1CFvavMDFPfqnq9/0=; b=OBva4X9y3Nzt08mhdJTYRXqKEo1P2MT7oh+QSkDEwDXTzWlYv3c8gu2pgYSRBFKFZ0 q+sIPnF8vXM8ijPer6YjjetCxGRtsVS8G6xWRQJBJLQpHve2ikFUnwN5Ej8iqg804AAy hZSlGXuxmqdX1rLa75wnYRc9ETBnwZAynrizqpvCEfBK3R1AvLcd9mSLTErP271ETr0Z wz/px/BHyTWVxbL6wMeCcHyGXMqzhgAPt1XmSXuvUjrh8pe5DrptiZtPzkNUV1xoOM4x VQVWXjc3NId5Re8g8a1ofwF3WUCSuLmUi/p3UO1vMI/zi3j6WNaL2Y/317p/YQ0jErK6 xf9w== MIME-Version: 1.0 X-Received: by 10.70.94.129 with SMTP id dc1mr11353357pdb.70.1422946458929; Mon, 02 Feb 2015 22:54:18 -0800 (PST) Received: by 10.70.45.228 with HTTP; Mon, 2 Feb 2015 22:54:18 -0800 (PST) In-Reply-To: <54D06E5C.3090701@freebsd.org> References: <54CFCD45.9070304@FreeBSD.org> <54D06E5C.3090701@freebsd.org> Date: Tue, 3 Feb 2015 14:54:18 +0800 Message-ID: Subject: Re: [RFC][patch] Two new actions: state-allow and state-deny From: bycn82 To: Julian Elischer Content-Type: text/plain; charset=UTF-8 X-Content-Filtered-By: Mailman/MimeDel 2.1.18-1 Cc: freebsd-ipfw , lev@freebsd.org, freebsd-net X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Feb 2015 06:54:19 -0000 *cool, I like this, it got some points.* *though the email is too looooong to be read.* On 3 February 2015 at 14:44, Julian Elischer wrote: > On 2/3/15 3:17 AM, Lev Serebryakov wrote: > >> >> I propose two new actions: state-allow and state-deny. >> >> They imply "keep-state" and create new dynamic rules, when called >> directly, but pass packet to NEXT rule after that (don't stop search). >> >> When they are called as dynamic rule, they acts as "allow" and "deny". >> >> So, stateful firewall with NAT could be rewritten like this: >> >> add 1000 skipto 2000 all from any to any out xmit outIface >> add 1010 skipto 3000 all from any to any in recv outIface >> >> add 2000 state-allow from any to any // keep-state is implied >> add 2010 nat NR from any to any // No "out" here! >> add 2020 allow all from any to any >> >> add 3000 nat NR from any to any >> add 3010 check-state // Use dynamic rule based on 2000 as "allow" here >> >> What do you think? >> > > I understand what you are trying to do.. > but part of the usefulness of the state runes is that they > can be any action, not just allow and deny. > I might try the following action: > > record: (or record-only) > it allows the rule to be stored, but the action is not performed. > on check-state, the rule is performed.. > > so skipto 2000 ip from me to fred 80 record-only out xmit bge0 > would do nothing but record the session > and on input the session packet would skipto 2000 > > you could do deny or accept as well so it's a superset of what you > suggest. > I'm not sure where in the rule record-only shoudl be put.. > maybe > > ipfw add 1000 log record-only skipto 2000 tcp from me to fred 80,443 out > xmit bge0 > > might be more syntactically correct? > > What I would find more useful, is separate state rules for each interface. > so you could not have the danger of a packet on interface A adding a rule > that eventually does something unexpected on a packet on interface B. > > > looking at my own rules I don't seem to have a problem.. > -------- > Just for kicks, > here is the base ipfw script.. just sets up the framework > > --- > #!/bin/sh > > fwcmd="/sbin/ipfw" > > # Suck in the configuration variables. > if [ -z "${source_rc_confs_defined}" ]; then > if [ -r /etc/defaults/rc.conf ]; then > . /etc/defaults/rc.conf > source_rc_confs > elif [ -r /etc/rc.conf ]; then > . /etc/rc.conf > fi > fi > > > # set these to your outside interface network and netmask and ip > oif="tun0" > onet="192.168.36.0" > omask="24" > oip="x.x.x.x" > > > # set these to your inside interface network and netmask and ip > iif="vr0" > inet="192.168.2.0" > imask="255.255.255.0" > iip="192.168.2.21" > > # for not the natd target is us but change this if you > # change that in natd.conf > natd_target=${oip} > work_vpnserver=y.y.y.y > > INCOMING=4000 > OUTGOING=8000 > LOCAL=1000 > SET=1 > > sysctl net.inet.ip.fw.enable=0 > ${fwcmd} -q flush > ${fwcmd} -q table 1 flush > ${fwcmd} -q table 2 flush > ${fwcmd} -q table 3 flush > ${fwcmd} -q table 4 flush > > ${fwcmd} table 1 add 10.0.0.0/8 > ${fwcmd} table 1 add 172.16.0.0/12 > #${fwcmd} table 1 add 192.168.0.0/16 > # Stop draft-manning-dsua-03.txt (1 May 2000) nets (includes > # RESERVED-1, DHCP auto-configuration, NET-TEST, MULTICAST (class > D), > # and class E) on the outside interface > ${fwcmd} table 1 add 0.0.0.0/8 > ${fwcmd} table 1 add 169.254.0.0/16 > ${fwcmd} table 1 add 192.0.2.0/24 > ${fwcmd} table 1 add 224.0.0.0/4 > ${fwcmd} table 1 add 240.0.0.0/4 > > # add legit sources of ssh.. DNS is not up yet so use IPs > # could add to /etc/hosts I guess. > # myotherhouse.org > ${fwcmd} table 2 add a.b.c.d > # work > ${fwcmd} table 2 add c.d.e.f/24 > # my vps > ${fwcmd} table 2 add f.g.h.i/24 > > # add legit DNS tcp (zone) sources > # my.dns.friends > ${fwcmd} table 3 add m.n.o.p > # my.dns.friend > ${fwcmd} table 3 add q.r.s.t > # my.vps > ${fwcmd} table 3 add f.g.h.i > > # Add our local networks here > ${fwcmd} table 4 add 192.168.2.0/24 > ${fwcmd} table 4 add 172.16.15.0/24 > > # common spoofing code > # --------------- ALL PACKETS START HERE. ------------ > > ${fwcmd} set disable ${SET} > > # Stop localhost spoofing > ${fwcmd} add 100 pass all from any to any via lo0 > ${fwcmd} add 200 deny log all from any to 127.0.0.0/8 > ${fwcmd} add 300 deny log ip from 127.0.0.0/8 to any > > # If we've already decided on it. keep our word. > ${fwcmd} add check-state > > #-------- Interception rules for external interfaces go here ------- > > #-------- Internal traffic. generally don't care > # except to stop spoofing. > # make extra sure we don't block DHCP to our server (me) > # as initial request will be from 0.0.0.0/0 > > ${fwcmd} add ${LOCAL} set ${SET} allow udp from any to any 67 in > recv ${iif} > ${fwcmd} add allow udp from any 67 to any out xmit ${iif} > > # other wise it has to be to and from a net we actually have. > ${fwcmd} add deny log all from not "table(4)" to any in recv ${iif} > ${fwcmd} add deny log all from any to not "table(4)" out xmit > ${iif} > > ${fwcmd} add reject log tcp from "table(5)" to any 80,443 in recv > vr0 > > ${fwcmd} add allow ip from any to any > > > > sysctl net.inet.ip.fw.enable=1 > > -------- > and now the rules for my external interface.. > you run this after the other file. note that the rules go into a separate > set > and can be disabled at once. > > #!/bin/sh > set -x > fwcmd="/sbin/ipfw" > > # Suck in the configuration variables. > if [ -z "${source_rc_confs_defined}" ]; then > if [ -r /etc/defaults/rc.conf ]; then > . /etc/defaults/rc.conf > source_rc_confs > elif [ -r /etc/rc.conf ]; then > . /etc/rc.conf > fi > fi > > # set these to your outside interface network and netmask and ip > oif="vr2" > oip="$1" > onet="$2" > omask="$3" > > > # set these to your inside interface network and netmask and ip > iif="vr0" > inet="192.168.2.0" > imask="255.255.255.0" > iip="192.168.2.21" > > # for not the natd target is us but change this if you > # change that in natd.conf > natd_target=${oip} > work_vpnserver=64.244.102.15 > > INTERCEPT=610 > INCOMING=14000 > OUTGOING=18000 > NATD2=8669 > SET=2 > > sysctl net.inet.ip.fw.enable=0 > ${fwcmd} -q delete ${INTERCEPT} > ${fwcmd} set disable ${SET} > # effectively clear it > ${fwcmd} set move 30 to ${SET} > > > # common spoofing code > # --------------- ALL PACKETS START HERE. ------------ > > > ${fwcmd} add ${INTERCEPT} set ${SET} skipto ${INCOMING} ip from > any to any in recv ${oif} > ${fwcmd} add ${INTERCEPT} set ${SET} skipto ${OUTGOING} ip from > any to any out xmit ${oif} > > #-------- Internal traffic. generally don't care > Add in a new incoming and outgoing section for the new interface > > #------- INCOMING > # don't allow packets from the wrong net! > ${fwcmd} add ${INCOMING} set ${SET} deny log all from "table(4)" > to any > > # in fact don't accept packets that are not for this interface > exactly > ${fwcmd} add set ${SET} deny log ip from any to not ${oip} > > # Allow access to our ssh from trusted places (work, freebsd > (sometimes)) > ${fwcmd} add set ${SET} pass tcp from "table(2)" to ${oip} 22 > setup keep-state > > # allow our DNS secondaries to get zone transfers > ${fwcmd} add set ${SET} pass tcp from "table(3)" to ${oip} 53 > setup keep-state > > # allow DNS requests, since we are authoratitive > ${fwcmd} add set ${SET} pass udp from any to ${oip} 53 > > # Allow setup of incoming email # not on this interface > > # me, DNS and root can start outgoing sessions and have > # them come in if there is a waiting socket > # !!@# Don't do this it breaks ntp from inside > # ${fwcmd} add set ${SET} allow ip from any to ${oip} uid 0 > # ${fwcmd} add set ${SET} allow ip from any to ${oip} uid 53 > # ${fwcmd} add set ${SET} allow ip from any to ${oip} uid 1000 > > # ignore any mention of RFC1918 nets on the outside interface > ${fwcmd} add set ${SET} deny log all from any to "table(1)" > # except the > ${fwcmd} add set ${SET} deny log not icmp from "table(1)" to any > > #^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v INCOMING NAT POINT > ^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v > # NAT anything that is left and trust NATD > ${fwcmd} add set ${SET} divert ${NATD2} all from any to any > > #After translation.. trust Nat to filter non matches > > # explicitly allow NAT-T from the vpn server to inside nets > ${fwcmd} add set ${SET} allow udp from ${work_vpnserver} to > "table(4)" > > # Allow TCP through if setup succeeded . > # bypass the logging step. too much data > ${fwcmd} add set ${SET} allow tcp from any to any established > > # take note of unexpected stuff. then drop it. > # hmm, NAtd must have let this through why? > ${fwcmd} add set ${SET} drop log ip from any to ${natd_target} > > # Allow IP fragments to pass through (NOPE) > # ${fwcmd} add set ${SET} pass all from any to any frag > > # XXX remove this if you turn on the target option on > # natd to allow a server > # Reject & Log all setup of incoming connections from the outside > # that have not been explicitly allowed above. > ${fwcmd} add set ${SET} deny log tcp from any to ${natd_target} > setup > > # anything here should be logged. it's intersting. > ${fwcmd} add set ${SET} count log ip from any to any > > # after that gauntlet, allow it to proceed. > ${fwcmd} add set ${SET} allow ip from any to any > > > > #----- OUTGOING > # Stop RFC1918 nets getting out to the outside interface > # except for the wierdness of our next hop being such an address. > ${fwcmd} add ${OUTGOING} set ${SET} allow icmp from ${oip} to > ${onet}:${omask} keep-state > ${fwcmd} add set ${SET} deny log all from any to "table(1)" > > # The firewall and inside can talk out if it wants to. > # these are local sessions by definition. > ${fwcmd} add set ${SET} pass all from ${oip} to any keep-state > > #^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v OUTGOING NAT POINT > ^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v > ${fwcmd} add set ${SET} divert ${NATD2} all from any to any out > recv ${iif} > > # just in case natd goes wierd. > ${fwcmd} add set ${SET} deny log all from "table(1)" to any > # in fact don't allow packets out that are not from this > interface exactly > ${fwcmd} add set ${SET} deny log ip from not ${oip} to any > ${fwcmd} add set ${SET} allow all from any to any > > ${fwcmd} set enable ${SET} > sysctl net.inet.ip.fw.enable=1 > > and here's rules for un untrusted tunnel > this file can also be run after the main one when hte tunnel is in use. > I'm not using this one at the moment, so I'm not sure it works but you can > get the idea.. > I add a separate script file for each interface.. and they slot in > separate rules as needed. > > #!/bin/sh > fwcmd="/sbin/ipfw" > > # Suck in the configuration variables. > if [ -z "${source_rc_confs_defined}" ]; then > if [ -r /etc/defaults/rc.conf ]; then > . /etc/defaults/rc.conf > source_rc_confs > elif [ -r /etc/rc.conf ]; then > . /etc/rc.conf > fi > fi > > > > # set these to your inside interface network and netmask and ip > iif="vr0" > inet="192.168.2.0" > imask="255.255.255.0" > iip="192.168.2.21" > > # set these to your outside interface network and netmask and ip > oif="tun0" > onet="192.168.36.0" > omask="24" > oip="l.m.n.o" > INTERCEPT=500 > INCOMING=4000 > OUTGOING=8000 > SET=1 > > # for now the natd target is us but change this if you > # change that in natd.conf > natd_target=${oip} > work_vpnserver=t.u.v.w > > sysctl net.inet.ip.fw.enable=0 > > #-------- Select direction and interface class > ${fwcmd} add ${INTERCEPT} set ${SET} skipto ${INCOMING} ip from > any to any in recv ${oif} > ${fwcmd} add ${INTERCEPT} set ${SET} skipto ${OUTGOING} ip from > any to any out xmit ${oif} > > > #------- INCOMING > # don't allow packets from the wrong net! > ${fwcmd} add ${INCOMING} set ${SET} deny log all from "table(4)" > to any > > # in fact don't accept packets that are not for this interface > exactly > ${fwcmd} add set ${SET} deny log ip from any to not ${oip} > > # Allow access to our ssh from trusted places (work, freebsd, > (sometimes)) > ${fwcmd} add set ${SET} pass tcp from "table(2)" to ${oip} 22 > setup keep-state > > # allow our DNS secondaries to get zone transfers > ${fwcmd} add set ${SET} pass tcp from "table(3)" to ${oip} 53 > setup keep-state > > # allow DNS requests, since we are authoratitive > ${fwcmd} add set ${SET} pass udp from any to ${oip} 53 > > # Allow setup of incoming email > > # julian and root can start outgoing sessions and have them come > in if there is a waiting socket :-) > ${fwcmd} add set ${SET} allow ip from any to ${oip} uid 0 > ${fwcmd} add set ${SET} allow ip from any to ${oip} uid 53 > ${fwcmd} add set ${SET} allow ip from any to ${oip} uid 1000 > > # ignore any mention of RFC1918 nets on the outside interface > ${fwcmd} add set ${SET} deny log all from any to "table(1)" > ${fwcmd} add set ${SET} deny log not icmp from "table(1)" to any > > #^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v INCOMING NAT POINT > ^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v > # NAT anything that is left and trust NATD > ${fwcmd} add set ${SET} divert natd all from any to any > > #After translation > > # explicitly allow NAT-T from the vpn server to inside nets > ${fwcmd} add set ${SET} allow udp from ${work_vpnserver} to > "table(4)" > > # Allow TCP through if setup succeeded . > # bypass the logging step. too much data > ${fwcmd} add set ${SET} allow tcp from any to any established > > # take note of unexpected stuff. then drop it. > ${fwcmd} add set ${SET} drop log ip from any to ${natd_target} > > # Allow IP fragments to pass through (NOPE) > # ${fwcmd} add set ${SET} pass all from any to any frag > > # XXX remove this if you turn on the target option on > # natd to allow a server > # Reject & Log all setup of incoming connections from the outside > # that have not been explicitly allowed above. > ${fwcmd} add set ${SET} deny log tcp from any to ${natd_target} > setup > > # anything here should be logged. it's interesting. > ${fwcmd} add set ${SET} count log ip from any to any > > #currently slam that door .. this rule comes and goes depending on > if I need it. > ${fwcmd} add set ${SET} deny log ip from any to any > > # after that gauntlet, allow it to proceed. > ${fwcmd} add set ${SET} allow ip from any to any > > > > #----- OUTGOING > # Stop RFC1918 nets getting out to the outside interface > # except for the wierdness of our next hop being such an address. > ${fwcmd} add ${OUTGOING} set ${SET} allow icmp from ${oip} to > ${onet}/${omask} keep-state > ${fwcmd} add set ${SET} deny log all from any to "table(1)" > > # The firewall (and my laptop) can talk out if it wants to. > # these are local sessions by definition. > ${fwcmd} add set ${SET} pass all from ${oip} to any keep-state > # ${fwcmd} add set ${SET} pass udp from ${oip} to any keep-state > # ${fwcmd} add set ${SET} pass icmp from ${oip} to any keep-state > > # Allow NTP queries out in the world from the firewall. > # ${fwcmd} add set ${SET} pass udp from ${oip} to any 123 keep-state > > # Allow DNS queries out in the world from the firewall. > # ${fwcmd} add set ${SET} pass udp from ${oip} to any 53 keep-state > > #^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v OUTGOING NAT POINT > ^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v > ${fwcmd} add set ${SET} divert natd all from any to any out recv > ${iif} > > # just in case natd goes wierd. > ${fwcmd} add set ${SET} deny log all from "table(1)" to any > # in fact don't allow packets out that are not from this > interface exactly > ${fwcmd} add set ${SET} deny log ip from not ${oip} to any > ${fwcmd} add set ${SET} allow all from any to any > > ${fwcmd} set enable ${SET} > > sysctl net.inet.ip.fw.enable=1 > > > > > _______________________________________________ > freebsd-ipfw@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-ipfw > To unsubscribe, send any mail to "freebsd-ipfw-unsubscribe@freebsd.org" >