Struggling with IPFW on CURRENT
Mark Felder
feld at FreeBSD.org
Thu Oct 8 14:07:56 UTC 2015
On Thu, Oct 8, 2015, at 03:12, Ian Smith wrote:
> On Wed, 7 Oct 2015 08:57:42 -0500, Mark Felder wrote:
> > Hi all,
> >
> > I've only used IPFW in the past for the most basic of tasks. I'd like to
> > use it with in-kernel NAT protecting both v4 and v6 and add
> > dummynet/pipe later, but I have to get the basic working first. I'm
> > either overlooking something obvious or there's a major issue. Has there
> > been work in CURRENT? I haven't tried on any RELEASE....
>
> I doubt there's anything in CURRENT that might affect your ruleset.
>
> > Problems I'm running into:
> >
> > * Inbound v4 traffic to the firewall is blocked, but inbound v6 traffic
> > to firewall and hosts behind it are not. Both v4 and v6 should be
> > handled by keywords: tcp, udp, ip, me.
>
> Firstly, I've read the whole thread but it's not clear to me whether you
> started out with one_pass=0 ? If not, you need that for sure, or NAT'd
> packets will just be passed without further checks. This could explain
> why e.g. your deny icmp rule wasn't working; they'd be already allowed.
>
> And later, when adding dummynet, you'll also want to use one_pass=0.
>
I am using one_pass=0 now.
> You need to use 'ip4' specifically on your nat rules, whether you use
> ipfw nat or divert with natd. natd can crash and ipfw nat results when
> passed ip6 packets are at best undefined. Apart from that, you may want
> to examine the various ipv6 rules in rc.firewall complementing your
> valid address checking rules for ipv4; otherwise I can't comment on ip6.
>
Interesting. I haven't found this advice from anyone else but I did
consider it to be more terse.
> > * TCP sessions seem to be killed every ~300s
>
> This seems to suggest that keepalives may be being blocked, not sure.
>
> > * "in via $pif" doesn't seem to work. ex: block icmp from internet to
> > $pif fails to do anything. However, "block out via $pif" blocks it...
>
> I'd suggest replacing every instance of 'in via' with 'in recv' and
> every instance of 'out via' with 'out xmit' for clarity. The only rule
> you have that uses via without any direction appropriately is rule 25.
> Seeing you're logging everything for now, I'd replace rule 20 with
>
> $cmd 00020 allow log all from any to any in recv $iif
> $cmd 00021 allow log all from any to any out xmit $iif
>
"The via keyword causes the interface to always be checked."
I thought that was a good thing, but perhaps it actually means "it's
wasting cycles checking the interface because you're not being more
specific in your rules."
> I'm never sure this rule is appropriate anyway, as you're passing all
> inbound traffic from the LAN without any checks, e.g. antispoofing or
> other restrictions you may wish to apply to LAN <-> internet traffic;
> splitting this rule in two leaves scope for later refinement.
>
Yeah, this wasn't a finished product. I just wanted basic access so I
could start migrating more rules over, adding restrictions for other
VLANs, etc.
> > * Does IPFW not track outbound traffic to allow it back through --
> > related/established ? I have trouble blocking inbound traffic without
> > blocking originated/outbound traffic because the firewall blocks the
> > return packets.
>
> Once we're sure that one_pass was/is 0, we can look at that. I see Kris
> mentioned that setting in the referenced article for ipfw nat, but not
> for the earlier ruleset for natd, although it's needed in either case.
>
> > * Port forwarding is failingl, probably due to the issues with the "in
> > via" that I'm experiencing. Research says once I have the redirect_port
> > configured I should be good to go as long as I match the traffic and
> > skip to the NAT rule. Skip rules don't stop processing, so it should hit
> > the next rule which is the last rule in my config -- allow from any to
> > any. (Documentation for in-kernel NAT is nonexistent and really needs
> > help). The rule 425 below should be working, but logs show that rule is
> > ignored and it's being blocked at 550. Comment out 550 and it works...
>
> Again depending on one_pass. I can't disagree about the thinness of
> ipfw nat docs, but you should refer to natd(8) as kind-of suggested as a
> fuller reference; apart from the recently discovered omission from ipfw
> nat of proxy_only, and the abbreviated operators, you can safely take
> natd(8) as a deeper explanation of ipfw nat. Both use libalias(3).
>
> Frankly I still find the 'skipto .. keep-state' approach relatively
> confusing compared to say the rc.firewall 'workstation' approach to
> (mostly) stateful rules, but we've been blighted by that for so long it
> seems irredeemable until $someone rewrites the dreadful handbook IPFW
> section, and I can't be that someone - way too verbose for one thing :)
>
I think skipto will work better for me because I will have multiple NATs
due to OpenVPN, etc.
> I'm quite sure you don't want to add 'setup keep-state' to the final
> pass-all rule after NAT'ing outbound-to-net packets; just 'allow all
> from any to any' would be appropriate there.
>
You're right. I noticed this when I had a 90% working config except
outbound ip4 was failing (ipv6 sites worked great!). I left a note in my
config to not ever add "setup keep-state" for that :-)
> In the earlier natd set, Kris had a 'deny log all from any to any'
> before the outbound nat skip target, but not the later set you followed.
> You should add that, so that packets not otherwise blocked don't fall
> through to the most likely inappropriate nat then pass-all rules.
>
Hmm I'll review this again, thanks for the tip.
> And do you really want to block ALL icmp, including unreachable and time
> exceeded, disallowing even the router or LAN clients ability to do TCP
> PMTU discovery, traceroutes or pings? If not you'll want to add a rule,
> best stateless, like 'allow icmp from any to any icmptypes 3,11' early
> on and if you like statefully, out to net, 'allow icmptypes 0,3,8,11'.
>
> cheers, Ian
>
No, it was not intentional. I always allow echoreq (0) for IPv4. Is that
not enough for PMTU? I'm going to have to go read docs on it again. I've
been a bad netizen and ignored 3 and 11 for quite a while, and echoreply
is outbound and allowed by default so I didn't have it explicitly
stated. I need to find that reference I was using that discussed ICMP
attacks... For IPv6 I always allow 1,2,3,4,128,129,135,136.
--
Mark Felder
ports-secteam member
feld at FreeBSD.org
More information about the freebsd-net
mailing list