# iptables DNAT equivalent in PF



## angryman1 (Sep 23, 2012)

Hi,

(im new to freebsd)

I have this rule in iptables :

[cmd=]iptables -t nat -A PREROUTING -i interfacehere-p tcp --dport porthere -j DNAT --to iphereorthere[/cmd]

I need to translate this into some PF rules.. I have tried literally 50 different configs, nothing working.. wondered if maybe someone here can do this in real time because maybe the different ideas I'm getting from tutorials/documentation may be out of date? 50% of the things I tried give me syntax errors and the rest just don't work at all.

Thank you to anyone that can help me!


----------



## SirDice (Sep 24, 2012)

Maybe you can explain what that rule is supposed to do?


----------



## ecazamir (Sep 24, 2012)

The sample pf.conf, located at /usr/src/share/examples/pf/pf.conf contains an example:
#rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021
Adjust it to suit your needs.

Translated from

```
iptables -t nat -A PREROUTING -i interfacehere-p tcp --dport requested_port_here -j DNAT --to iphere:real_listening_port_here
```
It will look like:

```
rdr pass on interface-here proto tcp to port requested_port_porthere -> iphere port real_listening_port_here
```

IPFW can be used for the same purpose.


----------



## angryman1 (Sep 25, 2012)

SirDice said:
			
		

> Maybe you can explain what that rule is supposed to do?



It basically takes all requests made to the node on port 7777 and forwards them to another external server on port 7777.



			
				ecazamir said:
			
		

> The sample pf.conf, located at /usr/src/share/examples/pf/pf.conf contains an example:
> #rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021
> Adjust it to suit your needs.
> 
> ...



This looked like it would really work, but then again every other config I have tried did.

Here's what I end up with ...


```
rdr pass on em0 proto tcp to port 7777 -> X.X.X.X port 7777
rdr pass on em0 proto udp to port 7777 -> X.X.X.X port 7777
```

And TCPDUMP logs which make no sense...


```
00:00:06.936110 aa:bb:ed:bb:bd:80 > cc:dd:4d:7a:66:62, ethertype IPv4 (0x0800), length 60: a.b.c.d.49157 > e.f.g.h.7777: UDP, length 15
00:00:00.000041 cc:dd:4d:7a:66:62 > ee:ff:b4:00:00:01, ethertype IPv4 (0x0800), length 57: a.b.c.d.49157 > e.f.g.h.7777: UDP, length 15
^C249 packets captured
251 packets received by filter
0 packets dropped by kernel
```

So no packets are being dropped, the translation is working perfectly fine (from what I can tell in tcpdump) - and yet it still is not working. Whereas the original IPTABLES server is working (adding x.x.x.x:7777 to your serverlist resolves perfectly) when I add the new FreeBSD/PF/NAT server using rules which _should_ work it simply doesn't resolve.

I'm done traceroutes, pings, and the connectivity between the original dst and the translated dst are perfectly fine - there is no issue there. The firewall is full-open with


```
pass  log  quick inet  from any  to any keep state  label "RULE 0 -- ACCEPT "
```

I'm just clueless now.. kernel settings are changed too..


```
ks3100103# sysctl -a | grep "forwarding"
net.inet.ip.forwarding: 1
net.inet.ip.fastforwarding: 1
net.inet6.ip6.forwarding: 0
```

I must have rebooted around 20 times, reloaded the pf config around 500 times.. so many alterations and it just DOES NOT work.

Any advice? The amount of flexibility I will have using FreeBSD/PF over CentOS/IPTables is insane and yet the most simple rule just will not work.


----------



## ecazamir (Sep 25, 2012)

When you change pf ruleset a reboot is NOT required. 

```
/etc/rc.d/pf reload
```
  should be enough.
Try to do a tcpdump on the external interface (em0) and on the private interface, please put the dumps here, but try to obfuscate less the addresses and the timestamps.
It's enough to obfuscate the public IP and eventually the first half of the MAC address.
The way I see it (from your tcpdump capture), it seems that the real server is connected on the public interface, which is a little bit weird. Why would you want to perform nat/port forwarding on the same side of the router?


----------



## SirDice (Sep 25, 2012)

You can't "bounce off" packets out the same interface as they came in.


----------



## angryman1 (Sep 25, 2012)

ecazamir said:
			
		

> When you change pf ruleset a reboot is NOT required.
> 
> ```
> /etc/rc.d/pf reload
> ...



I'm aware that you don't need to reboot for pf rulesets to take effect. I'm talking about other things outside of pf (rc rules, ipfw possibly interfering, natd, etc)




			
				SirDice said:
			
		

> You can't "bounce off" packets out the same interface as they came in.



Turns out you can  I just did it.

Anyway, I fixed this, it was some weird half-undocumented pre-required rule that needed to go before the RDR rule.


----------



## SirDice (Sep 25, 2012)

```
Redirections cannot reflect packets back through the interface they arrive on,
     they can only be redirected to hosts connected to different interfaces or
     to the firewall itself.
```

Taken from pf.conf(5).


----------



## angryman1 (Sep 25, 2012)

SirDice said:
			
		

> ```
> Redirections cannot reflect packets back through the interface they arrive on,
> they can only be redirected to hosts connected to different interfaces or
> to the firewall itself.
> ...



It must be out dated or wrong, but I won't argue with you  But it sure works, to my surprise.

Thanks for everyone's help! Thread can be closed now.


----------



## kpa (Sep 25, 2012)

Post your solution.


----------



## kisscool-fr (Sep 25, 2012)

SirDice said:
			
		

> You can't "bounce off" packets out the same interface as they came in.



That's true and not. You can't directly achieve this with a simple pf rule. There are workarounds, some cleaner than others and it depends what you want to do. One of them is to have 2 or 3 rules in pf for that, but it can break some other rules. 



			
				angryman1 said:
			
		

> Turns out you can  I just did it.
> 
> Anyway, I fixed this, it was some weird half-undocumented pre-required rule that needed to go before the RDR rule.



I'm also curious how did you do that.


----------

