Request for policy decision: kernel nat vs/and/or natd
Ian Smith
smithi at nimnet.asn.au
Sat Jan 8 14:30:58 UTC 2011
On Sat, 8 Jan 2011 15:02:29 +1100, Ian Smith wrote:
> On Fri, 7 Jan 2011, Brandon Gooch wrote:
> > On Thu, Dec 23, 2010 at 8:58 AM, Ian Smith <smithi at nimnet.asn.au> wrote:
[..]
> > > We could:
> > >
> > > 1) Preference kernel nat over natd when both are enabled.
> >
> > I vote for #1.
>
> Thanks. So far, that makes an overwhelming majority of 2 / NIL :)
>
> I see that hrs at freebsd.org has just grabbed two related PRs:
>
> kern/148928: [ipfw] Problem with loading of ipfw NAT rules during system startup
> conf/153155: [PATCH] [8.2-BETA1] ipfw rules fail to load cleanly on start if nat enabled
>
> so this seems a good time to work up patches to that effect for review
> (/etc/rc.d/ipfw, maybe natd, /etc/rc.firewall) later tonight my time.
Ok, the attached patches are against HEAD, which is currently identical
to 8-STABLE for these files. rc.d_ipfw.patch also applies to 7-STABLE
with an offset but rc.firewall.patch needs more work for 7. I've no box
on which to actually run-test tonight, and will be away for a few days.
/etc/rc.d/ipfw:
. prefer kernel nat (loading ipfw_nat) to natd when both are enabled
. add ipdivert to required_modules - when only natd is enabled - as
proposed by Thomas Sandford in conf/153155 and also re kern/148928
also fixing the related issue in conf/148137 (and possibly others)
. prefix /etc/rc.d/natd to firewall_coscripts when only natd is enabled
/etc/rc.d/natd:
. seems nothing is needed; has KEYWORD nostart and so should only be
started now by ipfw when natd - but not firewall_nat - is enabled
/etc/rc.firewall:
. move firewall_nat and natd code into a function, setup_nat()
preferring kernel firewall_nat to natd if both are enabled
. couldn't resist tidying up that code to within 80 columns
. call setup_nat also in 'simple' ruleset, with same intent as
proposed in conf/148144 by David Naylor
. couldn't resist fixing unnecessarily long line in 'workstation'
I've resisted other patches (enabling icmp) that I added to conf/148144
for which I apologise to David; one thing at a time ..
If folks prefer that this be submitted as yet another PR, please say.
cheers, Ian
-------------- next part --------------
--- rc.d_ipfw.1.24 Sat Jan 8 18:13:46 2011
+++ ipfw Sat Jan 8 21:00:18 2011
@@ -27,9 +27,9 @@
fi
if checkyesno firewall_nat_enable; then
- if ! checkyesno natd_enable; then
- required_modules="$required_modules ipfw_nat"
- fi
+ required_modules="$required_modules ipfw_nat"
+ elif checkyesno natd_enable; then
+ required_modules="$required_modules ipdivert"
fi
}
@@ -105,6 +105,7 @@
}
load_rc_config $name
-firewall_coscripts="/etc/rc.d/natd ${firewall_coscripts}"
+checkyesno natd_enable && ! checkyesno firewall_nat_enable && \
+ firewall_coscripts="/etc/rc.d/natd ${firewall_coscripts}"
run_rc_command $*
-------------- next part --------------
--- rc.firewall.1.69 Sat Jan 8 18:04:28 2011
+++ rc.firewall Sat Jan 8 21:24:54 2011
@@ -52,7 +52,7 @@
# filename - will load the rules in the given filename (full path required)
#
# For ``client'' and ``simple'' the entries below should be customized
-# appropriately.
+# appropriately with rc.conf variables.
############
#
@@ -112,6 +112,29 @@
${fwcmd} add pass ipv6-icmp from any to any icmp6types 2,135,136
}
+setup_nat () {
+ local iflag
+ if checkyesno firewall_nat_enable; then
+ if [ -n "${firewall_nat_interface}" ]; then
+ if echo "${firewall_nat_interface}" | \
+ grep -q -E '^[0-9]+(\.[0-9]+){0,3}$'; then
+ iflag="ip ${firewall_nat_interface}"
+ else
+ iflag="if ${firewall_nat_interface}"
+ fi
+ firewall_nat_flags="$iflag ${firewall_nat_flags}"
+ ${fwcmd} nat 123 config log ${firewall_nat_flags}
+ ${fwcmd} add $1 nat 123 ip4 from any to any \
+ via ${firewall_nat_interface}
+ fi
+ elif checkyesno natd_enable; then
+ if [ -n "${natd_interface}" ]; then
+ ${fwcmd} add $1 divert natd ip4 from any to any \
+ via ${natd_interface}
+ fi
+ fi
+}
+
if [ -n "${1}" ]; then
firewall_type="${1}"
fi
@@ -142,37 +165,17 @@
setup_ipv6_mandatory
############
-# Network Address Translation. All packets are passed to natd(8)
-# before they encounter your remaining rules. The firewall rules
-# will then be run again on each packet after translation by natd
-# starting at the rule number following the divert rule.
+# Network Address Translation. All packets are passed to kernel nat
+# or natd(8) before they encounter your remaining rules. The firewall
+# rules will then be run again on each packet after NAT translation
+# starting at the rule number following the nat or divert rule.
#
-# For ``simple'' firewall type the divert rule should be put to a
-# different place to not interfere with address-checking rules.
+# For ``simple'' firewall type the nat or divert rule is installed in
+# a different place to avoid interfering with address-checking rules.
#
case ${firewall_type} in
[Oo][Pp][Ee][Nn]|[Cc][Ll][Ii][Ee][Nn][Tt])
- 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
+ setup_nat 50
esac
############
@@ -311,13 +314,7 @@
# translated by natd(8) would match the `deny' rule above. Similarly
# an outgoing packet originated from it before being translated would
# match the `deny' rule below.
- case ${natd_enable} in
- [Yy][Ee][Ss])
- if [ -n "${natd_interface}" ]; then
- ${fwcmd} add divert natd ip4 from any to any via ${natd_interface}
- fi
- ;;
- esac
+ setup_nat
# Stop RFC1918 nets on the outside interface
${fwcmd} add deny all from 10.0.0.0/8 to any via ${oif}
@@ -519,7 +516,7 @@
# Deny and (if wanted) log the rest unconditionally.
log=""
- if [ ${firewall_logdeny:-x} = "YES" -o ${firewall_logdeny:-x} = "yes" ] ; then
+ if checkyesno firewall_logdeny; then
log="log logamount 500" # The default of 100 is too low.
sysctl net.inet.ip.fw.verbose=1 >/dev/null
fi
More information about the freebsd-ipfw
mailing list