Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Mar 2017 15:32:33 +0700
From:      Victor Sudakov <vas@mpeks.tomsk.su>
To:        Ian Smith <smithi@nimnet.asn.au>
Cc:        Polytropon <freebsd@edvax.de>, Michael Wilcox <michael.wilcox2016@gmail.com>, freebsd-questions@freebsd.org
Subject:   Re: UFW-Like frontend for IPFW
Message-ID:  <20170310083233.GA15405@admin.sibptus.transneft.ru>
In-Reply-To: <20170309023112.M80813@sola.nimnet.asn.au>
References:  <mailman.103.1488888002.35815.freebsd-questions@freebsd.org> <20170307233222.E87835@sola.nimnet.asn.au> <20170308122925.GA67654@admin.sibptus.transneft.ru> <20170309023112.M80813@sola.nimnet.asn.au>

next in thread | previous in thread | raw e-mail | index | archive | help
Ian Smith wrote:
>  > 
>  > >  > There is one thing that a higher level macro language on top of ipfw
>  > >  > would be nice to have for.
>  > > 
>  > > ipfw rules are very much like an assembly language, and 'assemble' to 
>  > > precisely executable opcodes in a well-defined virtual machine. pf feels 
>  > > (to me) more like 'higher level' coding, which seems to suit many people 
>  > > better .. but I'm an old assembler kind of guy, from S/370 onwards :)
>  > > 
>  > >  > Several times I have tried to emulate Cisco PIX/ASA logic with ipfw.
>  > >  > I just want to have e.g. 3 interfaces: inside, outside, dmz with
>  > >  > security levels of 100, 0, 50 respectively. Traffic can flow from the
>  > >  > interface with a higher security level to the interface with a lower
>  > >  > security level, and return traffic is permitted too.
>  > >  > 
>  > >  > Every time I have tried to express this with ipfw rules, I failed
>  > >  > miserably, though superficially it looks simple (with keep-state).
>  > > 
>  > > That's quite doable, but I wouldn't use numeric levels like that, 
>  > 
>  > When there are more than 2 interfaces, numeric levels are very useful.
> 
> Sure, if you have some way to map these to interfaces and to define the 
> allowable flows, but meanwhile I used those as method descriptors, which 
> you'd already clearly enough defined for this particular application.
> 
>  > > and 
>  > > I'd use static rules first to limit access between inside, outside and
>  > > dmz, adding dynamic (stateful) rules after those constraints are met.
>  > > 
>  > > Just roughly, as a partial sketch, and assuming all at layer 3 (ip):
>  > > 
>  > >   check-state	// pass established dynamic flows
>  > > 
>  > >     # can only check both interfaces on 'out' packets, leaving ipfw
>  > >   deny tcp from any to any out recv $dmz_if xmit $inside_if setup
>  > >   deny udp from any to any out recv $dmz_if xmit $inside_if
>  > > 
>  > >     # if dmz provides service/s to outside, skip over these for them
>  > >     # those can be allowed/denied on 'in' pass, using dest address/es.
>  > > 
>  > >   deny tcp from any to any out recv $outside_iface setup
>  > >   deny udp from any to any out recv $outside_iface
>  > > 
>  > >     # skip this for any static (setup then established) services below
>  > >   deny all from any to any established
>  > > 
>  > >     # best use static rules for icmp, see rc.firewall 'workstation'
>  > > 
>  > >     # then (or earlier, if you prefer) separate flows for inside|dmz
>  > >     # then allow services on inside and dmz, perhaps using static rules
>  > >     # then allow access from inside|dmz to dmz|outside statefully.
>  > 
>  > Yes, that's basically what I usually come to. 
>  > But it would be much nicer to write a macro like that:
>  > 
>  > nameif fxp0 outside security0
>  > nameif fxp1 inside security100
>  > nameif fxp2 dmz security50
>  > permit tcp from any to any eq 80 in interface dmz
>  > permit tcp from any to 10.10.5.1 eq 3389 in interface inside
>  > 
>  > and to have all the gory details configured for you automagically.
> 
> Well yes, but I think you'll find that non-trivial to do.  

I have.

> If you come 
> up with something, or enthuse somebody else to do so, I'll test it at 
> least as far as scrutinising output rulesets.
> 
> Perhaps start by declaring actual ipfw rules you expect such a syntax to 
> produce from your example above; then figure out how to generate those?

Oh, if I could imagine the actual ipfw rules, I would have done this
long ago. Superficially, they should boil down to a bunch of rules like

check-state
permit ip from any to any in via XXX out via YYY keep-state
permit ip from any to any in via QQQ out via ZZZ keep-state
deny ip from any to any

but in practice, there is always some show-stopper.

> I can't recall when or where, but have seen an example using ipfw's 
> preprocessor feature, using m4(1) to pre-process provided parameters to 
> generate customised rulesets, to some degree at least.
> 
>      ipfw [-cfnNqS] [-p preproc [preproc-flags]] pathname
> 
> See ipfw(8) /LIST OF RULES AND PREPROCESSING

Been there, done that. Using a shell script with loops and variables
for networks and interfaces turned out to be so much simpler than using a
preprocessor.

-- 
Victor Sudakov,  VAS4-RIPE, VAS47-RIPN
AS43859



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