Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 27 Feb 2011 17:08:39 +0600
From:      Eugene Grosbein <egrosbein@rdtc.ru>
To:        "net@freebsd.org" <net@freebsd.org>
Subject:   ipfw nat and dual-homed box
Message-ID:  <4D6A30B7.2010001@rdtc.ru>

next in thread | raw e-mail | index | archive | help
Hi!

Consider LAN using private IP addresses and NAT box with two uplinks to distinct
internet providers each of which supplies us with one public IP only.

With natd's "multiple instances" feature it's easy to setup dual-homed NAT box correctly,
so that replies for incoming packets get translated right, no matter what routing table
thinks about outgoing interface for such reply. ipfw configuration:

divert 8668 ip from any to any in recv $if0 # Deal with incoming packets.
divert 8669 ip from any to any in recv $if1
divert 8000 ip from any to any out xmit $if0 # For outgoing packets, first try to find existing
divert 8000 ip from any to any out xmit $if1 # translation table entry in all NAT instances and use it.
divert 8668 ip from any to any out xmit $if0 # Create new translation entry only if it was found nowhere.
divert 8669 ip from any to any out xmit $if1

fwd $if0_gate ip from $if0_ip to any out xmit $if1 # Force packet go out right interface.
fwd $if1_gate ip from $if1_ip to any out xmit $if0

Corresponding natd configuration file:

instance default
port 8668
interface $if0
unregistered_only yes

instance second
port 8669
interface $if1
unregistered_only yes

globalport 8000
#EOF

For performance reasons, I need to create similar setup using in-kernel "ipfw nat"
what does not have such "multiple instances" feature but has its own "keep-state" mechanics:

nat config if $if0 unreg_only
nat config if $if1 unreg_only
nat 123 ip from any to any via $if0 keep-state # For incoming packets create dynamic rule.
nat 124 ip from any to any via $if1 keep-state # For outgoing packet use corresponding NAT instance.
fwd $if0_gate ip from $if0_ip to any out xmit $if1 # Force packet go out right interface.
fwd $if1_gate ip from $if1_ip to any out xmit $if0

This works just fine if we do not try to use ipfw nat's port forwarding.
Here it breaks because "keep-state" creates dynamic rule for incoming connections
before translation's done, so it records external IP of the box as destination IP.
Hence, replies will be translated using wrong NAT instance when routing table
chooses wrong outgoing interface - replies won't match ipfw's dynamic rules.

I think this is a bug in 8.2-STABLE. Am I right?
Or, perhaps, there is another way to setup ipfw nat for dual-homed LAN?

Eugene Grosbein



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