[PATCH] updated /etc/rc.d/jail and added ZFS support
Martin Matuska
mm at FreeBSD.org
Fri Jul 29 20:53:22 UTC 2011
So what do you think about this updated patch (attached)?
Here we leave everything possible for jail_example_params.
Btw. you can also set jid=xxx in params to have a "static" jail id for
this jail.
Also stopping a persistent jail doesn't delete it (but you cannot start
it again).
Dňa 28. 7. 2011 20:47, Jamie Gritton wrote / napísal(a):
> Yes, it was intentional to move away from the global sysctls and to
> the per-jail parameters instead. It makes more sense once config
> files come into play, which can do a better job of providing global
> defaults as well as per-jail parameters.
>
> The connection between ZFS and persist makes sense. So for ZFS-based
> jail you'd want to set (and then reset) persist. For others, this
> could be left to the user. The changes to jail(8) for config files
> also sets persist when creating jails, and then clears it at a later
> stage unless the user specifies to keep it set. It looks like I might
> want to add some ZFS support to the new jail(8).
>
> I would prefer to keep things simpler regarding create/start and
> remove/stop, and keep them tied together.
>
> - Jamie
>
>
> On 07/28/11 12:00, Martin Matuska wrote:
>> If you start jail(8) witth "-c" (the new "param" way,) the values of the
>> actual security.jail. variables are not initialized inside the jail,
>> default values are used instead. I don't know if this is intentional,
>> but probably yes. Default enforce_statfs=2, allow.mount=0.
>> As of me we can leave everything for ${_params}, but then ${_zfs} makes
>> sense only if enforce_statfs<2 and allow.mount=1.
>>
>> Regarding zfs, if you want to operate zfs from the very start of a jail
>> (and e.g. make use of /etc/rc.d/zfs which has jail support), you have to
>> pair datasets with an existing jail. In simple words, you have to create
>> a process-less jail (persist=1), attach zfs datasets and then run the
>> command. The persist option can be made optional - but we always start
>> with persist=1, then we can set (or not) persist=0 depending on user
>> setting.
>>
>> The question that opens, should we remove a persisting jail on "stop"?
>> Or should we support new commands "create" and "remove" in addition to
>> "start" and "stop"? Create would just make a processless jail, remove
>> would wipe out a jail and start/stop would just deal with the processes
>> (if persist=0 the old way, of course)?
>>
>> Cheers,
>> mm
>>
>> Dňa 28. 7. 2011 18:25, Jamie Gritton wrote / napísal(a):
>>> Since I missed the 9.0 boat with jail config file capability, something
>>> like this seems necessary; rc.d/jail has long been unable to handle the
>>> full scale of what jail(8) can do.
>>>
>>> I gather that setting persist is necessary for the ZFS operation. As
>>> long as we're making the parameter setting more generic from rc, we
>>> should handle the case where persist is specified in ${_params}, and
>>> not
>>> always set/reset it around the jail creation unless ZFS is used.
>>>
>>> Also, why the specific inclusion of the security-related parameters?
>>> They could just be folded into ${_params}, and if left unspecified then
>>> jail(8) should by default do the right thing.
>>>
>>> - Jamie
>>>
>>>
>>> On 07/28/11 08:11, Martin Matuska wrote:
>>>> The attached patch allows better fine-tuning of jails started via
>>>> /etc/rc.d, uses the new jail(8) flags (-c -m), the persist
>>>> parameter and
>>>> adds ZFS support.
>>>> Patch is fully backward compatible.
>>>>
>>>> Please review, comment and/or test my attached patch.
>>>>
>>>> Cheers,
>>>> mm
--
Martin Matuska
FreeBSD committer
http://blog.vx.sk
-------------- next part --------------
Index: etc/rc.d/jail
===================================================================
--- etc/rc.d/jail (revision 224494)
+++ etc/rc.d/jail (working copy)
@@ -43,6 +43,9 @@
eval _ip=\"\$jail_${_j}_ip\"
eval _interface=\"\${jail_${_j}_interface:-${jail_interface}}\"
eval _exec=\"\$jail_${_j}_exec\"
+ eval _params=\"\$jail_${_j}_params\"
+ eval _persist=\"\$jail_${_j}_persist\"
+ eval _zfs=\"\${jail_${_j}_zfs:-}\"
i=0
while : ; do
@@ -98,6 +101,9 @@
fi
# The default jail ruleset will be used by rc.subr if none is specified.
+ if [ -n "jail_devfs_ruleset" -a -n "_zfs" ]; then
+ jail_devfs_ruleset="devfsrules_jail_zfs"
+ fi
eval _ruleset=\"\${jail_${_j}_devfs_ruleset:-${jail_devfs_ruleset}}\"
eval _devfs=\"\${jail_${_j}_devfs_enable:-${jail_devfs_enable}}\"
[ -z "${_devfs}" ] && _devfs="NO"
@@ -345,6 +351,36 @@
mount -a -F "${_fstab}"
}
+# jail_zfs_jailin
+# Make zfs datasets manageable from inside a jail
+# the "jailed" dataset property must be set to "on"
+jail_zfs_jailin()
+{
+ if [ -n "${_zfs}" ]; then
+ for _ds in ${_zfs}; do
+ _jailed=`zfs get -H jailed ${_ds} 2>/dev/null | awk '{ print $3 }'`
+ if [ "$_jailed" = "on" ]; then
+ zfs jail "${_jail_id}" ${_ds} 2>/dev/null
+ fi
+ done
+ fi
+}
+
+# jail_zfs_jailout
+# Unjail zfs datasets
+# the "jailed" dataset property must be set to "on"
+jail_zfs_jailout()
+{
+ if [ -n "${_zfs}" ]; then
+ for _ds in ${_zfs}; do
+ _jailed=`zfs get -H jailed ${_ds} 2>/dev/null | awk '{ print $3 }'`
+ if [ "$_jailed" = "on" ]; then
+ zfs unjail "${_jail_id}" ${_ds} 2>/dev/null
+ fi
+ done
+ fi
+}
+
# jail_show_addresses jail
# Debug print the input for the given _multi aliases
# for a jail for init_variables().
@@ -483,10 +519,27 @@
*) ;;
esac
- # Append address to list of addresses for the jail command.
- case "${_addrl}" in
- "") _addrl="${_addr}" ;;
- *) _addrl="${_addrl},${_addr}" ;;
+ case "${_type}" in
+ inet)
+ # Append address to list of ipv4 addresses for the
+ # jail command.
+ case "${_addrl}" in
+ "") _addrl="${_addr}" ;;
+ *) _addrl="${_addrl},${_addr}" ;;
+ esac
+ ;;
+ inet6)
+ # Append address to list of ipv6 addresses for the
+ # jail command.
+ case "${_addrl6}" in
+ "") _addrl6="${_addr}" ;;
+ *) _addrl6="${_addrl6},${_addr}" ;;
+ esac
+ ;;
+ *) warn "Could not determine address family. Not going" \
+ "to set address '${_addr}' for ${_jail}."
+ continue
+ ;;
esac
# Configure interface alias if requested by a given interface
@@ -494,14 +547,7 @@
case "${_iface}" in
"") continue ;;
esac
- case "${_type}" in
- inet) ;;
- inet6) ;;
- *) 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
;;
@@ -576,6 +622,7 @@
continue;
fi
_addrl=""
+ _addrl6=""
jail_ips "add"
if [ -n "${_fib}" ]; then
_setfib="setfib -F '${_fib}'"
@@ -644,42 +691,56 @@
i=$((i + 1))
done
- eval ${_setfib} jail ${_flags} -i ${_rootdir} ${_hostname} \
- \"${_addrl}\" ${_exec_start} > ${_tmp_jail} 2>&1 \
- </dev/null
+ _jail_id=`${_setfib} jail -i ${_flags} -c \
+ path="${_rootdir}" \
+ host.hostname="${_hostname}" \
+ ip4.addr="${_addrl}" \
+ ip6.addr="${_addrl6}" \
+ ${_params} \
+ persist=1`
- if [ "$?" -eq 0 ] ; then
- _jail_id=$(head -1 ${_tmp_jail})
- i=1
- while : ; do
- eval out=\"\${_exec_afterstart${i}:-''}\"
-
- if [ -z "$out" ]; then
- break;
+ if [ -n "$_jail_id" ]; then
+ jail_zfs_jailin
+ eval jail ${_flags} -m jid="${_jail_id}" \
+ command="${_exec_start}" > ${_tmp_jail} 2>&1 \
+ </dev/null
+ if [ "$?" -eq 0 ] ; then
+ if [ "${_persist}" != "1" ]; then
+ jail -m jid="${_jail_id}" persist=0
fi
+ i=1
+ while : ; do
+ eval out=\"\${_exec_afterstart${i}:-''}\"
- jexec "${_jail_id}" ${out}
- i=$((i + 1))
- done
+ if [ -z "$out" ]; then
+ break;
+ fi
- echo -n " $_hostname"
- tail +2 ${_tmp_jail} >${_consolelog}
- echo ${_jail_id} > /var/run/jail_${_jail}.id
+ jexec "${_jail_id}" ${out}
+ i=$((i + 1))
+ done
- i=0
- while : ; do
- eval out=\"\${_exec_poststart${i}:-''}\"
- [ -z "$out" ] && break
- ${out}
- i=$((i + 1))
- done
- else
- jail_umount_fs
- jail_ips "del"
- echo " cannot start jail \"${_jail}\": "
- tail +2 ${_tmp_jail}
+ 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
+ else
+ jail_zfs_jailout
+ jail -m jid="${_jail_id}" persist=0
+ jail_umount_fs
+ jail_ips "del"
+ echo " cannot start jail \"${_jail}\": "
+ tail +2 ${_tmp_jail}
+ fi
+ rm -f ${_tmp_jail}
fi
- rm -f ${_tmp_jail}
done
rmdir ${_tmp_dir}
echo '.'
@@ -707,6 +768,7 @@
eval env -i /usr/sbin/jexec ${_jail_id} ${_exec_stop} \
>> ${_consolelog} 2>&1
fi
+ jail_zfs_jailout
killall -j ${_jail_id} -TERM > /dev/null 2>&1
sleep 1
killall -j ${_jail_id} -KILL > /dev/null 2>&1
Index: etc/defaults/devfs.rules
===================================================================
--- etc/defaults/devfs.rules (revision 224471)
+++ etc/defaults/devfs.rules (working copy)
@@ -83,3 +83,9 @@
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
+
+# Jail with zfs support
+#
+[devfsrules_jail_zfs=5]
+add include $devfsrules_jail
+add path zfs unhide
Index: etc/defaults/rc.conf
===================================================================
--- etc/defaults/rc.conf (revision 224471)
+++ etc/defaults/rc.conf (working copy)
@@ -695,6 +695,15 @@
#jail_example_mount_enable="NO" # mount/umount jail's fs
#jail_example_fstab="" # fstab(5) for mount/umount
#jail_example_flags="-l -U root" # flags for jail(8)
+#jail_example_persist="" # Set to 1 to create a persistent jail
+#jail_example_params="" # Space-separated list of additional
+ # user-supplied parameters for jail(8)
+#jail_example_zfs="" # Space-separated list of ZFS datasets to be
+ # managed from this jail. For proper operation,
+ # allow.mount=1 and enforce_statfs=1 (or 0)
+ # must be added to jail_example_params.
+ # The "jailed" property must be set to "on"
+ # on desired datasets before starting the jail.
##############################################################
### Define source_rc_confs, the mechanism used by /etc/rc.* ##
More information about the freebsd-current
mailing list