Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 06 Sep 2022 15:52:55 +1000
From:      Ian Smith <smithi@nimnet.asn.au>
To:        "Dan Mahoney (Ports)" <freebsd@gushi.org>
Cc:        questions@freebsd.org,kpn@neutralgood.org
Subject:   Re: Firewall rules in a directory
Message-ID:  <268E4C90-FC85-4534-88AC-D3B82052EF0C@nimnet.asn.au>
In-Reply-To: <9BFB27DC-BA45-49B5-8EAD-B5BE7BC14E20@gushi.org>
References:  <3FAB82EC-2C82-4201-AA47-B1AA92B89677@gushi.org> <D666503D-E5E2-4B6D-A960-A362EEFE6F95@gushi.org> <DED6C218-0517-4A0D-8C7A-1FDBFFC84A3D@nimnet.asn.au> <9BFB27DC-BA45-49B5-8EAD-B5BE7BC14E20@gushi.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 5 September 2022 12:18:02 pm AEST, "Dan Mahoney (Ports)" <freebsd@gushi=
=2Eorg> wrote:
 >=20
 > > On Aug 31, 2022, at 10:47 AM, Ian Smith <smithi@nimnet=2Easn=2Eau>
 > wrote:
 > >=20
 > > On 30 August 2022 2:40:34 pm AEST, "Dan Mahoney (Ports)"
 > <freebsd@gushi=2Eorg> wrote:

 > >> Note, this wasn=E2=80=99t intended to be =E2=80=9Chere=E2=80=99s a d=
iff, please put it
 > in=E2=80=9D,
 > >> just an illustration of how trivial an addition it is=2E
 > >>=20
 > >>> On Aug 29, 2022, at 9:36 PM, Dan Mahoney (Ports)
 > >> <freebsd@gushi=2Eorg> wrote:
 > >>>=20
 > >>> All,
 > >>>=20
 > >>> At the dayjob, we=E2=80=99ve taken to putting our ipfw rules into a
 > >> directory using rcorder=E2=80=99able files=2E  This way, each of our=
 puppet
 > >> manifests can drop its own rules into place without having to
 > manage
 > >> a monolithic file=2E
 > >>>=20
 > >>> It=E2=80=99s a simple patch to rc=2Efirewall, where if you set
 > firewall_type
 > >> to a file, it just runs it, but if it=E2=80=99s a directory, it woul=
d
 > treat
 > >> it as such:
 > >>>=20
 > >>> *)
 > >>> if [ -r "${firewall_type}" ]; then
 > >>>   if [ -f "${firewall_type}" ]; then
 > >>>     ${fwcmd} ${firewall_flags} ${firewall_type}
 > >>>   else
 > >>>     if [ -d "${firewall_type}" ]; then
 > >>>       for fwfile in `rcorder $firewall_type/*`
 > >>>         do
 > >>>           ipfw -q $fwfile;
 > >>>       done
 > >>>     fi
 > >>>   fi
 > >>>=20
 > >>> Is there a possibility of getting this into base?
 > >>>=20
 > >>> -Dan
 > >=20
 > > Getting code into rc=2Efirewall has proven difficult over the years,
 > for me impossible=2E It even took julian@ a couple of years to get a
 > sensible use of tables into firewall_type 'simple' - but things may
 > have changed=2E

https://lists=2Efreebsd=2Eorg/archives/freebsd-ipfw/

From=20my perspective, this used to be a great list=2E  Now it's nearly all =
just bugzilla reports with very occasional human seeking discussion=2E  Cle=
arly, developers must prefer it that way=2E

I'm inclined to trim quotes somewhat Dan, but for starters let me say that
 a) I think this is a really good idea,
 b) getting it out there as a patch with explanation would be good at some=
where like /usr/share/examples/ipfw, and
 c) I wouldn't blow too much time trying to get it into /etc/rc=2Efirewall

