Solved PF Fails to Load Ruleset with Jails (lo1 interface)

This post is for anyone who may be using a jail, and after you set the jail to run at startup, PF rules are not loading (on the host machine). The odd thing that made me scratch my head is that you can manually start it and everything works; something is uniquely happening at startup that is causing this to fail. I had this problem and figured someone out there might have the same issue. I didn't see any correct solutions for this. Please correct me if I am wrong.

Relevant parts of config files:

/etc/rc.conf:
Code:
...
cloned_interfaces="lo1"
pf_enable="YES"
pflog_enable="YES"
...

/etc/pf.conf:
Code:
########
# defs #
########

ext_if = "vtnet0"
int_if = "lo1"

nat_ip = "1.2.3.4"

localnet = $int_if:network

inet_in_system = "{ 21, 22, 80, 443, 1000 }"

#######
# nat #
#######

nat on $ext_if from $localnet to any -> $nat_ip

#######
# rdr #
#######

# none yet

#########
# rules #
#########

block log all
pass from $localnet to any keep state
pass in on $ext_if proto { udp, tcp } from any to any port $inet_in_system keep state
pass out on $ext_if keep state
pass proto icmp

/etc/jail.conf:
Code:
helios {
        path = "/server/helios";
        host.hostname = "helios";
        host.domainname = "helios.domain.com";

        ip4.addr = "lo1|192.168.99.2/24";

        allow.raw_sockets;
        allow.mount.devfs;
        mount.devfs;
        persist;
        exec.start = "sh /etc/rc";
}

My issue had to do with my lo1 interface either not existing at startup or the network not existing (because jail(8) attaches the alias for the jail at some later time), so the rules that contain lo1 or its network fail to load, which apparently results in a null ruleset to load. You can test if this is the exact issue you are having by just doing pfctl -s rules when it boots up to see the ruleset. This is different than PF not starting.

Aside: if someone here know where the errors would be logged if this was the issue, please tell me. I assume the errors you see if you try to load a bad ruleset (however ambiguous) would be logged somewhere when rc.d tries to start pf.

The fix is to attach an IP for your host to the interface in the rc.conf like this:
/etc/rc.conf:
Code:
...
cloned_interfaces="lo1"
ifconfig_lo1="inet 192.168.99.1 netmask 0xffffff00 broadcast 192.168.99.255 up"
pf_enable="YES"
pflog_enable="YES"
...

This ensures that the network on lo1 is defined before the jail starts, and so the PF ruleset is loaded.

-gns
 
The issue you had was because of this:
Code:
localnet = $int_if:network
This is dynamically done when the rules are loaded. At that point lo1 didn't have an IP address assigned so there's no way to know what network it is attached to. One way to solve it would be to 'hardcode' the network address. The other way is how you solved it (which is also the one I would have used).
 
Back
Top