For some certain reasons I am also interested in solutions for the issue of the OP, and therefore I was investigating the various possibilities with a test setup which is quite similar to the one that the OP
@Labaman designed for his response above. Here comes a summary of the findings and here are the options, that were all working in my test setup:
1. Proxy on the gateway
The innermost internal clients have at least access to certain services on the internet. The OP told us already that squid is working as a transparent proxy on his gateway, and yes, on FreeBSD 10
ipfw fwd works without building a custom kernel with
options IPFIREWALL_FORWARD. This is of course not exactly the solution for the issue, however, in some usage cases a proxy might be an adequate option, and I mention it for the sake of completeness.
2. Manipulating the Routing Table
This was suggested already in some posts. However, the OP seemed to understand it wrong. The routing table of the modem+router has to be manipulated or at least a DMZ option has to be configured, and not the routing table of the FreeBSD gateway. If it is for any reasons not possible to manipulate the modem+router, then this is NOT an option (of course). And even if it would be possible to manipulate the modem+router, then IMHO, it would be better to put it into bridge mode and let the FreeBSD gateway talk to the WAN directly, and so, all that hassle is avoided. Anyway, again for the sake of completeness, the correct command (*BSD style) in the actual case for adding a route to the modem/router would be:
route add -net 192.168.0.0/24 192.168.1.100. I verified this in my test setup, and this would really solve the issue, again, provided the modem+router is configurable in that way.
3. Bridging on the FreeBSD gateway
I suggested this in a previous post. The advantage is, that this actually works without the need to change anything in the modem+router. The "disadvantage" is, that there is no innermost internal network. Nonetheless, all packets from/to the internet are forced to pass the firewall, and therefore this solution with proper FW rules would NOT impose higher risks on the internal clients compared to the desired setup of the OP, having the clients in a separated internal network.
4. Double NAT
As @usbmat already stated, "'Double NAT' isn't exactly the nicest setup...", however, it would bring to the OP what he was looking for. The point is, it does not work that simply as expected. The whole last sunday, I tried all possible and impossible ways to get it to work with my test setup employing ipfw+natd and ipfw+in-kernel-nat, to no avail. I told to myself, this must work, I saw it already working. VirtualBox defaults to NAT, and with the Host being on NAT this is 'Double NAT'. Mac OS X offers the so called 'Internet Sharing' among network devices which is actually a combo of DHCP/DNS/NAT and again if the Mac is on NAT, the whole setup is 'Double NAT'. Well, today, I examined what Mac OS X actually does for setting up its NAT for 'Internet Sharing' of the WLAN (
en1) to LAN-Devices on (
en0). The surprise was, that for the separated internal network it creates a bridge with the only one member
en0 and NAT's this via
en1. I reproduced this on the FreeBSD gateway, and surprisingly, I got 'Double NAT' working finally:
In file
/etc/rc.conf
Code:
...
# Interface Setup
cloned_interfaces="bridge0"
ifconfig_ue0="up -tso"
ifconfig_bridge0="inet 192.168.0.1/24 addm ue0 description LAN"
ifconfig_nfe0="inet 192.168.1.100/24 -tso description WAN"
defaultrouter="192.168.1.1"
# Gateway/Firewall/NAT
gateway_enable="YES"
firewall_enable="YES"
firewall_nat_enable="YES"
firewall_script="/etc/ipfw.conf"
In file
/etc/ipfw.conf
Code:
#!/bin/sh
for iface in `/sbin/ifconfig -l` ; do
desc=`/sbin/ifconfig $iface | /usr/bin/sed -n '/.description: /{s///;s/ .*//;p;}'`
if [ "$desc" == "LAN" ] ; then
LAN=$iface
elif [ "$desc" == "WAN" ] ; then
WAN=$iface
fi
done
/sbin/ipfw -q flush
/sbin/ipfw -q nat 1 config if $WAN reset
/sbin/ipfw -q add 100 nat 1 ip from any to any via $WAN
/sbin/ipfw -q add 65534 allow ip from any to any
Note: Without putting
ue0 into the bridge, 'Double NAT' DOES NOT WORK. And, don't blame me for this, the bridge in this NAT setup is not my invention, I copied this from Mac OS X 'Internet Sharing'.