Support for setting and using jail-bound ZFS datasets, cpuset(1) and setfib(1).

Jail-bound ZFS datasets still need the usual zfs+jail stuff like security.jail.mount_allowed=1 and security.jail.enforce_statfs=0 as well as "add path zfs unhide" in the devfs.rules for the jail.

The setfib utility requires FIBs to be enabled via kernel-config.

All features need at least FreeBSD 7.1-RELEASE.
This commit is contained in:
cryx 2009-12-28 22:09:17 +00:00
parent 12cf0c4f21
commit 7fd2408694
2 changed files with 127 additions and 5 deletions

View File

@ -46,7 +46,7 @@ ezjail_usage_install="Usage: ${ezjail_admin} install [-mMpPsS] [-h host] [-r rel
ezjail_usage_create="Usage: ${ezjail_admin} create [-xbi] [-f flavour] [-r jailroot] [-s size] [-c bde|eli|zfs] [-C args] [-a archive] jailname jailip" ezjail_usage_create="Usage: ${ezjail_admin} create [-xbi] [-f flavour] [-r jailroot] [-s size] [-c bde|eli|zfs] [-C args] [-a archive] jailname jailip"
ezjail_usage_delete="Usage: ${ezjail_admin} delete [-w] jailname" ezjail_usage_delete="Usage: ${ezjail_admin} delete [-w] jailname"
ezjail_usage_update="Usage: ${ezjail_admin} update [-s sourcetree] [-p] (-b|-i|-u|-P)" ezjail_usage_update="Usage: ${ezjail_admin} update [-s sourcetree] [-p] (-b|-i|-u|-P)"
ezjail_usage_config="Usage: ${ezjail_admin} config [-r run|norun] [-n newname] [-i attach|detach|fsck] jailname" ezjail_usage_config="Usage: ${ezjail_admin} config [-r run|norun] [-n newname] [-c cpuset] [-z zfs-datasets] [-f fib] [-i attach|detach|fsck] jailname"
ezjail_usage_console="Usage: ${ezjail_admin} console [-f] [-e command] jailname" ezjail_usage_console="Usage: ${ezjail_admin} console [-f] [-e command] jailname"
ezjail_usage_archive="Usage: ${ezjail_admin} archive [-Af] [-a archive] [-d archivedir] jailname [jailname...]" ezjail_usage_archive="Usage: ${ezjail_admin} archive [-Af] [-a archive] [-d archivedir] jailname [jailname...]"
ezjail_usage_restore="Usage: ${ezjail_admin} restore [-f] [-d archivedir] (archive|jailname)..." ezjail_usage_restore="Usage: ${ezjail_admin} restore [-f] [-d archivedir] (archive|jailname)..."
@ -170,6 +170,9 @@ fetchjailinfo () {
eval ezjail_attachparams=\"\$jail_${ezjail_safename}_attachparams\" eval ezjail_attachparams=\"\$jail_${ezjail_safename}_attachparams\"
eval ezjail_attachblocking=\"\$jail_${ezjail_safename}_attachblocking\" eval ezjail_attachblocking=\"\$jail_${ezjail_safename}_attachblocking\"
eval ezjail_forceblocking=\"\$jail_${ezjail_safename}_forceblocking\" eval ezjail_forceblocking=\"\$jail_${ezjail_safename}_forceblocking\"
eval ezjail_zfs_datasets=\"\$jail_${ezjail_safename}_zfs_datasets\"
eval ezjail_cpuset=\"\$jail_${ezjail_safename}_cpuset\"
eval ezjail_fib=\"\$jail_${ezjail_safename}_fib\"
ezjail_softlink=${ezjail_jaildir}/`basename -- "${ezjail_rootdir}"` ezjail_softlink=${ezjail_jaildir}/`basename -- "${ezjail_rootdir}"`
ezjail_devicelink="${ezjail_rootdir}.device" ezjail_devicelink="${ezjail_rootdir}.device"
@ -615,6 +618,9 @@ create)
echo export jail_${ezjail_safename}_attachparams=\"${ezjail_attachparams}\" echo export jail_${ezjail_safename}_attachparams=\"${ezjail_attachparams}\"
echo export jail_${ezjail_safename}_attachblocking=\"${ezjail_attachblocking}\" echo export jail_${ezjail_safename}_attachblocking=\"${ezjail_attachblocking}\"
echo export jail_${ezjail_safename}_forceblocking=\"${ezjail_forceblocking}\" echo export jail_${ezjail_safename}_forceblocking=\"${ezjail_forceblocking}\"
echo export jail_${ezjail_safename}_zfs_datasets=\"${ezjail_zfs_datasets}\"
echo export jail_${ezjail_safename}_cpuset=\"${ezjail_cpuset}\"
echo export jail_${ezjail_safename}_fib=\"${ezjail_fib}\"
) > "${ezjail_config}" ) > "${ezjail_config}"
# Final steps for flavour installation # Final steps for flavour installation
@ -1142,12 +1148,15 @@ restore)
######################## ezjail-admin CONFIG ######################## ######################## ezjail-admin CONFIG ########################
config) config)
# Clean variables, prevent polution # Clean variables, prevent polution
unset ezjail_setrunnable ezjail_imageaction ezjail_new_name unset ezjail_setrunnable ezjail_imageaction ezjail_new_name ezjail_new_zfs_datasets ezjail_new_cpuset ezjail_new_fib
shift; while getopts :r:i:n: arg; do case ${arg} in shift; while getopts :r:i:n:z:c:f: arg; do case ${arg} in
i) ezjail_imageaction=${OPTARG};; i) ezjail_imageaction=${OPTARG};;
r) ezjail_setrunnable=${OPTARG};; r) ezjail_setrunnable=${OPTARG};;
n) ezjail_new_name=${OPTARG};; n) ezjail_new_name=${OPTARG};;
z) ezjail_new_zfs_datasets=${OPTARG};;
c) ezjail_new_cpuset=${OPTARG};;
f) ezjail_new_fib=${OPTARG};;
?) exerr ${ezjail_usage_config};; ?) exerr ${ezjail_usage_config};;
esac; done; shift $(( ${OPTIND} - 1 )) esac; done; shift $(( ${OPTIND} - 1 ))
@ -1160,7 +1169,7 @@ config)
[ "${ezjail_config}" ] || exerr "Error: Nothing known about jail ${ezjail_name}." [ "${ezjail_config}" ] || exerr "Error: Nothing known about jail ${ezjail_name}."
# Nothing to be configured? # Nothing to be configured?
[ "${ezjail_setrunnable}" -o "${ezjail_new_name}" -o "${ezjail_imageaction}" ] || echo "Warning: No config option specified." [ "${ezjail_setrunnable}" -o "${ezjail_new_name}" -o "${ezjail_imageaction}" -o "${ezjail_new_zfs_datasets}" -o "${ezjail_new_cpuset}" -o "${ezjail_new_fib}" ] || echo "Warning: No config option specified."
# Do we want a new name for our jail? # Do we want a new name for our jail?
if [ "${ezjail_new_name}" ]; then if [ "${ezjail_new_name}" ]; then
@ -1190,12 +1199,15 @@ config)
eval ezjail_new_attachblocking=\"\$jail_${ezjail_safename}_attachblocking\" eval ezjail_new_attachblocking=\"\$jail_${ezjail_safename}_attachblocking\"
eval ezjail_new_forceblocking=\"\$jail_${ezjail_safename}_forceblocking\" eval ezjail_new_forceblocking=\"\$jail_${ezjail_safename}_forceblocking\"
eval ezjail_new_imagetype=\"\$jail_${ezjail_safename}_imagetype\" eval ezjail_new_imagetype=\"\$jail_${ezjail_safename}_imagetype\"
eval ezjail_new_zfs_datasets=\"\$jail_${ezjail_safename}_zfs_datasets\"
eval ezjail_new_cpuset=\"\$jail_${ezjail_safename}_cpuset\"
eval ezjail_new_fib=\"\$jail_${ezjail_safename}_fib\"
# This scenario really will only lead to real troubles in the 'fulljail' # This scenario really will only lead to real troubles in the 'fulljail'
# case, but I should still explain this to the user and not claim that # case, but I should still explain this to the user and not claim that
# "an ezjail would already exist" # "an ezjail would already exist"
case ${ezjail_new_hostname} in basejail|newjail|fulljail|flavours|ezjailtemp) exerr "Error: ezjail needs the ${ezjail_new_hostname} directory for its own administrative purposes.\n Please chose another name.";; esac case ${ezjail_new_hostname} in basejail|newjail|fulljail|flavours|ezjailtemp) exerr "Error: ezjail needs the ${ezjail_new_hostname} directory for its own administrative purposes.\n Please chose another name.";; esac
# jail names may lead to identical configs, eg. foo.bar.com == foo-bar.com # jail names may lead to identical configs, eg. foo.bar.com == foo-bar.com
# so check, whether we might be running into problems # so check, whether we might be running into problems
[ -e "${ezjail_new_config}" -o -e "${ezjail_new_config}.norun" ] && exerr "Error: An ezjail config already exists at ${ezjail_new_config}.\n Please chose another name." [ -e "${ezjail_new_config}" -o -e "${ezjail_new_config}.norun" ] && exerr "Error: An ezjail config already exists at ${ezjail_new_config}.\n Please chose another name."
@ -1264,6 +1276,9 @@ config)
echo export jail_${ezjail_new_safename}_attachparams=\"${ezjail_new_attachparams}\" echo export jail_${ezjail_new_safename}_attachparams=\"${ezjail_new_attachparams}\"
echo export jail_${ezjail_new_safename}_attachblocking=\"${ezjail_new_attachblocking}\" echo export jail_${ezjail_new_safename}_attachblocking=\"${ezjail_new_attachblocking}\"
echo export jail_${ezjail_new_safename}_forceblocking=\"${ezjail_new_forceblocking}\" echo export jail_${ezjail_new_safename}_forceblocking=\"${ezjail_new_forceblocking}\"
echo export jail_${ezjail_new_safename}_zfs_datasets=\"${ezjail_new_zfs_datasets}\"
echo export jail_${ezjail_new_safename}_cpuset=\"${ezjail_new_cpuset}\"
echo export jail_${ezjail_new_safename}_fib=\"${ezjail_new_fib}\"
) > "${ezjail_new_config}" ) > "${ezjail_new_config}"
# remove old config # remove old config
@ -1278,6 +1293,97 @@ config)
fetchjailinfo ${ezjail_new_safename} fetchjailinfo ${ezjail_new_safename}
fi fi
if [ "${ezjail_new_zfs_datasets}" ]; then
# if jail is still running, refuse to go any further
[ "${ezjail_id}" ] && exerr "Error: Jail appears to be still running.\n '${ezjail_admin} stop ${ezjail_name}' it first ."
# write new config file, preserve comments
(
grep -e ^\# "${ezjail_config}"
echo
echo export jail_${ezjail_safename}_hostname=\"${ezjail_hostname}\"
echo export jail_${ezjail_safename}_ip=\"${ezjail_ip}\"
echo export jail_${ezjail_safename}_rootdir=\"${ezjail_rootdir}\"
echo export jail_${ezjail_safename}_exec=\"${ezjail_exec}\"
echo export jail_${ezjail_safename}_mount_enable=\"${ezjail_mount_enable}\"
echo export jail_${ezjail_safename}_devfs_enable=\"${ezjail_devfs_enable}\"
echo export jail_${ezjail_safename}_devfs_ruleset=\"${ezjail_devfs_ruleset}\"
echo export jail_${ezjail_safename}_procfs_enable=\"${ezjail_procfs_enable}\"
echo export jail_${ezjail_safename}_fdescfs_enable=\"${ezjail_fdescfs_enable}\"
echo export jail_${ezjail_safename}_image=\"${ezjail_image}\"
echo export jail_${ezjail_safename}_imagetype=\"${ezjail_imagetype}\"
echo export jail_${ezjail_safename}_attachparams=\"${ezjail_attachparams}\"
echo export jail_${ezjail_safename}_attachblocking=\"${ezjail_attachblocking}\"
echo export jail_${ezjail_safename}_forceblocking=\"${ezjail_forceblocking}\"
echo export jail_${ezjail_safename}_zfs_datasets=\"${ezjail_new_zfs_datasets}\"
echo export jail_${ezjail_safename}_cpuset=\"${ezjail_cpuset}\"
echo export jail_${ezjail_safename}_fib=\"${ezjail_fib}\"
) > "${ezjail_config}_"
mv "${ezjail_config}_" "${ezjail_config}"
fi
if [ "${ezjail_new_cpuset}" ]; then
# configure the new cpuset if the jail is currently running
[ "${ezjail_id}" ] && /usr/bin/cpuset -l ${ezjail_new_cpuset} -j ${ezjail_id} || exerr "Error: The defined cpuset is malformed"
# write new config file, preserve comments
(
grep -e ^\# "${ezjail_config}"
echo
echo export jail_${ezjail_safename}_hostname=\"${ezjail_hostname}\"
echo export jail_${ezjail_safename}_ip=\"${ezjail_ip}\"
echo export jail_${ezjail_safename}_rootdir=\"${ezjail_rootdir}\"
echo export jail_${ezjail_safename}_exec=\"${ezjail_exec}\"
echo export jail_${ezjail_safename}_mount_enable=\"${ezjail_mount_enable}\"
echo export jail_${ezjail_safename}_devfs_enable=\"${ezjail_devfs_enable}\"
echo export jail_${ezjail_safename}_devfs_ruleset=\"${ezjail_devfs_ruleset}\"
echo export jail_${ezjail_safename}_procfs_enable=\"${ezjail_procfs_enable}\"
echo export jail_${ezjail_safename}_fdescfs_enable=\"${ezjail_fdescfs_enable}\"
echo export jail_${ezjail_safename}_image=\"${ezjail_image}\"
echo export jail_${ezjail_safename}_imagetype=\"${ezjail_imagetype}\"
echo export jail_${ezjail_safename}_attachparams=\"${ezjail_attachparams}\"
echo export jail_${ezjail_safename}_attachblocking=\"${ezjail_attachblocking}\"
echo export jail_${ezjail_safename}_forceblocking=\"${ezjail_forceblocking}\"
echo export jail_${ezjail_safename}_zfs_datasets=\"${ezjail_zfs_datasets}\"
echo export jail_${ezjail_safename}_cpuset=\"${ezjail_new_cpuset}\"
echo export jail_${ezjail_safename}_fib=\"${ezjail_fib}\"
) > "${ezjail_config}_"
mv "${ezjail_config}_" "${ezjail_config}"
fi
if [ "${ezjail_new_fib}" ]; then
# if jail is still running, refuse to go any further
[ "${ezjail_id}" ] && exerr "Error: Jail appears to be still running.\n '${ezjail_admin} stop ${ezjail_name}' it first ."
[ "${ezjail_new_fib}" -ge "0" ] && exerr "Error: fib number has to be an integer."
# write new config file, preserve comments
(
grep -e ^\# "${ezjail_config}"
echo
echo export jail_${ezjail_safename}_hostname=\"${ezjail_hostname}\"
echo export jail_${ezjail_safename}_ip=\"${ezjail_ip}\"
echo export jail_${ezjail_safename}_rootdir=\"${ezjail_rootdir}\"
echo export jail_${ezjail_safename}_exec=\"${ezjail_exec}\"
echo export jail_${ezjail_safename}_mount_enable=\"${ezjail_mount_enable}\"
echo export jail_${ezjail_safename}_devfs_enable=\"${ezjail_devfs_enable}\"
echo export jail_${ezjail_safename}_devfs_ruleset=\"${ezjail_devfs_ruleset}\"
echo export jail_${ezjail_safename}_procfs_enable=\"${ezjail_procfs_enable}\"
echo export jail_${ezjail_safename}_fdescfs_enable=\"${ezjail_fdescfs_enable}\"
echo export jail_${ezjail_safename}_image=\"${ezjail_image}\"
echo export jail_${ezjail_safename}_imagetype=\"${ezjail_imagetype}\"
echo export jail_${ezjail_safename}_attachparams=\"${ezjail_attachparams}\"
echo export jail_${ezjail_safename}_attachblocking=\"${ezjail_attachblocking}\"
echo export jail_${ezjail_safename}_forceblocking=\"${ezjail_forceblocking}\"
echo export jail_${ezjail_safename}_zfs_datasets=\"${ezjail_zfs_datasets}\"
echo export jail_${ezjail_safename}_cpuset=\"${ezjail_cpuset}\"
echo export jail_${ezjail_safename}_fib=\"${ezjail_new_fib}\"
) > "${ezjail_config}_"
mv "${ezjail_config}_" "${ezjail_config}"
fi
case "${ezjail_setrunnable}" in case "${ezjail_setrunnable}" in
run) [ "${ezjail_config}" = "${ezjail_config%.norun}" ] || mv "${ezjail_config}" "${ezjail_config%.norun}";; run) [ "${ezjail_config}" = "${ezjail_config%.norun}" ] || mv "${ezjail_config}" "${ezjail_config%.norun}";;
norun) [ "${ezjail_config}" = "${ezjail_config%.norun}" ] && mv "${ezjail_config}" "${ezjail_config}.norun" ;; norun) [ "${ezjail_config}" = "${ezjail_config%.norun}" ] && mv "${ezjail_config}" "${ezjail_config}.norun" ;;

