Request for policy decision: kernel nat vs/and/or natd
Ian Smith
smithi at nimnet.asn.au
Sun Jan 16 04:21:27 UTC 2011
On Sun, 16 Jan 2011, Hiroki Sato wrote:
> Ian Smith <smithi at nimnet.asn.au> wrote
> in <20110108220300.Q15397 at sola.nimnet.asn.au>:
>
> sm> On Sat, 8 Jan 2011 15:02:29 +1100, Ian Smith wrote:
> sm> > On Fri, 7 Jan 2011, Brandon Gooch wrote:
> sm> > > On Thu, Dec 23, 2010 at 8:58 AM, Ian Smith <smithi at nimnet.asn.au> wrote:
> sm> [..]
> sm> > > > We could:
> sm> > > >
> sm> > > > 1) Preference kernel nat over natd when both are enabled.
> sm> > >
> sm> > > I vote for #1.
> sm> >
> sm> > Thanks. So far, that makes an overwhelming majority of 2 / NIL :)
> sm> >
> sm> > I see that hrs at freebsd.org has just grabbed two related PRs:
> sm> >
> sm> > kern/148928: [ipfw] Problem with loading of ipfw NAT rules during system startup
> sm> > conf/153155: [PATCH] [8.2-BETA1] ipfw rules fail to load cleanly on start if nat enabled
> sm> >
> sm> > so this seems a good time to work up patches to that effect for review
> sm> > (/etc/rc.d/ipfw, maybe natd, /etc/rc.firewall) later tonight my time.
> sm>
> sm> Ok, the attached patches are against HEAD, which is currently identical
> sm> to 8-STABLE for these files. rc.d_ipfw.patch also applies to 7-STABLE
> sm> with an offset but rc.firewall.patch needs more work for 7. I've no box
> sm> on which to actually run-test tonight, and will be away for a few days.
> sm>
> sm> /etc/rc.d/ipfw:
> sm> . prefer kernel nat (loading ipfw_nat) to natd when both are enabled
> sm> . add ipdivert to required_modules - when only natd is enabled - as
> sm> proposed by Thomas Sandford in conf/153155 and also re kern/148928
> sm> also fixing the related issue in conf/148137 (and possibly others)
> sm> . prefix /etc/rc.d/natd to firewall_coscripts when only natd is enabled
> sm>
> sm> /etc/rc.d/natd:
> sm> . seems nothing is needed; has KEYWORD nostart and so should only be
> sm> started now by ipfw when natd - but not firewall_nat - is enabled
> sm>
> sm> /etc/rc.firewall:
> sm> . move firewall_nat and natd code into a function, setup_nat()
> sm> preferring kernel firewall_nat to natd if both are enabled
> sm> . couldn't resist tidying up that code to within 80 columns
> sm> . call setup_nat also in 'simple' ruleset, with same intent as
> sm> proposed in conf/148144 by David Naylor
> sm> . couldn't resist fixing unnecessarily long line in 'workstation'
>
> The patches look good to me, but one thing I am wondering is
> rc.d/natd invocation in rc.d/ipfw. When natd_enable="YES", rc.d/natd
> invokes the daemon after the rc.d/ipfw script eventually even if
> firewall_nat_enable="YES". What do you think about adding natd to
> REQUIRE: line of rc.d/ipfw? Although I did not test it extensively,
> rc.d/natd can run safely before rc.d/ipfw and using REQUIRE is
> reasonable instead of using $firewall_coscripts from a viewpoint of
> the rc.d framework.
Hello Hiroki,
I'm not sure why, with the use of firewall_coscripts, natd was made to
start AFTER ipfw rules are loaded but BEFORE enabling the firewall, so I
don't know whether there had been negative consequences of starting natd
first? Nor do I know of any other use of firewall_coscripts, so adding
emax@ to the (trimmed) cc list as the committer of that change.
http://www.freebsd.org/cgi/cvsweb.cgi/src/etc/rc.d/ipfw.diff?r1=1.22;r2=1.23;f=h
shows that prior to that change, rc.d/natd was run - so the daemon was
started - before the firewall rules were loaded, which would remove the
present need to add ipdivert to required_modules (conditionally) in
ipfw_prestart. ipfw_stop() still needs to kill natd if running though,
noticing also the comment with rc.d/natd rev 1.1 over 6 years ago:
===
Add separate script for natd. This fixes race condition with "ipfw restart"
(when new natd is started before old natd died) and allows to manage natd
without touching ipfw.
natd should probably be killed with SIGKILL when stopping natd.
===
Because rc.d/natd has KEYWORD nostart, I gathered that it won't run on
startup, and by NOT prefixing it to _coscripts when firewall_nat is also
enabled, as in this patch, it won't be invoked by ipfw either. However
it could still be run manually, so really should have an explicit test
to NOT start /sbin/natd whenever firewall_nat="YES", assuming policy #1.
And if rc.d/natd has such an explicit test for ! firewall_nat_enabled,
then it wouldn't matter when or how rc.d/natd was invoked? I'm not sure
how one should cleanly abandon an rc.d script without starting/stopping
anything though?, or I'd offer such a patch now.
If rc.d/natd can really _always_ be invoked safely before starting ipfw,
then the REQUIRE method should be fine - as long as rc.d/natd quits if
$firewall_nat is enabled - but I'm not sure how that may work especially
if the interface concerned relies on DHCP (ie -dynamic) and/or if the
interface hasn't an address yet, as CAN happen with ppp or (here) mpd?
Any more thoughts on start/stop ordering or interdependent conditions?
cheers, Ian
More information about the freebsd-ipfw
mailing list