Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 May 2017 10:19:11 -0700 (PDT)
From:      "Rodney W. Grimes" <freebsd-rwg@pdx.rh.CN85.dnsmgr.net>
To:        Freddie Cash <fjwcash@gmail.com>
Cc:        Karl Denninger <karl@denninger.net>, "freebsd-ipfw@freebsd.org" <freebsd-ipfw@freebsd.org>
Subject:   Re: Question that has dogged me for a while.
Message-ID:  <201705041719.v44HJBgF005292@pdx.rh.CN85.dnsmgr.net>
In-Reply-To: <CAOjFWZ6j7KAmwcP_DpzaOm%2BnvPTbF75XrnKUqXJaD5R997EFdA@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
[ Charset UTF-8 unsupported, converting... ]
> On Thu, May 4, 2017 at 9:22 AM, Karl Denninger <karl@denninger.net> wrote:
> 
> > Consider the following network configuration.
> >
> >
> > Internet ------- Gateway/Firewall ---------- Inside network (including a
> > web host)
> >             70.16.10.1/28     192.168.0.0/24
> >
> > The address of the outside is FICTIONAL, by the way.
> >
> > For policy reasons I do NOT want the gateway machine to actually have
> > the host on it.  There may be a number of things running on there but
> > for the instant moment let's assume a standard pedestrian web host on
> > port 80.
> >
> > I have DNS pointing at "webhost.domain" @ 70.16.10.1.
> >
> > I have NAT on the gateway (NAT internal to the kernel), and a "hole
> > punch" in there with redirect_port tcp 192.168.1.1:80 70.16.10.1:80 as
> > pat of the nat configuration statement.
> >
> > This works fine for anyone on the outside.  HOWEVER, anyone on the
> > INTERNAL network cannot see the host.
> >
> > My NAT configuration looks like this:
> >
> > #
> > # Now divert all inbound packets that should go through NAT. Since this
> > is NAT
> > # it can only match a packet that previously was NATted on the way out.
> > #
> >         ${fwcmd} add 6000 nat 100 ip4 from any to me recv ${oif}
> > #
> > # Check stateful rules; we want to go there directly if there is a match
> > #
> >         ${fwcmd} add 7000 check-state
> > #
> > # Now pick up all *outbound* packets that originated from an inside address
> > # and put them through NAT.  We then have
> > # a packet with a local source address and we can allow it to be sent.
> > # Therefore, if the packet is outbound let it pass and be done with it.
> > #
> >         ${fwcmd} add 8000 nat 100 ip4 from 192.168.0.0/16 to any xmit
> > ${oif}
> > >>    ${fwcmd} add 8001 nat 100 ip4 from 192.168.0.0/16 to ${oip}
> >         ${fwcmd} add 8009 deny log ip4 from 192.168.0.0/16 to any xmit
> > ${oif}
> >         ${fwcmd} add 8010 pass ip4 from ${onet} to any xmit ${oif}
> >
> > Without the ">>" line I get nothing; the packets get to the gateway and
> > disappear.
> >
> > With the ">>" line I DO get the packets re-emitted on the internal
> > interface HOWEVER there is no translation to the internal interface IP
> > on the gateway box.  So what I see on the internal box is this:
> >
> > 11:19:16.369634 IP 192.168.10.40.60924 > 192.168.10.100.11443: Flags
> > [S], seq 292171178, win 8192, options [mss 1460,nop,wscale
> > 8,nop,nop,sackOK], length 0
> > 11:19:16.369662 IP 192.168.10.100.11443 > 192.168.10.40.60924: Flags
> > [S.], seq 3088872007, ack 292171179, win 65535, options [mss
> > 1460,nop,wscale 6,sackOK,eol], length 0
> >
> > Which won't work because the internal box got and sent this:
> >
> > 11:19:16.369337 IP 192.168.10.40.60924 > 70.169.168.7.11443: Flags [S],
> > seq 292171178, win 8192, options [mss 1460,nop,wscale 8,nop,nop,sackOK],
> > length 0
> > 11:19:16.369433 IP 192.168.10.40.60925 > 70.169.168.7.11443: Flags [S],
> > seq 2666765817, win 8192, options [mss 1460,nop,wscale
> > 8,nop,nop,sackOK], length 0
> > >> 11:19:16.369502 IP 192.168.10.40.60924 > 192.168.10.100.11443: Flags
> > [S], seq 292171178, win 8192, options [mss 1460,nop,wscale
> > 8,nop,nop,sackOK], length 0
> > >> 11:19:16.369511 IP 192.168.10.40.60925 > 192.168.10.100.11443: Flags
> > [S], seq 2666765817, win 8192, options [mss 1460,nop,wscale
> > 8,nop,nop,sackOK], length 0
> >
> > But since the gateway emitted the packet back on the wire *without*
> > remapping the source address (to itself) it doesn't match on the client
> > box 'cause there's no way back for it.
> >
> > There has to be a solution to this somewhere and I'm obviously missing
> > it..... :)
> 
> 
> ?You need to do a double-NAT (or hairpin-NAT or whatever you want to call
> it), where you first NAT the destination address on the incoming interface
> which will initiate the routing decision for where to send the packet next,
> then NAT the source address on the outgoing interface (which can be the
> same interface) in order to get the return packets sent back to the correct
> gateway.
> 
> Something along the lines of:
> 
> ipfw nat 100 blah blah blah <convert from 192.168.0.0/16 to 70.16.10.x>
> ipfw nat 200 blah blah blah <convert from 70.16.10.1 to 192.168.1.1>
> 
> ipfw add nat 200 tcp from 192.168.0.0/16 to 70.16.10.1  80 in  recv <int>
> ipfw add nat 100 tcp from 192.168.0.0/16 to 192.168.1.1 80 out xmit <int>
> 
> ipfw add nat 100 tcp from 192.168.1.1 80 to 70.16.10.x     in  recv <int>
> ipfw add nat 200 tcp from 70.16.10.1  80 to 192.168.0.0/16 out xmit <int
> 
> ?Note:  I've only ever done this with non-stateful rulesets.  Once you add
> state keeping, NAT configuration becomes horribly, horribly complex with
> IPFW.  Stateless rules are super easy, though.  :)
> ?

This looks good too.   Note that you can do this inside loop back NAT
in a stateless manner, your only doing this to make it work, your not
trying to do any keep state type protection.  Then leave the NAT that
is going out to the world as a keep state type NAT.

I am a strong advocate of stateless firewalls, but they have security
concerns that can often be addressed by use of keep state.  No one
says you can not make firewalls that mixes the technologies :-)

For critical and often abused TCP ports that I need to allow some
traffic to I often shovel those off to a keep state, for other
less dangerious, and especially high volume traffic I send that
to a stateless filter.


-- 
Rod Grimes                                                 rgrimes@freebsd.org



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