Apart from arguably 'workstation', which I've found amenable to adding a f=
ew rules in /etc/rc=2Elocal, for years I've copied rc=2Efirewall to rc=2Emy=
firewall ono and hacked away, mostly on 'simple' for local nets=2E

 > > If it's really intended to launch multiple instances of ipfw, it
 > may win more favour - as a bug / feature request as Kevin suggests -
 > if you're sure how things like 'service ipfw status' or 'restart'
 > handle them in /etc/rc=2Ed/ipfw?

I see now that you're adding sections to the one instance, which makes the=
 above moot as these are just lists of ipfw commands, not scripts=2E

[=2E=2E]

 > So, right now, there are two knobs you can tweak in /etc/rc=2Econf --
 > firewall_type, and firewall_script=2E  Firewall_script defaults to
 > /etc/rc=2Efirewall which understands things like "open" or "client" or
 > "unknown", or a file=2E  The last bit of the stock rc=2Efirewall looks
 > like this:
 >=20
 > [Cc][Ll][Oo][Ss][Ee][Dd])
 >         ${fwcmd} add 65000 deny ip from any to any
 >         ;;
 > [Uu][Nn][Kk][Nn][Oo][Ww][Nn])
 >         ;;
 > *)
 >         if [ -r "${firewall_type}" ]; then
 >                 ${fwcmd} ${firewall_flags} ${firewall_type}
 >         fi
 >         ;;
 > esac
 >=20
 > Two problems there=2E  1) -r only checks for readability, not for it
 > being an actual file=2E

"-r   True if file exists and is readable"

I usually find -s more useful, but I often add 0-byte files as comments:
 touch -r flxbz 'what this flxbz is'

And in any case, only running ipfw on a file will tell you if it contained=
 valid contents - suggesting that the script should check ipfw's return cod=
