Date: Thu, 28 Jul 2011 16:11:37 +0200 From: Martin Matuska <mm@FreeBSD.org> To: freebsd-current@FreeBSD.org Subject: [PATCH] updated /etc/rc.d/jail and added ZFS support Message-ID: <4E316E19.9040309@FreeBSD.org>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------000605040303080100060003 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit The attached patch allows better fine-tuning of jails started via /etc/rc.d, uses the new jail(8) flags (-c -m), the persist parameter and adds ZFS support. Patch is fully backward compatible. Please review, comment and/or test my attached patch. Cheers, mm -- Martin Matuska FreeBSD committer http://blog.vx.sk --------------000605040303080100060003 Content-Type: text/x-patch; name="etc_jail.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="etc_jail.patch" Index: etc/rc.d/jail =================================================================== --- etc/rc.d/jail (revision 224471) +++ etc/rc.d/jail (working copy) @@ -43,6 +43,7 @@ eval _ip=\"\$jail_${_j}_ip\" eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\" eval _exec=\"\$jail_${_j}_exec\" + eval _params=\"\$jail_${_j}_params\" i=0 while : ; do @@ -83,6 +84,8 @@ i=$((i + 1)) done + eval _zfs=\"\${jail_${_j}_zfs:-}\" + if [ -n "${_exec}" ]; then # simple/backward-compatible execution _exec_start="${_exec}" @@ -98,6 +101,9 @@ fi # The default jail ruleset will be used by rc.subr if none is specified. + if [ -n "jail_devfs_ruleset" -a -n "_zfs" ]; then + jail_devfs_ruleset="devfsrules_jail_zfs" + fi eval _ruleset=\"\${jail_${_j}_devfs_ruleset:-${jail_devfs_ruleset}}\" eval _devfs=\"\${jail_${_j}_devfs_enable:-${jail_devfs_enable}}\" [ -z "${_devfs}" ] && _devfs="NO" @@ -200,6 +206,58 @@ if [ -z "${_rootdir}" ]; then err 3 "$name: No root directory has been defined for ${_j}" fi + + # Security-related parameters + eval _enforce_statfs=\"\$jail_${_j}_enforce_statfs\" + eval _allow_set_hostname=\"\$jail_${_j}_allow_set_hostname\" + eval _allow_sysvipc=\"\$jail_${_j}_allow_sysvipc\" + eval _allow_raw_sockets=\"\$jail_${_j}_allow_raw_sockets\" + eval _allow_chflags=\"\$jail_${_j}_allow_chflags\" + eval _allow_mount=\"\$jail_${_j}_allow_mount\" + eval _allow_socket_af=\"\$jail_${_j}_allow_socket_af\" + eval _allow_quotas=\"\$jail_${_j}_allow_quotas:-0\" + + if [ -z "${_enforce_statfs}" ]; then + _enforce_statfs=`${SYSCTL} -n security.jail.enforce_statfs` + fi + + if [ -z "${_allow_set_hostname}" ]; then + _allow_set_hostname=`${SYSCTL} -n security.jail.set_hostname_allowed` + fi + + if [ -z "${_allow_sysvipc}" ]; then + _allow_sysvipc=`${SYSCTL} -n security.jail.sysvipc_allowed` + fi + + if [ -z "${_allow_raw_sockets}" ]; then + _allow_raw_sockets=`${SYSCTL} -n security.jail.allow_raw_sockets` + fi + + if [ -z "${_allow_chflags}" ]; then + _allow_chflags=`${SYSCTL} -n security.jail.chflags_allowed` + fi + + if [ -z "${_allow_mount}" ]; then + _allow_mount=`${SYSCTL} -n security.jail.mount_allowed` + fi + + if [ -z "${_allow_socket_af}" ]; then + _tmpval=`${SYSCTL} -n security.jail.socket_unixiproute_only` + if [ "${_tmpval}" = "0" ]; then + _allow_socket_af=1 + else + _allow_socket_af=0 + fi + fi + + _security_params="enforce_statfs=${_enforce_statfs} \ + allow.set_hostname=${_allow_set_hostname} \ + allow.sysvipc=${_allow_sysvipc} \ + allow.raw_sockets=${_allow_raw_sockets} \ + allow.chflags=${_allow_chflags} \ + allow.mount=${_allow_mount} \ + allow.socket_af=${_allow_socket_af} \ + allow.quotas=${allow_quotas}" } # set_sysctl rc_knob mib msg @@ -345,6 +403,36 @@ mount -a -F "${_fstab}" } +# jail_zfs_jailin +# Make zfs datasets manageable from inside a jail +# the "jailed" dataset property must be set to "on" +jail_zfs_jailin() +{ + if [ -n "${_zfs}" ]; then + for _ds in ${_zfs}; do + _jailed=`zfs get -H jailed ${_ds} 2>/dev/null | awk '{ print $3 }'` + if [ "$_jailed" = "on" ]; then + zfs jail "${_jail_id}" ${_ds} 2>/dev/null + fi + done + fi +} + +# jail_zfs_jailout +# Unjail zfs datasets +# the "jailed" dataset property must be set to "on" +jail_zfs_jailout() +{ + if [ -n "${_zfs}" ]; then + for _ds in ${_zfs}; do + _jailed=`zfs get -H jailed ${_ds} 2>/dev/null | awk '{ print $3 }'` + if [ "$_jailed" = "on" ]; then + zfs unjail "${_jail_id}" ${_ds} 2>/dev/null + fi + done + fi +} + # jail_show_addresses jail # Debug print the input for the given _multi aliases # for a jail for init_variables(). @@ -483,10 +571,27 @@ *) ;; esac - # Append address to list of addresses for the jail command. - case "${_addrl}" in - "") _addrl="${_addr}" ;; - *) _addrl="${_addrl},${_addr}" ;; + case "${_type}" in + inet) + # Append address to list of ipv4 addresses for the + # jail command. + case "${_addrl}" in + "") _addrl="${_addr}" ;; + *) _addrl="${_addrl},${_addr}" ;; + esac + ;; + inet6) + # Append address to list of ipv6 addresses for the + # jail command. + case "${_addrl6}" in + "") _addrl6="${_addr}" ;; + *) _addrl6="${_addrl6},${_addr}" ;; + esac + ;; + *) warn "Could not determine address family. Not going" \ + "to set address '${_addr}' for ${_jail}." + continue + ;; esac # Configure interface alias if requested by a given interface @@ -494,14 +599,7 @@ case "${_iface}" in "") continue ;; esac - case "${_type}" in - inet) ;; - inet6) ;; - *) warn "Could not determine address family. Not going" \ - "to ${_action} address '${_addr}' for ${_jail}." - continue - ;; - esac + case "${_action}" in add) ifconfig ${_iface} ${_type} ${_addr}${_mask} alias ;; @@ -576,6 +674,7 @@ continue; fi _addrl="" + _addrl6="" jail_ips "add" if [ -n "${_fib}" ]; then _setfib="setfib -F '${_fib}'" @@ -644,42 +743,54 @@ i=$((i + 1)) done - eval ${_setfib} jail ${_flags} -i ${_rootdir} ${_hostname} \ - \"${_addrl}\" ${_exec_start} > ${_tmp_jail} 2>&1 \ - </dev/null + _jail_id=`${_setfib} jail -i ${_flags} -c \ + path="${_rootdir}" \ + host.hostname="${_hostname}" \ + ip4.addr="${_addrl}" \ + ip6.addr="${_addrl6}" \ + persist=1 \ + ${_security_params} ${_params}` - if [ "$?" -eq 0 ] ; then - _jail_id=$(head -1 ${_tmp_jail}) - i=1 - while : ; do - eval out=\"\${_exec_afterstart${i}:-''}\" + if [ -n "$_jail_id" ]; then + jail_zfs_jailin + eval jail ${_flags} -m jid="${_jail_id}" \ + command="${_exec_start}" > ${_tmp_jail} 2>&1 \ + </dev/null + if [ "$?" -eq 0 ] ; then + jail -m jid="${_jail_id}" persist=0 + i=1 + while : ; do + eval out=\"\${_exec_afterstart${i}:-''}\" - if [ -z "$out" ]; then - break; - fi + if [ -z "$out" ]; then + break; + fi - jexec "${_jail_id}" ${out} - i=$((i + 1)) - done + jexec "${_jail_id}" ${out} + i=$((i + 1)) + done - echo -n " $_hostname" - tail +2 ${_tmp_jail} >${_consolelog} - echo ${_jail_id} > /var/run/jail_${_jail}.id + echo -n " $_hostname" + tail +2 ${_tmp_jail} >${_consolelog} + echo ${_jail_id} > /var/run/jail_${_jail}.id - i=0 - while : ; do - eval out=\"\${_exec_poststart${i}:-''}\" - [ -z "$out" ] && break - ${out} - i=$((i + 1)) - done - else - jail_umount_fs - jail_ips "del" - echo " cannot start jail \"${_jail}\": " - tail +2 ${_tmp_jail} + i=0 + while : ; do + eval out=\"\${_exec_poststart${i}:-''}\" + [ -z "$out" ] && break + ${out} + i=$((i + 1)) + done + else + jail_zfs_jailout + jail -m jid="${_jail_id}" persist=0 + jail_umount_fs + jail_ips "del" + echo " cannot start jail \"${_jail}\": " + tail +2 ${_tmp_jail} + fi + rm -f ${_tmp_jail} fi - rm -f ${_tmp_jail} done rmdir ${_tmp_dir} echo '.' @@ -707,6 +818,7 @@ eval env -i /usr/sbin/jexec ${_jail_id} ${_exec_stop} \ >> ${_consolelog} 2>&1 fi + jail_zfs_jailout killall -j ${_jail_id} -TERM > /dev/null 2>&1 sleep 1 killall -j ${_jail_id} -KILL > /dev/null 2>&1 Index: etc/defaults/devfs.rules =================================================================== --- etc/defaults/devfs.rules (revision 224471) +++ etc/defaults/devfs.rules (working copy) @@ -83,3 +83,9 @@ add include $devfsrules_hide_all add include $devfsrules_unhide_basic add include $devfsrules_unhide_login + +# Jail with zfs support +# +[devfsrules_jail_zfs=5] +add include $devfsrules_jail +add path zfs unhide Index: etc/defaults/rc.conf =================================================================== --- etc/defaults/rc.conf (revision 224471) +++ etc/defaults/rc.conf (working copy) @@ -695,6 +695,21 @@ #jail_example_mount_enable="NO" # mount/umount jail's fs #jail_example_fstab="" # fstab(5) for mount/umount #jail_example_flags="-l -U root" # flags for jail(8) +#jail_example_params="" # additional parameters for jail(8) +#jail_example_enforce_statfs="" # jail(8) enforce_statfs parameter +#jail_example_allow_set_hostname="" # jail(8) allow.set_hostname parameter +#jail_example_allow_sysvipc="" # jail(8) allow.sysvipc parameter +#jail_example_allow_raw_sockets="" # jail(8) allow.raw_sockets parameter +#jail_example_allow_chflags="" # jail(8) allow.chflags parameter +#jail_example_allow_mount="" # jail(8) allow.mount parameter +#jail_example_allow_socket_af="" # jail(8) allow.socket_af parameter +#jail_example_allow_quotas="" # jail(8) allow.quotas parameter +#jail_example_zfs="" # Space-separated list of ZFS datasets to be + # managed from this jail. For proper operation, + # allow_mount must be defined and enforce_statfs + # must be lower than 2. The "jailed" property + # must be set to "on" on these datasets before starting + # the jail. ############################################################## ### Define source_rc_confs, the mechanism used by /etc/rc.* ## --------------000605040303080100060003--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4E316E19.9040309>