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