# PF redirects from $localnet to $ext_if



## fullauto (Jun 7, 2012)

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!


----------



## SirDice (Jun 8, 2012)

Use so-called split horizon DNS. Internal hosts resolve to the internal IP addresses. External requests resolve the external IP addresses.


----------



## fullauto (Jun 8, 2012)

Any chance you could recommend some further reading good sir?


----------



## SirDice (Jun 8, 2012)

Nice "simple" example for BIND: http://www.cyberciti.biz/faq/linux-unix-bind9-named-configure-views/


----------



## kpa (Jun 8, 2012)

This is how it could be done with BIND:
http://www.zytrax.com/books/dns/ch6/#split-view.

If you don't want to use BIND you can use a DNS forwarder like dns/dnsmasq and use exceptions in its configuration or in /etc/hosts to override DNS names so that local clients resolve the names to local addresses.


----------



## wblock@ (Jun 8, 2012)

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:


```
nat on $int_if proto tcp from $internal_net to $server port 1234 -> $int_if
```


----------



## fullauto (Jun 8, 2012)

*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


```
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.


----------



## wblock@ (Jun 9, 2012)

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.


----------



## kpa (Jun 9, 2012)

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.


----------



## fullauto (Jun 10, 2012)

*G*ood point. Can this be a security problem?


----------



## kpa (Jun 10, 2012)

It's just an inconv*e*nience when you want to debug something and want to know the real source IP address of a request.


----------



## fullauto (Jun 19, 2012)

*You were right.*



			
				kpa said:
			
		

> It's just an inconv*e*nience 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. *T*he 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.


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 
	
	



```
client-match { any; }
```
 at the top, it always wins.

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.


----------

