libioc icon indicating copy to clipboard operation
libioc copied to clipboard

how to (remember to) reload /etc/pf.conf when (re)starting a jail

Open igalic opened this issue 5 years ago • 3 comments

I declare my jails with ip4_addr=vnet0|dhcp, where the dnsmasq on the host provides IP addresses. My pf.conf uses names rather than IPs, and looks like this:

scrub in all
nat pass on vtnet0 from 192.168.1.1/24 to any -> (vtnet0:0)
rdr on vtnet0 proto tcp from any to vtnet0 port 80 -> webproxy port 80
rdr on vtnet0 proto tcp from any to vtnet0 port 443 -> webproxy port 443
rdr on vtnet0 proto tcp from 192.168.1.1/24 to vtnet0 port 9000 -> webirc port 9000

so i'd need to reload it every time a jail (re)starts, pf needs to be reloaded.

What's the best way to do this?

igalic avatar May 23 '20 18:05 igalic

I'm using prestart/poststart hooks with combination of anchors to add and remove this per jail basis.

urosgruber avatar Jul 27 '20 18:07 urosgruber

Would you mind sharing how, exactly?

igalic avatar Jul 28 '20 19:07 igalic

So first of all some related pf.conf configuration. I'm using a separate lo1 interface to handle all the traffic.

table <jails> persist counters
nat-anchor "jail-nat/*"
rdr-anchor "jail-rdr/*"
pass quick log on lo0 from <jails> to $jail_out  # allow connection from jail to external IP
pass quick on lo1 from <jails> to 172.16.0.1. # DNS for jails

Might be that some lines are missing but I hope you get the idea of how to dynamically handle this.

Poststart hook

  • add current IP to jails table
  • create rule on the anchor (jail interconnection, this example only allow connect to itself)
  • create nat on the anchor (I allow only http and https)
#!/usr/bin/env sh

# -e  If non interactive then exit immediately if a command fails.
# -u  Treat unset variables as an error when substituting.
# -v  Print shell input lines as they are read.
# -x  Print commands and their arguments as they are executed.

set -e

# get current jid
_name=$IOC_ID
_jid=$IOC_JID

_ip=$(echo "$IOC_IP4_ADDR" | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}')
_if=$(echo "$IOC_IP4_ADDR" | cut -d"|" -f1)
_eif="igb0"

# FW
printf "  + Allow outbound access    "
pfctl -t jails -T add $_ip 2>/dev/null
printf "pass on $_if from $_ip to $_ip\n" | pfctl -a "jail/$_name" -f -
echo "nat on $_eif inet proto tcp from $_ip to ! $_ip port "{ http, https }" -> (igb0:0)" | pfctl -a "jail-nat/$_name" -f -

Prestop hook

  • remove IP from jails table
  • remove rules for the anchor
  • remove nat from the anchor
#!/usr/bin/env sh

# -e  If non interactive then exit immediately if a command fails.
# -u  Treat unset variables as an error when substituting.
# -v  Print shell input lines as they are read.
# -x  Print commands and their arguments as they are executed.

set -e

_name=$IOC_ID
_jid=$IOC_JID

_ip=$(echo "$IOC_IP4_ADDR" | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}')
_if=$(echo "$IOC_IP4_ADDR" | cut -d"|" -f1)

# FW
pfctl -t jails -T delete $_ip 2>/dev/null
pfctl -a "jail/$_name" -F rules 2>/dev/null
pfctl -a "jail-nat/$_name" -F nat 2>/dev/null

urosgruber avatar Jul 28 '20 19:07 urosgruber