PF pf needs to be reloaded after jails are started

Hi guys,

I've been running into an issue lately with some of my clients. I am setting up jails with NAT to allow using a single IP address. I have the following simple setup

Code:
set limit { states 1600000, frags 400000, src-nodes 400000 }

SafeHosts="{IP1, IP2, IP3, IP4}"

ext_if="igb0"
jail_if="lo1"

IP_PUB="PUBLICIP"

set skip on { lo0, lo1 }

scrub in all

# NAT all jail traffic
nat pass on $ext_if from 192.168.0.0/24 to any -> $IP_PUB

rdr pass inet proto tcp from $SafeHosts to $ext_if port 8983 -> 192.168.0.2 port 8983

I also have the below in my rc.conf
Code:
cloned_interfaces="lo1"
ipv4_addrs_lo1="192.168.0.1/24"
gateway_enabled="YES"
pf_enable="YES"
iocage_enable="YES"

When I boot my server, the jail with the IP address 192.168.0.2 has full internet access, but I cannot access port 8983 from outside. It will only work when I reload pf.

Any idea what is going on? Maybe I'm missing something?

Thanks
 
Try this instead:
Code:
rdr pass inet proto tcp from $SafeHosts to ($ext_if) port 8983 -> 192.168.0.2 port 8983

Note the difference between $ext_if and ($ext_if).
 
Did you check if the rules file is properly loaded on boot? I use ipfw personally and if a non-standard rules file path is used, it needs to be specified in rc.conf like so: firewall_script=/path/to/ipfw.rules
Maybe when you reload the rules you give the path explicitly (if it is != /etc/pf.conf):
Bash:
# sysrc -A | grep '^pf_'     
pf_enable: NO
pf_flags:
pf_program: /sbin/pfctl
pf_rules: /etc/pf.conf
 
Thank you very much guys,

Try this instead:
Code:
rdr pass inet proto tcp from $SafeHosts to ($ext_if) port 8983 -> 192.168.0.2 port 8983

Note the difference between $ext_if and ($ext_if).

This fixed the issue, I've been using pf for so long and never noticed this before.

One question though, according to the man page

Host name resolution and interface to address translation are done
at ruleset load-time. When the address of an interface (or host
name) changes (under DHCP or PPP, for instance), the ruleset must
be reloaded for the change to be reflected in the kernel. Sur-
rounding the interface name (and optional modifiers) in parentheses
changes this behaviour. When the interface name is surrounded by
parentheses, the rule is automatically updated whenever the inter-
face changes its address. The ruleset does not need to be
reloaded. This is especially useful with nat.

($ext_if) means the IP address of the external interface changed, not the internal interface, any idea why the rules works like this? If rules with parentheses are reloaded whenever an IP address on any interface the documentation needs to be changed right?

Thanks again for solving something that has troubled me for so long
 
Back
Top