#!/bin/sh # Allow bhyve test VM egress by adding a PF include file. # This is opt-in and idempotent; it does not replace the main ruleset. set -eu PF_CONF="/etc/pf.conf" PF_BHYVE_INCLUDE="/etc/pf.bhyve.conf" require_root() { if [ "$(id -u)" -ne 0 ]; then echo "ERROR: must run as root" exit 1 fi } detect_ext_if() { if [ -n "${EXT_IF:-}" ]; then echo "$EXT_IF" return fi if command -v route >/dev/null 2>&1; then if out="$(route -n get default 2>/dev/null)"; then iface="$(echo "$out" | awk '/interface:/ { print $2; exit }')" if [ -n "$iface" ]; then echo "$iface" return fi fi fi echo "vtnet0" } ensure_include_line() { line="include \"$PF_BHYVE_INCLUDE\"" if ! grep -Fxq "$line" "$PF_CONF"; then printf '\n%s\n' "$line" >> "$PF_CONF" fi } pf_enabled() { pfctl -s info 2>/dev/null | grep -qi "Status: Enabled" } require_root if [ ! -f "$PF_CONF" ]; then echo "ERROR: missing $PF_CONF" exit 1 fi BHYVE_BRIDGE="${BHYVE_BRIDGE:-bhyve0}" BHYVE_NET="${BHYVE_NET:-10.99.0.0/24}" EXT_IF="$(detect_ext_if)" cat < "$PF_BHYVE_INCLUDE" ext_if = "$EXT_IF" bhyve_if = "$BHYVE_BRIDGE" bhyve_net = "$BHYVE_NET" nat on \$ext_if from \$bhyve_net to any -> (\$ext_if) pass quick on \$bhyve_if inet from \$bhyve_net to any keep state EOF chmod 0644 "$PF_BHYVE_INCLUDE" ensure_include_line pfctl -nf "$PF_CONF" pfctl -f "$PF_CONF" if ! pf_enabled; then pfctl -e fi echo "PF updated for ${BHYVE_NET} on ${BHYVE_BRIDGE} (ext: ${EXT_IF})" echo "Include: ${PF_BHYVE_INCLUDE}"