Women in Technology

Hear us Roar



Article:
  NAT with pf
Subject:   Incorrect Information in this Article
Date:   2003-12-15 12:06:55
From:   artymiak
Response to: Incorrect Information in this Article

It would help, if you described your LAN configuration and what exactly you are trying to achieve in a little more detail. What works in one case, may not work in another. If you do that, I'll try to help.


--Jacek

Main Topics Oldest First

Showing messages 1 through 1 of 1.

  • Thank you, Jacek
    2003-12-15 15:18:19  anonymous2 [View]

    Thanks for the offer, although I already have it working. I will explain it for other people's benefit, though.

    I want to rdr certain ports to certain internal hosts using pf, at the same time as using NAT on the external interface. The rdr rules work fine for this, but as you noted, internal hosts cannot connect to the external ip address with the single rdr rule. So you add a rdr rule on the internal NIC, right? Wrong. That's what that quote from the pf documentation is about--such a method doesn't work.

    3 Hosts, let's give them real IPs just to be clear:

    Gateway ($int) 10.0.0.1 ($ext) 1.2.3.4
    Host2 10.0.0.2
    Host3 10.0.0.3

    We do NAT on ext, and redirect port 5555 to Host2:

    nat on $ext proto $tcp from 10.0.0.0/24 to any -> $ext

    rdr on $ext proto tcp from any to $ext port 5555 -> Host2 port 5555

    Any external host connects to 1.2.3.4, the port is forwarded using the rdr rule. Host2 sees the forward, responds to the external host, and everything works.

    But what if Host3 connects to 1.2.3.4? It doesn't work, so we add another rdr rule (as you suggested):

    rdr on $int proto tcp from any to $ext port 5555 -> Host2 port 5555

    Host3 sends a packet to 1.2.3.4, which comes in on $int. Packet looks like this:

    Src: 10.0.0.3; Dest=1.2.3.4

    Then, pf redirects the packet to 10.0.0.2. So far, so good. Host2 responds, with a packet like this:

    Src: 10.0.0.2; Dest 10.0.0.3

    Host3 sees this packet and throws it away. Host3 says, essentially "I never sent anything to 10.0.0.3--why is it responding?" The rdr rule will never work because the wrong host responds to Host3's request to connect to 1.2.3.4.

    The solution from OpenBSD's pf page is to add a NAT rule that changes the source ip:

    nat on $int proto tcp from 10.0.0.0/24 to Host2 port 5555 -> $int

    What this does is make the initial packet appear to come from $int. Host2 then responds to $int, where pf's NAT will translate the source ip back to 1.2.3.4, so that Host3 thinks it's talking to 1.2.3.4. As the page notes, this is not exactly an elegant solution, but it works (they add another rule to tighten it a bit).

    I don't believe simply adding an rdr as you did in the article works, although I may have misunderstood your configuration. The internal rdr does forward the port, but the responding packet will be dropped as it comes from the wrong host. NAT similar to the external interfaces is needed in order to make the internal host believe it is talking to the external ip.

    -Dan