Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Sep 2011 12:57:17 -0700
From:      Freddie Cash <fjwcash@gmail.com>
To:        Marek Salwerowicz <marek_sal@wp.pl>
Cc:        freebsd-net@freebsd.org
Subject:   Re: ipfw - accessing DMZ from LAN
Message-ID:  <CAOjFWZ4XOU2dT3%2BL6AJeUNO7QcC=0ymLXN3GMkzCuoB3a1Qyew@mail.gmail.com>
In-Reply-To: <4E84B447.7010509@wp.pl>
References:  <4E412116.1070305@wp.pl> <CAOjFWZ4B3uUfOLAzL=B1WY98rqi6X32j7FM61VjJ3td76NkADg@mail.gmail.com> <4E422A74.3090601@wp.pl> <CAOjFWZ5CK62nQMA8JsfW1b4BQh3hAJbAAynortzaUBqSWBwdSQ@mail.gmail.com> <4E7B450F.5050802@wp.pl> <CAOjFWZ6wf9NnVeffUV4uA6h1t-1T8juxXycZbM7%2BGgpFC-HkUg@mail.gmail.com> <4E84B447.7010509@wp.pl>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Sep 29, 2011 at 11:09 AM, Marek Salwerowicz <marek_sal@wp.pl> wrote:

> W dniu 2011-09-26 21:20, Freddie Cash pisze:
>
> Your rules are too generic, they will not work for a double-NAT setup.
>> Each and every single rule must specify the network interface.  And it
>> must
>> specify whether it's incoming (in recv) or outgoing (out xmit) traffic.
>>  Don't use "via" anywhere.
>>
>> While it's easier to use generic rules to start with, you really need to
>> get
>> very specific, at least for the double-NAT setup.
>>
>> See my example above.
>>
>> I look at it but I have problems with understanding the rules.
> So far I understand the double-NAT like:
>
> 1. There are two NAT instances, one for LAN, the other for DMZ host (with
> public address redirection to DMZ private IP). The first is $lanport, the
> other $dmzport. The LAN interface is $LANIF, the DMZ interface is $DMZIF
>
> 2. When client from LAN wants to connect to DMZ host, using DMZ public IP
> *only*, the packet goes like this:
>
>    i. the packet is allowed to enter the router by DMZ NAT port ($dmzport)
> and $LANIF:
>        ipfw add divert $dmzport ip from $LAN to $DMZ_PUBLIC_IP in recv
> $LANIF
>        ipfw add allow ip from $LAN to $DMZ_PUBLIC_IP in recv $LANIF <---
> why in your example are you using PRIVATE_IP instead of PUBLIC?
>

You use the private DMZ IP in the second rule because you are allowing the
NAT'd packet through.

The first rule matches a packet with src $LAN and dest $DMZ_PUBLIC_IP, and
converts it to a packet with src $LAN and dest $DMZ_PRIVATE_IP.

Thus, your second rule has to match the new packet.

Remember, diverted packets are re-injected into the IPFW rules.


> ii. the packet is redirected to go out to DMZ, using DMZ NAT port:
>        ipfw add divert $dmzport ip from $LAN to $DMZ_PRIVATE_IP out xmit
> $DMZIF
>        ipfw add allow ip from $ROUTER_PUBLIC_IP to $DMZ_PRIVATE_IP out xmit
> $DMZIF
>
>
No, the packet is routed to the DMZ network (since the dest is now
$DMZ_PRIVATE).  But the src is still $LAN (which are private, non-routable
IPs), so you have to NAT the packet again, using the $lanport.

ipfw add divert $lanport ip from $LAN to $DMZ_PRIVATE_IP  out xmit $DMZIF

That sends the packet to the LAN NAT instance.  The packet starts with src
$LAN and dest $DMZ_PRIVATE_IP, and ends up with src $LAN_PUBLIC_IP and dest
$DMZ_PRIVATE_IP.  So now you need a rule to match that packet:

ipfw add allow ip from $LAN_PUBLIC_IP to $DMZ_PRIVATE_IP out xmit $DMZIF


Thus, the client connects to $DMZ_PUBLIC_IP, and the server sees the
connection comming from $LAN_PUBLIC_IP.  Neither side sees any private IPs.

3. When DMZ host wants to connect with LAN client:
>
>
You just reverse the order of the rules:

ipfw add divert $lanport ip from $DMZ_PRIVATE_IP to $LAN_PUBLIC_IP in recv
$DMZIF
ipfw add allow ip from $DMZ_PRIVATE_IP to $LAN in recv $DMZIF

ipfw add divert $dmzport ip from $DMZ_PRIVATE_IP to $LAN out xmit $LANIF
ipfw add allow ip from $DMZ_PUBLIC_IP to $LAN out xmit $LANIF


In generic terms, the packet flow is like this:

<packet comes in on the lan interface>
src:  lan private subnet     dest:  server public ip

<packet gets NAT'd, then re-injected into the rules>
src:  lan private subnet     dest:  server private ip

<packet is routed/sent out the dmz interface>
src:  lan private subnet     dest:  server private ip

<packet is NAT'd, then re-injected into the rules>
src:  lan public ip             dest:   server private ip


Note how you change first the destination IP via NAT (on the LAN interface);
then you change the source IP via NAT (on the DMZ interface).


If I want also to set up  NAT rules for my LAN (to allow it to access the
> Internet, and router), and also for my DMZ hosts (also for the Internet),
> what should be the order of rules?
> First 'LAN-DMZ', then 'DMZ', then 'LAN' ?
>

There's no hard-and-fast rules on how you should order your rules (at least,
none that I've found anywhere).

I prefer to write them such that you have the most specific rules first, and
the most generic ones last.  So my rulesets generally look like:
  - rules for the firewall itself
  - rules for vpn connections end-pointing on the firewall
  - rules for specific servers with public IPs
  - rules for the LAN (generally just outgoing traffic)
  - deny everything as the last rule

In the set of rules for the specific servers, I'll split my incoming rules
into two sections:  from the Internet, from the LAN.  That way, all the
rules for accessing a specific server are together in one spot.

You just have to remember what the LAN private subnet is, the LAN public
(NAT) IP is, and the LAN divert port is, so you can use those in the rules
for the specific servers.  Having everything in one giant rules file, or
including config files, helps.

-- 
Freddie Cash
fjwcash@gmail.com



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAOjFWZ4XOU2dT3%2BL6AJeUNO7QcC=0ymLXN3GMkzCuoB3a1Qyew>