jail revision 138027
1#!/bin/sh
2#
3# $FreeBSD: head/etc/rc.d/jail 138027 2004-11-23 20:09:58Z mux $
4#
5
6# PROVIDE: jail
7# REQUIRE: LOGIN
8# BEFORE: securelevel
9# KEYWORD: nojail shutdown
10
11. /etc/rc.subr
12
13name="jail"
14rcvar=`set_rcvar`
15start_cmd="jail_start"
16stop_cmd="jail_stop"
17
18# init_variables _j
19#	Initialize the various jail variables for jail _j.
20#
21init_variables()
22{
23	_j="$1"
24
25	if [ -z "$_j" ]; then
26		warn "init_variables: you must specify a jail"
27		return
28	fi
29
30	eval jail_rootdir=\"\$jail_${_j}_rootdir\"
31	jail_devdir="${jail_rootdir}/dev"
32	jail_fdescdir="${jail_devdir}/fd"
33	jail_procdir="${jail_rootdir}/proc"
34	eval jail_hostname=\"\$jail_${_j}_hostname\"
35	eval jail_ip=\"\$jail_${_j}_ip\"
36	eval jail_exec=\"\$jail_${_j}_exec\"
37	[ -z "${jail_exec}" ] && jail_exec="/bin/sh /etc/rc"
38
39	# The default jail ruleset will be used by rc.subr if none is specified.
40	eval jail_ruleset=\"\$jail_${_j}_devfs_ruleset\"
41	eval jail_devfs=\"\$jail_${_j}_devfs_enable\"
42	[ -z "${jail_devfs}" ] && jail_devfs="NO"
43	eval jail_fdescfs=\"\$jail_${_j}_fdescfs_enable\"
44	[ -z "${jail_fdescfs}" ] && jail_fdescfs="NO"
45	eval jail_procfs=\"\$jail_${_j}_procfs_enable\"
46	[ -z "${jail_procfs}" ] && jail_procfs="NO"
47
48	eval jail_mount=\"\$jail_${_j}_mount_enable\"
49	[ -z "${jail_mount}" ] && jail_mount="NO"
50	# "/etc/fstab.${_j}" will be used for {,u}mount(8) if none is specified.
51	eval jail_fstab=\"\$jail_${_j}_fstab\"
52	[ -z "${jail_fstab}" ] && jail_fstab="/etc/fstab.${_j}"
53
54	# Debugging aid
55	#
56	debug "$_j devfs enable: $jail_devfs"
57	debug "$_j fdescfs enable: $jail_fdescfs"
58	debug "$_j procfs enable: $jail_procfs"
59	debug "$_j mount enable: $jail_mount"
60	debug "$_j hostname: $jail_hostname"
61	debug "$_j ip: $jail_ip"
62	debug "$_j root: $jail_rootdir"
63	debug "$_j devdir: $jail_devdir"
64	debug "$_j fdescdir: $jail_fdescdir"
65	debug "$_j procdir: $jail_procdir"
66	debug "$_j ruleset: $jail_ruleset"
67	debug "$_j fstab: $jail_fstab"
68}
69
70# set_sysctl rc_knob mib msg
71#	If the mib sysctl is set according to what rc_knob
72#	specifies, this function does nothing. However if
73#	rc_knob is set differently than mib, then the mib
74#	is set accordingly and msg is displayed followed by
75#	an '=" sign and the word 'YES' or 'NO'.
76#
77set_sysctl()
78{
79	_knob="$1"
80	_mib="$2"
81	_msg="$3"
82
83	_current=`${SYSCTL} -n $_mib 2>/dev/null`
84	if checkyesno $_knob ; then
85		if [ "$_current" -ne 1 ]; then
86			echo -n " ${_msg}=YES"
87			${SYSCTL_W} 1>/dev/null ${_mib}=1
88		fi
89	else
90		if [ "$_current" -ne 0 ]; then
91			echo -n " ${_msg}=NO"
92			${SYSCTL_W} 1>/dev/null ${_mib}=0
93		fi
94	fi
95}
96
97# jail_umount_fs
98#	This function unmounts certain special filesystems in the
99#	currently selected jail. The caller must call the init_variables()
100#	routine before calling this one.
101#
102jail_umount_fs()
103{
104	if checkyesno jail_fdescfs; then
105		if [ -d "${jail_fdescdir}" ] ; then
106			umount -f ${jail_fdescdir} >/dev/null 2>&1
107		fi
108	fi
109	if checkyesno jail_devfs; then
110		if [ -d "${jail_devdir}" ] ; then
111			umount -f ${jail_devdir} >/dev/null 2>&1
112		fi
113	fi
114	if checkyesno jail_procfs; then
115		if [ -d "${jail_procdir}" ] ; then
116			umount -f ${jail_procdir} >/dev/null 2>&1
117		fi
118	fi
119	if checkyesno jail_mount; then
120		[ -f "${jail_fstab}" ] || warn "${jail_fstab} does not exist"
121		umount -a -F "${jail_fstab}" >/dev/null 2>&1
122	fi
123}
124
125jail_start()
126{
127	echo -n 'Configuring jails:'
128	set_sysctl jail_set_hostname_allow security.jail.set_hostname_allowed \
129	    set_hostname_allow
130	set_sysctl jail_socket_unixiproute_only \
131	    security.jail.socket_unixiproute_only unixiproute_only
132	set_sysctl jail_sysvipc_allow security.jail.sysvipc_allowed \
133	    sysvipc_allow
134	echo '.'
135
136	echo -n 'Starting jails:'
137	_tmp_dir=`mktemp -d /tmp/jail.XXXXXXXX` || \
138	    err 3 "$name: Can't create temp dir, exiting..."
139	for _jail in ${jail_list}
140	do
141		init_variables $_jail
142		if checkyesno jail_mount; then
143			info "Mounting fstab for jail ${_jail} (${jail_fstab})"
144			if [ ! -f "${jail_fstab}" ]; then
145				err 3 "$name: ${jail_fstab} doest not exist"
146			fi
147			mount -a -F "${jail_fstab}"
148		fi
149		if checkyesno jail_devfs; then
150			info "Mounting devfs on ${jail_devdir}"
151			devfs_mount_jail "${jail_devdir}" ${jail_ruleset}
152
153			# Transitional symlink for old binaries
154			if [ ! -L "${jail_devdir}/log" ]; then
155				__pwd="`pwd`"
156				cd "${jail_devdir}"
157				ln -sf ../var/run/log log
158				cd "$__pwd"
159			fi
160
161			# XXX - It seems symlinks don't work when there
162			#	is a devfs(5) device of the same name.
163			# Jail console output
164			#	__pwd="`pwd`"
165			#	cd "${jail_devdir}"
166			#	ln -sf ../var/log/console console
167			#	cd "$__pwd"
168		fi
169		if checkyesno jail_fdescfs; then
170			info "Mounting fdescfs on ${jail_fdescdir}"
171			mount -t fdescfs fdesc "${jail_fdescdir}"
172		fi
173		if checkyesno jail_procfs; then
174			info "Mounting procfs onto ${jail_procdir}"
175			if [ -d "${jail_procdir}" ] ; then
176				mount -t procfs proc "${jail_procdir}"
177			fi
178		fi
179		_tmp_jail=${_tmp_dir}/jail.$$
180		jail -i ${jail_rootdir} ${jail_hostname} \
181			${jail_ip} ${jail_exec} > ${_tmp_jail} 2>&1
182		[ "$?" -eq 0 ] && echo -n " $jail_hostname"
183		_jail_id=$(head -1 ${_tmp_jail})
184		tail +2 ${_tmp_jail} >${jail_rootdir}/var/log/console.log
185		rm -f ${_tmp_jail}
186		echo ${_jail_id} > /var/run/jail_${_jail}.id
187	done
188	rmdir ${_tmp_dir}
189	echo '.'
190}
191
192jail_stop()
193{
194	echo -n 'Stopping jails:'
195	for _jail in ${jail_list}
196	do
197		if [ -f "/var/run/jail_${_jail}.id" ]; then
198			_jail_id=$(cat /var/run/jail_${_jail}.id)
199			if [ ! -z "${_jail_id}" ]; then
200				init_variables $_jail
201				killall -j ${_jail_id} -TERM > /dev/null 2>&1
202				jail_umount_fs
203				echo -n " $jail_hostname"
204			fi
205			rm /var/run/jail_${_jail}.id
206		else
207			echo "cannot stop jail ${_jail}. No jail id in /var/run"
208		fi
209	done
210	echo '.'
211}
212
213load_rc_config $name
214[ -n "$2" ] && jail_list="$2"
215run_rc_command "$1"
216