View File

@ -65,6 +65,8 @@ do_cmd()
eval ezjail_attachparams=\"\$jail_${ezjail}_attachparams\" eval ezjail_attachparams=\"\$jail_${ezjail}_attachparams\"
eval ezjail_attachblocking=\"\$jail_${ezjail}_attachblocking\" eval ezjail_attachblocking=\"\$jail_${ezjail}_attachblocking\"
eval ezjail_forceblocking=\"\$jail_${ezjail}_forceblocking\" eval ezjail_forceblocking=\"\$jail_${ezjail}_forceblocking\"
eval ezjail_zfs_datasets=\"\$jail_${ezjail}_zfs_datasets\"
eval ezjail_cpuset=\"\$jail_${ezjail}_cpuset\"
# Do we still have a root to run in? # Do we still have a root to run in?
[ ! -d "${ezjail_rootdir}" ] && echo " Warning: root directory ${ezjail_rootdir} of ${ezjail} does not exist." && continue [ ! -d "${ezjail_rootdir}" ] && echo " Warning: root directory ${ezjail_rootdir} of ${ezjail} does not exist." && continue
@ -88,6 +90,20 @@ do_cmd()
# Pass control to jail script which does the actual work # Pass control to jail script which does the actual work
[ "${ezjail_pass}" ] && sh /etc/rc.d/jail one${action%crypto} ${ezjail_pass} [ "${ezjail_pass}" ] && sh /etc/rc.d/jail one${action%crypto} ${ezjail_pass}
if [ "${action}" = "start" ]; then
ezjail_safename=`echo -n "${ezjail}" | tr -c '[:alnum:]' _`
# Get the JID of the jail
[ -f "/var/run/jail_${ezjail_safename}.id" ] && ezjail_id=`cat /var/run/jail_${ezjail_safename}.id` || return
# Attach ZFS-datasets to the jail
for zfs in ${ezjail_zfs_datasets}; do
/sbin/zfs jail ${ezjail_id} ${zfs} ||Êecho -n "Error: ${zfs} could not be configured"
done
# Configure processor sets for the jail via cpuset(1)
[ "${ezjail_cpuset}" ] && /usr/bin/cpuset -l ${ezjail_cpuset} -j ${ezjail_id} || echo -n "Error: The defined cpuset is malformed"
fi
# Can only detach after unmounting (from fstab.JAILNAME in /etc/rc.d/jail) # Can only detach after unmounting (from fstab.JAILNAME in /etc/rc.d/jail)
attach_detach_post attach_detach_post
} }