Understand pf rules for mldonkey in jail

After some hours trying to set up pf to allow access from the Internet to the web page controlling mldonkey, I've finally found a solution. But I don't understand why the rule has to be constructed like that.

mldonkey is in a jail with IP 192.168.1.20, same network as host, FreeBSD 9.1. Jail has an alias to the host network card (re0) that is in a DMZ. I want port 4080 to be available to the Internet.

Code:
# pfctl -vf pf.conf
No ALTQ support in kernel
ALTQ related functions disabled
table <local> { 192.168.1.0/24 }
mldonkey = "192.168.1.20"
mldonkey_web_port = "4080"
mldonkey_tcp_port = "18662"
mldonkey_udp_port = "18666"
sshd_port = "22222"
ext_if = "re0"
set block-policy return
rdr on re0 inet proto tcp [color="DarkOrchid"]from ! (re0)[/color] to (re0) port = 4080 -> 192.168.1.20
block return in log all
pass in quick on lo0 all flags S/SA keep state
pass out quick on lo0 all flags S/SA keep state
pass in proto tcp from any to any port = 22222 flags S/SA keep state
pass in log on re0 inet proto tcp [color="DarkOrchid"]from ! (re0) [/color]to 192.168.1.20 port = 4080 flags S/SA modulate state
pass in log on re0 inet proto udp [color="DarkOrchid"]from ! (re0)[/color] to 192.168.1.20 port = 4080 keep state
pass out all flags S/SA keep state

What I don't understand is the "from !(re0) " expression in both TCP and UDP rules. I took the rule from the calomel webpage. What I had previously tried was:

Code:
pass in proto { tcp, udp } to port 4080 keep state

But it didn't work. So, why do I have to negate the origin re0? Although it didn't work for me, the above rule was present, supposedly working, in pf.conf files of other people.
 
Works for me.

Try to remove redirect rule (aliases are on one interface, hence no need to redirect). 'modulate state' is for outgoing TCP packets, and better use 'set skip on lo0'.
 
Remove modulate state all together. You never should use it under normal operation. It is reserved for cases when you're under a spoofed TCP SYN flood attack and turning it on then might be a life saver.

It's better to qualify the interface in the rules like is done here with
Code:
pass in log on re0 ...
using rules without interface qualification might throw a nasty surprise when they match traffic on unintended interfaces.
 
Thank you for your suggestions!

The rule that "made it" was actually this:

Code:
rdr pass on $ext_if proto tcp from any to any port $mldonkey_web_port -> $mldonkey

As this might be useful for someone, I leave the other rules concerning mldonkey:
Code:
rdr pass on $ext_if proto tcp from any to any port $mldonkey_tcp_port -> $mldonkey
rdr pass on $ext_if proto udp from any to any port $mldonkey_udp_port -> $mldonkey
rdr pass on $ext_if proto tcp from any to any port $overnet_port -> $mldonkey
rdr pass on $ext_if proto udp from any to any port $kademlia_port -> $mldonkey
rdr pass on $ext_if proto tcp from any to any port $bt_dht_port -> $mldonkey
rdr pass on $ext_if proto udp from any to any port $directconnect_port -> $mldonkey

(I know I could make a list for the ports and have only one statement)

For some udp ports, additional pass in rules were necessary:
Code:
pass in on re0 proto udp to port $kademlia_port keep state
pass in on re0 proto udp to port $bt_dht_port keep state
 
Back
Top