Struggling with IPFW on CURRENT

Ian Smith smithi at nimnet.asn.au
Thu Oct 8 08:12:32 UTC 2015


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.

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.

 > * 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

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.

 > * 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'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.

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.

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


More information about the freebsd-net mailing list