summaryrefslogtreecommitdiffstats
path: root/etc/rc.d/jail
blob: 33072ea37868886a4f29260d7edaf0d71551c9a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/bin/sh
#
# $FreeBSD$
#

# PROVIDE: jail
# REQUIRE: LOGIN
# BEFORE: securelevel
# KEYWORD: FreeBSD shutdown

. /etc/rc.subr

name="jail"
rcvar=`set_rcvar`
start_cmd="jail_start"
stop_cmd="jail_stop"

# init_variables _j
#	Initialize the various jail variables for jail _j.
#
init_variables()
{
	_j="$1"

	if [ -z "$_j" ]; then
		warn "init_variables: you must specify a jail"
		return
	fi

	eval jail_rootdir=\"\$jail_${_j}_rootdir\"
	jail_devdir="${jail_rootdir}/dev"
	jail_fdescdir="${jail_devdir}/fd"
	jail_procdir="${jail_rootdir}/proc"
	eval jail_hostname=\"\$jail_${_j}_hostname\"
	eval jail_ip=\"\$jail_${_j}_ip\"
	eval jail_exec=\"\$jail_${_j}_exec\"
	[ -z "${jail_exec}" ] && jail_exec="/bin/sh /etc/rc"

	# The default jail ruleset will be used by rc.subr if none is specified.
	eval jail_ruleset=\"\$jail_${_j}_devfs_ruleset\"
	eval jail_devfs=\"\$jail_${_j}_devfs_enable\"
	[ -z "${jail_devfs}" ] && jail_devfs="NO"
	eval jail_fdescfs=\"\$jail_${_j}_fdescfs_enable\"
	[ -z "${jail_fdescfs}" ] && jail_fdescfs="NO"
	eval jail_procfs=\"\$jail_${_j}_procfs_enable\"
	[ -z "${jail_procfs}" ] && jail_procfs="NO"

	# Debugging aid
	#
	debug "$_j devfs enable: $jail_devfs"
	debug "$_j fdescfs enable: $jail_fdescfs"
	debug "$_j procfs enable: $jail_procfs"
	debug "$_j hostname: $jail_hostname"
	debug "$_j ip: $jail_ip"
	debug "$_j root: $jail_rootdir"
	debug "$_j devdir: $jail_devdir"
	debug "$_j fdescdir: $jail_fdescdir"
	debug "$_j procdir: $jail_procdir"
	debug "$_j ruleset: $jail_ruleset"
}

# 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_W} 1>/dev/null ${_mib}=1
		fi
	else
		if [ "$_current" -ne 0 ]; then
			echo -n " ${_msg}=NO"
			${SYSCTL_W} 1>/dev/null ${_mib}=0
		fi
	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()
{
	if checkyesno jail_fdescfs; then
		if [ -d ${jail_fdescdir} ] ; then
			umount -f ${jail_fdescdir} >/dev/null 2>&1
		fi
	fi
	if checkyesno jail_devfs; then
		if [ -d ${jail_devdir} ] ; then
			umount -f ${jail_devdir} >/dev/null 2>&1
		fi
	fi
	if checkyesno jail_procfs; then
		if [ -d ${jail_procdir} ] ; then
			umount -f ${jail_procdir} >/dev/null 2>&1
		fi
	fi
}

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 '.'

	echo -n 'Starting jails:'
	for _jail in ${jail_list}
	do
		init_variables $_jail
		if checkyesno jail_devfs; then
			info "Mounting devfs on ${jail_devdir}"
			devfs_mount_jail "${jail_devdir}" ${jail_ruleset}

			# Transitional symlink for old binaries
			if [ ! -L ${jail_devdir}/log ]; then
				__pwd="`pwd`"
				cd "${jail_devdir}"
				ln -sf ../var/run/log log
				cd "$__pwd"
			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 "${jail_devdir}"
			#	ln -sf ../var/log/console console
			#	cd "$__pwd"
		fi
		if checkyesno jail_fdescfs; then
			info "Mounting fdescfs on ${jail_fdescdir}"
			mount -t fdescfs fdesc "${jail_fdescdir}"
		fi
		if checkyesno jail_procfs; then
			info "Mounting procfs onto ${jail_procdir}"
			if [ -d ${jail_procdir} ] ; then
				mount -t procfs proc "${jail_procdir}"
			fi
		fi
		_tmp_jail=/tmp/jail.$$
		jail -i ${jail_rootdir} ${jail_hostname} \
			${jail_ip} ${jail_exec} > ${_tmp_jail} 2>&1
		[ "$?" -eq 0 ] && echo -n " $jail_hostname"
		_jail_id=$(head -1 ${_tmp_jail})
		tail +2 ${_tmp_jail} >${jail_rootdir}/var/log/console.log
		rm -f ${_tmp_jail}
		echo ${_jail_id} > /var/run/jail_${_jail}.id
	done
	echo '.'
}

jail_stop()
{
	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
				killall -j ${_jail_id} -TERM > /dev/null 2>&1
				jail_umount_fs
				echo -n " $jail_hostname"
			fi
			rm /var/run/jail_${_jail}.id
		else
			echo "cannot stop jail ${_jail}. No jail id in /var/run"
		fi
	done
	echo '.'
}

load_rc_config $name
[ -n "$2" ] && jail_list="$2"
run_rc_command "$1"
OpenPOWER on IntegriCloud