kernel NAT with ipfw failing
Andrzej Tobola
ato at iem.pw.edu.pl
Tue Mar 26 16:11:03 UTC 2013
On Tue, Mar 26, 2013 at 05:28:41PM +0200, Jukka Ukkonen wrote:
>
> Hello,
>
> Does anyone have a confirmed working example (one that is
> in daily active use) of the ipfw NAT inside the kernel?
Yes.
>From a long time. On FreeBSD 9.1-STABLE amd64.
% # ipfw -a list
00100 21174480 25689611435 allow ip from any to any via lo0
00200 0 0 deny ip from any to 127.0.0.0/8
00300 0 0 deny ip from 127.0.0.0/8 to any
00500 25956378 24125425085 nat 1 ip from any to 194.29.146.4
00500 88469999 28195999566 nat 1 ip from any to any recv lagg0
.............
% grep nat /etc/rc.conf
nat_enable=YES # NAT (/usr/local/etc/rc.d)
nat_LAN=lagg0 # LAN
nat_IP=194.29.146.4 # nat1
% cat /usr/local/etc/rc.d/nat
#!/bin/sh
#
# $FreeBSD: src/etc/rc.d/nat,v 0.1 2010/11/7 22:04:50 ato Exp $
#
# ato 2010
# PROVIDE: nat
# REQUIRE: NETWORKING
# REQUIRE: named
# KEYWORD: nojail
# To enable User must define:
# nat_enable=YES
# nat_IP= or nat_WAN= # NATed IP (raw or DNS name) or WAN interface name
# nat_LAN= # LAN interface name
# # if not specified get `route -n get -inet default | grep interface:`
. /etc/rc.subr
name=nat
rcvar=nat_enable
load_rc_config $name
: ${nat_enable:=NO}
: ${nat_CONF="reset unreg_only same_ports log"} # deny_in
: ${nat_N:=1}
: ${nat_R:=500}
#set_rcvar nat_enable NO "NAT (ipfw)" >/dev/null
start_precmd=nat_prestart
start_cmd=nat_start
required_modules="ipfw_nat.ko" # XXX why .ko necessary ?
stop_cmd=nat_stop
extra_commands="status show dump"
status_cmd=nat_show
show_cmd=nat_show
dump_cmd=nat_dump
nat_prestart()
{
[ "$nat_WAN$nat_IP" ] || err 1 "You must define \$nat_IP or \$nat_WAN."
[ "$nat_LAN" ] || err 1 "You must define \$nat_LAN."
ifconfig -l ether | grep -q $nat_LAN || err 1 "Can't find LAN interface $nat_LAN."
if [ "$nat_IP" ]; then
# TODO test czy IP przypisany:
ping -q -c1 -W100 $nat_IP 2> /dev/null | grep -q '100.0% packet loss' && return 1
else
nat_IP=me
fi
return 0
}
nat_start()
{
# XXX test if ON
echo "Enabling NAT on $nat_LAN."
if [ "$nat_WAN" ] ; then
nat_CONF="if $nat_WAN $nat_CONF"
elif [ "$nat_IP" ]; then
nat_CONF="ip $nat_IP $nat_CONF"
else # no nat_WAN or nat_IP defined - get default inet gateway interface:
nat_WAN=`route -n get -inet default | grep interface:` ; nat_WAN=${nat_WAN##*: }
nat_CONF="if $nat_WAN $nat_CONF"
fi
ipfw nat $nat_N config $nat_CONF
ipfw add $nat_R nat $nat_N all from any to $nat_IP
ipfw add $nat_R nat $nat_N all from any to any recv $nat_LAN
sysctl net.inet.ip.forwarding=1
#sysctl net.inet.ip.fw.one_pass=1 # def=0 (nie wplywa?)
#Bound dummynet to CPU0:
#cpuset -l 0 -t $(procstat -t 0 | awk '/dummynet/ {print $2}')
}
nat_stop()
{
echo "Disabling NAT"
# XXX test if ON
ipfw delete $nat_R
kldunload $required_modules
}
nat_show()
{
# XXX test if ON
ipfw nat $nat_N show config
ipfw -a list $nat_R && ipfw nat $nat_N show
arp -ai $nat_LAN
}
nat_dump()
{
# XXX test if ON
sysctl net.inet.ip.fw.verbose=0
tcpdump -i ipfw0
sysctl net.inet.ip.fw.verbose=1
}
run_rc_command "$1"
cheers,
-a
More information about the freebsd-ipfw
mailing list