e, and say something useful if it's non-zero?

 > and 2) For us, we *like* it being a directory=2E
 >=20
 > Here's an output of rcorder:
 >=20
 > rcorder /etc/ipfw=2Ed/*
 > /etc/ipfw=2Ed/setup
 > /etc/ipfw=2Ed/production_networks
 > /etc/ipfw=2Ed/production_static
 > /etc/ipfw=2Ed/routing
 > /etc/ipfw=2Ed/services
 > /etc/ipfw=2Ed/snmp_agent
 > /etc/ipfw=2Ed/ssh_service
 > /etc/ipfw=2Ed/tftp_service
 > /etc/ipfw=2Ed/mosh_service
 > /etc/ipfw=2Ed/node_exporter_agent
 > /etc/ipfw=2Ed/nrpe_agent
 > /etc/ipfw=2Ed/ssh_vpn
 > /etc/ipfw=2Ed/outbound
 > /etc/ipfw=2Ed/local
 > /etc/ipfw=2Ed/krb5_client
 > /etc/ipfw=2Ed/dns_client
 > /etc/ipfw=2Ed/syslog_client
 > /etc/ipfw=2Ed/ntp_client
 > /etc/ipfw=2Ed/final
 >=20
 > And=2E=2E=2Eas an example, here's some of /etc/ipfw=2Ed/setup (note the
 > PROVIDE and BEFORE entries at top, like rcorder wants)=2E
 >=20
 > #
 > # PROVIDE: setup blocked bogons
 > # BEFORE: services routing outbound final
 > #
 >=20
 > # remove all existing tables
 > table all destroy
 > table blocked create

All good stuff=2E

 > # standard (non-service specific) tables
 > table bogons create
 > table bogons add 0=2E0=2E0=2E0/8
 > table bogons add 10=2E0=2E0=2E0/8
 > table bogons add 172=2E12=2E0=2E0/12
 > table bogons add 192=2E168=2E0=2E0/16
 > table bogons add 169=2E254=2E0=2E0/16
 > table bogons add 240=2E0=2E0=2E0/4
 >=20
 > # permit existing TCP sessions
 > add allow tcp from any to any established
 >=20
 > # permit existing stateful traffic
 > add check-state :default // permit stateful traffic
 >=20
 > # permit internal loopback traffic
 > add allow ip from any to any via lo0
 > add allow ip from any to any via lo1
 >=20
 > # deny directed loopback traffic
 > add deny ip from any to 127=2E0=2E0=2E0/8 in
 > add deny ip from any to ::/64 in
 >=20
 > # deny unexpected sources
 > add deny ip from table(bogons) to me in // unexpected sources
 >=20
 > # deny explicitly disabled (non-persistent) sources
 > add deny ip from table(blocked) to me in // emergency
 > (non-persistent) blocklist
 >=20
 > # allow bsd-standard-port traceroutes
 > add allow udp from me to any 33434-33600 // traceroute in
 > add allow udp from any to me 33434-33600 // traceroute out
 >=20
 > # moderately permissive ICMPv4
 > add allow icmp from any to any icmptypes 0,3,8,11,13,14 // safe
 > ICMPv4

I couldn't get even icmptypes 0,3,8,11 into 'client' and especially 'simpl=
e' seen as a good idea, but that was before phk@ added 'workstation' which =
fixed that there=2E

I'll have to take your word on ipv6=2E

 > # link-local ICMPv6 (RS, RA, NS, NA) - per FreeBSD standard rules
 > add allow ipv6-icmp from :: to fe80::/10 // ICMPv6 DAD
 > add allow ipv6-icmp from fe80::/10 to fe80::/10 // ICMPv6 NDP
 > add allow ipv6-icmp from fe80::/10 to ff02::/16 // ICMPv6 NDP
 > add allow ipv6-icmp from any to any icmp6types 1,2,3,128,129,135,136
 > // safe ICMPv6
 >=20
 > =2E=2E=2E=2E
 >=20
 > And here's a service entry=2E=2E=2E
 >=20
 > more /etc/ipfw=2Ed/ssh_service
 > # REQUIRE: services
 > # PROVIDE: ssh_service ssh_clients
 > # BEFORE: outbound
 >=20
 > table ssh_clients create
 >=20
 > table ssh_clients add 1=2E2=2E3=2E4
 > table ssh_clients add 2001:dead:beef:cafe::d00d
 >=20
 > add allow tcp from table(ssh_clients) to me 22 in setup         //
 > inbound SSH
 >=20
 > =3D=3D
 >=20
 > Also unique to our setup: the "local" script is created by puppet but
 > not managed by it, so if you need to drop an emergency override in
 > there for something (i=2Ee=2E block an attacker, or open a port that yo=
u
 > haven't added to automation yet, add a counter to debug an issue, you
 > can, quickly)=2E
 >=20
 > Some of our scripts are placeholders, just existing as a no-op to
 > anchor things like BEFORE=2E

To me, this is a great example of leveraging things like rcorder to anothe=
r if similar purpose=2E

 > If people wanted things to put in /usr/share/examples (say
 > /usr/share/examples/ipfw/client, or /usr/share/examples/ipfw/closed?)
 > that mimic'd the main setup, I'd be happy to contribute them=2E

Maybe you could offer the whole thing as a script that includes
 a) a patch to rc=2Efirewall making say /etc/rc=2Efirewall_builder
 b) sysrc commands to set firewall_script to that, and firewall_type to th=
e directory, perhaps a subdir off 'here'=2E
 c) 2 or 3 example sections?

So at least there'd be somewhere people could point or refer to, while awa=
iting favour from ipfw deities :)

 > (I'm also not thrilled with the fact that the stock firewall script
 > adds rules before it determines what kind of firewall you want, and
 > then applies your rules=2E=2E=2Ethat could perhaps be a different bug
 > though)=2E

You've included setup_loopback and setup_ipv6_mandatory rules anyway, most=
ly, but you could always just start off with perhaps
 delete 1-1200

 > If there's a diffferent list I should be posting this to, let me
 > know=2E

Excuse my cynicism re once-great lists; I've been too long out of touch=2E

cheers, Ian



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?268E4C90-FC85-4534-88AC-D3B82052EF0C>