2020-11-06 20:37:13 +01:00
#!/bin/sh
2021-07-05 14:26:10 +02:00
version=1.22
2020-11-06 20:37:13 +01:00
usage_jaildk() {
beg=`tput -T ${TERM:-cons25} md`
end=`tput -T ${TERM:-cons25} me`
usage=$(cat <<EOF
This is jaildk version $version, a jail management toolkit.
Usage: $0 <command> <mode-args>
${beg}Building Jails:${end}
2020-11-29 16:22:36 +01:00
base -b <name> [-w] - build a new base
build <jail> <mode> [-b <base>] [-v <version>] - install a build chroot of a jail
create - create a new jail from a template
clone -s <src> -d <dst> [-o <v>] [-n <v>] - clone an existing jail or jail version
2020-12-13 14:37:20 +01:00
fetchports [-v <version>] - fetch current port collection
2020-11-06 20:37:13 +01:00
${beg}Installing Jails:${end}
2020-11-29 16:22:36 +01:00
install <jail> <mode> [-r function] - install a jail (prepare mounts, devfs etc)
2020-11-29 18:46:50 +01:00
uninstall <jail> [-w] - uninstall a jail
remove <jail> - remove a jail or a jail version
2020-12-14 20:18:20 +01:00
reinstall <jail> [-b <base>] [-v <version>] - stop, remove, install and start a jail, if
-b and/or -v is set, update the jail config
2020-11-06 20:37:13 +01:00
${beg}Maintaining Jails:${end}
2020-11-29 18:46:50 +01:00
start <jail> - start a jail
stop <jail> - stop a jail
restart <jail> - restart a jail
2021-06-30 15:15:28 +02:00
status [<jail>] [-v] - display status of jails or <jail>
2020-11-29 18:46:50 +01:00
rc <jail> <mode> [-r <rc.d script>] - execute an rc-script inside a jail
2020-12-01 18:40:32 +01:00
ipfw <jail> <mode> - add or remove ipfw rules
2020-11-06 20:37:13 +01:00
${beg}Managing Jails:${end}
2020-11-29 18:46:50 +01:00
login <jail> [<user>] - login into a jail
blogin <jail> - chroot into a build jail
2020-11-06 20:37:13 +01:00
2020-11-28 20:41:05 +01:00
${beg}Transferring Jails:${end}
2020-11-29 18:46:50 +01:00
freeze <jail> [-a -b -v <version>] - freeze (build an image of) a jail
thaw <image> - thaw (install) an image of a jail
2020-11-28 20:41:05 +01:00
2020-11-29 18:46:50 +01:00
${beg}Getting help:${end}
help <command> - request help on <command>
2020-11-06 20:37:13 +01:00
EOF
)
2020-11-29 18:46:50 +01:00
echo "$usage"
exit 1
}
usage_help() {
command=$1
usage="usage_${command}"
if ! type "$usage" > /dev/null 2>&1; then
die "Unknown command $command!"
else
$usage
fi
2020-11-06 20:37:13 +01:00
}
ex() {
echo $rcscript - $*
$*
}
err () {
2020-11-27 19:08:57 +01:00
echo "$@" >&2
2020-11-06 20:37:13 +01:00
}
bold() {
2021-01-25 00:22:54 +01:00
if [ -z "$NO_BOLD" ]; then
if [ -z "$BOLD_ON" ]; then
BOLD_ON=`tput -T ${TERM:-cons25} md`
export BOLD_ON
BOLD_OFF=`tput -T ${TERM:-cons25} me`
export BOLD_OFF
fi
echo -n "$BOLD_ON"
echo "$@"
echo -n "$BOLD_OFF"
else
echo "$@"
2020-11-06 20:37:13 +01:00
fi
}
2020-11-29 18:46:50 +01:00
fin() {
echo "$*" >&2
exit
}
2020-11-06 20:37:13 +01:00
die() {
bold "$*" >&2
exit 1
}
load-jail-config() {
2021-07-05 14:26:10 +02:00
local jail=$1
2020-11-06 20:37:13 +01:00
if test -d $j/etc/$jail; then
2021-07-05 14:26:10 +02:00
# everything inside gets global
2020-11-06 20:37:13 +01:00
. $j/etc/$jail/jail.conf
else
die "Jail $jail is not configured!"
fi
}
die_if_not_exist() {
2021-07-05 14:26:10 +02:00
local jail which jailversion
2020-11-06 20:37:13 +01:00
jail=$1
which=$2
2020-12-13 14:49:39 +01:00
jailversion=$3
2020-11-06 20:37:13 +01:00
if test -z "$which"; then
which="Jail"
fi
2020-11-28 20:41:05 +01:00
2020-11-06 20:37:13 +01:00
if ! test -d $j/etc/$jail; then
die "$which $jail doesn't exist!"
fi
2020-11-28 20:41:05 +01:00
2020-12-13 14:49:39 +01:00
if test -n "$jailversion"; then
if ! test -d $j/etc/$jail/etc-$jailversion; then
die "$which $jail $jailversion doesn't exist!"
2020-11-28 20:41:05 +01:00
fi
fi
2020-11-06 20:37:13 +01:00
}
2020-12-03 19:01:05 +01:00
parse_jail_conf() {
#
# just in case we want or have to fetch variables out of
# /etc/jail.conf, this is the way to go. Call it like this:
#
# ip=`parse_jail_conf $jail ip4.addr`
#
# Output may be empty, so check before using. Multiple variables
# of the same type (like multiple ip addresses) will be returned
# comma separated.
2021-07-05 14:26:10 +02:00
local jail=$1
local search=$2
local JAIL list
2020-12-03 19:01:05 +01:00
# fetch 20 lines after "^$jail {", ignore comments
egrep -A20 "^$jail" jail.conf | egrep -v "^ *#" | \
# turn each line into an evaluable shell expression \
sed -e 's/ *{//g' -e 's/}//g' -e 's/ *= */=/g' -e 's/;$//' | \
# ignore empty lines \
egrep -v '^$' | while read LINE; do
if echo "$LINE" | egrep -q "="; then
case $JAIL in
$jail)
var=`echo "$LINE" | cut -d= -f1`
opt=`echo "$LINE" | cut -d= -f2 | sed -e 's/^"//' -e 's/"$//'`
case $var in
$search)
if test -z "$list"; then
list="$opt"
else
list="$list,$opt"
fi
;;
esac
;;
*)
echo $list
return
;;
esac
else
case $LINE in
\*) JAIL=any;;
*) JAIL="$LINE";;
esac
fi
done
}
2020-11-29 16:22:36 +01:00
usage_build() {
2020-11-29 18:46:50 +01:00
fin "Usage: $0 build <jail> [<start|stop|status>] [-b <base>] [-v <version>]
Mount <jail> to $j/build read-writable for maintenance. Options:
-b <base> Use specified <base>. default: use configured base.
-v <version> Mount <version> of <jail>.
<mode> One of start, stop or status. default: start."
2020-11-29 16:22:36 +01:00
}
2020-11-06 20:37:13 +01:00
jaildk_build() {
2021-07-05 14:26:10 +02:00
local jail mode BASE VERSION base version
2020-11-06 20:37:13 +01:00
jail=$1
mode=$2
2020-11-29 16:22:36 +01:00
shift
shift
2020-12-13 14:58:54 +01:00
BASE=''
2020-12-13 14:54:16 +01:00
VERSION=''
2020-11-06 20:37:13 +01:00
2020-11-29 16:22:36 +01:00
while getopts "b:v:" arg; do
case $arg in
2020-12-13 14:58:54 +01:00
b) BASE=${OPTARG};;
2020-12-13 14:54:16 +01:00
v) VERSION=${OPTARG};;
2020-11-29 16:22:36 +01:00
*) usage_build;;
esac
done
2020-11-27 08:52:58 +01:00
2020-12-13 14:24:14 +01:00
if test -z "$jail"; then
usage_build
fi
2020-11-06 20:37:13 +01:00
if test -z "$mode"; then
2020-11-29 18:46:50 +01:00
mode=start
2020-11-06 20:37:13 +01:00
fi
2020-12-13 14:54:16 +01:00
die_if_not_exist $jail $VERSION
2020-11-29 16:22:36 +01:00
load-jail-config $jail
2020-12-13 14:54:16 +01:00
if test -n "$VERSION"; then
# overridden with -v
version=$VERSION
fi
2020-12-13 14:58:54 +01:00
if test -n "$BASE"; then
# dito
base=$BASE
fi
2020-11-27 23:21:34 +01:00
if test -n "$buildbase"; then
2020-11-27 19:08:57 +01:00
base="$buildbase"
2020-11-27 08:52:58 +01:00
elif test -z "$base"; then
2020-11-29 16:22:36 +01:00
# nothing configured, use default: latest
2020-11-06 20:37:13 +01:00
base=`ls $j/base | tail -1`
fi
2020-11-28 11:51:38 +01:00
# install the jail to build/
2020-11-29 16:22:36 +01:00
jaildk_install $jail $mode -r all -w -b $base -v $version
2020-11-28 11:18:39 +01:00
2020-11-28 11:51:38 +01:00
case $mode in
start)
# make it usable
ex chroot $j/build/$jail /etc/rc.d/ldconfig onestart
2020-11-28 12:35:48 +01:00
ex mkdir -p $j/build/$jail/usr/local/db
2020-11-28 11:51:38 +01:00
;;
esac
}
2021-07-05 14:26:10 +02:00
pf_ruleset() {
2021-07-02 13:03:33 +02:00
# internal helper to [un]install a pf ruleset
2021-07-05 14:26:10 +02:00
local conf mode anchor jail
conf=$1
mode=$2
anchor=$3
jail=$4
2021-07-02 13:03:33 +02:00
2021-07-05 14:26:10 +02:00
case $mode in
2021-07-02 13:03:33 +02:00
start)
2021-07-05 14:26:10 +02:00
bold "Installing PF rules for jail $jail:"
pfctl -a /jail/$anchor -f $conf -v
2021-07-02 13:03:33 +02:00
;;
status)
2021-07-05 14:26:10 +02:00
bold "PF NAT rules for jail $jail:"
pfctl -a /jail/$anchor -s nat -v
2021-07-02 13:03:33 +02:00
echo
2021-07-05 14:26:10 +02:00
bold "PF rules for jail $jail:"
pfctl -a /jail/$anchor -s rules -v
2021-07-02 13:03:33 +02:00
;;
stop)
2021-07-05 14:26:10 +02:00
bold "Removing PF rules for jail $jail:"
pfctl -a /jail/$anchor -v -F all
2021-07-02 13:03:33 +02:00
;;
restart)
2021-07-05 14:26:10 +02:00
pf_ruleset $conf stop $anchor $jail
pf_ruleset $conf start $anchor $jail
2021-07-02 13:03:33 +02:00
;;
esac
}
2021-07-05 14:26:10 +02:00
pf_map() {
local extif proto eip eport mport ip v6
2021-07-02 13:03:33 +02:00
extif=$1
proto=$2
eip=$3
eport=$4
mport=$5
ip=$6
v6=$7
2021-07-03 16:32:19 +02:00
echo "rdr pass on $extif $v6 proto ${proto} from any to ${eip} port ${eport} -> ${ip} port ${mport}"
2021-07-02 13:03:33 +02:00
}
2021-07-05 14:26:10 +02:00
pf_rule() {
local extif proto eip eport v6
2021-07-02 13:03:33 +02:00
extif=$1
proto=$2
eip=$3
eport=$4
v6=$5
2021-07-03 16:32:19 +02:00
echo "pass in quick on $extif $v6 proto ${proto} from any to ${eip} port ${eport}"
2021-07-02 13:03:33 +02:00
}
2021-07-05 14:26:10 +02:00
pf_nat() {
local extif srcip dstip v6
2021-07-03 16:32:19 +02:00
extif=$1
srcip=$2
dstip=$3
v6=$4
echo "nat on $extif $v6 from $srcip to any -> $dstip"
}
2021-07-02 13:03:33 +02:00
2021-07-05 14:26:10 +02:00
rc_pf() {
local jail mode conf ruleset extif ipv4 anchor _proto _eport _mport _eports _eip
2020-12-03 19:01:05 +01:00
jail=$1
mode=$2
conf=$j/etc/$jail/pf.conf
2021-07-02 13:03:33 +02:00
ruleset=$j/etc/$jail/pf-ruleset.conf
load-jail-config $jail
2021-07-02 19:46:56 +02:00
# TODO:
# - put this into a separate function
# - clean up if generation of pf-ruleset.conf fails somehow
# - make a syntax check of the generated rules, if possible
case $mode in
start|restart)
2021-07-03 16:32:19 +02:00
if test -n "$masq_ip" -o -n "$rules" -o -n "$maps"; then
2021-07-02 19:46:56 +02:00
# 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)
2021-07-02 13:03:33 +02:00
fi
2021-07-03 16:32:19 +02:00
# we need to make sure the ip address doesn't contain a mask which
# is not required for these rules
2021-07-05 14:26:10 +02:00
ipv4=$(dirname $ip)
2021-07-03 16:32:19 +02:00
2021-07-05 14:26:10 +02:00
if test -n "$ipv4" -a -n "$maps"; then
2021-07-02 19:46:56 +02:00
# 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_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}
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
2021-07-05 14:26:10 +02:00
pf_map $extif ${_proto} ${_eip} ${_eport} ${_mport} ${ip} >> $ruleset
2021-07-02 19:46:56 +02:00
fi
for port in ${_eports}; do
2021-07-05 14:26:10 +02:00
pf_map $extif ${_proto} ${_eip} ${port} ${port} ${ip} >> $ruleset
2021-07-02 19:46:56 +02:00
done
done
2021-07-02 13:03:33 +02:00
fi
2021-07-03 16:32:19 +02:00
# masq_ip="123.12.12.33"
2021-07-05 14:26:10 +02:00
if test -n "$ipv4" -a -n "${masq_ip}"; then
pf_nat $extif $ipv4 ${masq_ip} >> $ruleset
2021-07-03 16:32:19 +02:00
fi
2021-07-05 14:26:10 +02:00
if test -n "$ipv4" -a -n "$rules"; then
2021-07-02 19:46:56 +02:00
# rules="open web"
2021-07-03 20:35:05 +02:00
# only required for ipv6, ipv4 is already opened with exposed ports
2021-07-02 19:46:56 +02:00
# rule_open="any"
2021-07-03 20:35:05 +02:00
# rule_web_proto="tcp"
2021-07-02 19:46:56 +02:00
# rule_web_port="80,443"
2021-07-03 16:32:19 +02:00
for rule in $rules; do
2021-07-02 19:46:56 +02:00
eval _proto=\${rule_${rule}_proto:-tcp}
2021-07-05 14:26:10 +02:00
eval _eport=\${rule_${rule}_port}
2021-07-02 19:46:56 +02:00
if test -n "${_port}"; then
2021-07-03 20:35:05 +02:00
if test -n "${ip6}"; then
echo "# from map $map" >> $ruleset
2021-07-05 14:26:10 +02:00
pf_rule $extif ${_proto} ${ip6} ${_eport} inet6 >> $ruleset
2021-07-03 20:35:05 +02:00
fi
2021-07-02 19:46:56 +02:00
else
echo "Warning: incomplete rule: $rule!"
continue
fi
done
2021-07-02 13:03:33 +02:00
fi
2021-07-02 19:46:56 +02:00
;;
esac
2021-07-02 13:03:33 +02:00
if test -s $ruleset; then
2021-07-03 16:32:19 +02:00
anchor="${jail}-jaildk"
2021-07-05 14:26:10 +02:00
pf_ruleset $ruleset $mode $anchor $jail
2021-07-02 13:03:33 +02:00
fi
2020-12-03 19:01:05 +01:00
2021-07-03 16:32:19 +02:00
if test -s $conf; then
anchor="${jail}-custom"
2021-07-05 14:26:10 +02:00
pf_ruleset $conf $mode $anchor $jail
2020-12-03 19:01:05 +01:00
fi
}
2021-07-05 14:26:10 +02:00
rc_mtree() {
local jail mode base version rw conf
2020-11-28 12:26:24 +01:00
jail=$1
mode=$2
base=$3
version=$4
rw=$5
2020-11-29 18:46:50 +01:00
rcscript=mtree
2020-11-28 12:26:24 +01:00
2021-07-05 14:26:10 +02:00
conf=$j/etc/$jail/$rcscript.conf
if test -s $conf; then
case mode in
start|restart)
if test -n "$rw"; then
run=$j/build/$jail/
else
run=$j/run/$jail/
fi
ex mtree -p $run -Ue -f $j/etc/$jail/mtree.conf | grep -v "extra:"
;;
esac
2020-11-28 12:26:24 +01:00
fi
}
2021-07-05 14:26:10 +02:00
rc_rcoff() {
2020-11-28 11:51:38 +01:00
# avoid starting services inside the build chroot
2021-07-05 14:26:10 +02:00
# + rc_rcoff db start 12.1-RELEASE-p10 20201026
local jail mode base VERSION BASE rw
2020-11-28 11:51:38 +01:00
jail=$1
mode=$2
2020-11-28 12:26:24 +01:00
BASE=$3
VERSION=$4
rw=$5
2020-11-28 11:51:38 +01:00
rcscript=rcoff
if test -n "$rw"; then
# not required in run mode
case $mode in
start)
2020-11-28 11:59:19 +01:00
if mount | egrep -q "rcoff.*build/$jail"; then
bold "union mount $j/build/jail/etc already mounted"
else
if ! test -d $j/etc/rcoff; then
# in order to be backwards compatible to older jaildk
# create the rcoff directory on the fly
2020-11-28 12:36:49 +01:00
mkdir -p $j/etc/rcoff
2020-11-28 11:59:19 +01:00
( echo "#!/bin/sh"
echo 'echo "$0 disabled in build chroot!"' ) > $j/etc/rcoff/rc
fi
ex mount -t unionfs $j/etc/rcoff $j/build/$jail/etc
2020-11-28 11:51:38 +01:00
fi
;;
stop)
# might fail if executed on a yet not union'ed etc
if mount | egrep -q "rcoff.*build/$jail"; then
ex umount $j/build/$jail/etc
fi
;;
esac
fi
2020-11-06 20:37:13 +01:00
}
2021-07-05 14:26:10 +02:00
rc_ports() {
local jail mode BASE VERSION rw
2020-11-27 08:52:58 +01:00
jail=$1
mode=$2
2020-11-28 12:26:24 +01:00
BASE=$3
VERSION=$4
rw=$5
2020-11-27 08:52:58 +01:00
rcscript=ports
load-jail-config $jail
2020-12-13 14:37:20 +01:00
if test -z "$ports"; then
# ports not configured, abort
return
fi
if ! test -d "$j/ports/$VERSION"; then
die "Ports tree $j/ports/$VERSION doesn't exist yet. Consider creating it with 'jaildk fetchports [-v <version>]'"
2020-11-27 19:08:57 +01:00
fi
2020-11-27 08:52:58 +01:00
if test -n "$buildbase" -a -n "$rw"; then
# we only support ports if a buildbase is configured
case $mode in
start)
if mount -v | grep -q " $j/build/$jail/usr/ports "; then
bold "$j/build/$jail/usr/ports already mounted!"
else
ex mount -t nullfs -o rw $j/ports/$version $j/build/$jail/usr/ports
fi
;;
stop)
if mount -v | grep -q " $j/build/$jail/usr/ports "; then
ex umount $j/build/$jail/usr/ports
else
bold "$j/build/$jail/usr/ports not mounted!"
fi
;;
esac
fi
}
2021-07-05 14:26:10 +02:00
rc_mount() {
local jail mode BASE VERSION rw conf run base version \
src dest fs opts size perm source
2020-11-06 20:37:13 +01:00
jail=$1
mode=$2
2020-11-28 12:26:24 +01:00
BASE=$3
VERSION=$4
rw=$5
2020-11-06 20:37:13 +01:00
rcscript=mount
load-jail-config $jail
conf=$j/etc/$jail/$rcscript.conf
if ! test -e "$conf"; then
return
fi
if test -n "$rw"; then
run=$j/build
if test -n "$BASE"; then
base=$BASE
fi
if test -n "$VERSION"; then
version=$VERSION
fi
else
run=$j/run
fi
die_if_not_exist $jail
# parse the config and (u)mount
case $mode in
stop)
tail -r $conf | grep -v "#"
;;
*)
grep -v "#" $conf
;;
esac | while read LINE; do
# This command expands variables and performs field-splitting:
set -- $(eval echo \""$LINE"\")
# Skip empty lines:
case "$1" in
"") continue ;;
esac
src=$1
dest=$2
fs=$3
opts=$4
size=$5
perm=$6
if test -n "$rw"; then
2020-11-25 11:09:10 +01:00
if ! echo $src | grep -q base/; then
opts=`echo "$opts" | sed 's/ro/rw/g'`
fi
2020-11-06 20:37:13 +01:00
fi
case $mode in
start)
if mount -v | grep " $run/$dest " > /dev/null ; then
bold "$run/$dest already mounted!"
else
case $fs in
mfs)
ex mdmfs -o $opts -s $size -p $perm md $run/$dest
;;
2021-06-25 07:52:03 +02:00
nullfs|unionfs)
2020-11-06 20:37:13 +01:00
source=$j/$src
if echo $src | egrep -q "^/"; then
source=$src
fi
2020-11-27 19:08:57 +01:00
if ! test -d "$source"; then
die "Source dir $source doesn't exist!"
fi
if ! test -d "$run/$dest"; then
die "Dest dir $run/$dest doesn't exist!"
fi
2020-11-06 20:37:13 +01:00
ex mount -t $fs -o $opts $source $run/$dest
;;
devfs)
ex mount -t devfs dev $run/$dest
;;
*)
bold "unknown filesystem type $fs!"
;;
esac
fi
;;
stop)
if mount -v | grep " $run/$dest " > /dev/null ; then
ex umount $run/$dest
if mount -v | grep " $run/$dest " > /dev/null ; then
# still mounted! forcing
ex umount -f $run/$dest
fi
else
bold "$run/$dest not mounted!"
fi
;;
status)
if mount -v | grep " $run/$dest " > /dev/null ; then
echo "$run/$dest mounted"
else
bold "$run/$dest not mounted"
fi
;;
*)
bold "Usage: $0 install <jail> mount {start|stop|status|restart}"
;;
esac
done
}
2020-12-01 18:40:32 +01:00
2020-11-29 16:22:36 +01:00
usage_install() {
2020-11-29 18:46:50 +01:00
fin "Usage: $0 install <jail> [<mode>] [-r rc-function]
2020-11-29 16:22:36 +01:00
Install <jail> according to its config. Options:
<mode> Mode can either be start, stop or status. default: start
-r <function> Only execute function with <mode> parameter. default: all.
Available rc.d-scripts: $RCSCRIPTS_START"
2020-11-06 20:37:13 +01:00
}
jaildk_install() {
2021-07-05 14:26:10 +02:00
local jail mode rcd rw base version rcscripts type
2020-11-06 20:37:13 +01:00
jail=$1
2020-11-29 16:22:36 +01:00
mode=$2
shift
shift
rcd=''
2020-11-06 20:37:13 +01:00
2020-11-29 16:22:36 +01:00
# options -b -w -v are undocumented, used by jaildk_build() only
rw=''
base=''
version=''
2020-11-29 18:46:50 +01:00
while getopts "r:b:v:w" arg; do
2020-11-29 16:22:36 +01:00
case $arg in
w) rw=1;;
b) base=${OPTARG};;
v) version=${OPTARG};;
r) rcd=${OPTARG};;
2020-11-29 19:03:57 +01:00
*) usage_install;;
2020-11-29 16:22:36 +01:00
esac
done
2020-11-06 20:37:13 +01:00
if test -z "$jail"; then
2020-11-29 16:22:36 +01:00
usage_install
2020-11-06 20:37:13 +01:00
fi
2020-11-29 16:22:36 +01:00
if test -z "$mode"; then
2020-11-06 20:37:13 +01:00
mode=start
fi
2020-11-29 16:22:36 +01:00
if test -z "$rcd"; then
# default just install everything
rcd=all
2020-11-06 20:37:13 +01:00
fi
2020-11-29 16:22:36 +01:00
case $mode in
start|stop|restart|status) :;;
*) usage_install;;
esac
2020-11-06 20:37:13 +01:00
die_if_not_exist $jail
if test "$rcd" = "all"; then
2020-12-13 14:43:18 +01:00
if test -n "$rw"; then
case $mode in
start) rcscripts="$RW_RCSCRIPTS_START";;
stop) rcscripts="$RW_RCSCRIPTS_STOP";;
esac
else
case $mode in
start) rcscripts="$RCSCRIPTS_START";;
stop) rcscripts="$RCSCRIPTS_STOP";;
esac
fi
2020-11-06 20:37:13 +01:00
else
2021-07-05 14:26:10 +02:00
rcscripts="rc_${rcd}"
2020-11-06 20:37:13 +01:00
if ! type "$rcscripts" > /dev/null 2>&1; then
die "rc function $rcd doesn't exist!"
fi
fi
2021-01-28 20:18:35 +01:00
type="jail"
if test -n "$rw"; then
type="build chroot"
fi
2020-11-06 20:37:13 +01:00
case $mode in
start)
2021-01-28 20:18:35 +01:00
bold "Installing $type $jail"
2020-11-06 20:37:13 +01:00
;;
stop)
2021-01-28 20:18:35 +01:00
bold "Unstalling $type $jail"
2020-11-06 20:37:13 +01:00
;;
esac
2020-11-26 22:25:45 +01:00
2020-11-06 20:37:13 +01:00
for rcscript in $rcscripts; do
2020-11-28 12:26:24 +01:00
$rcscript $jail $mode $base $version $rw || exit 1
2020-11-06 20:37:13 +01:00
done
}
2020-11-29 18:46:50 +01:00
usage_uninstall() {
fin "Usage: $0 uninstall <jail> [-w]
Uninstall <jail>. Options:
2021-01-28 20:18:35 +01:00
-w Uninstall writable build chroot.
-a Uninstall jail and build chroot."
2020-11-29 18:46:50 +01:00
}
2020-11-06 20:37:13 +01:00
jaildk_uninstall() {
# wrapper around _install
2021-07-05 14:26:10 +02:00
local jail mode base version all rw
2020-11-06 20:37:13 +01:00
jail=$1
2020-11-29 18:46:50 +01:00
shift
rw=''
2021-01-28 20:18:35 +01:00
all=''
base=''
version=''
2020-11-29 18:46:50 +01:00
2021-01-28 20:18:35 +01:00
while getopts "wa" arg; do
2020-11-29 18:46:50 +01:00
case $arg in
2021-01-28 20:00:33 +01:00
w) rw="-w";;
2021-01-28 20:18:35 +01:00
a) all=1; rw="-w";;
2020-11-29 18:46:50 +01:00
*) usage_uninstall;;
esac
done
2020-11-06 20:37:13 +01:00
if test -z "$jail"; then
2020-11-29 18:46:50 +01:00
usage_uninstall
2020-11-06 20:37:13 +01:00
fi
die_if_not_exist $jail
if jls | egrep -q "${jail}"; then
die "Jail $jail($version) is still running, stop it before removing!"
fi
2021-01-28 20:18:35 +01:00
if test -n "$rw"; then
# we need to find out base and version of actually
# mounted jail, but cannot just use the jail config
# since the user might have mounted another version
base=$(mount | egrep "/base/.*/$jail " | cut -d' ' -f1 | sed 's|.*/||')
version=$(mount | egrep "/appl/.*/$jail/" | cut -d' ' -f1 | sed 's/.*\-//')
fi
if test -z "$base"; then
# no base no umount!
rw=''
all=''
fi
if test -n "$all"; then
jaildk_install $jail stop -r all
jaildk_install $jail stop -r all -b $base -v $version -w
else
jaildk_install $jail stop -r all -b $base -v $version $rw
fi
2020-11-29 16:22:36 +01:00
}
usage_base() {
2021-06-26 20:31:02 +02:00
fin "Usage: $0 base [-f] -b <basename|basedir> [-w]
2020-11-29 18:46:50 +01:00
Build a base directory from bsd install media. Options:
2020-11-29 16:22:36 +01:00
-b <name> <name> can be the name of a base (e.g. 12.2-RELEASE)
or a directory where it shall be created
-w Create a writable base, including compiler and other
build stuff. Use this if you want to use the ports
2021-06-26 20:31:02 +02:00
collection.
-f force mode, remove any old dist files.
"
2020-11-06 20:37:13 +01:00
}
jaildk_base() {
2021-07-05 14:26:10 +02:00
local jail mode base force removelist basedir clean file rw
2020-11-29 16:22:36 +01:00
base=""
2021-06-26 20:31:02 +02:00
force=""
2020-11-29 16:22:36 +01:00
rw=""
2021-06-26 20:31:02 +02:00
while getopts "b:wf" arg; do
2020-11-29 16:22:36 +01:00
case $arg in
w) rw=1;;
b) base=${OPTARG};;
2021-06-26 20:31:02 +02:00
f) force=1;;
2020-11-29 16:22:36 +01:00
*) usage_base;;
esac
done
2020-11-27 08:52:58 +01:00
if test -z "$base"; then
2020-11-29 16:22:36 +01:00
usage_base
2020-11-06 20:37:13 +01:00
fi
removelist="tests
usr/bin/objdump
usr/bin/llvm-profdata
usr/bin/ranlib
usr/bin/ar
usr/bin/as
usr/bin/llvm-tblgen
usr/bin/llvm-symbolizer
usr/bin/llvm-cov
usr/bin/llvm-objdump
usr/bin/ld.lld
usr/bin/lldb
usr/bin/cpp
usr/bin/clang-cpp
usr/bin/clang++
usr/bin/clang
usr/bin/cc
usr/bin/c++
usr/bin/lex
usr/bin/lex++
usr/bin/flex
usr/bin/flex++
usr/bin/telnet
usr/bin/kadmin
usr/bin/kcc
usr/bin/kdestroy
usr/bin/kdump
usr/bin/keylogin
usr/bin/keylogout
usr/bin/kf
usr/bin/kgetcred
usr/bin/kinit
usr/bin/klist
usr/bin/kpasswd
usr/bin/krb5-config
usr/bin/ksu
usr/bin/kswitch
usr/bin/ktrace
usr/bin/ktrdump
usr/bin/finger
usr/bin/crunch*
usr/bin/ibv*
usr/bin/nc
usr/bin/pftp
usr/bin/ssh*
usr/bin/scp
usr/bin/sftp
usr/bin/svn*
usr/bin/yacc
usr/include
usr/lib/*.a
usr/lib32/*.a
usr/share/doc
usr/share/dict
usr/share/examples
usr/share/man
rescue
media
mnt
2020-11-27 23:21:34 +01:00
boot
var/run
var/cache
var/tmp"
2020-11-27 08:52:58 +01:00
if echo "$base" | egrep -vq "^/"; then
basedir=$j/base/$base
else
basedir=$base
2020-11-06 20:37:13 +01:00
fi
if test -d "$basedir"; then
echo "base $basedir already exist!"
exit 1
else
ex mkdir -p $basedir
2021-06-26 20:31:02 +02:00
if test -e /usr/freebsd-dist/MANIFEST; then
clean=''
if test -n "$force"; then
clean=1
else
echo "Found old dist files:"
ls -l /usr/freebsd-dist
2021-06-28 07:34:08 +02:00
echo -n "Want to remove them [nY]? "
2021-06-26 20:31:02 +02:00
read yesno
2021-06-28 07:34:08 +02:00
case $yesno in
y|Y) clean=1;;
*) clean='';;
2021-06-26 20:31:02 +02:00
esac
fi
if test -n "$clean"; then
ex rm -f /usr/freebsd-dist/*
fi
fi
2020-11-29 18:46:50 +01:00
bsdinstall jail $basedir || exit 1
2020-11-06 20:37:13 +01:00
2020-11-27 19:08:57 +01:00
if test -z "$rw"; then
# run base
2020-11-27 08:52:58 +01:00
for file in $removelist; do
ex rm -rf $basedir/$file
done
2020-11-27 19:08:57 +01:00
else
# build base with ports support
2020-11-27 08:52:58 +01:00
ex mkdir -p $basedir/usr/ports
fi
2020-11-27 19:08:57 +01:00
ex mkdir $basedir/home
2020-11-06 20:37:13 +01:00
ex rm -rf $basedir/var/db
ex ln -s /usr/local/db $basedir/var/db
2020-11-27 19:08:57 +01:00
2020-11-27 23:21:34 +01:00
# add some symlinks from /var to /tmp to make pkg work properly
2020-11-28 11:18:39 +01:00
ex rm -rf $basedir/var/tmp $basedir/var/cache $basedir/var/run
ex ln -s /tmp $basedir/var/tmp
ex ln -s /tmp $basedir/var/cache
ex ln -s /tmp $basedir/var/run
2020-11-27 23:21:34 +01:00
2020-11-27 19:08:57 +01:00
if test -n "$rw"; then
echo "You have choosen to create a build base with ports support"
echo -n "Want to fetch the ports collection now [Yn]? "
read yesno
case $yesno in
y|Y|yes|YES)
2020-12-13 14:37:20 +01:00
jaildk_fetchports
2020-11-27 19:08:57 +01:00
;;
esac
fi
2020-11-06 20:37:13 +01:00
fi
}
clone() {
2021-07-05 14:26:10 +02:00
local srcdir dstdir
2020-11-06 20:37:13 +01:00
srcdir=$1
dstdir=$2
if test -d $srcdir; then
if ! test -d $dstdir; then
mkdir -p $dstdir
fi
2020-12-14 15:26:32 +01:00
if test $srcdir = $dstdir; then
echo "$srcdir == $dstdir, ignored"
else
ex cpdup -x $srcdir $dstdir
fi
2020-11-06 20:37:13 +01:00
else
echo "$srcdir doesn't exist, ignored"
fi
}
2020-11-29 16:22:36 +01:00
usage_clone() {
2020-11-29 18:46:50 +01:00
fin "Usage: $0 clone -s <jail> -d <jail> [-o <version>] [-n <version>]
2020-11-29 16:22:36 +01:00
-s <jail> Source jail to clone from
-d <jail> Destionation jail to create from source
-o <version> Old version
-n <version> New version
Hints:
- if no source version has been given, tha latest version will be used.
- if no new version has been given, source version will be used.
- if source and new jail are the same, both versions must be given
and a new version of the same jail will be created (update)"
}
2020-11-06 20:37:13 +01:00
jaildk_clone() {
2021-07-05 14:26:10 +02:00
local src new srcversion newversion update cloneto clonefrom fs srcmount dstmount opts size perm
2020-11-29 16:22:36 +01:00
while getopts "s:d:o:n:" arg; do
case $arg in
o) srcversion=${OPTARG};;
n) newversion=${OPTARG};;
s) src=${OPTARG};;
d) new=${OPTARG};;
*) usage_clone;;
esac
done
2020-11-06 20:37:13 +01:00
if test -z "$new"; then
2020-11-29 16:22:36 +01:00
usage_clone
2020-11-06 20:37:13 +01:00
fi
if test "$src" = "$new"; then
# same jail, expect different versions
if test -z "$newversion" -o -z "$srcversion"; then
die "source and new version required!"
fi
if test "$srcversion" = "$newversion"; then
die "new version must be different from source version!"
fi
update=1
2020-12-14 15:26:32 +01:00
fi
2020-11-06 20:37:13 +01:00
2020-12-14 15:26:32 +01:00
die_if_not_exist $src "Source jail"
load-jail-config $jail
if test -z "$srcversion"; then
srcversion=$version
fi
if test -z "$newversion"; then
newversion=$version
2020-11-06 20:37:13 +01:00
fi
2020-12-14 15:26:32 +01:00
if ! test -d $j/etc/$src/etc-$srcversion; then
die "Version $srcversion of source jail $src doesn't exist!"
fi
2020-11-06 20:37:13 +01:00
2020-12-14 15:26:32 +01:00
if test -e "$j/etc/$src/mount.conf"; then
grep -v "#" $j/etc/$src/mount.conf | while read srcmount dstmount fs opts size perm; do
# we are not automatically interpolating variables here,
# because it's much more easier to replace \$name with the
# jail name than an already resolved $name which might be
# part of the path and cause confusion what to clone and
# what not.
if test -z "$srcmount"; then
continue
fi
2020-11-06 20:37:13 +01:00
2020-12-14 15:26:32 +01:00
cloneto=$(echo "$srcmount" | sed -e "s/\$version/$newversion/g" -e "s/\$name/$new/g")
clonefrom=$(echo "$srcmount" | sed -e "s/\$version/$srcversion/g" -e "s/\$name/$src/g")
case $fs in
nullfs)
if ! echo "$srcmount" | egrep -q "^/"; then
# only clone mounts relative to $j, which are
# either versioned or have the src jail name
# in it
if echo "$srcmount" | egrep -q '\$version|\$name'; then
# srcversion versioned nullfs mount at $j/
clone $j/$clonefrom $j/$cloneto
fi
fi
;;
esac
done
else
die "Error: $j/etc/$src/mount.conf doesn't exist, cannot clone!"
fi
if test -z "$update"; then
echo "Copying configs"
ex cp -pRp $j/etc/$src/*.conf $j/etc/$new/
2020-11-06 20:37:13 +01:00
echo "Creating $j/etc/$src/jail.conf"
cat $j/etc/$src/jail.conf | egrep -v "^(name|version)=" > $j/etc/$new/jail.conf
(echo "name=$new"; echo "version=$newversion") >> $j/etc/$new/jail.conf
echo "Creating run and build dirs"
ex mkdir -p $j/run/$new
ex mkdir -p $j/build/$new
fi
echo "DONE."
if test -z "$update"; then
if ! egrep -q "^$new" /etc/jail.conf; then
bold "Consider adding the jail $new to /etc/jail.conf!"
echo
fi
bold "To mount the build chroot of the new jail, execute:"
echo "jaildk build $new start"
echo
bold "To login into the build chroot"
echo "jaildk blogin $new"
echo
bold "To mount the production chroot of the new jail, execute:"
echo "jaildk install $new"
echo
bold "To login into the build chroot"
echo "jaildk login $new"
echo
bold "To start the jail, execute:"
echo "jaildk start $new"
echo
else
. $j/etc/$src/jail.conf
2021-07-05 14:26:10 +02:00
# FIXME: possibly not needed! see comment in jaildk_create()
# jail=$new
2020-11-06 20:37:13 +01:00
bold "To mount the build chroot of the new jail, execute:"
2020-12-14 15:26:32 +01:00
echo "jaildk build $new start -b $base -v $newversion"
2020-11-06 20:37:13 +01:00
fi
}
2020-11-29 16:22:36 +01:00
usage_create() {
2020-11-29 18:46:50 +01:00
fin "Usage: $0 create <jail>
Create a new jail from template."
2020-11-29 16:22:36 +01:00
}
2020-11-06 20:37:13 +01:00
jaildk_create() {
2021-07-05 14:26:10 +02:00
local jail newjail src srcversion newversion jailhostname
2020-11-06 20:37:13 +01:00
jail=$1
2020-11-30 22:22:36 +01:00
# $jail gets overwritten in jaildk_clone or some subcall to .template :-( ...
2020-11-29 22:18:34 +01:00
newjail=$jail
2020-11-06 20:37:13 +01:00
src=.template
if test -z "$jail"; then
2020-11-29 16:22:36 +01:00
usage_create
2020-11-06 20:37:13 +01:00
fi
. $j/etc/$src/jail.conf
srcversion=$version
newversion=`date +%Y%m%d`
mkdir -p $j/etc/$jail
2020-11-29 22:18:34 +01:00
2020-11-29 16:22:36 +01:00
jaildk_clone -s $src -d $jail -o $srcversion -n $newversion
2020-11-29 22:18:34 +01:00
# some perl magic to extract the hostname (if any) from /etc/jail.conf - and write it into the jails rc.conf
jailhostname=$(cat /etc/jail.conf | tr -d '\t\r\n ' | perl -ne '$_ =~ /.*'"$newjail"'(\{(?:\{.*\}|[^{])*\})|\w+/; print $1;' | grep -oE 'hostname=[^;]+' | cut -d= -f2)
2020-11-30 22:22:36 +01:00
if [ -n "$jailhostname" ]; then
echo "new name: $jailhostname"
echo "in path $j/etc/$jail/local-etc-$newversion/rc.conf"
sed -iE 's/^hostname.*$/hostname="'"$jailhostname"'"/' $j/etc/$newjail/local-etc-$newversion/rc.conf
fi
2020-11-06 20:37:13 +01:00
}
remove() {
2021-07-05 14:26:10 +02:00
local dir=$1
2020-11-06 20:37:13 +01:00
if test -d $dir; then
ex rm -rf $dir
else
echo "$dir doesn't exist anymore"
fi
}
2020-11-29 18:46:50 +01:00
usage_remove() {
fin "Usage: $0 remove <jail> [-v <version>]
Remove <jail> from disk."
}
2020-11-06 20:37:13 +01:00
jaildk_remove() {
2021-07-05 14:26:10 +02:00
local jail version
2020-11-06 20:37:13 +01:00
jail=$1
2020-11-29 18:46:50 +01:00
shift
version=''
while getopts "v:" arg; do
case $arg in
v) version=${OPTARG};;
*) usage_remove;;
esac
done
2020-11-06 20:37:13 +01:00
if test -z "$jail"; then
2020-11-29 18:46:50 +01:00
usage_remove
2020-11-06 20:37:13 +01:00
fi
if jls | egrep -q "${jail}"; then
die "Jail $jail($version) is still running, stop it before removing!"
fi
if mount | egrep -q "${jail}.*${version}"; then
die "Jail $jail($version) is still mounted, umount it before removing!"
fi
die_if_not_exist $jail
if test -n "$version"; then
if ! test -d $j/etc/$jail/etc-$version; then
die "Jail $jail $version doesn't exist!"
fi
remove $j/etc/$jail/etc-$version
remove $j/etc/$jail/local-etc-$version
remove $j/home/$jail/root-$version
remove $j/log/$jail-$version
remove $j/data/$jail/www
remove $j/data/$jail/spool
else
remove $j/etc/$jail
remove $j/home/$jail
remove $j/log/$jail-*
remove $j/data/$jail
fi
}
jaildk_jail_usage() {
2020-11-29 18:46:50 +01:00
fin "Usage: $0 <start|stop|restart|status> <jail> | status"
}
usage_start() {
fin "Usage $0 start <jail>
Start <jail>."
}
usage_stop() {
fin "Usage $0 stop <jail>
Stop <jail>."
}
usage_restart() {
fin "Usage $0 restart <jail>
Restart <jail>."
}
usage_status() {
fin "Usage $0 status [<jail>]
Show status of <jail>. Without <jail>, show status of all jails."
2020-11-06 20:37:13 +01:00
}
jaildk_jail() {
2021-07-05 14:26:10 +02:00
local jail mode jid ip path runs build base _eip ip4addr osrelease path build
# FIXME: reversed argument order for historical reasons, maybe change this?
2020-11-29 18:46:50 +01:00
mode=$1
2021-07-05 14:26:10 +02:00
jail=$2
2020-11-06 20:37:13 +01:00
2020-12-13 14:17:13 +01:00
if test -z "$jail" -a $mode = "status"; then
2020-11-06 20:37:13 +01:00
bold "Running jails:"
2021-06-30 15:15:28 +02:00
(
2021-07-04 20:46:52 +02:00
echo "Jail IP-Address Path Is-Running RW-mounted Current-Version Base"
2021-06-30 15:15:28 +02:00
grep -h "name=" $j/etc/*/jail.conf | cut -d= -f2 | while read jail; do
jid=''
ip=''
path=''
runs=''
build='no'
base=''
2021-07-04 20:46:52 +02:00
2021-06-30 15:15:28 +02:00
load-jail-config $jail
2021-07-04 20:46:52 +02:00
_eip=''
for map in $maps; do
eval _eip=\${map_${map}_exposed_ip}
if test -n "${_eip}"; then
# we only display the first exposed ip we find, if any
break
fi
done
2021-06-30 15:15:28 +02:00
if jls -j $jail > /dev/null 2>&1; then
# jail is running
eval `jls -j $jail -qn | perl -n -e 'chomp; %j = map { ($a,$b) = split /=/; $a=~ s/\.//g; $a => $b } split/ /; foreach (keys %j) {print "$_=$j{$_}\n"}'`
if test -n "$ip4addr"; then
ip=$ip4addr
else
if test -z "$ip"; then
ip="n/a"
2021-07-04 20:46:52 +02:00
else
# ip configured
if test -n "${_eip}"; then
ip="${_eip}->${ip}"
fi
2021-06-30 15:15:28 +02:00
fi
fi
jid="yes,jid=$jid"
else
jid="no"
osrelease=$base
path=$j/run/$jail
if test -z "$ip"; then
ip="n/a"
fi
fi
2020-11-06 20:37:13 +01:00
2021-06-30 15:15:28 +02:00
if mount | egrep "$j/build/$jail" > /dev/null 2>&1; then
build='yes'
fi
echo "$jail $ip $path $jid $build $version $osrelease"
done
) | column -t
2020-12-13 14:17:13 +01:00
elif test -z "$jail"; then
usage_$mode
2020-11-06 20:37:13 +01:00
else
bold "Jail $jail $mode:"
case $mode in
status)
service jail $mode $jail | egrep "IP|$jail"
jaildk_rc $jail status
;;
*)
service jail $mode $jail
2020-11-30 22:17:49 +01:00
jaildk_ipfw $jail $mode
2020-11-06 20:37:13 +01:00
;;
esac
fi
}
2020-11-28 12:26:24 +01:00
get_rc_scripts() {
2021-07-05 14:26:10 +02:00
local jail jaipath files rcvar
2020-11-28 15:16:40 +01:00
jail="$1"
2021-01-25 00:22:54 +01:00
jailpath=`get_jail_path $jail`
2020-11-06 20:37:13 +01:00
2021-01-25 00:22:54 +01:00
files=$(ls $j/run/$jailpath/usr/local/etc/rc.d/* $j/run/$jailpath/etc/rc.d/* 2>/dev/null)
2020-11-28 15:16:40 +01:00
2021-01-25 00:22:54 +01:00
rcorder $files 2>/dev/null | while read SCRIPT; do
2020-11-28 15:16:40 +01:00
rcvar=`egrep "^rcvar=" $SCRIPT | cut -d= -f2 | sed 's/"//g' | tail -1`
2021-01-25 00:22:54 +01:00
if egrep -iq "^${rcvar}=.*yes" $j/run/$jailpath/usr/local/etc/rc.conf; then
echo $SCRIPT | sed "s|$j/run/$jailpath||"
2020-11-28 15:16:40 +01:00
fi
done
2020-11-06 20:37:13 +01:00
}
2020-11-29 18:46:50 +01:00
usage_rc() {
fin "Usage: $0 rc <jail> [<mode>] [-r <rc.d script]
Execute an rc.d script inside <jail> with parameter <mode>. Options:
-r <rc.d script> Execute <rc.d script>. default: execute all enabled scripts."
2020-11-06 20:37:13 +01:00
}
jaildk_rc() {
2021-07-05 14:26:10 +02:00
local jail mode rcd jailpath ok script jid
2020-11-06 20:37:13 +01:00
jail=$1
2020-12-13 14:17:13 +01:00
mode=$2
2020-11-29 18:46:50 +01:00
shift
shift
2020-12-19 17:34:53 +01:00
rcd=''
2020-11-29 18:46:50 +01:00
while getopts "r:" arg; do
case $arg in
r) rcd=${OPTARG};;
*) usage_rc;;
esac
done
2020-11-06 20:37:13 +01:00
2020-12-19 17:34:53 +01:00
if test -z "$rcd"; then
rcd='all'
2020-11-06 20:37:13 +01:00
fi
2020-11-29 18:46:50 +01:00
if test -z "$jail" -o -z "$mode"; then
usage_rc
2020-11-06 20:37:13 +01:00
fi
if ! jls | egrep -q "${jail}"; then
die "Jail $jail is not running."
fi
2021-01-25 00:22:54 +01:00
2020-11-28 12:26:24 +01:00
rcs=`get_rc_scripts $jail`
2020-11-06 20:37:13 +01:00
2021-01-25 00:22:54 +01:00
jid=`get_jid $jail`
jailpath=`get_jail_path $jail`
2020-12-19 17:34:53 +01:00
if test $rcd = "all"; then
2021-01-25 00:22:54 +01:00
if [ "$jail" == "$jailpath" ]; then
bold "Jail $jail rc status:"
else
bold "Jail $jail/$jailpath rc status:"
fi
2020-11-06 20:37:13 +01:00
for script in $rcs; do
2021-01-25 00:22:54 +01:00
jexec $jid $script $mode
2020-11-06 20:37:13 +01:00
done
else
ok=''
for script in $rcs; do
2020-12-19 17:34:53 +01:00
if echo "$script" | egrep -q "/${rcd}\$"; then
2021-01-25 00:22:54 +01:00
jexec $jid $script $mode
2020-11-06 20:37:13 +01:00
ok=1
fi
done
if test -z "$ok"; then
die "Script $rc doesn't exist in $jail or is not enabled."
fi
fi
}
2021-01-25 00:22:54 +01:00
get_jail_path() {
2021-07-05 14:26:10 +02:00
local jail="$1"
2021-01-25 00:22:54 +01:00
echo "$(jls |grep -E "^ +[0-9]+ +[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ *${jail} +" | awk '{print $4}' | xargs basename)"
}
get_jid() {
2021-07-05 14:26:10 +02:00
local jail="$1"
2021-01-25 00:22:54 +01:00
echo "$(jls | grep -E "^ +[0-9]+ +[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ *${jail} +" | awk '{print $1}' | xargs basename)"
}
2020-11-29 18:46:50 +01:00
usage_blogin() {
err "Usage: $file <jail>
Chroot into a build jail.
Mounted build chroot's:"
mount|egrep "base.*build" | awk '{print $3}' | cut -d/ -f 4
exit 1
}
2020-11-27 23:21:34 +01:00
2020-11-06 20:37:13 +01:00
jaildk_blogin() {
2021-07-05 14:26:10 +02:00
local jail chroot file shell term home path
2020-11-06 20:37:13 +01:00
jail=$1
if test -z "$jail"; then
file=`basename $0`
if test "$file" = "jaildk"; then
file="$0 blogin"
else
file="$0"
fi
2020-11-29 18:46:50 +01:00
usage_blogin
2020-11-06 20:37:13 +01:00
fi
chroot="$j/build/$jail"
if ! test -d $chroot/root; then
echo "build jail $jail not mounted!"
echo "Mount it with jaildk build $jail start"
exit 1
fi
shell=/bin/csh
term=vt100
home=/root
path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
if test -e $chroot/root/.bashrc; then
shell=/usr/local/bin/bash
fi
chroot $chroot /etc/rc.d/ldconfig onestart > /dev/null 2>&1
2020-11-28 14:34:10 +01:00
env - HOME=$home TERM=$term SHELL=$shell PATH=$path chroot $chroot $shell
2020-11-06 20:37:13 +01:00
}
2020-11-29 18:46:50 +01:00
usage_login() {
err "Usage: $file <jail-name|jail-domain|jail-ip> [<user>]
Login into a jail by name, ip or domain. If <user> has not been
specified, login as root.
Available jails:"
jls
exit 1
}
2020-11-06 20:37:13 +01:00
jaildk_login() {
2021-07-05 14:26:10 +02:00
local jail user chroot file shell term home path me
2020-11-06 20:37:13 +01:00
jail=$1
user=$2
me=`id -u`
jexec="jexec"
if test -z "$jail"; then
file=`basename $0`
if test "$file" = "jaildk"; then
file="$0 jlogin"
else
file="$0"
fi
2020-11-29 18:46:50 +01:00
usage_login
2020-11-06 20:37:13 +01:00
fi
jid=""
2020-11-27 23:21:34 +01:00
jid=`jls | grep "$jail" | awk '{print $1}'`
2020-11-06 20:37:13 +01:00
if test -z "$jid"; then
echo "jail $jail doesn't run!"
exit 1
fi
2021-01-14 13:10:09 +01:00
shell=/bin/csh
2020-11-06 20:37:13 +01:00
home=/home/$user
term=vt100
path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
2021-01-14 13:10:09 +01:00
chroot="$j/run/$jail"
2020-11-06 20:37:13 +01:00
if test -z "$user"; then
user=root
2021-01-14 13:10:09 +01:00
home=/root
2020-11-06 20:37:13 +01:00
fi
2021-01-14 13:10:09 +01:00
if test -e $chroot/$home/.bashrc; then
shell=/usr/local/bin/bash
2020-11-06 20:37:13 +01:00
fi
2021-01-14 13:10:09 +01:00
if test "$me" != "0"; then
jexec="sudo $jexec"
2020-11-06 20:37:13 +01:00
fi
2021-01-14 13:10:09 +01:00
echo "# Logging into jail $jail with jid $jid #"
2020-11-06 20:37:13 +01:00
env - JAIL=$jail HOME=$home TERM=$term SHELL=$shell PATH=$path $jexec -U $user $jid $shell
}
2020-11-29 18:46:50 +01:00
usage_reinstall() {
2020-12-14 20:18:20 +01:00
fin "Usage: $0 reinstall <jail> [-b <base>] [-v <version>]
Stop, uninstall, install and start <jail>. If <base> and/or
<version> is given, modify the jail config before reinstalling.
2020-11-29 18:46:50 +01:00
"
}
2020-11-06 20:37:13 +01:00
jaildk_reinstall() {
2021-07-05 14:26:10 +02:00
local jail NEWBASE NEWVERSION ts change base version
2020-11-06 20:37:13 +01:00
jail=$1
2020-12-14 20:18:20 +01:00
shift
while getopts "b:v:" arg; do
case $arg in
b) NEWBASE=${OPTARG};;
v) NEWVERSION=${OPTARG};;
*) usage_reinstall;;
esac
done
2020-11-06 20:37:13 +01:00
2020-11-29 18:46:50 +01:00
if test -z "$jail"; then
usage_reinstall
fi
2020-11-06 20:37:13 +01:00
die_if_not_exist $jail
if jls | egrep -q "${jail}"; then
jaildk_jail stop $jail
fi
jaildk_uninstall $jail
sleep 0.2
sync
2020-12-14 20:18:20 +01:00
if test -n "$NEWBASE" -o -n "$NEWVERSION"; then
load-jail-config $jail
ts=`date +%Y%m%d%H%M`
change=''
if test $NEWBASE != $base; then
base=$NEWBASE
change=1
fi
if test $NEWVERSION != $version; then
version=$NEWVERSION
change=1
fi
if test -n "$change"; then
bold "Saving current $jail config"
ex cp -p $j/etc/$jail/jail.conf $j/etc/$jail/jail.conf-$ts
bold "Creating new $jail config"
cat $j/etc/$jail/jail.conf-$ts \
| sed -e "s/^base=.*/base=$base/" -e "s/^version=.*/version=$version/" \
> $j/etc/$jail/jail.conf
fi
fi
2020-11-06 20:37:13 +01:00
jaildk_install $jail start
jaildk_jail start $jail
sleep 0.2
jaildk_jail status $jail
}
jaildk_setup() {
2021-07-05 14:26:10 +02:00
local j version subdir
2020-11-06 20:37:13 +01:00
j=$1
if test -z "$j"; then
2020-11-29 18:46:50 +01:00
fin "Usage: $0 setup <base dir for jail environment>"
2020-11-06 20:37:13 +01:00
fi
bold "preparing directories"
ex mkdir -p $j
2020-11-26 22:08:19 +01:00
for subdir in etc bin appl base data home log run ports; do
2020-11-06 20:37:13 +01:00
ex mkdir -p $j/$subdir
done
version=`date +%Y%m%d`
2020-11-27 23:21:34 +01:00
for subdir in appl/default-$version/db/ports appl/default-$version/etc etc/.template/etc-$version etc/.template/local-etc-$version home/.template/root-$version log/.template-$version; do
2020-11-06 20:37:13 +01:00
ex mkdir -p $j/$subdir
done
bold "building jail template"
2020-11-26 12:36:36 +01:00
ex cpdup /etc $j/etc/.template/etc-$version
2020-11-06 20:37:13 +01:00
echo "creating $j/etc/.template/etc-$version/rc.conf"
2020-11-27 23:21:34 +01:00
rm -f $j/etc/.template/etc-$version/rc.conf
2020-11-06 20:37:13 +01:00
echo 'rc_conf_files="/etc/rc.conf /etc/rc.conf.local /usr/local/etc/rc.conf"' > $j/etc/.template/etc-$version/rc.conf
echo "creating $j/etc/.template/local-etc-$version/rc.conf"
echo 'hostname="TEMPLATE"
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"' > $j/etc/.template/local-etc-$version/rc.conf
bold "creating template config $j/etc/.template/jail.conf"
os=`uname -r`
(echo "base=$os"; echo "version=$version"; name=template) > $j/etc/.template/jail.conf
bold "creating template config $j/etc/.template/mount.conf"
echo 'base/$base $name nullfs ro
md $name/tmp mfs rw,nosuid,async 128m 1777
dev $name/dev devfs
log/$name-$version $name/var/log nullfs rw
appl/default-$version $name/usr/local nullfs ro
etc/$name/etc-$version $name/etc nullfs ro
etc/$name/local-etc-$version $name/usr/local/etc nullfs ro
home/$name/root-$version $name/root nullfs rw' > $j/etc/.template/mount.conf
bold "creating template config $j/etc/.template/ports.conf"
(echo bash; echo ca_root_nss) > $j/etc/.template/ports.conf
2020-11-30 22:37:18 +01:00
bold "creating template config $j/etc/.template/ipfw.conf"
touch $j/etc/.template/ipfw.conf
2020-11-06 20:37:13 +01:00
bold "creating template config $j/etc/.template/mtree.conf"
2020-11-27 23:21:34 +01:00
echo '/set type=dir uid=0 gid=0 mode=01777
. type=dir mode=0755
tmp
var
cache
pkg
..
..
run
..
tmp' > $j/etc/.template/mtree.conf
2020-11-06 20:37:13 +01:00
bold "installing jaildk"
realj=`cd $j; pwd`
sed "s|^JAILDIR=.*|JAILDIR=$realj|" $0 > $j/bin/jaildk
ex chmod 755 $j/bin/jaildk
2020-11-25 10:42:52 +01:00
bold "configuring root shell template"
echo "# root shell inside jail
alias h history 25
alias j jobs -l
alias la ls -a
alias lf ls -FA
alias ll ls -lA
alias l ls -laF
alias .. cd ..
alias ... cd ../..
alias .... cd ../../../
umask 22
set path = (/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin)
setenv EDITOR vi
setenv PAGER less
setenv BLOCKSIZE K
if (\$?prompt) then
2020-11-27 23:21:34 +01:00
set chroot=`ps axu|grep /sbin/init | grep -v grep | awk '{print $1}'`
2020-11-25 10:45:13 +01:00
if("\$chroot" == \"\") then
set prompt = \"(jail) %N@%m:%~ %# \"
2020-11-25 10:42:52 +01:00
else
2020-11-25 10:45:13 +01:00
set prompt = \"(build chroot) %N@%m:%~ %# \"
2020-11-25 10:42:52 +01:00
endif
set promptchars = \"%#\"
set filec
set history = 1000
set savehist = (1000 merge)
set autolist = ambiguous
# Use history to aid expansion
set autoexpand
set autorehash
endif
" > $j/home/.template/root-$version/.cshrc
2020-11-06 20:37:13 +01:00
bold "building base"
echo -n "Do you want to build a base directory [Yn]? "
read yesno
case $yesno in
y|Y|yes|YES)
2020-11-29 16:22:36 +01:00
jaildk_base -b $j/base/$os
2020-11-06 20:37:13 +01:00
;;
esac
}
2020-12-13 14:37:20 +01:00
usage_fetchports() {
die "Usage $0 fetchports [-v <version>]
Fetch current portscollection, use <version> or todays timestamp as new version"
}
jaildk_fetchports() {
2021-07-05 14:26:10 +02:00
local version=`date +%Y%m%d`
2020-12-13 14:37:20 +01:00
while getopts "v:" arg; do
case $arg in
v) version=${OPTARG};;
*) usage_fetchports;;
esac
done
2020-11-27 19:08:57 +01:00
if test -d "$j/ports/$version"; then
echo -n "Ports dir $version already exist. Do you want to recreate it [y/N]? "
2020-11-26 22:08:19 +01:00
read yesno
case $yesno in
y|Y|yes|YES)
2020-11-27 19:08:57 +01:00
ex rm -rf $j/ports/$version
2021-07-05 14:26:10 +02:00
fetch_ports
2020-11-26 22:08:19 +01:00
;;
esac
else
2021-07-05 14:26:10 +02:00
fetch_ports
2020-11-26 22:08:19 +01:00
fi
}
2021-07-05 14:26:10 +02:00
fetch_ports() {
2020-11-27 19:08:57 +01:00
ex mkdir -p $j/ports/tmp
ex fetch -o $j/ports/tmp/ports.tar.gz http://ftp.freebsd.org/pub/FreeBSD/ports/ports/ports.tar.gz
2020-11-27 23:21:34 +01:00
ex tar xzfC $j/ports/tmp/ports.tar.gz $j/ports/tmp
2020-11-27 19:08:57 +01:00
ex mv $j/ports/tmp/ports $j/ports/$version
ex rm -rf $j/ports/tmp/ports*
2020-11-26 22:08:19 +01:00
}
2020-11-06 20:37:13 +01:00
2020-11-29 16:22:36 +01:00
usage_freeze() {
2020-11-28 20:41:05 +01:00
echo "Usage: $0 freeze <jail> [options]
Options:
-v <version> freeze <version> of <jail>
-b include the base layer (default: no)
-a include the application layer (default: no)"
exit 1
}
freeze_dir() {
2021-07-05 14:26:10 +02:00
local dstdir src srcdir layer layerfile
2020-11-28 20:41:05 +01:00
dstdir=$1
src=$2
srcdir=$(echo $src | cut -d/ -f1)
layer=$(echo $src | sed "s|$srcdir/||")
layerfile=$(echo $layer | sed 's|/|-|g')
2021-07-05 14:26:10 +02:00
2020-11-28 20:41:05 +01:00
ex tar -C $j/$srcdir -cpf $dstdir/$srcdir-$layerfile.tar $layer
}
2020-11-28 15:16:40 +01:00
jaildk_freeze() {
2021-07-05 14:26:10 +02:00
local jail VERSION ADDBASE ADDAPPL version host freeze tmp mountconf \
src dest fs opts size perm files
2020-11-28 15:16:40 +01:00
jail=$1
2020-11-28 20:41:05 +01:00
shift
VERSION=""
ADDBASE=""
ADDAPPL=""
while getopts "abv:" arg; do
case $arg in
a) ADDAPPL=1;;
b) ADDBASE=1;;
v) VERSION=${OPTARG};;
2020-11-29 16:22:36 +01:00
*) usage_freeze;;
2020-11-28 20:41:05 +01:00
esac
done
if test -z "$jail"; then
2020-11-29 16:22:36 +01:00
usage_freeze
2020-11-28 20:41:05 +01:00
fi
die_if_not_exist $jail "Jail to freeze" $VERSION
if jls | egrep -q "${jail}"; then
echo "The jail $jail is actually running. It's recommended"
echo -n "to stop it before freezing. Stop the jail now [Ny]? "
read yesno
case $yesno in
y|Y|yes|YES|Yes)
service jail stop $jail
;;
esac
fi
load-jail-config $jail
if test -n "$VERSION"; then
version=$VERSION
fi
bold "Freezing jail $jail $version"
host=$(hostname | cut -d\. -f1)
freeze=$j/images/$host-$jail-$version.tgz
tmp=$j/images/tmp/$jail-$version
ex mkdir -p $tmp
mountconf=$j/etc/$jail/mount.conf
if ! test -e "$mountconf"; then
die "$mountconf doesn't exist!"
fi
# create sub tarballs from every layer
grep -v "#" $mountconf | while read LINE; do
2021-07-05 14:26:10 +02:00
# this is a copy of the code in rc_mount()
2020-11-28 20:41:05 +01:00
# FIXME: put this into a function somehow
set -- $(eval echo \""$LINE"\")
# Skip empty lines:
case "$1" in
"") continue ;;
esac
src=$1
dest=$2
fs=$3
opts=$4
size=$5
perm=$6
case $fs in
nullfs)
if ! echo $src | egrep -q "^/"; then
# only freeze nullfs mounts relative to $j
if echo $src | egrep -q "^base/"; then
if test -n "$ADDBASE"; then
freeze_dir $tmp $src
fi
elif echo $src | egrep -q "^appl/"; then
if test -n "$ADDAPPL"; then
freeze_dir $tmp $src
fi
else
freeze_dir $tmp $src
fi
fi
;;
esac
done
# add the jail config
files=$(find $j/etc/$jail -type f -maxdepth 1)
for file in $files; do
cp -pP $file $tmp/
done
# build the final image file
ex tar -C $j/images/tmp -cpf $freeze $jail-$version
# cleaning up
ex rm -rf $j/images/tmp
bold "Done, jail $jail frozen to $freeze."
}
thaw_tarball() {
2021-07-05 14:26:10 +02:00
local srcdir tarball layer
2020-11-28 20:41:05 +01:00
srcdir=$1
tarball=$2
# etc-test-local-etc-20201128.tar
layer=$(echo $tarball | cut -d\- -f1)
if ! test -d $j/$layer; then
ex mkdir -p $j/$layer
fi
ex tar -C $j/$layer -xf $srcdir/$tarball
ex rm -f $srcdir/$tarball
}
2020-11-29 16:22:36 +01:00
usage_thaw() {
2020-11-29 18:46:50 +01:00
fin "Usage: $0 thaw <image>"
2020-11-29 16:22:36 +01:00
}
2020-11-28 20:41:05 +01:00
jaildk_thaw() {
2021-07-05 14:26:10 +02:00
local image j version jail tmp files bak
2020-11-28 20:41:05 +01:00
image=$1
if test -n "$J"; then
j=$J
fi
jail=$(echo $image | cut -d\- -f2)
version=$(echo $image | cut -d\- -f3 | cut -d\. -f1)
if ! test -n "$version" -o -n "$jail"; then
2020-11-29 16:22:36 +01:00
usage_thaw
2020-11-28 20:41:05 +01:00
fi
if test -d $j/etc/$jail/etc-$version; then
bold -n "Jail $jail $version already exists, overwrite [Ny]? "
read yesno
case $yesno in
y|Y|yes|YES|Yes)
:;;
*)
echo "abort.";;
esac
fi
bold "Thawing jail $image"
tmp=$j/images/tmp
ex mkdir -p $tmp
# too many things can go wrong from here, so better abort on error
set -e
ex tar -C $tmp -xf $image
if ! test -d $tmp/$jail-$version; then
die "Invalid image format!"
ex rm -rf $tmp
fi
for tarball in `cd $tmp/$jail-$version && ls *.tar`; do
thaw_tarball $tmp/$jail-$version $tarball
done
files=$(find $tmp -type f)
bak=""
if test -e $j/etc/$jail/jail.conf; then
bold -n "$j/etc/$jail/jail.conf already exist. Overwrite configs [Ny]? "
read yesno
case $yesno in
y|Y|yes|YES|Yes)
:;;
*)
bold "Copying configs with extension -$version"
bak="-$version"
;;
esac
fi
for file in $files; do
filename=$(basename $file)
ex cp -Pp $file $j/etc/$jail/$filename$bak
done
bold "Done. Thawed jail $jail $version from $image."
2020-11-28 15:16:40 +01:00
}
2020-12-01 18:40:32 +01:00
usage_ipfw() {
echo "Usage: $0 ipfw <jail> <mode>
[Un]install ipfw rules. <mode> can be start or stop.
The jail needs to have a ipfw.conf file, containing
ipfw rules. You can use variables like \$ip and \$ip6
and you need to omit the 'ipfw add' of the command."
exit 1
}
2020-11-30 22:17:49 +01:00
jaildk_ipfw() {
2021-07-05 14:26:10 +02:00
local jail mode
2020-11-30 22:17:49 +01:00
jail=$1
mode=$2
2020-12-01 18:40:32 +01:00
if test -z "$mode"; then
usage_ipfw
fi
if test -f "$j/etc/$jail/ipfw.conf"; then
2020-11-30 22:17:49 +01:00
echo
bold "Managing IPFW Rules..."
case $mode in
start)
2021-07-05 14:26:10 +02:00
ipfw_delete $jail "y"
ipfw_add $jail
2020-11-30 22:17:49 +01:00
;;
stop)
2021-07-05 14:26:10 +02:00
ipfw_delete $jail
2020-11-30 22:17:49 +01:00
;;
esac
bold "... done"
echo
fi
}
2021-07-05 14:26:10 +02:00
ipfw_add() {
local jail ipv4 ipv6 rule
2020-11-30 23:04:30 +01:00
jail=$1
2020-12-01 18:40:32 +01:00
# support jail variables as well
load-jail-config $jail
2021-07-05 14:26:10 +02:00
if test -z $ip; then
# Getting current jails IP..
ipv4=`jls -n -j $jail ip4.addr | cut -d= -f2`
else
ipv4=$ip
fi
2020-12-01 18:40:32 +01:00
2021-07-05 14:26:10 +02:00
if test -z "$ipv4"; then
2020-12-01 18:40:32 +01:00
die "Jail $jail doesn't have an ipv4 address!"
fi
2021-07-05 14:26:10 +02:00
if test -z $ip6; then
ip6=`jls -n -j $jail ip6.addr | cut -d= -f2` # optional, no checks
else
ipv6=$ip6
fi
2020-12-01 18:40:32 +01:00
2020-11-30 23:04:30 +01:00
# Adding rules
2020-12-01 18:40:32 +01:00
egrep "^[a-z]" $j/etc/$jail/ipfw.conf | while read LINE; do
rule=$(eval echo "ipfw add $LINE // $jail")
echo $rule
$rule
done
2020-11-30 23:04:30 +01:00
}
2021-07-05 14:26:10 +02:00
ipfw_delete() {
local jail noout
2020-11-30 23:04:30 +01:00
jail=$1
noout=$2
2021-07-05 14:26:10 +02:00
2020-11-30 23:04:30 +01:00
ipfw show | grep -E "// $jail\$" | while read rule; do [ -z "$2" ] && bold "Deleting rule $rule"; sh -c "ipfw delete $(echo $rule| awk '{print $1}')"; done
}
2020-11-28 20:41:05 +01:00
2021-06-30 15:15:28 +02:00
usage_vnet() {
2021-07-05 14:26:10 +02:00
echo "$0 vnet <jail> <mode> -b <bridge>
Configure VIMAGE (vnet) networking for a jail. Usually called from
jail.conf. You need to configure the bridge manually in advance.
You need the following in your /etc/rc.conf:
cloned_interfaces=\"bridge0\"
ipv6_ifconfig_bridge0=\"2a01:...::1/80\"
ifconfig_bridge0=\"name jailsw0 up 172.20.20.1/24\"
ipv6_gateway_enable=\"YES\"
And something like this in your jail.conf:
billa {
vnet;
exec.created = \"/jail/bin/jaildk vnet $name start -b jailsw0\";
exec.prestop = \"/jail/bin/jaildk vnet $name stop -b vm-jailnet\";
}
Finally, the jail.conf for a vnet jail needs to contain these parameters:
ip=172.20.20.10/24
gw=172.20.20.1
and if using v6 v6 address in bridge subet, gw6 is default gw => bridge interface
ip6=2a01:.....ff
gw6=2a01:.....1
You'll also need PF nat rules in order to be able to reach the outside
from the jail or vice versa."
2021-07-02 13:03:33 +02:00
exit
2021-06-30 15:15:28 +02:00
}
jaildk_vnet() {
2021-07-02 13:03:33 +02:00
#
# This is no rc.d subcommand, but a standalone command, because it must
# be executed by jail(8) via exec.created hook.
2021-07-05 14:26:10 +02:00
local jail mode BRIDGE vnethost vnetjail epairA epairB
2021-06-30 15:15:28 +02:00
jail=$1
mode=$2
shift
shift
BRIDGE=''
while getopts "b:i:r:" arg; do
case $arg in
b) BRIDGE=${OPTARG};;
*) usage_vnet;;
esac
done
if test -z "$mode"; then
usage_vnet
fi
die_if_not_exist $jail
load-jail-config $jail
2021-07-02 13:03:33 +02:00
if test -z "$ip" -a -z "$gw"; then
usage_vnet
fi
2021-06-30 15:15:28 +02:00
vnethost="ep${jail}.h"
vnetjail="ep${jail}.j"
2021-07-04 12:49:34 +02:00
epairA=''
epairB=''
2021-06-30 15:15:28 +02:00
case $mode in
start)
2021-07-04 12:49:34 +02:00
if ! ifconfig $vnethost > /dev/null 2>&1; then
# setup epair
epairA=$(ifconfig epair create)
epairB="${epairA%?}b"
2021-06-30 15:15:28 +02:00
2021-07-04 12:49:34 +02:00
ex ifconfig $epairA name $vnethost || true
ex ifconfig $epairB name $vnetjail || true
2021-06-30 15:15:28 +02:00
2021-07-04 12:49:34 +02:00
ex ifconfig $vnetjail up
ex ifconfig $vnethost up
fi
2021-06-30 15:15:28 +02:00
2021-07-04 12:49:34 +02:00
if ! ifconfig $BRIDGE | egrep member:.$vnethost > /dev/null 2>&1; then
# add the host to the bridge
ex ifconfig $BRIDGE addm $vnethost up || true
2021-06-30 15:15:28 +02:00
2021-07-04 12:49:34 +02:00
# add the jail to the bridge (gets invisible from host)
ex ifconfig $vnetjail vnet $jail || true
fi
2021-07-03 20:35:05 +02:00
2021-07-04 12:49:34 +02:00
if ! jexec $jail ifconfig $vnetjail inet | grep netmask > /dev/null 2>&1; then
# configure the jail v4 network stack inside the jail
ex jexec $jail ifconfig $vnetjail $ip up || true
ex jexec $jail route add default $gw || true
2021-07-04 11:52:04 +02:00
fi
2021-07-04 12:49:34 +02:00
2021-07-04 11:52:04 +02:00
if test -n "$ip6" -a -n "$gw6"; then
2021-07-04 12:49:34 +02:00
if ! jexec $jail ifconfig $vnetjail inet6 | grep -v fe80 | grep prefixlen > /dev/null 2>&1; then
# configure the jail v4 network stack inside the jail
ex jexec $jail ifconfig $vnetjail inet6 $ip6 || true
ex jexec $jail route -6 add default $gw6 || true
fi
2021-07-03 20:35:05 +02:00
fi
2021-06-30 15:15:28 +02:00
;;
stop)
# remove vnet from the jail
ifconfig $vnetjail -vnet $jail || true
# remove interfaces (removes jail interface as well, since this is an epair)
ifconfig $vnethost destroy || true
;;
*)
usage_vnet;;
esac
}
2021-01-14 13:10:09 +01:00
usage_bootstrap() {
echo "$0 bootstrap <jail> [-b <base>] [-v <version>] [-p <port,...>] [-a <appl>] [-i <ip,..>]
Create, build and install a new jail with name <jail>. Options:
-b <base> Use <base> as base, create if not existent.
-v <version> Assign <version> to new jail, otherwise use YYYYMMDD.
-p <port,...> Install specified ports into jail.
-a <appl> Use <appl>-<version> as /usr/local/, create if not existent.
-i <ip,..> Configure the jail in /etc/jail.conf with ip addresses <ip,...>
"
exit 1
}
jaildk_bootstrap() {
# combines base, create and build functions into a oneshot command
# to create a new jail
2021-07-05 14:26:10 +02:00
local jail BASE VERSION APPL PORTS IP loadbase RUN subdir port
2021-01-14 13:10:09 +01:00
jail=$1
shift
BASE=''
VERSION=''
APPL=''
PORTS=''
IP=''
while getopts "b:v:p:a:" arg; do
case $arg in
b) BASE=${OPTARG};;
v) VERSION=${OPTARG};;
p) PORTS=${OPTARG};;
a) APPL=${OPTARG};;
i) IP==${OPTARG};;
*) usage_bootstrap;;
esac
done
if test -z "$jail"; then
usage_bootstrap
fi
# if no base specified, use last existing one or create one if no
# base exists at all
if test -z "$BASE"; then
lastbase=$(ls -1tr $j/base/ | grep -v build | tail -1)
if test -n "$lastbase"; then
BASE=$lastbase
else
BASE=$(uname -r)
$(jaildk_base -b $BASE)
fi
else
if ! test -d "$j/base/$BASE"; then
# base specified but doesnt exist, so create
$(jaildk_base -b $BASE)
fi
fi
# version no specified
if test -z "$VERSION"; then
VERSION=$(date +%Y%m%d)
fi
# creation
$(jaildk_create $jail)
# appl specified, do NOT clone but start empty IF it doesnt' exist yet
if test -n "$APPL"; then
if ! test -d "$j/appl/$APPL-$VERSION"; then
for subdir in db/ports etc; do
ex mkdir -p $j/$APPL-$VERSION/$subdir
done
fi
# also fix mount.conf
echo "Setting appl to $APPL"
sed -iE "s|appl/.+-\$version|appl/$APPL-\$version|" $j/etc/$jail/mount.conf
fi
# mount build
if test -n "$PORTS"; then
jaildk_build $jail start -b $BASE -v $VERSION
echo "Installing ports"
for port in `echo "$PORTS" | sed 's/,/ /g'`; do
chroot $j/build/$jail pkg install $port
done
fi
# install
jaildk_install $jail start
# run
RUN=''
if egrep -q "^${jail} " /etc/jail.conf; then
RUN=1
else
if test -n "$IP"; then
echo "Adding $jail with ip addrs $IP to /etc/jail.conf"
(echo
echo "$jail {"
for addr in `echo "$IP" | sed 's/,/ /g'`; do
if echo "$addr" | egrep -q :; then
echo " ip6.addr = \"$addr\";"
else
echo " ip4.addr = \"$addr\";"
fi
done
echo "}"
) >> /etc/jail.conf
RUN=1
fi
fi
if test -n "$RUN"; then
service jail start $jail
fi
}
2021-07-04 12:27:17 +02:00
mustberoot() {
if test "$( id -u )" -ne 0; then
echo "Must run as root!" >&2
exit 1
fi
}
2021-01-14 13:10:09 +01:00
2020-11-06 20:37:13 +01:00
##########################
#
# main()
# will be modified during installation
JAILDIR=/jail
2020-11-27 08:52:58 +01:00
# install modules
2021-07-05 14:26:10 +02:00
RCSCRIPTS_START="rc_mount rc_ports rc_mtree rc_pf"
RCSCRIPTS_STOP="rc_pf rc_mount rc_ports"
RW_RCSCRIPTS_START="rc_mount rc_ports rc_mtree"
RW_RCSCRIPTS_STOP="rc_mount rc_ports"
2020-11-27 08:52:58 +01:00
2020-11-06 20:37:13 +01:00
# globals
j=$JAILDIR
rcdir=$j/bin
runner=$1
shift
2020-11-27 19:08:57 +01:00
if test -z "$runner"; then
usage_jaildk
fi
2020-11-06 20:37:13 +01:00
case $runner in
2021-07-04 12:27:17 +02:00
start|stop|restart)
2021-07-04 20:46:52 +02:00
# running jails
2021-07-04 12:27:17 +02:00
mustberoot
2020-11-06 20:37:13 +01:00
jaildk_jail $runner $*
;;
2021-07-04 12:27:17 +02:00
status)
2021-07-04 20:46:52 +02:00
# same, w/o root
2021-07-04 12:27:17 +02:00
jaildk_jail status $*
;;
login)
2021-07-04 20:46:52 +02:00
# login into jail as non root user allowed
# eventually calls sudo
2021-07-04 12:49:34 +02:00
jaildk_login $*
2021-07-04 12:27:17 +02:00
;;
2020-11-06 20:37:13 +01:00
*)
2021-07-04 20:46:52 +02:00
# every other management command, if it exists
2021-07-05 14:26:10 +02:00
if type "jaildk_$runner" 2>&1 > /dev/null; then
2021-07-04 20:46:52 +02:00
mustberoot
jaildk_$runner $*
else
usage_jaildk $*
fi
2020-11-06 20:37:13 +01:00
;;
esac