PF redirects from $localnet to $ext_if

Hi.

I was wondering if anyone could shed some light on a particular problem I'm sure most of you have already dealt with at one time or another.

I have a gateway/firewall running PF with a small network behind it on NAT. The problem I'm running into is when a local machine (192.168.1.x) requests something from my local system, nothing goes through.

I have figured it out as being because my local machines (192.168.1.x) requests the document, and my DNS reports my external IP as it should. But, the server, apache22 in this case, is sending back the information from its internal IP. The local machine, having sent the request to the external IP, drops the packets.

Not sure if any of you have a work around you have used before that you can share. I'm completely open to suggestions.

This is more of an annoyance than anything, becuase I can just as easily type in http://(internal address), but having to explain this to several new people in the next month is making me sweat!
 
Use so-called split horizon DNS. Internal hosts resolve to the internal IP addresses. External requests resolve the external IP addresses.
 
After looking at that, the firewall solution doesn't seem so bad any more. :)

There's an example of using PF NAT to do this in the OpenBSD PF documentation: http://www.openbsd.org/faq/pf/rdr.html

The syntax might not work exactly on FreeBSD's somewhat older PF, but it can be made to work. I use:

Code:
nat on $int_if proto tcp from $internal_net to $server port 1234 -> $int_if
 
Solved

I tried the split horizon method.
Not for the faint of heart. :\

Wblock is right. :stud

The PF based solution is MUCH easier and faster to debug and such.
However, your solution was only half right.

Here is the final solution;)

Code:
rdr on $int_if proto tcp from $localnet to $ext_if port $apache_port \
        -> $webserver
nat on $int_if from $localnet to $webserver port $apache_port -> $int_if

Epic thanks for the help.
 
I have a similar redirect in my rules, but skipped it thinking it was for redirecting outside traffic. Sorry about that.

Incidentally, you can use service names from /etc/services. So www instead of $apache_port. Unless you have more than one service in that macro, in which case, never mind.
 
That works but there's a side effect of hiding the real source IP address for client machines on your internal net that connect to the webserver using the public IP address. The connections will look like coming from the internal interface instead of the client's real local IP address.
 
It's just an inconvenience when you want to debug something and want to know the real source IP address of a request.
 
You were right.

kpa said:
It's just an inconvenience when you want to debug something and want to know the real source IP address of a request.

In the end, I opted for the Split-Horizon DNS. The problem that made me want to NOT use SH-DNS is that I was having problems with the client-match feature.

I wanted to share my resolution with the crew for future newbs, since I'm sure someone else will be pulling their hair out in the future trying to figure out why named is offering up the wrong zone file. It's actually quite stupid of me, but I'm not to proud to admit it and share my hurt with you all so as to avoid hurt in others down the line.

  1. Make sure your last client-match is the 'any' line. It seems that first-match-wins is the order of the day with regards to named.conf. If your external view is listed with the
    Code:
    client-match { any; }
    at the top, it always wins.
  2. Make sure you add 127.0.0.1 to the internal client-match list.
That is all. I really hope this helps someone else out in the future. ;)
 
Back
Top