added pf rule generator

This commit is contained in:
Thomas von Dein
2021-07-02 13:03:33 +02:00
parent a9fb600f4b
commit 7e5c2ad591

183
jaildk
View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
version=1.20 version=1.21
usage_jaildk() { usage_jaildk() {
beg=`tput -T ${TERM:-cons25} md` beg=`tput -T ${TERM:-cons25} md`
@@ -242,34 +242,162 @@ jaildk_build() {
esac esac
} }
jaildk_pf_ruleset() {
# internal helper to [un]install a pf ruleset
conf=$1
mode=$2
anchor=$3
jail=$4
case $mode in
start)
bold "Installing PF rules for jail $jail:"
pfctl -a /jail/$anchor -f $conf -v
;;
status)
bold "PF NAT rules for jail $jail:"
pfctl -a /jail/$anchor -s nat -v
echo
bold "PF rules for jail $jail:"
pfctl -a /jail/$anchor -s rules -v
;;
stop)
bold "Removing PF rules for jail $jail:"
pfctl -a /jail/$anchor -v -F all
;;
restart)
jaildk_pf_ruleset $jail $conf stop $anchor $jail
jaildk_pf_ruleset $jail $conf start $anchor $jail
;;
esac
}
jaildk_pf_map() {
extif=$1
proto=$2
eip=$3
eport=$4
mport=$5
ip=$6
v6=$7
echo "rdr pass on $extif $v6 proto ${proto} from any to ${eip} port ${port} -> ${ip} port ${mport}"
}
jaildk_pf_rule() {
extif=$1
proto=$2
eip=$3
eport=$4
v6=$5
echo "pass in quick on $extif $v6 proto ${eproto} from any to ${eip} port ${eport}"
}
jaildk_rc_pf() { jaildk_rc_pf() {
jail=$1 jail=$1
mode=$2 mode=$2
conf=$j/etc/$jail/pf.conf conf=$j/etc/$jail/pf.conf
ruleset=$j/etc/$jail/pf-ruleset.conf
load-jail-config $jail
if test -n "$rules" -o -n "$maps"; then
# generate a pf.conf based on config variables
echo "# generated pf ruleset for jail, generated on ` date`" > $ruleset
extif=$(netstat -rnfinet | grep default | cut -f4 -w)
fi
if test -n "$ip" -a -n "$maps"; then
# nat and rdr come first
# SAMPLE ruleset
# maps="web ntp kjk"
# map_web_proto="tcp"
# map_web_exposed_port=80
# map_web_mapped_port=8080
# map_web_exposed_ip="123.12.12.3"
# map_web_exposed_ip6="2a01::ff"
# map_ntp_proto="udp"
# map_ntp_exposed_port=123
# map_ntp_mapped_port=1234
# map_ntp_exposed_ip="123.12.12.33"
# map_kjk_proto="tcp"
# map_kjk_exposed_ports="1501 1502 1502" # maped 1:1
# map_kjk_exposed_ip="123.12.12.33"
for map in $maps; do
# slurp in the values for this map
eval _proto=\${map_${map}_proto:-tcp}
eval _eport=\${map_${map}_exposed_port}
eval _mport=\${map_${map}_mapped_port:-${_eport}}
eval _eports=\${map_${map}_exposed_ports}
eval _eip=\${map_${map}_exposed_ip:-$extif}
eval _eip6=\${map_${map}_exposed_ip6:-$extif}
if test -z ${_eport} -o -z ${_eip}; then
echo "Warning: ignoring incomplete map: $map!"
continue
fi
if test -n "${_eport}"; then
if test -z "{_mport}"; then
# map ports 1:1
_mport=${_eport}
fi
echo "# from map $map" >> $ruleset
jaildk_pf_map $extif ${_eproto} ${_eip} ${_eport} ${_mport} ${ip} >> $ruleset
if test -n "${_eip6}" -a -n "$ip6"; then
jaildk_pf_map $extif ${_eproto} ${_eip6} ${_eport} ${_mport} ${ip6} inet6 >> $ruleset
fi
fi
for port in ${_eports}; do
jaildk_pf_map $extif ${_eproto} ${_eip} ${port} ${port} ${ip} >> $ruleset
if test -n "${_eip6}" -a -n "$ip6"; then
jaildk_pf_map $extif ${_eproto} ${_eip6} ${port} ${port} ${ip6} inet6 >> $ruleset
fi
done
done
fi
if test -n "$ip" -a -n "$rules"; then
# rules="open web"
# rule_open="any"
# rule_web_proto="tcp"_
# rule_web_port="80,443"
# pass in quick on $ext proto tcp from any to $extip port 80 keep state
for rule $rules; do
eval _proto=\${rule_${rule}_proto:-tcp}
eval _port=\${rule_${rule}_port}
if test -n "${_port}"; then
echo "# from map $map" >> $ruleset
jaildk_pf_rule $extif ${_proto} ${ip} ${_port} >> $ruleset
else
echo "Warning: incomplete rule: $rule!"
continue
fi
if test -n "${ip6}"; then
jaildk_pf_rule $extif ${_proto} ${ip6} ${_port} inet6 >> $ruleset
fi
done
fi
if test -s $ruleset; then
anchor="$jail/jaildk"
jaildk_pf_ruleset $ruleset $mode $anchor $jail
fi
# FIXME: maybe we use parse_jail_conf() to fetch ip addresses,
# generate a config file containing pf macros, which the user
# needs to include in the jails pf.conf? On the other hand,
# there's not that much duplication in the config. So, maybe not.
if test -f $conf; then if test -f $conf; then
case $mode in anchor="$jail/custom"
start) jaildk_pf_ruleset $conf $mode $anchor $jail
bold "Installing PF rules for jail $jail:"
pfctl -a /jail/$jail -f $conf -v
;;
status)
bold "PF rules for jail $jail:"
pfctl -a /jail/$jail -s rules -v
;;
stop)
bold "Removing PF rules for jail $jail:"
pfctl -a /jail/$jail -v -F all
;;
restart)
jaildk_rc_pf $jail stop
jaildk_rc_pf $jail start
;;
esac
fi fi
} }
@@ -1838,9 +1966,14 @@ usage_vnet() {
echo "You'll also need PF nat rules in order to be able to reach the outside" echo "You'll also need PF nat rules in order to be able to reach the outside"
echo "from the jail or vice versa." echo "from the jail or vice versa."
exit
} }
jaildk_vnet() { jaildk_vnet() {
#
# This is no rc.d subcommand, but a standalone command, because it must
# be executed by jail(8) via exec.created hook.
jail=$1 jail=$1
mode=$2 mode=$2
shift shift
@@ -1863,6 +1996,10 @@ jaildk_vnet() {
load-jail-config $jail load-jail-config $jail
if test -z "$ip" -a -z "$gw"; then
usage_vnet
fi
vnethost="ep${jail}.h" vnethost="ep${jail}.h"
vnetjail="ep${jail}.j" vnetjail="ep${jail}.j"