Date: Sun, 06 Oct 2013 10:23:10 +0900 (JST) From: Hiroki Sato <hrs@FreeBSD.org> To: des@des.no Cc: arch@FreeBSD.org, dteske@FreeBSD.org, jamie@FreeBSD.org, slw@zxy.spb.ru Subject: Re: jail configuration Message-ID: <20131006.102310.20550923549608963.hrs@allbsd.org> In-Reply-To: <86d2o8k6zf.fsf@nine.des.no> References: <86k3igki36.fsf@nine.des.no> <13CA24D6AB415D428143D44749F57D720FBCA6EB@LTCFISWMSGMB21.FNFIS.com> <86d2o8k6zf.fsf@nine.des.no>
next in thread | previous in thread | raw e-mail | index | archive | help
----Security_Multipart0(Sun_Oct__6_10_23_10_2013_987)-- Content-Type: Multipart/Mixed; boundary="--Next_Part(Sun_Oct__6_10_23_10_2013_182)--" Content-Transfer-Encoding: 7bit ----Next_Part(Sun_Oct__6_10_23_10_2013_182)-- Content-Type: Text/Plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Dag-Erling Sm=F8rgrav <des@des.no> wrote in <86d2o8k6zf.fsf@nine.des.no>: de> "Teske, Devin" <Devin.Teske@fisglobal.com> writes: de> > I've been thinking about maybe writing a tool (or 2). Options on = the table: de> > de> > 1. Tool like sysrc that allows you to modify/maintain jail.conf f= rom CLI? de> > 2. Tool to migrate from rc.conf to jail.conf? de> > 3. Both? de> = de> A shell script that does 2. should be sufficient, IMHO. I tried to rewrite a rc.d/jail with backward compatibility. It still looks complex but LOC falls into one-half. I think we can remove the compat part later before 11.0. After the removal, this will be much similar to your patch. A patch for jail(8) is a small bug fix. a) config file support jail_enable=3D"YES" jail_conf=3D"/etc/jail.conf" # /etc/jail.conf if not specified. jail_list=3D"hosta hostb" # all of instances if not specified. b) old rc.conf variables support (will be removed eventually) jail_enable=3D"YES" jail_list=3D"hosta hostb" jail_hosta_hostname=3D"hosta.example.com" jail_hosta_ip=3D"192.168.2.1,192.168.2.2" jail_hosta_rootdir=3D"/jail/hosta" .... These configuration variables will be converted into /var/run/jail_{name}.conf. While this is basically backward compatible, procfs_enable and fdescfs_enable are not supported. c) mixed environment Even if /etc/jail.conf exists, rc.d/jail attempts to create and use /var/run/jail_{name}.conf when both jail_{name}_hostname and jail_{name}_rootdir are defined. If not defined, it attempts to use /etc/jail.conf (or $jail_conf). This decision is made in a per-jail basis. d) conversion from rc.conf variables to config file # /etc/rc.d/jail config <name in jail_list> /var/run/jail_{name}.conf is created. I think this do not break the existing configurations (more testing needed, of course) and one can convert by "rc.d/jail convert" and copy-n-paste the results to /etc/jail.conf. If one uses /etc/jail.conf, just $jail_enable variable will do the trick. What do you think about this? -- Hiroki ----Next_Part(Sun_Oct__6_10_23_10_2013_182)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="jail_20131006-1.diff" Index: etc/rc.d/jail =================================================================== --- etc/rc.d/jail (revision 256066) +++ etc/rc.d/jail (working copy) @@ -8,27 +8,84 @@ # BEFORE: securelevel # KEYWORD: nojail shutdown -# WARNING: This script deals with untrusted data (the data and -# processes inside the jails) and care must be taken when changing the -# code related to this! If you have any doubt whether a change is -# correct and have security impact, please get the patch reviewed by -# the FreeBSD Security Team prior to commit. - . /etc/rc.subr name="jail" rcvar="jail_enable" -start_precmd="jail_prestart" start_cmd="jail_start" stop_cmd="jail_stop" +config_cmd="jail_config" +console_cmd="jail_console" +status_cmd="jail_status" +extra_commands="config console status" +need_dad_wait= +: ${jail_conf:=/etc/jail.conf} +: ${jail_program:=/usr/sbin/jail} +: ${jail_consolecmd:=/bin/sh} +: ${jail_jexec:=/usr/sbin/jexec} +: ${jail_jls:=/usr/sbin/jls} -# init_variables _j -# Initialize the various jail variables for jail _j. +# extact_var jail name param num defval +# Extract value from ${jail_$jail_$name} or ${jail_$name} and +# set it to $param. If not defined, $defval is used. +# When $num is [0-9]*, ${jail_$jail_$name$num} are looked up and +# $param is set by using +=. +# When $num is YN or NY, the value is interpret as boolean. +extract_var() +{ + local i _j _name _param _num _def + _j=$1 + _name=$2 + _param=$3 + _num=$4 + _def=$5 + + case $_num in + YN) + eval : \${jail_${_j}_${_name}:=\${jail_${_name}:-${_def}}} + if checkyesno jail_${_j}_$_name; then + echo " $_param = 1;" + else + echo " $_param = 0;" + fi + ;; + NY) + eval : \${jail_${_j}_${_name}:=\${jail_${_name}:-${_def}}} + if checkyesno jail_${_j}_$_name; then + echo " $_param = 0;" + else + echo " $_param = 1;" + fi + ;; + [0-9]*) + i=$_num + while : ; do + eval _tmpargs=\"\${jail_${_j}_${_name}${i}:-\${jail_${_name}${i}:-${_def}}}\" + if [ -n "$_tmpargs" ]; then + echo " $_param += \"$_tmpargs\";" + else + break; + fi + i=$(($i + 1)) + done + ;; + *) + eval _tmpargs=\"\${jail_${_j}_${_name}:-\${jail_${_name}:-${_def}}}\" + if [ -n "$_tmpargs" ]; then + echo " $_param = \"$_tmpargs\";" + fi + ;; + esac +} + +# parse_options _j +# Parse options and create a temporary configuration file if necessary. # -init_variables() +parse_options() { - _j="$1" + local _j + _j=$1 if [ -z "$_j" ]; then warn "init_variables: you must specify a jail" @@ -36,53 +93,43 @@ fi eval _rootdir=\"\$jail_${_j}_rootdir\" + eval _hostname=\"\$jail_${_j}_hostname\" + if [ -z "$_rootdir" -o \ + -z "$_hostname" ]; then + if [ -r /etc/jail.${_j}.conf ]; then + _conf=/etc/jail.${_j}.conf + return 0 + elif [ -r "$jail_conf" ]; then + _conf="$jail_conf" + return 0 + else + warn "Invalid configuration for $_j " \ + "(no hostname or no path). " \ + "Jail $_j was ignored." + fi + return 1 + fi + eval _ip=\"\$jail_${_j}_ip\" + if [ -z "$_ip" ] && ! check_kern_features vimage; then + warn "no ipaddress specified and no vimage support. " \ + "Jail $_j was ignored." + return 1 + fi _devdir="${_rootdir}/dev" _fdescdir="${_devdir}/fd" _procdir="${_rootdir}/proc" - eval _hostname=\"\$jail_${_j}_hostname\" - eval _ip=\"\$jail_${_j}_ip\" - eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\" - eval _exec=\"\$jail_${_j}_exec\" + _conf=/var/run/jail.${_j}.conf - i=0 - while : ; do - eval _exec_prestart${i}=\"\${jail_${_j}_exec_prestart${i}:-\${jail_exec_prestart${i}}}\" - [ -z "$(eval echo \"\$_exec_prestart${i}\")" ] && break - i=$((i + 1)) - done + # To relieve confusion, show a warning message. + if [ -r "$jail_conf" ]; then + warn "$_conf is created and used for jail $_j." + fi + /usr/bin/install -m 0644 -o root -g wheel /dev/null $_conf || return 1 - eval _exec_start=\"\${jail_${_j}_exec_start:-${jail_exec_start}}\" - - i=1 - while : ; do - eval _exec_afterstart${i}=\"\${jail_${_j}_exec_afterstart${i}:-\${jail_exec_afterstart${i}}}\" - [ -z "$(eval echo \"\$_exec_afterstart${i}\")" ] && break - i=$((i + 1)) - done - - i=0 - while : ; do - eval _exec_poststart${i}=\"\${jail_${_j}_exec_poststart${i}:-\${jail_exec_poststart${i}}}\" - [ -z "$(eval echo \"\$_exec_poststart${i}\")" ] && break - i=$((i + 1)) - done - - i=0 - while : ; do - eval _exec_prestop${i}=\"\${jail_${_j}_exec_prestop${i}:-\${jail_exec_prestop${i}}}\" - [ -z "$(eval echo \"\$_exec_prestop${i}\")" ] && break - i=$((i + 1)) - done - - eval _exec_stop=\"\${jail_${_j}_exec_stop:-${jail_exec_stop}}\" - - i=0 - while : ; do - eval _exec_poststop${i}=\"\${jail_${_j}_exec_poststop${i}:-\${jail_exec_poststop${i}}}\" - [ -z "$(eval echo \"\$_exec_poststop${i}\")" ] && break - i=$((i + 1)) - done - + eval : \${jail_${_j}_flags:=${jail_flags}} + eval _exec=\"\$jail_${_j}_exec\" + eval _exec_start=\"\$jail_${_j}_exec_start\" + eval _exec_stop=\"\$jail_${_j}_exec_stop\" if [ -n "${_exec}" ]; then # simple/backward-compatible execution _exec_start="${_exec}" @@ -96,285 +143,86 @@ fi fi fi - - # The default jail ruleset will be used by rc.subr if none is specified. - eval _ruleset=\"\${jail_${_j}_devfs_ruleset:-${jail_devfs_ruleset}}\" - eval _devfs=\"\${jail_${_j}_devfs_enable:-${jail_devfs_enable}}\" - [ -z "${_devfs}" ] && _devfs="NO" - eval _fdescfs=\"\${jail_${_j}_fdescfs_enable:-${jail_fdescfs_enable}}\" - [ -z "${_fdescfs}" ] && _fdescfs="NO" - eval _procfs=\"\${jail_${_j}_procfs_enable:-${jail_procfs_enable}}\" - [ -z "${_procfs}" ] && _procfs="NO" - - eval _mount=\"\${jail_${_j}_mount_enable:-${jail_mount_enable}}\" - [ -z "${_mount}" ] && _mount="NO" - # "/etc/fstab.${_j}" will be used for {,u}mount(8) if none is specified. - eval _fstab=\"\${jail_${_j}_fstab:-${jail_fstab}}\" - [ -z "${_fstab}" ] && _fstab="/etc/fstab.${_j}" - eval _flags=\"\${jail_${_j}_flags:-${jail_flags}}\" - [ -z "${_flags}" ] && _flags="-l -U root" - eval _consolelog=\"\${jail_${_j}_consolelog:-${jail_consolelog}}\" - [ -z "${_consolelog}" ] && _consolelog="/var/log/jail_${_j}_console.log" + eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\" eval _parameters=\"\${jail_${_j}_parameters:-${jail_parameters}}\" - [ -z "${_parameters}" ] && _parameters="" - eval _fib=\"\${jail_${_j}_fib:-${jail_fib}}\" + eval _fstab=\"\${jail_${_j}_fstab:-${jail_fstab:-/etc/fstab.$_j}}\" + ( + date +"# Generated by rc.d/jail at %Y-%m-%d %H:%M:%S" + echo "$_j {" + extract_var $_j hostname host.hostname - "" + extract_var $_j rootdir path - "" + if [ -n "$_ip" ]; then + extract_var $_j interface interface - "" + jail_handle_ips_option $_ip $_interface + alias=0 + while : ; do + eval _x=\"\$jail_${_jail}_ip_multi${alias}\" + [ -z "$_x" ] && break - # Debugging aid - # - debug "$_j devfs enable: $_devfs" - debug "$_j fdescfs enable: $_fdescfs" - debug "$_j procfs enable: $_procfs" - debug "$_j mount enable: $_mount" - debug "$_j hostname: $_hostname" - debug "$_j ip: $_ip" - jail_show_addresses ${_j} - debug "$_j interface: $_interface" - debug "$_j fib: $_fib" - debug "$_j root: $_rootdir" - debug "$_j devdir: $_devdir" - debug "$_j fdescdir: $_fdescdir" - debug "$_j procdir: $_procdir" - debug "$_j ruleset: $_ruleset" - debug "$_j fstab: $_fstab" - - i=0 - while : ; do - eval out=\"\${_exec_prestart${i}:-''}\" - if [ -z "$out" ]; then - break + jail_handle_ips_option $_x $_interface + alias=$(($alias + 1)) + done + case $need_dad_wait in + 1) + # Sleep to let DAD complete before + # starting services. + echo " exec.start += \"sleep " \ + $(($(${SYSCTL_N} net.inet6.ip6.dad_count) + 1)) \ + "\";" + ;; + esac + # These are applicable only to non-vimage jails. + extract_var $_j fib exec.fib - "" + extract_var $_j socket_unixiproute_only \ + allow.raw_sockets NY YES + _vnet=0 + else + echo " vnet;" + _vnet=1 fi - debug "$_j exec pre-start #${i}: ${out}" - i=$((i + 1)) - done - debug "$_j exec start: $_exec_start" + echo " exec.clean;" + echo " exec.system_user = \"root\";" + echo " exec.jail_user = \"root\";" + extract_var $_j exec_prestart exec.prestart 0 "" + extract_var $_j exec_poststart exec.poststart 0 "" + extract_var $_j exec_prestop exec.prestop 0 "" + extract_var $_j exec_poststop exec.poststop 0 "" - i=1 - while : ; do - eval out=\"\${_exec_afterstart${i}:-''}\" + echo " exec.start += \"$_exec_start\";" + extract_var $_j exec_afterstart exec.start 1 "" + echo " exec.stop = \"$_exec_stop\";" - if [ -z "$out" ]; then - break; - fi + extract_var $_j consolelog exec.consolelog - \ + /var/log/jail_${_j}_console.log - debug "$_j exec after start #${i}: ${out}" - i=$((i + 1)) - done - - i=0 - while : ; do - eval out=\"\${_exec_poststart${i}:-''}\" - if [ -z "$out" ]; then - break + eval : \${jail_${_j}_devfs_enable:=${jail_devfs_enable:-NO}} + if checkyesno jail_${_j}_devfs_enable; then + echo " mount.devfs;" + extract_var $_j devfs_ruleset devfs_ruleset - 4 + if [ -r $_fstab ]; then + echo " mount.fstab = \"$_fstab\";" + fi fi - debug "$_j exec post-start #${i}: ${out}" - i=$((i + 1)) - done - i=0 - while : ; do - eval out=\"\${_exec_prestop${i}:-''}\" - if [ -z "$out" ]; then - break - fi - debug "$_j exec pre-stop #${i}: ${out}" - i=$((i + 1)) - done + # fdescfs and procfs should be added for backward compatibility. - debug "$_j exec stop: $_exec_stop" + echo " ${_parameters};" - i=0 - while : ; do - eval out=\"\${_exec_poststop${i}:-''}\" - if [ -z "$out" ]; then - break + eval : \${jail_${_j}_mount_enable:=${jail_mount_enable:-NO}} + if checkyesno jail_${_j}_mount_enable; then + echo " allow.mount;" >> $_conf fi - debug "$_j exec post-stop #${i}: ${out}" - i=$((i + 1)) - done - debug "$_j flags: $_flags" - debug "$_j consolelog: $_consolelog" - debug "$_j parameters: $_parameters" + extract_var $_j set_hostname_allow allow.set_hostname YN NO + extract_var $_j sysvipc_allow allow.sysvipc YN NO + echo "}" + ) >> $_conf - if [ -z "${_hostname}" ]; then - err 3 "$name: No hostname has been defined for ${_j}" - fi - if [ -z "${_rootdir}" ]; then - err 3 "$name: No root directory has been defined for ${_j}" - fi + return 0 } -# set_sysctl rc_knob mib msg -# If the mib sysctl is set according to what rc_knob -# specifies, this function does nothing. However if -# rc_knob is set differently than mib, then the mib -# is set accordingly and msg is displayed followed by -# an '=" sign and the word 'YES' or 'NO'. -# -set_sysctl() -{ - _knob="$1" - _mib="$2" - _msg="$3" - - _current=`${SYSCTL} -n $_mib 2>/dev/null` - if checkyesno $_knob ; then - if [ "$_current" -ne 1 ]; then - echo -n " ${_msg}=YES" - ${SYSCTL} 1>/dev/null ${_mib}=1 - fi - else - if [ "$_current" -ne 0 ]; then - echo -n " ${_msg}=NO" - ${SYSCTL} 1>/dev/null ${_mib}=0 - fi - fi -} - -# is_current_mountpoint() -# Is the directory mount point for a currently mounted file -# system? -# -is_current_mountpoint() -{ - local _dir _dir2 - - _dir=$1 - - _dir=`echo $_dir | sed -Ee 's#//+#/#g' -e 's#/$##'` - [ ! -d "${_dir}" ] && return 1 - _dir2=`df ${_dir} | tail +2 | awk '{ print $6 }'` - [ "${_dir}" = "${_dir2}" ] - return $? -} - -# is_symlinked_mountpoint() -# Is a mount point, or any of its parent directories, a symlink? -# -is_symlinked_mountpoint() -{ - local _dir - - _dir=$1 - - [ -L "$_dir" ] && return 0 - [ "$_dir" = "/" ] && return 1 - is_symlinked_mountpoint `dirname $_dir` - return $? -} - -# secure_umount -# Try to unmount a mount point without being vulnerable to -# symlink attacks. -# -secure_umount() -{ - local _dir - - _dir=$1 - - if is_current_mountpoint ${_dir}; then - umount -f ${_dir} >/dev/null 2>&1 - else - debug "Nothing mounted on ${_dir} - not unmounting" - fi -} - - -# jail_umount_fs -# This function unmounts certain special filesystems in the -# currently selected jail. The caller must call the init_variables() -# routine before calling this one. -# -jail_umount_fs() -{ - local _device _mountpt _rest - - if checkyesno _fdescfs; then - if [ -d "${_fdescdir}" ] ; then - secure_umount ${_fdescdir} - fi - fi - if checkyesno _devfs; then - if [ -d "${_devdir}" ] ; then - secure_umount ${_devdir} - fi - fi - if checkyesno _procfs; then - if [ -d "${_procdir}" ] ; then - secure_umount ${_procdir} - fi - fi - if checkyesno _mount; then - [ -f "${_fstab}" ] || warn "${_fstab} does not exist" - tail -r ${_fstab} | while read _device _mountpt _rest; do - case ":${_device}" in - :#* | :) - continue - ;; - esac - secure_umount ${_mountpt} - done - fi -} - -# jail_mount_fstab() -# Mount file systems from a per jail fstab while trying to -# secure against symlink attacks at the mount points. -# -# If we are certain we cannot secure against symlink attacks we -# do not mount all of the file systems (since we cannot just not -# mount the file system with the problematic mount point). -# -# The caller must call the init_variables() routine before -# calling this one. -# -jail_mount_fstab() -{ - local _device _mountpt _rest - - while read _device _mountpt _rest; do - case ":${_device}" in - :#* | :) - continue - ;; - esac - if is_symlinked_mountpoint ${_mountpt}; then - warn "${_mountpt} has symlink as parent - not mounting from ${_fstab}" - return - fi - done <${_fstab} - mount -a -F "${_fstab}" -} - -# jail_show_addresses jail -# Debug print the input for the given _multi aliases -# for a jail for init_variables(). -# -jail_show_addresses() -{ - local _j _type alias - _j="$1" - alias=0 - - if [ -z "${_j}" ]; then - warn "jail_show_addresses: you must specify a jail" - return - fi - - while : ; do - eval _addr=\"\$jail_${_j}_ip_multi${alias}\" - if [ -n "${_addr}" ]; then - debug "${_j} ip_multi${alias}: $_addr" - alias=$((${alias} + 1)) - else - break - fi - done -} - -# jail_extract_address argument +# jail_extract_address argument iface # The second argument is the string from one of the _ip # or the _multi variables. In case of a comma separated list # only one argument must be passed in at a time. @@ -382,8 +230,9 @@ # jail_extract_address() { - local _i + local _i _interface _i=$1 + _interface=$2 if [ -z "${_i}" ]; then warn "jail_extract_address: called without input" @@ -439,12 +288,12 @@ _mask=${_mask:-/32} elif [ "${_type}" = "inet6" ]; then - # In case _maske is not set for IPv6, use /128. - _mask=${_mask:-/128} + # In case _maske is not set for IPv6, use /64. + _mask=${_mask:-/64} fi } -# jail_handle_ips_option {add,del} input +# jail_handle_ips_option input iface # Handle a single argument imput which can be a comma separated # list of addresses (theoretically with an option interface and # prefix/netmask/prefixlen). @@ -451,9 +300,9 @@ # jail_handle_ips_option() { - local _x _action _type _i - _action=$1 - _x=$2 + local _x _type _i _iface + _x=$1 + _iface=$2 if [ -z "${_x}" ]; then # No IP given. This can happen for the primary address @@ -468,282 +317,134 @@ *,*) # Extract the first argument and strip it off the list. _i=`expr "${_x}" : '^\([^,]*\)'` _x=`expr "${_x}" : "^[^,]*,\(.*\)"` - ;; + ;; *) _i=${_x} _x="" - ;; + ;; esac _type="" - _iface="" _addr="" _mask="" - jail_extract_address "${_i}" + jail_extract_address $_i $_iface # make sure we got an address. - case "${_addr}" in + case $_addr in "") continue ;; *) ;; esac # Append address to list of addresses for the jail command. - case "${_type}" in + case $_type in inet) - case "${_addrl}" in - "") _addrl="${_addr}" ;; - *) _addrl="${_addrl},${_addr}" ;; - esac - ;; + echo " ip4.addr += \"${_addr}${_mask}\";" + ;; inet6) - case "${_addr6l}" in - "") _addr6l="${_addr}" ;; - *) _addr6l="${_addr6l},${_addr}" ;; - esac - ;; + echo " ip6.addr += \"${_addr}${_mask}\";" + need_dad_wait=1 + ;; esac - - # Configure interface alias if requested by a given interface - # and if we could correctly parse everything. - case "${_iface}" in - "") continue ;; - esac - case "${_type}" in - inet) ;; - inet6) ipv6_address_count=$((ipv6_address_count + 1)) ;; - *) 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 - ;; - del) # When removing the IP, ignore the _mask. - ifconfig ${_iface} ${_type} ${_addr} -alias - ;; - esac done } -# jail_ips {add,del} -# Extract the comma separated list of addresses and return them -# for the jail command. -# Handle more than one address via the _multi option as well. -# If an interface is given also add/remove an alias for the -# address with an optional netmask. -# -jail_ips() + +jail_config() { - local _action - _action=$1 - - case "${_action}" in - add) ;; - del) ;; - *) warn "jail_ips: invalid action '${_action}'" - return - ;; + case $1 in + _ALL) return ;; esac - - # Handle addresses. - ipv6_address_count=0 - jail_handle_ips_option ${_action} "${_ip}" - # Handle jail_xxx_ip_multi<N> - alias=0 - while : ; do - eval _x=\"\$jail_${_jail}_ip_multi${alias}\" - case "${_x}" in - "") break ;; - *) jail_handle_ips_option ${_action} "${_x}" - alias=$((${alias} + 1)) - ;; - esac + for _jail in $@; do + if parse_options $_jail; then + echo "$_jail: parameters are in $_conf." + fi done - case ${ipv6_address_count} in - 0) ;; - *) # Sleep 1 second to let DAD complete before starting services. - sleep 1 - ;; - esac } -jail_prestart() +jail_console() { - if checkyesno jail_parallel_start; then - command_args='&' + if [ $# != 1 ]; then + err 3 "Specify a jail name." fi + case $1 in + _ALL) err 3 "Specify a jail name." ;; + esac + eval _cmd=\${jail_$1_consolecmd:-${jail_consolecmd}} + $jail_jexec $1 $_cmd } +jail_status() +{ + + $jail_jls -N +} + jail_start() { - echo -n 'Configuring jails:' - set_sysctl jail_set_hostname_allow security.jail.set_hostname_allowed \ - set_hostname_allow - set_sysctl jail_socket_unixiproute_only \ - security.jail.socket_unixiproute_only unixiproute_only - set_sysctl jail_sysvipc_allow security.jail.sysvipc_allowed \ - sysvipc_allow - echo '.' + if [ $# = 0 ]; then + return + fi + echo -n 'Starting jails:' + case $1 in + _ALL) + echo -n ' ' + command=$jail_program + rc_flags=$jail_flags + command_args="-f $jail_conf -c" + $command $rc_flags $command_args "*" + echo '.' + return + ;; + esac + _tmp=`mktemp -t jail` || exit 3 + for _jail in $@; do + parse_options $_jail || continue - echo -n 'Starting jails:' - _tmp_dir=`mktemp -d /tmp/jail.XXXXXXXX` || \ - err 3 "$name: Can't create temp dir, exiting..." - for _jail in ${jail_list} - do - init_variables $_jail - if [ -f /var/run/jail_${_jail}.id ]; then - echo -n " [${_hostname} already running (/var/run/jail_${_jail}.id exists)]" - continue; - fi - _addrl="" - _addr6l="" - jail_ips "add" - if [ -n "${_fib}" ]; then - _setfib="setfib -F '${_fib}'" + eval rc_flags=\${jail_${_j}_flags:-$jail_flags} + eval command=\${jail_${_j}_program:-$jail_program} + if checkyesno jail_parallel_start; then + command_args="-i -f $_conf -c $_jail &" else - _setfib="" + command_args="-i -f $_conf -c $_jail" fi - if checkyesno _mount; then - info "Mounting fstab for jail ${_jail} (${_fstab})" - if [ ! -f "${_fstab}" ]; then - err 3 "$name: ${_fstab} does not exist" - fi - jail_mount_fstab - fi - if checkyesno _devfs; then - # If devfs is already mounted here, skip it. - df -t devfs "${_devdir}" >/dev/null - if [ $? -ne 0 ]; then - if is_symlinked_mountpoint ${_devdir}; then - warn "${_devdir} has symlink as parent - not starting jail ${_jail}" - continue - fi - info "Mounting devfs on ${_devdir}" - devfs_mount_jail "${_devdir}" ${_ruleset} - # Transitional symlink for old binaries - if [ ! -L "${_devdir}/log" ]; then - ln -sf ../var/run/log "${_devdir}/log" - fi - fi - - # XXX - It seems symlinks don't work when there - # is a devfs(5) device of the same name. - # Jail console output - # __pwd="`pwd`" - # cd "${_devdir}" - # ln -sf ../var/log/console console - # cd "$__pwd" - fi - if checkyesno _fdescfs; then - if is_symlinked_mountpoint ${_fdescdir}; then - warn "${_fdescdir} has symlink as parent, not mounting" - else - info "Mounting fdescfs on ${_fdescdir}" - mount -t fdescfs fdesc "${_fdescdir}" - fi - fi - if checkyesno _procfs; then - if is_symlinked_mountpoint ${_procdir}; then - warn "${_procdir} has symlink as parent, not mounting" - else - info "Mounting procfs onto ${_procdir}" - if [ -d "${_procdir}" ] ; then - mount -t procfs proc "${_procdir}" - fi - fi - fi - _tmp_jail=${_tmp_dir}/jail.$$ - - i=0 - while : ; do - eval out=\"\${_exec_prestart${i}:-''}\" - [ -z "$out" ] && break - ${out} - i=$((i + 1)) - done - - eval ${_setfib} jail -n ${_jail} ${_flags} -i -c path=${_rootdir} host.hostname=${_hostname} \ - ${_addrl:+ip4.addr=\"${_addrl}\"} ${_addr6l:+ip6.addr=\"${_addr6l}\"} \ - ${_parameters} command=${_exec_start} > ${_tmp_jail} 2>&1 \ - </dev/null - - if [ "$?" -eq 0 ] ; then - _jail_id=$(head -1 ${_tmp_jail}) - i=1 - while : ; do - eval out=\"\${_exec_afterstart${i}:-''}\" - - if [ -z "$out" ]; then - break; - fi - - jexec "${_jail_id}" ${out} - i=$((i + 1)) - done - - 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 + case $_vnet in + 0) eval _fib=\${jail_${_j}_fib:-${jail_fib}} ;; + *) _fib= ;; + esac + if ${_fib:+${SETFIB_CMD} -F $_fib} \ + $command $rc_flags $command_args \ + >> $_tmp 2>&1 </dev/null; then + echo -n " ${_hostname:-${_jail}}" else - jail_umount_fs - jail_ips "del" - echo " cannot start jail \"${_jail}\": " - tail +2 ${_tmp_jail} + echo " cannot start jail \"${_hostname:-${jail}}\": " + tail +2 $_tmp fi - rm -f ${_tmp_jail} + rm -f $_tmp done - rmdir ${_tmp_dir} echo '.' } jail_stop() { + if [ $# = 0 ]; then + return + fi echo -n 'Stopping jails:' - for _jail in ${jail_list} - do - if [ -f "/var/run/jail_${_jail}.id" ]; then - _jail_id=$(cat /var/run/jail_${_jail}.id) - if [ ! -z "${_jail_id}" ]; then - init_variables $_jail - - i=0 - while : ; do - eval out=\"\${_exec_prestop${i}:-''}\" - [ -z "$out" ] && break - ${out} - i=$((i + 1)) - done - - if [ -n "${_exec_stop}" ]; then - eval env -i /usr/sbin/jexec ${_jail_id} ${_exec_stop} \ - >> ${_consolelog} 2>&1 - fi - killall -j ${_jail_id} -TERM > /dev/null 2>&1 - sleep 1 - killall -j ${_jail_id} -KILL > /dev/null 2>&1 - jail_umount_fs - echo -n " $_hostname" - - i=0 - while : ; do - eval out=\"\${_exec_poststop${i}:-''}\" - [ -z "$out" ] && break - ${out} - i=$((i + 1)) - done - fi - jail_ips "del" - rm /var/run/jail_${_jail}.id - else - echo " cannot stop jail ${_jail}. No jail id in /var/run" + case $1 in + _ALL) + echo -n ' ' + command=$jail_program + rc_flags=$jail_flags + command_args="-f $jail_conf -r" + $command $rc_flags $command_args "*" + echo '.' + return + ;; + esac + for _jail in $@; do + parse_options $_jail || continue + eval command=\${jail_${_j}_program:-$jail_program} + if $command -q -f $_conf -r $_jail; then + echo -n " ${_hostname:-${_jail}}" fi done echo '.' @@ -750,12 +451,7 @@ } load_rc_config $name -cmd="$1" -if [ $# -gt 0 ]; then - shift -fi -if [ -n "$*" ]; then - jail_list="$*" -fi - -run_rc_command "${cmd}" +case $# in +1) run_rc_command $@ ${jail_list:-_ALL} ;; +*) run_rc_command $@ ;; +esac Index: usr.sbin/jail/jail.c =================================================================== --- usr.sbin/jail/jail.c (revision 255979) +++ usr.sbin/jail/jail.c (working copy) @@ -470,10 +470,12 @@ if (dep_check(j)) continue; if (j->jid < 0) { - if (!(j->flags & (JF_DEPEND | JF_WILD)) - && verbose >= 0) - jail_quoted_warnx(j, - "not found", NULL); + if (!(j->flags & (JF_DEPEND|JF_WILD))) { + if (verbose >= 0) + jail_quoted_warnx(j, + "not found", NULL); + failed(j); + } goto jail_remove_done; } j->comparam = stopcommands; ----Next_Part(Sun_Oct__6_10_23_10_2013_182)---- ----Security_Multipart0(Sun_Oct__6_10_23_10_2013_987)-- Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.13 (FreeBSD) iEYEABECAAYFAlJQu34ACgkQTyzT2CeTzy2Q2wCfUKcx7Wftbq8flp6g09qhYaxW E54AnjWliuTFHCD60p1JJ7j776Pad+1J =fkbb -----END PGP SIGNATURE----- ----Security_Multipart0(Sun_Oct__6_10_23_10_2013_987)----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20131006.102310.20550923549608963.hrs>