jail revision 159072
170178Sassar#!/bin/sh 270178Sassar# 370178Sassar# $FreeBSD: head/etc/rc.d/jail 159072 2006-05-30 16:20:48Z matteo $ 470178Sassar# 570178Sassar 670178Sassar# PROVIDE: jail 770178Sassar# REQUIRE: LOGIN cleanvar 870178Sassar# BEFORE: securelevel 970178Sassar# KEYWORD: nojail shutdown 1070178Sassar 1170178Sassar. /etc/rc.subr 1270178Sassar 1370178Sassarname="jail" 1470178Sassarrcvar=`set_rcvar` 1597748Sschweikhstart_cmd="jail_start" 1670178Sassarstop_cmd="jail_stop" 1770178Sassar 1870178Sassar# init_variables _j 1970178Sassar# Initialize the various jail variables for jail _j. 2070178Sassar# 2170178Sassarinit_variables() 2270178Sassar{ 2370178Sassar _j="$1" 2470178Sassar 2570178Sassar if [ -z "$_j" ]; then 2670178Sassar warn "init_variables: you must specify a jail" 2770178Sassar return 2870178Sassar fi 2970178Sassar 3070178Sassar eval _rootdir=\"\$jail_${_j}_rootdir\" 3170178Sassar _devdir="${_rootdir}/dev" 3270178Sassar _fdescdir="${_devdir}/fd" 3370178Sassar _procdir="${_rootdir}/proc" 3470178Sassar eval _hostname=\"\$jail_${_j}_hostname\" 3570178Sassar eval _ip=\"\$jail_${_j}_ip\" 3670178Sassar eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\" 3770178Sassar eval _exec=\"\$jail_${_j}_exec\" 3870178Sassar eval _exec_start=\"\${jail_${_j}_exec_start:-${jail_exec_start}}\" 3970178Sassar 4070178Sassar i=1 4170178Sassar while [ true ]; do 4270178Sassar eval _exec_afterstart${i}=\"\${jail_${_j}_exec_afterstart${i}:-\${jail_exec_afterstart${i}}}\" 4370178Sassar [ -z "$(eval echo \"\$_exec_afterstart${i}\")" ] && break 4470178Sassar i=$((i + 1)) 4570178Sassar done 4670178Sassar 4770178Sassar eval _exec_stop=\"\${jail_${_j}_exec_stop:-${jail_exec_stop}}\" 4870178Sassar if [ -n "${_exec}" ]; then 4970178Sassar # simple/backward-compatible execution 5070178Sassar _exec_start="${_exec}" 51192284Sdchagin _exec_stop="" 5270178Sassar else 53185442Skib # flexible execution 54185442Skib if [ -z "${_exec_start}" ]; then 55185442Skib _exec_start="/bin/sh /etc/rc" 56220031Savg if [ -z "${_exec_stop}" ]; then 57185442Skib _exec_stop="/bin/sh /etc/rc.shutdown" 58185442Skib fi 59185442Skib fi 60185442Skib fi 61185442Skib 62185442Skib # The default jail ruleset will be used by rc.subr if none is specified. 63185442Skib eval _ruleset=\"\${jail_${_j}_devfs_ruleset:-${jail_devfs_ruleset}}\" 64185442Skib eval _devfs=\"\${jail_${_j}_devfs_enable:-${jail_devfs_enable}}\" 65185442Skib [ -z "${_devfs}" ] && _devfs="NO" 66185442Skib eval _fdescfs=\"\${jail_${_j}_fdescfs_enable:-${jail_fdescfs_enable}}\" 67185442Skib [ -z "${_fdescfs}" ] && _fdescfs="NO" 68185442Skib eval _procfs=\"\${jail_${_j}_procfs_enable:-${jail_procfs_enable}}\" 69185442Skib [ -z "${_procfs}" ] && _procfs="NO" 70220031Savg 71220031Savg eval _mount=\"\${jail_${_j}_mount_enable:-${jail_mount_enable}}\" 72185442Skib [ -z "${_mount}" ] && _mount="NO" 73185442Skib # "/etc/fstab.${_j}" will be used for {,u}mount(8) if none is specified. 74185442Skib eval _fstab=\"\${jail_${_j}_fstab:-${jail_fstab}}\" 75185442Skib [ -z "${_fstab}" ] && _fstab="/etc/fstab.${_j}" 76185442Skib eval _flags=\"\${jail_${_j}_flags:-${jail_flags}}\" 77220031Savg [ -z "${_flags}" ] && _flags="-l -U root" 78185442Skib 79185442Skib # Debugging aid 80185442Skib # 81185442Skib debug "$_j devfs enable: $_devfs" 82185442Skib debug "$_j fdescfs enable: $_fdescfs" 83185442Skib debug "$_j procfs enable: $_procfs" 84185442Skib debug "$_j mount enable: $_mount" 85185442Skib debug "$_j hostname: $_hostname" 86191876Sdchagin debug "$_j ip: $_ip" 87191876Sdchagin debug "$_j interface: $_interface" 88191876Sdchagin debug "$_j root: $_rootdir" 89191876Sdchagin debug "$_j devdir: $_devdir" 90191876Sdchagin debug "$_j fdescdir: $_fdescdir" 91191876Sdchagin debug "$_j procdir: $_procdir" 92191876Sdchagin debug "$_j ruleset: $_ruleset" 93191876Sdchagin debug "$_j fstab: $_fstab" 94191876Sdchagin debug "$_j exec start: $_exec_start" 95191876Sdchagin 96192205Sdchagin i=1 97192205Sdchagin while [ true ]; do 98192205Sdchagin eval out=\"\${_exec_afterstart${i}:-''}\" 99192205Sdchagin 100192205Sdchagin if [ -z "$out" ]; then 101192205Sdchagin break; 102192205Sdchagin fi 103192205Sdchagin 104192205Sdchagin debug "$_j exec after start #${i}: ${out}" 105192205Sdchagin i=$((i + 1)) 106192206Sdchagin done 107192206Sdchagin 108192206Sdchagin debug "$_j exec stop: $_exec_stop" 109192206Sdchagin debug "$_j flags: $_flags" 110192206Sdchagin 111192206Sdchagin if [ -z "${_hostname}" ]; then 112192206Sdchagin err 3 "$name: No hostname has been defined for ${_j}" 113192203Sdchagin fi 114192203Sdchagin if [ -z "${_rootdir}" ]; then 115192203Sdchagin err 3 "$name: No root directory has been defined for ${_j}" 116192203Sdchagin fi 117192203Sdchagin if [ -z "${_ip}" ]; then 118192203Sdchagin err 3 "$name: No IP address has been defined for ${_j}" 119246085Sjhb fi 120246085Sjhb 121246085Sjhb} 122246085Sjhb 123246085Sjhb# set_sysctl rc_knob mib msg 124246085Sjhb# If the mib sysctl is set according to what rc_knob 125246085Sjhb# specifies, this function does nothing. However if 126246085Sjhb# rc_knob is set differently than mib, then the mib 127246085Sjhb# is set accordingly and msg is displayed followed by 128246085Sjhb# an '=" sign and the word 'YES' or 'NO'. 129246085Sjhb# 130246085Sjhbset_sysctl() 131246085Sjhb{ 132246085Sjhb _knob="$1" 133246085Sjhb _mib="$2" 134246085Sjhb _msg="$3" 135246085Sjhb 136246085Sjhb _current=`${SYSCTL} -n $_mib 2>/dev/null` 137246085Sjhb if checkyesno $_knob ; then 138246085Sjhb if [ "$_current" -ne 1 ]; then 139246085Sjhb echo -n " ${_msg}=YES" 140246085Sjhb ${SYSCTL_W} 1>/dev/null ${_mib}=1 141246085Sjhb fi 142246085Sjhb else 143246085Sjhb if [ "$_current" -ne 0 ]; then 144246085Sjhb echo -n " ${_msg}=NO" 145246085Sjhb ${SYSCTL_W} 1>/dev/null ${_mib}=0 146246085Sjhb fi 147246085Sjhb fi 148246085Sjhb} 149246085Sjhb 150246085Sjhb# jail_umount_fs 151246085Sjhb# This function unmounts certain special filesystems in the 152246085Sjhb# currently selected jail. The caller must call the init_variables() 153246085Sjhb# routine before calling this one. 154246085Sjhb# 155246085Sjhbjail_umount_fs() 156246085Sjhb{ 157246085Sjhb if checkyesno _fdescfs; then 158246085Sjhb if [ -d "${_fdescdir}" ] ; then 15970178Sassar umount -f ${_fdescdir} >/dev/null 2>&1 160 fi 161 fi 162 if checkyesno _devfs; then 163 if [ -d "${_devdir}" ] ; then 164 umount -f ${_devdir} >/dev/null 2>&1 165 fi 166 fi 167 if checkyesno _procfs; then 168 if [ -d "${_procdir}" ] ; then 169 umount -f ${_procdir} >/dev/null 2>&1 170 fi 171 fi 172 if checkyesno _mount; then 173 [ -f "${_fstab}" ] || warn "${_fstab} does not exist" 174 umount -a -F "${_fstab}" >/dev/null 2>&1 175 fi 176} 177 178jail_start() 179{ 180 echo -n 'Configuring jails:' 181 set_sysctl jail_set_hostname_allow security.jail.set_hostname_allowed \ 182 set_hostname_allow 183 set_sysctl jail_socket_unixiproute_only \ 184 security.jail.socket_unixiproute_only unixiproute_only 185 set_sysctl jail_sysvipc_allow security.jail.sysvipc_allowed \ 186 sysvipc_allow 187 echo '.' 188 189 echo -n 'Starting jails:' 190 _tmp_dir=`mktemp -d /tmp/jail.XXXXXXXX` || \ 191 err 3 "$name: Can't create temp dir, exiting..." 192 for _jail in ${jail_list} 193 do 194 init_variables $_jail 195 if [ -f /var/run/jail_${_jail}.id ]; then 196 echo -n " [${_hostname} already running (/var/run/jail_${_jail}.id exists)]" 197 continue; 198 fi 199 if [ -n "${_interface}" ]; then 200 ifconfig ${_interface} alias ${_ip} netmask 255.255.255.255 201 fi 202 if checkyesno _mount; then 203 info "Mounting fstab for jail ${_jail} (${_fstab})" 204 if [ ! -f "${_fstab}" ]; then 205 err 3 "$name: ${_fstab} does not exist" 206 fi 207 mount -a -F "${_fstab}" 208 fi 209 if checkyesno _devfs; then 210 # If devfs is already mounted here, skip it. 211 df -t devfs "${_devdir}" >/dev/null 212 if [ $? -ne 0 ]; then 213 info "Mounting devfs on ${_devdir}" 214 devfs_mount_jail "${_devdir}" ${_ruleset} 215 # Transitional symlink for old binaries 216 if [ ! -L "${_devdir}/log" ]; then 217 __pwd="`pwd`" 218 cd "${_devdir}" 219 ln -sf ../var/run/log log 220 cd "$__pwd" 221 fi 222 fi 223 224 # XXX - It seems symlinks don't work when there 225 # is a devfs(5) device of the same name. 226 # Jail console output 227 # __pwd="`pwd`" 228 # cd "${_devdir}" 229 # ln -sf ../var/log/console console 230 # cd "$__pwd" 231 fi 232 if checkyesno _fdescfs; then 233 info "Mounting fdescfs on ${_fdescdir}" 234 mount -t fdescfs fdesc "${_fdescdir}" 235 fi 236 if checkyesno _procfs; then 237 info "Mounting procfs onto ${_procdir}" 238 if [ -d "${_procdir}" ] ; then 239 mount -t procfs proc "${_procdir}" 240 fi 241 fi 242 _tmp_jail=${_tmp_dir}/jail.$$ 243 eval jail ${_flags} -i ${_rootdir} ${_hostname} \ 244 ${_ip} ${_exec_start} > ${_tmp_jail} 2>&1 245 246 if [ "$?" -eq 0 ] ; then 247 _jail_id=$(head -1 ${_tmp_jail}) 248 i=1 249 while [ true ]; do 250 eval out=\"\${_exec_afterstart${i}:-''}\" 251 252 if [ -z "$out" ]; then 253 break; 254 fi 255 256 jexec "${_jail_id}" ${out} 257 i=$((i + 1)) 258 done 259 260 echo -n " $_hostname" 261 tail +2 ${_tmp_jail} >${_rootdir}/var/log/console.log 262 echo ${_jail_id} > /var/run/jail_${_jail}.id 263 else 264 jail_umount_fs 265 if [ -n "${jail_interface}" ]; then 266 ifconfig ${jail_interface} -alias ${jail_ip} 267 fi 268 echo " cannot start jail \"${_jail}\": " 269 tail +2 ${_tmp_jail} 270 fi 271 rm -f ${_tmp_jail} 272 done 273 rmdir ${_tmp_dir} 274 echo '.' 275} 276 277jail_stop() 278{ 279 echo -n 'Stopping jails:' 280 for _jail in ${jail_list} 281 do 282 if [ -f "/var/run/jail_${_jail}.id" ]; then 283 _jail_id=$(cat /var/run/jail_${_jail}.id) 284 if [ ! -z "${_jail_id}" ]; then 285 init_variables $_jail 286 if [ -n "${_exec_stop}" ]; then 287 eval env -i /usr/sbin/jexec ${_jail_id} ${_exec_stop} \ 288 >> ${_rootdir}/var/log/console.log 2>&1 289 fi 290 killall -j ${_jail_id} -TERM > /dev/null 2>&1 291 sleep 1 292 killall -j ${_jail_id} -KILL > /dev/null 2>&1 293 jail_umount_fs 294 echo -n " $_hostname" 295 fi 296 if [ -n "${_interface}" ]; then 297 ifconfig ${_interface} -alias ${_ip} 298 fi 299 rm /var/run/jail_${_jail}.id 300 else 301 echo " cannot stop jail ${_jail}. No jail id in /var/run" 302 fi 303 done 304 echo '.' 305} 306 307load_rc_config $name 308cmd="$1" 309if [ $# -gt 0 ]; then 310 shift 311fi 312if [ -n "$*" ]; then 313 jail_list="$*" 314fi 315run_rc_command "${cmd}" 316