ipfw / natd does not allow lan traffic to reach external num

Toomas Aas toomas.aas at raad.tartu.ee
Mon Aug 11 11:46:51 PDT 2003


Hi!

> I have a problem with our firewall/NAT, on a FreeBSD 4.7 box... Here 
> a list with some details:
> 
> *) The FreeBSD box uses natd and ipfw, and have two external IP:s, 
> lets say aaa.bbb.ccc.20 and ddd.eee.fff.21.
> 
> *) natd is used to redirect access to external IP addresses and ports 
> to internal LAN IP:s, for example 192.168.0.20 and 192.168.0.21, 
> where for example webservers are located.
> 
> *) natd rules:

<snipped>

> 
> *) ipfw lets things through:

<snipped>

> Most things works just fine, external access are redirected to 
> correct ports, and the webservers work just fine. BUT the problem 
> comes when a box on the LAN tries to reach a site residing on 
> 192.168.0.20 using the _external_ IP aaa.bbb.ccc.20. 

I don't use ipfw but I encountered the same problem when I first
attempted to do the similar setup using ipfilter/ipnat.

The problem (at least with ipfilter/ipnat) is that nat does not change the
*source* address of packets to that of the machine doing the NAT.

So, if you are at machine 192.168.1.10, the internal IP of the NAT
box is 192.168.1.1 and you are trying to access a service running
on 192.168.1.2 via the external interface of the NAT box, this is
what happens:

* Your PC sends initial SYN with source=192.168.1.10, target=<natbox_external_ip>.
  This packet goes to the natbox, as that is your default gateway.

* NAT on natbox translates the target address to 192.168.1.2 and sends the packet 
  there. The source address remains unchanged (192.168.1.10).

* 192.168.1.2 sees the packet coming from 192.168.1.10, and - this is where
  it goes wrong - sends response (SYN+ACK) directly to 192.168.1.10.

* since 192.168.1.10 did not initiate session with 192.168.1.2 but with
  natbox, it doesn't want anything to do with this strange SYN+ACK packet 
  and just drops it.

There are several possible solutions recommended for ipfilter, but the one
that I myself ended up using was set up netcat on the natbox.

Basically (using inetd) you set up netcat to listen on an arbitrary port X and 
pipe all traffic to the machine:port on your internal net where the actual
service is running (such as 192.168.1.2:80). Then you forward all traffic with 
src=<your_internal_net> and dst=<natbox_external_ip:80> to 127.0.0.1:X. That way 
the internal server sees packets coming from natbox, sends its responses there, 
and the natbox in turn sends responses back to the original client. Everybody's 
happy.

As I said I don't use ipfw myself so I can't give you any specific ipfw
commands, but I'm sure it all can be done. If only my explanation wasn't too
confusing :-)
--
Toomas Aas | toomas.aas at raad.tartu.ee | http://www.raad.tartu.ee/~toomas/
* (A)bort, (R)etry, (I)nfluence with large hammer?



More information about the freebsd-questions mailing list