From owner-freebsd-rc@FreeBSD.ORG Wed Feb 11 03:24:40 2009 Return-Path: Delivered-To: freebsd-rc@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D9314106566B; Wed, 11 Feb 2009 03:24:40 +0000 (UTC) (envelope-from delphij@delphij.net) Received: from tarsier.delphij.net (delphij-pt.tunnel.tserv2.fmt.ipv6.he.net [IPv6:2001:470:1f03:2c9::2]) by mx1.freebsd.org (Postfix) with ESMTP id 0549B8FC15; Wed, 11 Feb 2009 03:24:40 +0000 (UTC) (envelope-from delphij@delphij.net) Received: from tarsier.geekcn.org (tarsier.geekcn.org [211.166.10.233]) (using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by tarsier.delphij.net (Postfix) with ESMTPS id E4E4E28449; Wed, 11 Feb 2009 11:24:38 +0800 (CST) Received: from localhost (tarsier.geekcn.org [211.166.10.233]) by tarsier.geekcn.org (Postfix) with ESMTP id 5EDD5EC5F3F; Wed, 11 Feb 2009 11:24:38 +0800 (CST) X-Virus-Scanned: amavisd-new at geekcn.org Received: from tarsier.geekcn.org ([211.166.10.233]) by localhost (mail.geekcn.org [211.166.10.233]) (amavisd-new, port 10024) with ESMTP id DlZ5fODzqsZS; Wed, 11 Feb 2009 11:24:32 +0800 (CST) Received: from charlie.delphij.net (adsl-76-237-33-62.dsl.pltn13.sbcglobal.net [76.237.33.62]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by tarsier.geekcn.org (Postfix) with ESMTPSA id 3B7CEEC5F3B; Wed, 11 Feb 2009 11:24:29 +0800 (CST) DomainKey-Signature: a=rsa-sha1; s=default; d=delphij.net; c=nofws; q=dns; h=message-id:date:from:reply-to:organization:user-agent: mime-version:to:cc:subject:x-enigmail-version:openpgp:content-type; b=cz71M8fNQ2aL2xH4nJ6J9HJxJ/+t7FzWiAskgiAJvDkWWgb3UTaZQZ/i5QGnQQkhN Rp+zxByEk52CRzc1nXFDg== Message-ID: <499244E6.9030205@delphij.net> Date: Tue, 10 Feb 2009 19:24:22 -0800 From: Xin LI Organization: The FreeBSD Project User-Agent: Thunderbird 2.0.0.19 (X11/20090202) MIME-Version: 1.0 To: freebsd-rc@FreeBSD.org X-Enigmail-Version: 0.95.7 OpenPGP: id=18EDEBA0; url=http://www.delphij.net/delphij.asc Content-Type: multipart/mixed; boundary="------------010704020508080109030502" Cc: FreeBSD Current Subject: [RFC] Skeleton jail (rc.d feature proposal) X-BeenThere: freebsd-rc@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: d@delphij.net List-Id: "Discussion related to /etc/rc.d design and implementation." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Feb 2009 03:24:41 -0000 This is a multi-part message in MIME format. --------------010704020508080109030502 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, Ok, some local users has prodded me in committing the "skeleton jail" feature, I find it useful myself but not sure if it's appropriate to commit it against -HEAD, so I'd like to explain it, try to present it in a better way, and request for comments. I'd like to have some native English speakers to proof read the manual page changes if this is found useful for general consumption. Some descriptions: ===== What is it? Basically, a "skeleton" jail is a jail which has part of its directories, typically directories containing the base system, say the binaries, libraries, mount_nullfs'ed from a template, usually /. What I did implemented is some helper scripts as well as some Makefile changes to make the task easier. A NULLFS mount, typically, read-only, from either a template (an installed world located in some directory, or the host system, say, / itself), would reduce the time that is taken upon system upgrade; on the other hand, it makes it possible to switch the base system libraries on-the-fly. The read-only nature of these NULLFS mounts also helps development environments that don't want programmers to make unauthorized changes to the base system itself, we actually have used it in our development environment and found this as an useful side effect. ===== How to use it? One make(1) target, "installskel" has been added to top-level (/usr/src) Makefile. This can be used to populate a skeleton where only a minimal set of files and directories are installed that will support the startup of a skeleton jail. "installskel" is actually a shortcut of "make hierarchy" and "cd etc; make distribution". So, to create a skeleton: cd /usr/src make installskel DESTDIR=$D Where "D" is the directory where you want the skeleton to be placed at, say, /vhost/myjail in this example; then, set up rc.conf(5) parameters like this: jail_myjail_rootdir="/vhost/myjail/" jail_myjail_devfs_enable="YES" jail_myjail_skel_enable="YES" The rc.d infrastructure would automatically mount the following directories from the template (when not specified, /) as read-only: bin lib libexec sbin usr/bin usr/include usr/lib usr/libdata usr/libexec usr/sbin usr/share usr/src usr/obj Cheers, - -- Xin LI http://www.delphij.net/ FreeBSD - The Power to Serve! -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (FreeBSD) iEYEARECAAYFAkmSROUACgkQi+vbBBjt66DncwCguU5YAytGEhvwMGbLzk0uFqkI lKEAn3RhVNxIF4XROQj0ijWyEsZgP+IJ =Sd9e -----END PGP SIGNATURE----- --------------010704020508080109030502 Content-Type: text/plain; name="skel.diff" Content-Transfer-Encoding: 8bit Content-Disposition: inline; filename="skel.diff" Index: Makefile =================================================================== --- Makefile (版本 188424) +++ Makefile (工作副本) @@ -84,6 +84,7 @@ depend distribute distributeworld distrib-dirs distribution doxygen \ everything hierarchy install installcheck installkernel \ installkernel.debug reinstallkernel reinstallkernel.debug \ + installskel \ installworld kernel-toolchain libraries lint maninstall \ obj objlink regress rerelease showconfig tags toolchain update \ _worldtmp _legacy _bootstrap-tools _cleanobj _obj \ @@ -98,6 +99,7 @@ .ORDER: buildworld installworld .ORDER: buildworld distributeworld .ORDER: buildworld buildkernel +.ORDER: buildworld installskel .ORDER: buildkernel installkernel .ORDER: buildkernel installkernel.debug .ORDER: buildkernel reinstallkernel Index: Makefile.inc1 =================================================================== --- Makefile.inc1 (版本 188424) +++ Makefile.inc1 (工作副本) @@ -651,6 +651,18 @@ ${IMAKEENV} rm -rf ${INSTALLTMP} # +# installskel +# +# Installs a minimum set of files that can support a mini-jail +# +installskel: + @echo "--------------------------------------------------------------" + @echo ">>> Making installskel" + @echo "--------------------------------------------------------------" + ${_+_}cd ${.CURDIR}; ${MAKE} hierarchy + ${_+_}cd ${.CURDIR}/etc; ${MAKE} distribution + +# # reinstall # # If you have a build server, you can NFS mount the source and obj directories Index: etc/defaults/rc.conf =================================================================== --- etc/defaults/rc.conf (版本 188424) +++ etc/defaults/rc.conf (工作副本) @@ -611,6 +611,11 @@ jail_set_hostname_allow="YES" # Allow root user in a jail to change its hostname jail_socket_unixiproute_only="YES" # Route only TCP/IP within a jail jail_sysvipc_allow="NO" # Allow SystemV IPC use from within a jail +jail_skel_enable="NO" # Whether to globally enable "skel" jail +jail_skel_root="/" # The root directory for skel template +jail_skel_romounts="bin lib libexec sbin usr/bin usr/include usr/lib usr/libdata usr/libexec usr/sbin usr/share usr/src usr/obj" + # Read-only nullfs mounts from the template +jail_skel_rwmounts="" # Read-write nullfs mounts from the template # # To use rc's built-in jail infrastructure create entries for @@ -640,6 +645,11 @@ #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_skel_enable="NO" # Whether to enable "skel" jail +#jail_example_skel_root="/" # The root directory for skel template +#jail_example_skel_romounts="bin lib libexec sbin usr/bin usr/include usr/lib usr/libdata usr/libexec usr/sbin usr/share usr/src usr/obj usr/ports" + # Read-only nullfs mounts from the template +#jail_example_skel_rwmounts="" # Read-write nullfs mounts from the template ############################################################## ### Define source_rc_confs, the mechanism used by /etc/rc.* ## Index: etc/rc.d/jail =================================================================== --- etc/rc.d/jail (版本 188424) +++ etc/rc.d/jail (工作副本) @@ -85,6 +85,16 @@ [ -z "${_consolelog}" ] && _consolelog="/var/log/jail_${_j}_console.log" eval _fib=\"\${jail_${_j}_fib:-${jail_fib}}\" + # Default settings for skel jail + eval _skel_enable=\"\${jail_${_j}_skel_enable:-${jail_skel_enable}}\" + [ -z "${_skel_enable}" ] && _skel_enable="NO" + eval _skel_root=\"\${jail_${_j}_skel_root:-${jail_skel_root}}\" + [ -z "${_skel_root}" ] && _skel_root="/" + eval _skel_romounts=\"\${jail_${_j}_skel_romounts:-${jail_skel_romounts}}\" + [ -z "${_skel_romounts}" ] && _skel_romounts="bin lib libexec sbin usr/bin usr/include usr/lib usr/libdata usr/libexec usr/sbin usr/share usr/src usr/obj" + eval _skel_rwmounts=\"\${jail_${_j}_skel_rwmounts:-${jail_skel_rwmounts}}\" + [ -z "${_skel_rwmounts}" ] && _skel_rwmounts="" + # Debugging aid # debug "$_j devfs enable: $_devfs" @@ -120,6 +130,10 @@ debug "$_j exec stop: $_exec_stop" debug "$_j flags: $_flags" debug "$_j consolelog: $_consolelog" + debug "$_j skel enable: $_skel_enable" + debug "$_j skel mount-readonly: $_skel_romounts" + debug "$_j skel mount-readwrite: $_skel_rwmounts" + debug "$_j skel mount skeleton from: $_skel_root" if [ -z "${_hostname}" ]; then err 3 "$name: No hostname has been defined for ${_j}" @@ -241,6 +255,14 @@ secure_umount ${_mountpt} done fi + if checkyesno _skel_enable; then + for _mntpt in ${_skel_romounts} ${_skel_rwmounts} + do + if [ -d "${_rootdir}/${_mntpt}" ] ; then + umount -f ${_rootdir}/${_mntpt} > /dev/null 2>&1 + fi + done + fi } # jail_mount_fstab() @@ -509,6 +531,17 @@ fi jail_mount_fstab fi + if checkyesno _skel_enable; then + info "Mounting skeleton for jail ${_jail} from ${_skel_root}" + for _mntpt in $_skel_rwmounts + do + mount_nullfs ${_skel_root}/${_mntpt} ${_rootdir}/${_mntpt} > /dev/null 2>&1 + done + for _mntpt in $_skel_romounts + do + mount_nullfs -ordonly ${_skel_root}/${_mntpt} ${_rootdir}/${_mntpt} > /dev/null 2>&1 + done + fi if checkyesno _devfs; then # If devfs is already mounted here, skip it. df -t devfs "${_devdir}" >/dev/null Index: share/man/man5/rc.conf.5 =================================================================== --- share/man/man5/rc.conf.5 (版本 188424) +++ share/man/man5/rc.conf.5 (工作副本) @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 27, 2009 +.Dd February 10, 2009 .Dt RC.CONF 5 .Os .Sh NAME @@ -3413,6 +3413,46 @@ .Va jail_ Ns Ao Ar jname Ac Ns Va _exec_stop for every jail in .Va jail_list . +.It Va jail_skel_enable +.Pq Vt bool +Set to +.Dq Li NO +by default. +When set to +.Dq Li YES , +sets +.Va jail_ Ns Ao Ar jname Ac Ns Va _skel_enable +to +.Dq Li YES +by default for every jail in +.Va jail_list . +.It Va jail_skel_root +.Pq Vt str +Set to +.Dq Li / +by default. +When set, use as default value for +.Va jail_ Ns Ao Ar jname Ac Ns Va _skel_root +for every jail in +.Va jail_list . +.It Va jail_skel_romount +.Pq Vt str +Set to +.Dq Li bin lib libexec sbin usr/bin usr/include usr/lib usr/libdata usr/libexec usr/sbin usr/share usr/src usr/obj +by default. +When set, use as default value for +.Va jail_ Ns Ao Ar jname Ac Ns Va _skel_romount +for every jail in +.Va jail_list . +.It Va jail_skel_rwmount +.Pq Vt str +Set to empty by default. +When set, use as default value for +.Va jail_ Ns Ao Ar jname Ac Ns Va _skel_rwmount +for every jail in +.Va jail_list . .It Va jail_ Ns Ao Ar jname Ac Ns Va _rootdir .Pq Vt str Unset by default. @@ -3549,6 +3589,38 @@ .Dq Li /bin/sh /etc/rc.shutdown by default. This is the command executed at jail shutdown. +.It Va jail_ Ns Ao Ar jname Ac Ns Va _skel_enable +.Pq Vt bool +Set to +.Dq Li NO +by default. +When set to +.Dq Li YES , +enable the skeleton jail, which +.Xr mount_nullfs 8 +two lists of filesystems, one of which lists read-only, +another lists read-write as specified by the administrator, +relative to the template root, into inside jail +.Ar jname +respectively, at jail startup. +.It Va jail_ Ns Ao Ar jname Ac Ns Va _skel_root +.Pq Vt str +Set to +.Dq Li / +by default. +Specifies the root directory that a skeleton template is based on. +.It Va jail_ Ns Ao Ar jname Ac Ns Va _skel_romounts +.Pq Vt str +Specifies a list of directories that is expected to be mounted from +the skeleton template, into inside jail +.Ar jname , +as read-only. +.It Va jail_ Ns Ao Ar jname Ac Ns Va _skel_rwmounts +.Pq Vt str +Specifies a list of directories that is expected to be mounted from +the skeleton template, into inside jail +.Ar jname , +as read-write. .It Va jail_set_hostname_allow .Pq Vt bool If set to Index: usr.sbin/jail/jail.8 =================================================================== --- usr.sbin/jail/jail.8 (版本 188424) +++ usr.sbin/jail/jail.8 (工作副本) @@ -412,6 +412,46 @@ /etc/rc.d/jail start myjail /etc/rc.d/jail stop myjail .Ed +.Ss "Setting up a Jail from a template directory" +A so-called skeleton jail, is an environment where part of its +directories comes from +.Xr mount_nullfs 8 +from a template directory. +.Pp +Such setup can save the time for the administrator because it makes +it possible to share certain binaries and libraries between several +jails, as well as easy experimenting different releases of the +operating system libraries by switching template directories. +Also, this type of setup would save certain amount of disk space. +.Pp +A template directory can be populated with +.Dq "make world" , +or, the host system environment +.Aq Dq "/" , +can be used as well. +.Pp +To set up a jail directory tree containing the jail, one can use +the following +.Xr sh 1 +command script: +.Bd -literal +D=/here/is/the/jail +cd /usr/src +mkdir -p $D +make installskel DESTDIR=$D +.Ed +.Pp +One should explicitly specify that the jail is skeleton jail, by +either enabling the global flag +.Dq jail_skel_enable , +or the per-jail flag +.Dq Va jail_ Ns Ao Ar jname Ac Ns Va _skel_enable +in +.Xr rc.conf 5 +configuration. The system supplied a set of defaults that is +useful for typical setup, and is tweakable through several variables +as described in +.Xr rc.conf 5 . .Ss "Managing the Jail" Normal machine shutdown commands, such as .Xr halt 8 , --------------010704020508080109030502--