Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 24 Dec 2010 01:58:55 +1100 (EST)
From:      Ian Smith <smithi@nimnet.asn.au>
To:        freebsd-ipfw@freebsd.org
Subject:   Request for policy decision: kernel nat vs/and/or natd
Message-ID:  <20101223233437.Q27345@sola.nimnet.asn.au>

next in thread | raw e-mail | index | archive | help
Folks,

[ If someone implements an /etc/rc.d/ipfw reload command that reliably 
works over a remote session without any open firewall window, great, but 
I'd rather not discuss the related issues below in reponses to any PR ]

In order to address issues (and PRs) introduced by and since adding 
kernel nat and more recently firewall_coscripts, before offering any 
code it's clearly necessary to determine policy for what we should do 
when both natd_enable and firewall_nat_enable are set in rc.conf.

"Don't do that" is not a policy, people will and already are bumping 
into this, affecting startup scripts and nat[d] rules in rc.firewall.

We could:

1) Preference kernel nat over natd when both are enabled.

2) Preference natd over kernel nat when both are enabled.

3) Load both, including both modules, and include both nat and divert 
rules in the firewall constructed by rc.firewall types and/or another 
script configured as firewall_type - as happens now with rc.firewall, 
except kernel nat rules may crash if ipfw_nat isn't loaded, as below.

My vote, so it's out of the way, is for (1).  We've already seen people 
enabling firewall_nat while still having natd enabled, and to me it 
seems clear that adding firewall_nat will be intended to supercede natd.

I think this would require a new test in /etc/rc.d/natd as well, or 
perhaps just making the prefixing of natd to _coscripts conditional.

Relatively recent ipfw_prestart (paste, tabs lost) has chosen (2):

1.17      mtm        23: ipfw_prestart()
                     24: {
                     25:        if checkyesno dummynet_enable; then
                     26:                required_modules="$required_modules dummynet"
                     27:        fi
1.19      emax       28: 
                     29:        if checkyesno firewall_nat_enable; then
                     30:                if ! checkyesno natd_enable; then
                     31:                        required_modules="$required_modules ipfw_nat"
                     32:                fi
1.24    ! dougb      33:        fi

ie ipfw_nat module is only required when natd is NOT also enabled - but 
this won't affect anything with ipfw_nat in kernel, or loaded at boot.

http://www.freebsd.org/cgi/query-pr.cgi?pr=153155 doesn't address the 
above quandary, but does provide what seems to be the necessary and 
correct fix for that and 2 other 2010 PRs, namely, again de-tabbed:

--- rc.d/ipfw    (revision 216439)
+++ rc.d/ipfw    (working copy)
@@ -31,6 +31,10 @@
                         required_modules="$required_modules ipfw_nat"
                 fi
         fi
+
+        if checkyesno natd_enable; then
+                required_modules="$required_modules ipdivert"
+        fi
 }
 ipfw_start()

which removes any temptation to suggest running /etc/rc.d/natd first.

Then there's rc.firewall .. currently the NAT section (except for 
firewall_type="simple") will load both nat and divert rules, perhaps 
fortunately having the same rule number (again, pasted):

	case ${natd_enable} in
	[Yy][Ee][Ss])
		if [ -n "${natd_interface}" ]; then
			${fwcmd} add 50 divert natd ip4 from any to any via ${natd_interface}
		fi
		;;
	esac
	case ${firewall_nat_enable} in
	[Yy][Ee][Ss])
		if [ -n "${firewall_nat_interface}" ]; then
			if echo "${firewall_nat_interface}" | \
				grep -q -E '^[0-9]+(\.[0-9]+){0,3}$'; then
				firewall_nat_flags="ip ${firewall_nat_interface} ${firewall_nat_flags}"
			else
				firewall_nat_flags="if ${firewall_nat_interface} ${firewall_nat_flags}"
			fi
			${fwcmd} nat 123 config log ${firewall_nat_flags}
			${fwcmd} add 50 nat 123 ip4 from any to any via ${firewall_nat_interface}
		fi
		;;
	esac

Garrett Cooper ran into this a while ago.  We later figured that as the 
divert rule reenters the firewall at the next higher-numbered rule, not 
the next rule, then only natd would actually be invoked - but still it's
not an ideal situation in the face of a possibly not uncommon config.

Suggested patches (David Naylor's or mine) to add kernel nat support to 
'simple' ruleset in http://www.freebsd.org/cgi/query-pr.cgi?pr=148144 
would generate two different-numbered rules now if both were enabled, so 
this is another place where a clear decision on policy 1,2 or 3 above 
(or 4 if you've got a better idea :) would be really helpful.

cheers, Ian

PS I've got both 7.4-PRE and 8.2-PRE installed here, and apart from the 
IPv6 stuff, /etc/rc.d/{ipfw,natd} are in synch between both versions, 
and also with HEAD if I'm not mistaken.  It's a bit harder to tell when
http://www.freebsd.org/cgi/cvsweb.cgi/src/etc/rc.d/ipfw is out of date 
at least re what's in 7.4-PRE, ie rev 1.15.2.6 2010/08/17 21:28:40 jhb



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