source: src-sh/warden/scripts/backend/startjail.sh

Last change on this file was dcad170, checked in by Kris Moore <kris@…>, 7 weeks ago

Update the warden to support jailed ZFS datasets. This can be
enabled by setting "allow.mount.zfs=1" on a jail. If this is
set, the jails ZFS dataset will be set to jailed mode, and
made visible to the jail. The user should also set
"enforce_statfs=0" and "allow.mount=1" on the jails flags as well,
for this to work properly.

Requested vie RedMine?: #6495

  • Property mode set to 100755
File size: 13.1 KB
Line 
1#/bin/sh
2# Script to startup a jail
3# Args $1 = jail-name
4#######################################################################
5
6# Source our functions
7PROGDIR="/usr/local/share/warden"
8
9# Source our variables
10. ${PROGDIR}/scripts/backend/functions.sh
11
12start_jail_vimage()
13{
14
15  BRIDGE=
16
17  # See if we need to create a new bridge, or use an existing one
18  _bridges=`get_bridge_interfaces`
19  if [ -n "${_bridges}" ] ; then
20     for _bridge in ${_bridges}
21     do
22        _members=`get_bridge_members ${_bridge}`
23        for _member in ${_members}
24        do
25           if [ "${_member}" = "${IFACE}" ] ; then
26              BRIDGE=${_bridge}
27              break
28           fi
29        done
30        if [ -n "${BRIDGE}" ] ; then
31           break
32        fi
33     done
34  fi
35
36  if [ -z "${BRIDGE}" ] ; then
37     BRIDGE=`ifconfig bridge create mtu ${MTU}`
38  fi
39  if [ -n "${IFACE}" ] ; then
40     if ! is_bridge_member "${BRIDGE}" "${IFACE}" ; then
41        ifconfig ${BRIDGE} addm ${IFACE}
42     fi
43  fi
44
45  # create epair for vimage jail
46  EPAIRA=`ifconfig epair create mtu ${MTU}`
47  ifconfig ${EPAIRA} up
48
49  EPAIRB=`echo ${EPAIRA}|sed -E "s/([0-9])a$/\1b/g"`
50  ifconfig ${BRIDGE} addm ${EPAIRA} up
51
52  # If no bridge specified, and IP4 is enabled, lets suggest one
53  if [ -z "$BRIDGEIP4" -a -n "$IP4" ] ; then
54     BRIDGEIP4="`echo $IP4 | cut -d '.' -f 1-3`.254"
55  fi
56
57  if [ -n "${BRIDGEIP4}" ] ; then
58     if ! ipv4_configured "${BRIDGE}" ; then
59        ifconfig ${BRIDGE} inet "${BRIDGEIP4}"
60
61     elif ! ipv4_address_configured "${BRIDGE}" "${BRIDGEIP4}" ; then
62        ifconfig ${BRIDGE} inet alias "${BRIDGEIP4}"
63     fi
64  fi
65  if [ -n "${BRIDGEIPS4}" ] ; then
66     for _ip in ${BRIDGEIPS4}
67     do
68        if ! ipv4_address_configured "${BRIDGE}" "${_ip}" ; then
69           ifconfig ${BRIDGE} inet alias "${_ip}"
70        fi
71     done
72  fi
73
74  if [ -n "${BRIDGEIP6}" ] ; then
75     if ! ipv6_configured "${BRIDGE}" ; then
76        ifconfig ${BRIDGE} inet6 "${BRIDGEIP6}"
77
78     elif ! ipv6_address_configured "${BRIDGE}" "${BRIDGEIP6}" ; then
79        ifconfig ${BRIDGE} inet6 alias "${BRIDGEIP6}"
80     fi
81  fi
82  if [ -n "${BRIDGEIPS6}" ] ; then
83     for _ip in ${BRIDGEIPS6}
84     do
85        if ! ipv6_address_configured "${BRIDGE}" "${_ip}" ; then
86           ifconfig ${BRIDGE} inet6 alias "${_ip}"
87        fi
88     done
89  fi
90
91  # Start the jail now
92  echo "jail -c path=${JAILDIR} host.hostname=${HOST} ${jFlags} persist vnet"
93  jail -c path=${JAILDIR} host.hostname=${HOST} ${jFlags} persist vnet
94  if [ $? -ne 0 ] ; then
95     echo "ERROR: Failed starting jail with above command..."
96     umountjailxfs "${JAILNAME}"
97     exit 1
98  fi
99
100  JID="`jls | grep ${JAILDIR}$ | tr -s " " | cut -d " " -f 2`"
101
102  # Move epairb into jail
103  ifconfig ${EPAIRB} vnet ${JID}
104
105  # Configure the IPv4 addresses
106  if [ -n "${IP4}" ] ; then
107     echo "Setting IP4 address: ${IP4}"
108     jexec ${JID} ifconfig ${EPAIRB} inet "${IP4}"
109  fi
110  for ip4 in ${IPS4}
111  do
112     ipv4_configured ${EPAIRB} ${JID}
113     if [ "$?" = "0" ] ; then
114        if ! ipv4_address_configured "${EPAIRB}" "${ip4}" "${JID}" ; then
115           jexec ${JID} ifconfig ${EPAIRB} inet alias ${ip4}
116        fi
117     else
118        jexec ${JID} ifconfig ${EPAIRB} inet ${ip4}
119     fi
120  done
121
122  # Configure the IPv6 addresses
123  if [ -n "${IP6}" ] ; then
124     echo "Setting IP6 address: ${IP6}"
125     jexec ${JID} ifconfig ${EPAIRB} inet6 "${IP4}"
126  fi
127  for ip6 in ${IPS6}
128  do
129     ipv6_configured ${EPAIRB} ${JID}
130     if [ "$?" = "0" ] ; then
131        if ! ipv6_address_configured "${EPAIRB}" "${ip6}" "${JID}" ; then
132           jexec ${JID} ifconfig ${EPAIRB} inet6 alias ${ip6}
133        fi
134     else
135        jexec ${JID} ifconfig ${EPAIRB} inet6 ${ip6}
136     fi
137  done
138
139  #
140  # Configure default IPv4 gateway
141  #
142  if [ -n "${GATEWAY4}" ] ; then
143     jexec ${JID} route add -inet default ${GATEWAY4}
144
145  #
146  # No defaultrouter configured for IPv4, so if bridge IP address was
147  # configured, we set the default router to that IP.
148  #
149  elif [ -n "${BRIDGEIP4}" ] ; then
150     get_ip_and_netmask "${BRIDGEIP4}"
151     jexec ${JID} route add -inet default ${JIP}
152  fi
153
154  #
155  # Configure default IPv6 gateway
156  #
157  if [ -n "${GATEWAY6}" ] ; then
158     jexec ${JID} route add -inet6 default ${GATEWAY6}
159
160  #
161  # No defaultrouter configured for IPv6, so if bridge IP address was
162  # configured, we set the default router to that IP.
163  #
164  elif [ -n "${BRIDGEIP6}" ] ; then
165     get_ip_and_netmask "${BRIDGEIP6}"
166     jexec ${JID} route add -inet6 default ${JIP}
167  fi
168
169  #
170  # Set ourself to be a jail router with NAT. Don't
171  # use PF since it will panic the box when used
172  # with VIMAGE.
173  #
174  ip_forwarding=`sysctl -n net.inet.ip.forwarding`
175  if [ "${ip_forwarding}" = "0" ] ; then
176     sysctl net.inet.ip.forwarding=1
177  fi
178
179  ip6_forwarding=`sysctl -n net.inet6.ip6.forwarding`
180  if [ "${ip6_forwarding}" = "0" ] ; then
181     sysctl net.inet6.ip6.forwarding=1
182  fi
183
184  firewall_enable=`egrep '^firewall_enable' /etc/rc.conf|cut -f2 -d'='|sed 's|"||g'`
185  firewall_type=`egrep '^firewall_type' /etc/rc.conf|cut -f2 -d'='|sed 's|"||g'`
186
187  if [ "${firewall_enable}" != "YES" -o "${firewall_type}" != "open" ] ; then
188     tmp_rcconf=`mktemp /tmp/.wdn.XXXXXX`
189     egrep -v '^firewall_(enable|type)' /etc/rc.conf >> "${tmp_rcconf}"
190
191     cat<<__EOF__>>"${tmp_rcconf}"
192firewall_enable="YES"
193firewall_type="open"
194__EOF__
195
196     if [ -s "${tmp_rcconf}" ] ; then
197        cp /etc/rc.conf /var/tmp/rc.conf.bak
198        mv "${tmp_rcconf}" /etc/rc.conf
199        if [ "$?" != "0" ] ; then
200           mv /var/tmp/rc.conf.bak /etc/rc.conf
201        fi
202     fi
203     /etc/rc.d/ipfw forcerestart
204  fi
205
206  instance=`get_ipfw_nat_instance "${IFACE}"`
207  if [ -z "${instance}" ] ; then
208     priority=`get_ipfw_nat_priority`
209     instance=`get_ipfw_nat_instance`
210
211     ipfw "${priority}" add nat "${instance}" all from any to any
212     ipfw nat "${instance}" config if "${IFACE}" reset
213  fi
214# End of jail VIMAGE startup function
215}
216
217# Function to start a jail up the normal way
218start_jail_standard()
219{
220  # Check for primary IPV4 / IPV6
221  if [ -n "$IP4" ] ; then
222    _ipflags="ip4.addr=${IP4}"
223    ifconfig $IFACE inet alias ${IP4}
224  fi
225  if [ -n "$IP6" ] ; then
226    _ipflags="${_ipflags} ip6.addr=${IP6}"
227    ifconfig $IFACE inet6 alias ${IP6}
228  fi
229
230  # Setup the extra IP4s for this jail
231  for _ip in $IPS4
232  do
233    ifconfig $IFACE inet alias ${_ip}
234    _ipflags="${_ipflags} ip4.addr=${_ip}"
235  done
236
237  # Setup the extra IP6s for this jail
238  for _ip in $IPS6
239  do
240    ifconfig $IFACE inet6 alias ${_ip}
241    _ipflags="${_ipflags} ip6.addr=${_ip}"
242  done
243
244  echo "jail -c path=${JAILDIR} ${_ipflags} host.hostname=${HOST} ${jFlags} persist"
245  jail -c path=${JAILDIR} ${_ipflags} host.hostname=${HOST} ${jFlags} persist
246  if [ $? -ne 0 ] ; then
247     echo "ERROR: Failed starting jail with above command..."
248     umountjailxfs "${JAILNAME}"
249     exit 1
250  fi
251
252  JID="`jls | grep ${JAILDIR}$ | tr -s " " | cut -d " " -f 2`"
253
254}
255
256JAILNAME="${1}"
257
258if [ -z "${JAILNAME}" ]
259then
260  echo "ERROR: No jail specified to start!"
261  exit 5
262fi
263
264if [ -z "${JDIR}" ]
265then
266  echo "ERROR: JDIR is unset!!!!"
267  exit 5
268fi
269
270JAILDIR="${JDIR}/${JAILNAME}"
271
272if [ ! -d "${JAILDIR}" ]
273then
274  echo "ERROR: No jail located at ${JAILDIR}"
275  exit 5
276fi
277
278# Make sure the jail is NOT already running
279jls | grep ${JAILDIR}$ >/dev/null 2>/dev/null
280if [ "$?" = "0" ]
281then
282  echo "ERROR: Jail appears to be running already!"
283  exit 6
284fi
285
286IFACE=
287
288DEFAULT=0
289
290# Make sure jail uses special interface if specified
291if [ -e "${JMETADIR}/iface" ] ; then
292  IFACE=`cat "${JMETADIR}/iface"`
293fi
294if [ -z "${IFACE}" ] ; then
295  if [ -n "$NIC" ] ; then
296    IFACE="$NIC"
297  else
298    IFACE=`get_default_interface`
299    DEFAULT=1
300  fi
301fi
302if [ -z "${IFACE}" ] ; then
303  echo "ERROR: no interface specified and a default doesn't exist!"
304  exit 6
305fi
306
307# Check if this interface is valid
308ifconfig $IFACE >/dev/null 2>/dev/null
309if [ $? -ne 0 ] ; then
310   echo "ERROR: No such network interface $IFACE"
311   echo "Please set a correct network interface in /usr/local/etc/warden.conf"
312   exit 6
313fi
314
315MTU=`ifconfig ${IFACE} | head -1 | sed -E 's/.*mtu ([0-9]+)/\1/g'`
316
317GATEWAY4=
318if [ -e "${JMETADIR}/defaultrouter-ipv4" ] ; then
319  GATEWAY4=`cat "${JMETADIR}/defaultrouter-ipv4"`
320fi
321GATEWAY6=
322if [ -e "${JMETADIR}/defaultrouter-ipv6" ] ; then
323  GATEWAY6=`cat "${JMETADIR}/defaultrouter-ipv6"`
324fi
325
326BRIDGEIP4=
327if [ -e "${JMETADIR}/bridge-ipv4" ] ; then
328  BRIDGEIP4=`cat "${JMETADIR}/bridge-ipv4"`
329fi
330
331BRIDGEIPS4=
332if [ -e "${JMETADIR}/alias-bridge-ipv4" ] ; then
333  while read line
334  do
335    BRIDGEIPS4="${BRIDGEIPS4} $line" 
336  done < ${JMETADIR}/alias-bridge-ipv4
337fi
338
339BRIDGEIP6=
340if [ -e "${JMETADIR}/bridge-ipv6" ] ; then
341  BRIDGEIP6=`cat "${JMETADIR}/bridge-ipv6"`
342fi
343
344BRIDGEIPS6=
345if [ -e "${JMETADIR}/alias-bridge-ipv6" ] ; then
346  while read line
347  do
348    BRIDGEIPS6="${BRIDGEIPS6} $line" 
349  done < ${JMETADIR}/alias-bridge-ipv6
350fi
351
352# Check if we need to enable vnet
353VIMAGEENABLE="NO"
354if [ -e "${JMETADIR}/vnet" ] ; then
355  VIMAGEENABLE="YES"
356fi
357
358set_warden_metadir
359
360if [ -e "${JMETADIR}/jail-linux" ] ; then
361   LINUXJAIL="YES"
362fi
363
364HOST="`cat ${JMETADIR}/host`"
365
366jFlags=""
367# Grab any additional jail flags
368if [ -e "${JMETADIR}/jail-flags" ] ; then
369  jFlags=`cat ${JMETADIR}/jail-flags`
370fi
371
372# Make sure the dataset is mounted
373jDataSet=`mount | grep "on ${JAILDIR} " | awk '{print $1}'`
374if [ -z "$jDataSet" ] ; then
375  pDataSet=`mount | grep "on ${JDIR} " | awk '{print $1}'`
376  rc_halt "mount -t zfs $pDataSet/$JAILNAME $JAILDIR"
377  jDataSet="$oDataSet/$JAILNAME"
378fi
379
380# If the user has enabled mounting of ZFS dataset, lets export this dataset to the jail
381echo $jFlags | grep -q "allow.mount.zfs=1"
382if [ $? -eq 0 ] ; then
383   jProp=`zfs get -H jailed $jDataSet | awk '{print $3}'`
384   if [ "$jProp" = "off" ] ; then
385     rc_halt "zfs set jailed=on $jDataSet"
386     if [ ! -d "$JAILDIR" ] ; then mkdir ${JAILDIR} ; fi
387     rc_halt "mount -t zfs $jDataSet ${JAILDIR}"
388   fi
389fi
390if is_symlinked_mountpoint ${JAILDIR}/dev; then
391   echo "${JAILDIR}/dev has symlink as parent, not mounting"
392else
393   mount -t devfs devfs "${JAILDIR}/dev"
394fi
395
396if [ "$LINUXJAIL" = "YES" ] ; then
397  # Linux Jail
398  if is_symlinked_mountpoint ${JAILDIR}/proc; then
399     echo "${JAILDIR}/proc has symlink as parent, not mounting"
400  else
401     mount -t linprocfs linproc "${JAILDIR}/proc"
402  fi
403  if is_symlinked_mountpoint ${JAILDIR}/dev/fd; then
404     echo "${JAILDIR}/dev/fd has symlink as parent, not mounting"
405  else
406     mount -t fdescfs null "${JAILDIR}/dev/fd"
407  fi
408  if is_symlinked_mountpoint ${JAILDIR}/sys; then
409     echo "${JAILDIR}/sys has symlink as parent, not mounting"
410  else
411     mount -t linsysfs linsys "${JAILDIR}/sys"
412  fi
413  if [ -e "${JAILDIR}/lib/init/rw" ] ; then
414    if is_symlinked_mountpoint ${JAILDIR}/lib/init/rw; then
415       echo "${JAILDIR}/lib/init/rw has symlink as parent, not mounting"
416    else
417       mount -t tmpfs tmpfs "${JAILDIR}/lib/init/rw"
418    fi
419  fi
420else
421  # FreeBSD Jail
422  if is_symlinked_mountpoint ${JAILDIR}/proc; then
423     echo "${JAILDIR}/proc has symlink as parent, not mounting"
424  else
425     mount -t procfs proc "${JAILDIR}/proc"
426  fi
427
428  if [ -e "${JMETADIR}/jail-portjail" ] ; then mountjailxfs ${JAILNAME} ; fi
429fi
430
431# Check for user-supplied mounts
432if [ -e "${JMETADIR}/fstab" ] ; then
433   echo "Mounting user-supplied file-systems"
434   cp ${JMETADIR}/fstab /tmp/.wardenfstab.$$
435   sed -i '' "s|%%JAILDIR%%|${JAILDIR}|g" /tmp/.wardenfstab.$$
436   mount -a -F /tmp/.wardenfstab.$$
437   rm /tmp/.wardenfstab.$$
438fi
439
440IP4=
441if [ -e "${JMETADIR}/ipv4" ] ; then
442  IP4=`cat "${JMETADIR}/ipv4"`
443
444  # Check if somebody snuck in a IP without / on it
445  echo $IP4 | grep -q '/' 
446  if [ $? -ne 0 ] ; then
447     IP4="${IP4}/24"
448  fi
449fi
450
451IPS4=
452if [ -e "${JMETADIR}/alias-ipv4" ] ; then
453  while read line
454  do
455    IPS4="${IPS4} $line" 
456  done < ${JMETADIR}/alias-ipv4
457fi
458
459IP6=
460if [ -e "${JMETADIR}/ipv6" ] ; then
461  IP6=`cat "${JMETADIR}/ipv6"`
462  # Check if somebody snuck in a IP without / on it
463  echo $IP6 | grep -q '/' 
464  if [ $? -ne 0 ] ; then
465     IP6="${IP6}/64"
466  fi
467fi
468
469IPS6=
470if [ -e "${JMETADIR}/alias-ipv6" ] ; then
471  while read line
472  do
473    IPS6="${IPS6} $line" 
474  done < ${JMETADIR}/alias-ipv6
475fi
476
477# Are we using VIMAGE, if so start it up!
478if [ "$VIMAGEENABLE" = "YES" ] ; then
479  start_jail_vimage
480else
481  # Using a standard jail configuration
482  start_jail_standard
483fi
484
485# If the user has enabled mounting of ZFS dataset, lets export this dataset to the jail
486echo $jFlags | grep -q "allow.mount.zfs=1"
487if [ $? -eq 0 ] ; then
488   # Run the ZFS command to export the dataset
489   jDataSet=`mount | grep "on ${JAILDIR} " | awk '{print $1}'`
490   zfs jail $JID $jDataSet
491fi
492
493if [ "$LINUXJAIL" = "YES" ] ; then
494  # If we have a custom start script
495  if [ -e "${JMETADIR}/jail-start" ] ; then
496    sCmd=`cat ${JMETADIR}/jail-start`
497    echo "Starting jail with: ${sCmd}"
498    jexec ${JID} ${sCmd} 2>&1
499  else
500    # Check for different init styles
501    if [ -e "${JAILDIR}/etc/init.d/rc" ] ; then
502      jexec ${JID} /bin/sh /etc/init.d/rc 3 2>&1
503    elif [ -e "${JAILDIR}/etc/rc" ] ; then
504      jexec ${JID} /bin/sh /etc/rc 3 2>&1
505    fi
506  fi
507else
508  # If we have a custom start script
509  if [ -e "${JMETADIR}/jail-start" ] ; then
510    sCmd=`cat ${JMETADIR}/jail-start`
511    echo "Starting jail with: ${sCmd}"
512    jexec ${JID} ${sCmd} 2>&1
513  else
514    echo "Starting jail with: /etc/rc"
515    jexec ${JID} /bin/sh /etc/rc 2>&1
516  fi
517fi
518
519# Send notification of jail changes
520pc-systemflag WARDENUPDATE SUCCESS
Note: See TracBrowser for help on using the repository browser.