diff options
Diffstat (limited to 'config/jailctl')
-rwxr-xr-x | config/jailctl/jailctl | 1053 | ||||
-rw-r--r-- | config/jailctl/jailctl-utils.inc | 272 | ||||
-rw-r--r-- | config/jailctl/jailctl.inc | 217 | ||||
-rw-r--r-- | config/jailctl/jailctl.xml | 233 | ||||
-rw-r--r-- | config/jailctl/jailctl_defaults.xml | 122 | ||||
-rw-r--r-- | config/jailctl/jailctl_list.inc | 112 | ||||
-rw-r--r-- | config/jailctl/jailctl_settings.xml | 121 | ||||
-rwxr-xr-x | config/jailctl/sysinstall | bin | 0 -> 447888 bytes |
8 files changed, 2130 insertions, 0 deletions
diff --git a/config/jailctl/jailctl b/config/jailctl/jailctl new file mode 100755 index 00000000..542c2db6 --- /dev/null +++ b/config/jailctl/jailctl @@ -0,0 +1,1053 @@ +#!/bin/sh + +# ------------------------------------- +# Jail management script +# Copyright (c) 2004-2008 Eirik Oeverby +# All rights reserved. +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * The name(s) of the author(s) may not be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------- + +############################################################################## +# Configuration section # +# # +# Change the CFGFILE variable to point to your jail configuration file. # +############################################################################## + +# Clear the hook lists (for security reasons) +unset BEFORESTART_HOOKS +unset AFTERSTART_HOOKS +unset BEFORESTOP_HOOKS +unset AFTERSTOP_HOOKS +unset BEFORESTATUS_HOOKS +unset AFTERSTATUS_HOOKS +unset BEFOREBACKUP_HOOKS +unset AFTERBACKUP_HOOKS +unset BEFORERESTORE_HOOKS +unset AFTERRESTORE_HOOKS +unset BEFORECREATE_HOOKS +unset AFTERCREATE_HOOKS +unset BEFOREUPGRADE_HOOKS +unset AFTERUPGRADE_HOOKS +unset BEFOREDELETE_HOOKS +unset AFTERDELETE_HOOKS + +CFGFILE="/usr/local/etc/jails.conf" +. ${CFGFILE} + +PROCFS=`expr "$PROCFS" : "[tT][rR][uU][eE]"` +LINPROCFS=`expr "$LINPROCFS" : "[tT][rR][uU][eE]"` + +############################################################################## +# Main function section # +# # +# These functions are wrappers for the action functions below. They do # +# various sanity checking of input parameters, and verify the existence and # +# required states of the affected jail(s). # +############################################################################## + +usage() { + ## Output usage information + echo "Usage:" >&2 + echo "jailctl <command> <jail> [<path>]" >&2 + echo "<command> = start|stop|status|create|delete|upgrade|backup|restore" >&2 + echo "<jail> = hostname|all" >&2 + echo "<path> = Backup destination / restore source" >&2 + echo >&2 +} + +jail_status() { + ## Output the status of one or several jails + if [ ! $JAIL ] || [ $JAIL = "all" ] || jail_exists ; then + # Jail exists (or "all" was specified), we can query its status + if [ ! $JAIL ] || [ $JAIL = "all" ] ; then + # Output a brief list for all jails + echo "Jail status (*=running, !=not configured):" + for JAIL in $JAILS ; do + # Loop through jails + JAIL=`expr "$JAIL" : "\(.*\):.*"` + # Run hooks + jail_run_hooks before-status + if jail_exists && jail_running ; then + # Jail is running + echo "*$JAIL ($(jail_ip))" + elif jail_exists ; then + # Jail not running + echo " $JAIL ($(jail_ip))" + else + # Jail nonexistant or not configured + echo "!$JAIL ($(jail_ip))" + fi + # Run hooks + jail_run_hooks after-status + done + else + # Output information for a specific jail + # Run hooks + jail_run_hooks before-status + if jail_running ; then + # Jail is running, be verbose + echo "$JAIL ($(jail_ip)) is up." + echo "Path: $(jail_path)" + echo "Interface: $(jail_if)" + echo "Process list:" + # Output process list for jail + jps + elif jail_exists; then + # Jail not running + echo "$JAIL ($(jail_ip)) is down." + echo "Path: $(jail_path)" + echo "Interface: $(jail_if)" + else + # Jail nonexistant or not configured + echo "Unable to query jail $JAIL!" + echo "Incomplete configuration?" + fi + # Run hooks + jail_run_hooks after-status + fi + else + echo "Path: $(jail_path)" + echo "Interface: $(jail_if)" + # No jail was specified, or the specified jail doesn't exist (on disk + # or in jails.conf. Show usage information) + echo "No valid jail specified!" + echo + usage + fi +} + +jail_start() { + ## Start one or several jails + if [ $JAIL ] && (jail_exists || [ $JAIL = "all" ]) ; then + # Jail exists (or "all" was specified), we can attempt to start it + if [ $JAIL = "all" ] ; then + # Attempting to start all jails + for JAIL in $JAILS ; do + # Loop through jails + JAIL=`expr "$JAIL" : "\(.*\):.*"` + if jail_running ; then + # Jail is running, cannot start + echo "Jail already running!" + elif jail_exists ; then + # Jail not running, starting + echo "Starting jail $JAIL..." + jstart + else + # Jail nonexistant or not configured + echo "Unable to start jail $JAIL!" + echo "Incomplete configuration?" + fi + done + else + # Start a specific jail + if jail_running && [ ! $FORCE ] ; then + # Jail is running, cannot start + echo "Jail already running!" + elif jail_exists ; then + # Jail not running, starting + echo "Starting jail $JAIL..." + jstart + else + # Jail nonexistant or not configured + echo "Unable to start jail $JAIL!" + echo "Incomplete configuration?" + fi + fi + else + # No jail was specified, or the specified jail doesn't exist (on disk + # or in jails.conf. Show usage information) + echo "No valid jail specified!" + echo + usage + fi +} + +jail_stop() { + ## Stop one or several jails + if [ $JAIL ] && (jail_exists || [ $JAIL = "all" ]) ; then + # Jail exists (or "all" was specified), we can attempt to stop it + if [ $JAIL = "all" ] ; then + # Attempting to stop all jails + if [ $VERSION -eq 4 ] && [ `ls /proc | wc -l` -eq 0 ] ; then + # We are on FreeBSD 4.x, and we have no /proc to rely on + jstop + else + for JAIL in $JAILS ; do + # Loop through jails + JAIL=`expr "$JAIL" : "\(.*\):.*"` + if jail_exists && jail_running ; then + # Jail is running, stopping + echo "Stopping jail $JAIL..." + jstop + elif jail_exists && ! jail_running ; then + # Jail not running, cannot stop + echo "Jail not running ($JAIL)!" + else + # Jail nonexistant or not configured + echo "Unable to stop jail $JAIL!" + echo "Incomplete configuration?" + fi + done + fi + else + if jail_exists && jail_running ; then + if [ $VERSION -eq 4 ] && [ `ls /proc | wc -l` -eq 0 ] ; then + # We are on FreeBSD 4.x, and we have no /proc to rely on + echo 'Without a proc filesystem, you must use "jailctl stop all"!' + else + # Jail running, stopping + echo "Stopping jail $JAIL..." + jstop + fi + elif jail_exists && ! jail_running ; then + # Jail not running, cannot stop + echo "Jail not running!" + else + # Jail nonexistant or not configured + echo "Unable to start jail $JAIL!" + echo "Incomplete configuration?" + fi + fi + else + # No jail was specified, or the specified jail doesn't exist (on disk + # or in jails.conf. Show usage information) + echo "No valid jail specified!" + echo + usage + fi +} + +jail_create() { + ## Create a jail + # Be more specific in distinguishing return codes from jail_exists + jail_exists ; RC=$? + if [ $JAIL ] && [ $RC -eq 1 ] ; then + # If the jail is configured but does not exist on disk, create the jail + echo "Creating jail $JAIL..." + jcreate + else + # Jail not configured or already exists + echo "Jail $JAIL cannot be created!" + fi + return 0 +} + +jail_upgrade() { + ## Upgrade one or several jails + if [ $JAIL ] && (jail_exists || [ $JAIL = "all" ]) ; then + # Jail exists (or "all" was specified), we can attempt to upgrade it + if [ $JAIL = "all" ] ; then + # Attempting to upgrade all jails + for JAIL in $JAILS ; do + # Loop through jails + JAIL=`expr "$JAIL" : "\(.*\):.*"` + if jail_exists ; then + # Jail exists and is not running, upgrading + echo "Upgrading jail $JAIL..." + jupgrade + else + # Jail nonexistant or not configured + echo "Jail does not exist, or not configured!" + fi + done + else + if jail_exists ; then + # Jail exists and is not running, upgrading + echo "Upgrading jail $JAIL..." + jupgrade + else + # Jail nonexistant or not configured + echo "Jail does not exist, or not configured!" + fi + fi + else + # No jail was specified, or the specified jail doesn't exist (on disk + # or in jails.conf. Show usage information) + echo "No valid jail specified!" + echo + usage + fi +} + +jail_delete() { + ## Delete a specific jail + if [ $JAIL ] && ((jail_exists && ! jail_running) || [ $FORCE ]) ; then + # Jail exists and is not running, deleting + echo "Deleting jail $JAIL..." + jdelete + else + # Jail nonexistant, running or not configured, cannot delete + echo "Jail $JAIL cannot be deleted!" + fi + return 0 +} + +jail_backup() { + ## Back up one or several jails + if [ $JAIL ] && (jail_exists || [ $JAIL = "all" ]) ; then + # Jail exists (or "all" was specified), we can attempt to back it up + if [ $JAIL = "all" ] ; then + # Attempting to back up all jails + for JAIL in $JAILS ; do + # Loop through jails + JAIL=`expr "$JAIL" : "\(.*\):.*"` + if jail_exists && ! jail_running ; then + # Jail exists and is not running, doing cold backup + echo "Doing cold backup of jail $JAIL..." + jbackup cold + elif jail_exists && jail_running ; then + # Jail is running, doing warm backup + echo "Doing warm backup of jail $JAIL..." + jbackup + else + # Jail nonexistant or not configured + echo "Jail does not exist, or not configured!" + fi + done + else + if jail_exists && ! jail_running ; then + # Jail exists and is not running, doing cold backup + echo "Doing cold backup of jail $JAIL..." + jbackup cold + elif jail_exists && jail_running ; then + # Jail is running, doing warm backup + echo "Doing warm backup of jail $JAIL..." + jbackup + else + # Jail nonexistant or not configured + echo "Jail does not exist, or not configured!" + fi + fi + else + # No jail was specified, or the specified jail doesn't exist (on disk + # or in jails.conf. Show usage information) + echo "No valid jail specified!" + echo + usage + fi +} + +jail_restore() { + ## Restore a jail + # Be more specific in distinguishing return codes from jail_exists + jail_exists ; RC=$? + if [ $JAIL ] && [ $RC -eq 1 ] ; then + echo "Restoring jail $JAIL from backup" + local JP=$(jail_path) + # Restore the jail + jrestore + else + # No jail was specified, or the specified jail doesn't exist (on disk + # or in jails.conf. Show usage information) + echo "No valid jail specified!" + echo + usage + fi +} + + +# +### Helper function section +# + +jail_exists() { + ## Query a jails existence + local J=`echo $JAILS | tr " " "\n" | grep "^${JAIL}:"` +# for J in $JAILS ; do + # Loop through configured jails + local J_NAME=`expr "$J" : "\(.*\):.*"` + if [ $J_NAME = $JAIL ] && [ -d "$(jail_path)" ] && \ + [ `expr $(ls -a $(jail_path) | grep -v "^.snap$" | wc -l)` -gt 2 ]; then + # Jail is configured, its directory exists, and the + # directory contains more than . and .. + return 0 + elif [ $J_NAME = $JAIL ] && [ ! -d "$(jail_path)" ] || \ + ( [ -d "$(jail_path)" ] && \ + [ `expr $(ls -a $(jail_path) | grep -v "^.snap$" | wc -l)` -le 2 ]); then + # Jail is defined, but not yet created (directory missing or empty) + return 1 + fi +# done + # Jail doesn't exist + return 2 +} + +jail_name() { + ## Query the name of a jail + ## Must be updated to be able to search per IP. Searching per name makes + ## no sense + local J=`echo $JAILS | tr " " "\n" | grep "^${JAIL}:"` +# for J in $JAILS ; do + # Loop through configured jails + local J_NAME=`expr "$J" : "\(.*\):.*"` + if [ $J_NAME = $JAIL ] ; then + # Name part of jail definition matches + echo $J_NAME + return 0 + fi +# done + # Jail not found or error + return 1 +} + +jail_ip() { + ## Query the IP of a jail + local J=`echo $JAILS | tr " " "\n" | grep "^${JAIL}:"` +# for J in $JAILS ; do + # Loop through configured jails + local J_NAME=`expr "$J" : "\([^;].*\):.*"` + if [ $J_NAME = $JAIL ] ; then + # Name part of jail definition matches, output IP +echo $J > debug.file + local J_IP=`expr "$J" : ".*:\([^;]*\)"` + echo $J_IP + return 0 + fi +# done + # Jail not found or error + return 1 +} + +jail_path() { + ## Query the path to a jail + local J=`echo $JAILS | tr " " "\n" | grep "^${JAIL}:"` +# for J in $JAILS ; do + # Loop through configured jails + local J_NAME=`expr "$J" : "\(.*\):.*"` + if [ $J_NAME = $JAIL ] ; then + # Name part of jail definition matches, output path + local J_HOME=`expr "$J" : "[^;]*;\([^;]*\).*$"` + if [ -n "$J_HOME" ] ; then + if [ `expr "$J_HOME" : ".*\/$"` -gt 0 ] ; then + local J_PATH=`expr "$J_HOME" : "\(.*\)/$"` + else + local J_PATH="${J_HOME}/${J_NAME}" + fi + else + local J_PATH="${JAIL_HOME}$J_NAME" + fi + echo $J_PATH + return 0 + fi +# done + # Jail not found or error + return 1 +} + +jail_if() { + ## Query the path to a jail + local J=`echo $JAILS | tr " " "\n" | grep "^${JAIL}:"` +# for J in $JAILS ; do + # Loop through configured jails + local J_NAME=`expr "$J" : "\(.*\):.*"` + if [ $J_NAME = $JAIL ] ; then + # Name part of jail definition matches, output path + local J_HOME=`expr "$J" : "[^;]*;\([^;]*\).*$"` + local J_IF=`expr "$J" : ".*;[^;]*;\([^;]*\).*$"` + if [ -z "$J_IF" ] ; then + local J_IF=$IF + fi + echo $J_IF + return 0 + fi +# done + # Jail not found or error + return 1 +} + +jail_running() { + ## Query the running state of a jail + if [ $VERSION -ge 5 ] ; then + # We are on FreeBSD 5.x, using jls(1) tool + local JLS="`/usr/sbin/jls | grep \"\/${JAIL}$\"`" + if [ ! "$JLS" ] ; then + # Jail is not running + return 1 + fi + for i in "$JLS" ; do + # Fetching output string, concatenating + local J_LIST="$J_LIST $i" + done + # Setting JAIL_ID variable; this is the system jail ID + JAIL_ID=`echo $J_LIST | cut -d \ -f 1` + local JPS=`expr "\`/usr/sbin/jexec $JAIL_ID /bin/ps ax | grep -v \"ps\ ax\" | wc -l | cut -f 2\`" : "[[:space:]]*\([0-9]*\).*"` + if [ "$JPS" -lt 2 ] ; then + # Jail is not running (no processes, anyway) + return 1 + fi + else + # We are on FreeBSD 4.x, use old dirty trick + if [ ! -f "/var/run/jails/${JAIL}.running" ] ; then + # Jail is not running + return 1 + fi + fi + # Jail is running + return 0 +} + +# +### Activity function section +# + +jail_run_hooks() { + ## Select a hook list to run + case $1 in + before-start) + jrunhooks "$1" "$BEFORESTART_HOOKS" + ;; + after-start) + jrunhooks "$1" "$AFTERSTART_HOOKS" + ;; + before-stop) + jrunhooks "$1" "$BEFORESTOP_HOOKS" + ;; + after-stop) + jrunhooks "$1" "$AFTERSTOP_HOOKS" + ;; + before-status) + jrunhooks "$1" "$BEFORESTATUS_HOOKS" + ;; + after-status) + jrunhooks "$1" "$AFTERSTATUS_HOOKS" + ;; + before-backup) + jrunhooks "$1" "$BEFOREBACKUP_HOOKS" + ;; + after-backup) + jrunhooks "$1" "$AFTERBACKUP_HOOKS" + ;; + before-restore) + jrunhooks "$1" "$BEFORERESTORE_HOOKS" + ;; + after-restore) + jrunhooks "$1" "$AFTERRESTORE_HOOKS" + ;; + before-create) + jrunhooks "$1" "$BEFORECREATE_HOOKS" + ;; + after-create) + jrunhooks "$1" "$AFTERCREATE_HOOKS" + ;; + before-upgrade) + jrunhooks "$1" "$BEFOREUPGRADE_HOOKS" + ;; + after-upgrade) + jrunhooks "$1" "$AFTERUPGRADE_HOOKS" + ;; + before-delete) + jrunhooks "$1" "$BEFOREDELETE_HOOKS" + ;; + after-delete) + jrunhooks "$1" "$AFTERDELETE_HOOKS" + ;; + esac +} + +jps() { + ## List running processes in a jail + if [ $VERSION -ge 5 ] ; then + # We are on FreeBSD 5.x, use jexec(1) tool + /usr/sbin/jexec $JAIL_ID ps auxwww + else + # We are on FreeBSD 4.x, use old dirty trick (requires /proc on host!) + echo "CMD PID TIME UTIME STIME" + cat /proc/*/status | grep "${JAIL}" | cut -d \ -f 1 -f 2 -f 8 -f 9 -f 10 + fi + return 0 +} + +jstart() { + ## Start a jail + local JP=$(jail_path) + local IP=$(jail_ip) + local JIF=$(jail_if) + if [ $PROCFS -gt 0 ] ; then + # Mount proc filesystem into jail + /sbin/mount_procfs procfs ${JP}/proc + fi + if [ $LINPROCFS -gt 0 ] ; then + # Mount Linux proc filesystem into jail + /sbin/mount_linprocfs linprocfs ${JP}/compat/linux/proc + fi + + if [ $VERSION -ge 5 ] ; then + # Run hooks + jail_run_hooks before-start + # We are on FreeBSD 5.x, use devfs + /sbin/mount -t devfs devfs ${JP}/dev + devfs -m ${JP}/dev ruleset 4 + devfs -m ${JP}/dev rule applyset + fi + + # Bring up network interface alias and start jail + [ $(echo $JIF | cut -c 1-4) != 'carp' ] && ifconfig $JIF inet $IP netmask 0xffffffff alias + echo >> ${JP}/var/log/jailstart.log + echo $(date) >> ${JP}/var/log/jailstart.log + jail $JP $JAIL $IP /bin/sh /etc/rc 2>&1 >${JP}/var/log/jailstart.log & + + if [ $VERSION -eq 4 ] ; then + # We're on FreeBSD 4.x, Create run file + touch /var/run/jails/${JAIL}.running + fi + + if [ $VERSION -ge 5 ] ; then + # Run hooks + jail_run_hooks after-start + fi + + return 0 +} + +jstop() { + ## Stop a jail + local JP=$(jail_path) + local IP=$(jail_ip) + local JIF=$(jail_if) + + if [ $VERSION -ge 5 ] ; then + # Run hooks + jail_run_hooks before-stop + fi + + echo "Sending TERM signal to jail processes..." + if [ $VERSION -ge 5 ] ; then + # We are on FreeBSD 5.x, use jexec(1) tool + /usr/sbin/jexec $JAIL_ID /bin/sh /etc/rc.shutdown + sleep 2 + /usr/sbin/jexec $JAIL_ID kill -15 -1 + # Waiting for processes to die + sleep 4 + while jail_running ; do + # Some processes are still running, do a kill -9 -1 + echo "Some processes would not terminate; sending KILL signal..." + /usr/sbin/jexec $JAIL_ID kill -9 -1 + # Give processes some time to die + sleep 2 + done + umount -f ${JP}/dev + else + # We are on FreeBSD 4.x + if [ "$JAIL" = "all" ] ; then + # /proc is unavailable, so we can only stop ALL jails at once + local PS="`ps ax|cut -c 1-16|grep J|cut -d \ -f 1`" + for PID in "$PS" ; do + kill -15 $PID 2>/dev/null 1>/dev/null + done + # Waiting for processes to die + sleep 4 + local PS="`ps ax|cut -c 1-16|grep J|cut -d \ -f 1`" + while [ "$PS" ] ; do + # Some processes are still running, do a kill -9 on each + echo "Some processes would not terminate; sending KILL signal..." + for PID in "$PS" ; do + # Sending KILL signal to all processes in the jail + kill -9 $PID 2>/dev/null 1>/dev/null + done + # Give processes some time to die + sleep 2 + local PS="`ps ax|cut -c 1-16|grep J|cut -d \ -f 1`" + done + else + # Use /proc filesystem (REQUIRED for single-jail operation!) + local PS="`cat /proc/*/status | cut -d \ -f 2 -f 15 2>/dev/null | grep \" ${JAIL} \" | cut -d \ -f 1`" + for PID in "$PS" ; do + # Sending TERM signal to all processes in the jail + kill -15 $PID 2>/dev/null 1>/dev/null + done + # Waiting for processes to die + sleep 4 + local PS="`cat /proc/*/status | cut -d \ -f 2 -f 15 2>/dev/null | grep \" ${JAIL} \" | cut -d \ -f 1`" + while [ "$PS" ] ; do + # Some processes are still running, do a kill -9 on each + echo "Some processes would not terminate; sending KILL signal..." + for PID in "$PS" ; do + # Sending KILL signal to all processes in the jail + kill -9 $PID 2>/dev/null 1>/dev/null + done + # Give processes some time to die + sleep 2 + local PS="`cat /proc/*/status | cut -d \ -f 2 -f 15 2>/dev/null | grep \" ${JAIL} \" | cut -d \ -f 1`" + done + fi + fi + + if [ $PROCFS -gt 0 ] ; then + # Unmount the jail proc filesystem + umount -f ${JP}/proc + fi + if [ $LINPROCFS -gt 0 ] ; then + # Unmount the jail Linux proc filesystem + umount -f ${JP}/compat/linux/proc + fi + + if [ $VERSION -eq 4 ] ; then + # We are on FreeBSD 4.x, remove runfile + rm /var/run/jails/${JAIL}.running + fi + + # Bring down network interface alias + [ $(echo $JIF | cut -c 1-4) != 'carp' ] && ifconfig $JIF inet $IP netmask 0xffffffff -alias + + if [ $VERSION -ge 5 ] ; then + # Run hooks + jail_run_hooks after-stop + fi + + return 0 +} + +jcreate() { + jail_run_hooks before-create + ## Create a jail + local JP=$(jail_path) + local IP=$(jail_ip) + local JIF=$(jail_if) + + # Create jail directory + mkdir -p $JP + # Populate jail directory + jpopulate + # Initialize jail directory contents + jinit + # Remove unneeded files and clean up + jcleanup + jail_run_hooks after-create + return 0 +} + +jupgrade() { + jail_run_hooks before-upgrade + ## Upgrade a jail + local JP=$(jail_path) + # Run mergemaster to prepare the jail for upgrade + mergemaster -Upi -D $JP + # Populate jail directory + jpopulate + # Run mergemaster to update default configuration files + mergemaster -Ui -D $JP + # Remove unneeded files and clean up + jcleanup + if jail_running ; then + echo "Jail running, please restart!" + fi + jail_run_hooks after-upgrade + +} + +jdelete() { + jail_run_hooks before-delete + ## Delete a jail + local JP=$(jail_path) + local m_search="" + if [ $PROCFS -gt 0 ] ; then m_search="${JP}/proc" ; fi + if [ $LINPROCFS -gt 0 ] ; then + if [ -n "${m_search}" ] ; then m_search="${m_search}\|" ; fi + m_search="${m_search}${JP}/compat/linux/proc" + fi + if [ $VERSION -ge 5 ] ; then + if [ -n "${m_search}" ] ; then m_search="${m_search}\|" ; fi + m_search="${m_search}${JP}/dev" + fi + MOUNTS=`mount | grep "$JP" | grep -v "${m_search} | cut -d \ -f 3"` + MOUNTS_NO=`echo -n $MOUNTS | wc -l` + if [ $MOUNTS_NO -gt 0 ]; then + echo "WARNING: Mounted directories found in ${JP}:" + echo $MOUNTS + echo -n "Unmount ('n' will cancel delete)? [y/n] " + read ANS + if [ x$ANS = xy ]; then + for m in $MOUNTS ; do + echo -n "Unmounting $m ..." + umount_msg=`umount -f $m 2>&1` + umount_res=$? + sleep 1 + if [ $umount_res -ne 0 ] ; then + echo "FAILED!" + echo "$umount_msg" + else + echo "ok." + fi + done + MOUNTS=`mount | grep "$JP" | grep -v "${m_search}"` + MOUNTS_NO=`echo -n $MOUNTS | wc -l` + echo $MOUNTS_NO + if [ $MOUNTS_NO -gt 0 ] ; then + echo "Unmounting failed. Jail not deleted." + else + echo "All filesystems unmounted successfully. Deleting jail." + # Pass one: removing unprotected files + rm -Rf $JP 2>&1 > /dev/null + # Pass two: removing SCHG flag from jail tree + chflags -R noschg $JP + # Pass three: Removing jail directory + rm -Rf $JP + fi + fi + else + # Pass one: removing unprotected files + rm -Rf $JP 2>&1 > /dev/null + # Pass two: removing SCHG flag from jail tree + chflags -R noschg $JP + # Pass three: Removing jail directory + rm -Rf $JP + fi + jail_run_hooks after-delete + +} + +jbackup() { + ## Back up a jail + local JP=$(jail_path) + + # Determine target file for backup + if [ -n "$CMD" ] ; then + TARGET=$CMD + else + TARGET="${BACKUPDIR}/${JAIL}.tar" + fi + + # Run backup + jail_run_hooks before-backup + if [ ! "$1" = "cold" -a $VERSION -ge 5 ] ; then + # Run warm backup - FreeBSD >=5 only + if [ -z "$GPG" ] ; then + /usr/sbin/jexec $JAIL_ID /usr/bin/tar --one-file-system -C / $BACKUP_EXCLUDE -cf - ./. | gzip --fast > ${TARGET}.gz + else + /usr/sbin/jexec $JAIL_ID /usr/bin/tar --one-file-system -C / $BACKUP_EXCLUDE -cf - ./. | gzip --fast | $GPG -o ${TARGET}.gz.gpg + fi + else + # Run cold backup + if [ -z "$GPG" ] ; then + chroot $JP /usr/bin/tar --one-file-system -C / $BACKUP_EXCLUDE -cf - ./. | gzip --fast > ${TARGET}.gz + else + chroot $JP /usr/bin/tar --one-file-system -C / $BACKUP_EXCLUDE -cf - ./. | gzip --fast | $GPG -o ${TARGET}.gz.gpg + fi + fi + jail_run_hooks after-backup +} + +jrestore() { + ## Restore a jail from backup + # Create jail home + mkdir -p $JP && cd $JP + + # Determine source file for backup + if [ -n "$CMD" ] ; then + SOURCE=$CMD + else + SOURCE="${BACKUPDIR}/${JAIL}.tar.gz" + fi + + [ -f $SOURCE ] && jail_run_hooks before-restore + # Restore + tar -zpxf $SOURCE + [ $? -eq 0 ] && jail_run_hooks after-restore +} + + +# +### Activity helper function section +# + +jpopulate() { + ## Populate a jail directory + cd /usr/src + # Running installworld into jail directory + make installworld ${INSTALLWORLD_FLAGS} DESTDIR=${JP} 2>&1 | grep '>>>' +} + +jcleanup() { + ## Remove unneeded files and clean up a jail + # Copying the most recent list of files to delete + if [ $VERSION -ge 5 ] ; then + cp ${JAIL_HOME}addons/dellist5.txt $JP/dellist.txt + else + cp ${JAIL_HOME}addons/dellist4.txt $JP/dellist.txt + fi + # Removing protection from files to be deleted + chroot $JP chflags -R noschg $(cat ${JP}/dellist.txt) 2>/dev/null 1>/dev/null + # Deleting files + chroot $JP rm -Rf $(cat ${JP}/dellist.txt) 2>/dev/null 1>/dev/null + + # Changing binaries to be jail compatible + chroot ${JP} ln -f /usr/bin/true /sbin/mount + chroot ${JP} ln -f /usr/bin/true /sbin/umount + chroot ${JP} ln -f /usr/bin/true /sbin/swapon + chroot ${JP} ln -f /usr/bin/true /sbin/swapoff + chroot ${JP} chflags noschg /sbin/init + chroot ${JP} rm /sbin/init + chroot ${JP} ln -f /usr/bin/true /sbin/init + chroot ${JP} ln -f /usr/bin/true /sbin/adjkerntz + chroot ${JP} ln -f /usr/bin/true /sbin/ifconfig + + # Copy timezone information from host + cp /etc/localtime ${JP}/etc/localtime +} + +jinit() { + ## Install default set of configuration files + cd /usr/src/etc + # Installing distribution files to jail directory + make distribution DESTDIR=${JP} -DNO_MAKEDEV_RUN 2>/dev/null 1>/dev/null + + # Create directories in jail + mkdir -p ${JP}/proc + mkdir -p ${JP}/usr/home + mkdir -p ${JP}/root/.ssh + mkdir -p ${JP}/compat/linux/proc + mkdir -p ${JP}/usr/local/bin + chroot ${JP} ln -sf /usr/home /home + + # Update passwd database with default root user/pw + IFS2=$IFS + IFS=$(echo -e '\n\t') + if [ -z "$BATCH" ] ; then + echo "Setting root password in jail" + chroot ${JP} /usr/bin/passwd root + else + for L in $(cat ${JP}/etc/master.passwd) ; do + if [ "$L" = 'root::0:0::0:0:Charlie &:/root:/bin/csh' ] ; then + echo "root:${ROOT_PW}:0:0::0:0:Charlie &:/root:/bin/csh" >> ${JP}/tmp/jailctl.001 + else + echo $L >> ${JP}/tmp/jailctl.001 + fi + done + pwd_mkdb -p -d ${JP}/etc ${JP}/tmp/jailctl.001 + IFS=$IFS2 + fi + + # Install jail hostname and IP into hosts file + JAIL_HOST=$(expr $JAIL : "\([a-zA-Z0-9\-]*\)\..*") + JAIL_DOMAIN=$(expr $JAIL : "${JAIL_HOST}\.\(.*\)") + echo "$IP $JAIL $JAIL_HOST" >> ${JP}/etc/hosts + + # Create new rc.conf + echo '# Default jail rc.conf' > ${JP}/etc/rc.conf + for L in $RC_CONF ; do + echo $L >> ${JP}/etc/rc.conf + done + echo "hostname=\"$JAIL\"" >> ${JP}/etc/rc.conf + + # Update SSH configuration + sed -i .jailctl -Ee "s/#?PermitRootLogin no/PermitRootLogin yes/" ${JP}/etc/ssh/sshd_config + + # Update resolv.conf + echo "domain $JAIL_DOMAIN" > ${JP}/etc/resolv.conf + # Update resolv.conf + for L in $NAMESERVERS ; do + echo "nameserver $L" >> ${JP}/etc/resolv.conf + done + + # Creating symlinks + chroot ${JP} ln -sf /dev/null /kernel + if [ $VERSION -ge 5 ] ; then + # We are on FreeBSD 5.x, work around distribution bug + chroot ${JP} ln -sf /lib/libm.so.3 /lib/libm.so.2 + fi + + if [ $VERSION -eq 4 ] ; then + # We are on FreeBSD 4.x, initializing device tree + cd ${JP}/dev + sh MAKEDEV jail + fi + + # Installing addons + cp -R ${JAIL_HOME}addons/* ${JP}/ + + # Starting jail for the first time, calling runme.sh to install software + [ $(echo $JIF | cut -c 1-4) != 'carp' ] && ifconfig $JIF inet $IP netmask 0xffffffff alias + JSTART=$(jail $JP $JAIL $IP /bin/sh /runme.sh) + [ $(echo $JIF | cut -c 1-4) != 'carp' ] && ifconfig $JIF inet $IP netmask 0xffffffff -alias + + # Output commmands used to run installation script for easy re-run + [ $(echo $JIF | cut -c 1-4) != 'carp' ] && echo "ifconfig $JIF inet $IP netmask 0xffffffff alias" + echo "jail $JP $JAIL $IP /bin/sh /runme.sh" + [ $(echo $JIF | cut -c 1-4) != 'carp' ] && echo "ifconfig $JIF inet $IP netmask 0xffffffff -alias" +} + +jrunhooks() { + ## Run a hook list + # Find jail ID on FreeBSD >5 + local JAIL_ID=0 + if [ $VERSION -ge 5 ] && jail_running ; then + local JLS="`/usr/sbin/jls | grep \"\/${JAIL}$\"`" + for i in "$JLS" ; do + # Fetching output string, concatenating + local J_LIST="$J_LIST $i" + done + # Setting JAIL_ID variable; this is the system jail ID + local JAIL_ID=`echo $J_LIST | cut -d \ -f 1` + fi + + for HOOK in $@; do + # Skip first parameter + [ ! "$HOOK" = "$1" ] && $HOOK $1 $JAIL $(jail_path) $JAIL_ID + done +} + +# +### Main block +# + +## Get current working directory +CWD=$(pwd) + +## Get command line parameters +ACTION=$1 +JAIL=$2 +CMD=$3 + +if [ "$CMD" = "force" ] ; then + FORCE=1 +fi + +## Checking current FreeBSD version +VERSION="`uname -r | cut -c 1`" + +if [ $VERSION -eq 4 ] ; then + # We are on FreeBSD 4.x, creating statefile directory + if [ ! -d "/var/run/jails" ] ; then + mkdir -p /var/run/jails + fi +fi + +case "$ACTION" in +status) jail_status ;; +start) jail_start ;; +stop) jail_stop ;; +create) jail_create ;; +upgrade) jail_upgrade ;; +delete) jail_delete ;; +backup) jail_backup ;; +restore) jail_restore ;; +*) usage ;; + +esac + +cd $CWD + +exit 0 + diff --git a/config/jailctl/jailctl-utils.inc b/config/jailctl/jailctl-utils.inc new file mode 100644 index 00000000..df16750c --- /dev/null +++ b/config/jailctl/jailctl-utils.inc @@ -0,0 +1,272 @@ +<?php +$GLOBALS['jailctl_tmp']['mounts'][]='bin'; +$GLOBALS['jailctl_tmp']['mounts'][]='lib'; +$GLOBALS['jailctl_tmp']['mounts'][]='libexec'; +$GLOBALS['jailctl_tmp']['mounts'][]='sbin'; +$GLOBALS['jailctl_tmp']['mounts'][]='usr/bin'; +$GLOBALS['jailctl_tmp']['mounts'][]='usr/include'; +$GLOBALS['jailctl_tmp']['mounts'][]='usr/lib'; +$GLOBALS['jailctl_tmp']['mounts'][]='usr/libdata'; +$GLOBALS['jailctl_tmp']['mounts'][]='usr/libexec'; +$GLOBALS['jailctl_tmp']['mounts'][]='usr/sbin'; +$GLOBALS['jailctl_tmp']['mounts'][]='usr/share'; + +$GLOBALS['jailctl_tmp']['unionmounts'][]='etc'; +$GLOBALS['jailctl_tmp']['unionmounts'][]='var'; +$GLOBALS['jailctl_tmp']['unionmounts'][]='usr/local/etc'; + +$GLOBALS['jailctl_tmp']['mount_unionfs']='mount -t unionfs -o below '; +$GLOBALS['jailctl_tmp']['mount_nullfs']='mount -t nullfs -o ro'; + +function jailctl_initialize_jail($jail, $jstatus, $jconfig) { + $cmd='sed -I "" -e s/"^root:[^:]*:"/"root:'.addcslashes($jconfig['jpasswd'], '$/').':"/ '.$jstatus['jpath'].'/etc/master.passwd '."\n"; + $cmd.='sed -I "" -e s/"^.PermitRootLogin.*"/"PermitRootLogin yes"/ '.$jstatus['jpath'].'/etc/ssh/sshd_config '."\n"; + $cmd.="pwd_mkdb -d ".$jstatus['jpath']."/etc ".$jstatus['jpath']."/etc/master.passwd \n"; + $cmd.="echo '".$jail['jip']." ".$jail['jname']." ".$jstatus['jhostname'][0]."' >> ".$jstatus['jpath']."/etc/hosts \n"; + $cmd.="echo 'hostname=\"".$jail['jname']."\"' > ".$jstatus['jpath']."/etc/rc.conf \n"; + + if(is_array($jconfig['row']) { + foreach($jconfig['row'] as $_row) { + $cmd.="echo '".$_row['rcconfline']."' >> ".$jstatus['jpath']."/etc/rc.conf \n"; + #$cmd.="echo '".str_replace(' ', "\n", $jconfig['jrcconf'])."' >> ".$jstatus['jpath']."/etc/rc.conf \n"; + } + } + $cmd.="echo 'domain ".$jstatus['jhostname'][1]."' > ".$jstatus['jpath']."/etc/resolv.conf \n"; + foreach(explode(' ', trim($jconfig['jdnsservers'])) as $_ns) { + $cmd.="echo 'nameserver ".str_replace(' ', "\nnameserver ", $_ns)."' >> ".$jstatus['jpath']."/etc/resolv.conf \n"; + } + return $cmd; +} + +function jailctl_create_template($jail, $jstatus, $jconfig) { + $mounts=$GLOBALS['jailctl_tmp']['mounts']; + $unionmounts=$GLOBALS['jailctl_tmp']['unionmounts']; + $mount_unionfs=$GLOBALS['jailctl_tmp']['mount_unionfs']; + $mount_nullfs=$GLOBALS['jailctl_tmp']['mount_nullfs']; + + $_path=$jstatus['jpath']; + $_name=$jail['name']; + $_ip=$jail['jip']; + $_hostname=$jstatus['jhostname']; + $_dnsservers=$jconfig['jdnsservers']; + $_passwd=$jconfig['jpasswd']; + $_template=$jail['jtemplates']; + + exec('mkdir -p '.$_path.'/dev'); + exec('mkdir -p '.$_path.'/root'); + exec('ln -s /usr/home '.$_path.'/home'); + + $jail['juse_unionfs']=='on' ? $mount=$mount_unionfs : $mount=$mount_nullfs ; + + foreach($mounts as $mp) { + $cmd[]='mkdir -p '.$_path.'/'.$mp; + $cmd[]=$mount.' '.$_template.'/'.$mp.' '.$_path.'/'.$mp; + } + + foreach($unionmounts as $mp) { + $cmd[]='mkdir -p '.$_path.'/'.$mp; + $cmd[]=$mount_unionfs.' '.$_template.'/'.$mp.' '.$_path.'/'.$mp; + } + + foreach($cmd as $_t) { +# exec($_t.' 2>&1 ', $_mount); + exec($_t.' 2>&1 '); + } +# foreach($_mount as $_out) { +# echo $_out."<br>"; +# } + + $cmd=jailctl_initialize_jail($jail, $jstatus, $jconfig); + $fd=fopen('/tmp/jcreate_'.$jail['jname'], 'w+'); + fwrite($fd, $cmd); + fclose($fd); + exec("sh /tmp/jcreate_".$jail['jname']." 2>&1 >/var/log/jcreate_exec &"); + + foreach(array_reverse($mounts, true) as $mp) { + exec('umount -f '.$_path.'/'.$mp); + } + + foreach(array_reverse($unionmounts, true) as $mp) { + exec('umount -f '.$_path.'/'.$mp); + } +} + +function jailctl_create_sysinstall($jail, $jstatus, $jconfig) { + exec('mkdir -p '.$jstatus['jpath']); + $cmd="sysinstall "; + $cmd.="_ftpPath=".$jconfig['jftpmirror']." "; + $cmd.="nonInteractive=yes "; + $cmd.="mediaSetFTP "; + $cmd.="releaseName=7.1-RELEASE "; + if($jail['jdists']) { + $cmd.="dists=\"base ".str_replace(',', ' ', $jail['jdists'])."\" "; + $cmd.="distSetCustom "; + } else { + $cmd.=$jail['jdistset']." "; + } + $cmd.="installRoot=".$jstatus['jpath']." "; + $cmd.="installCommit "; + $cmd.="> /var/log/jcreate.log 2>/var/log/jcreate.err \n"; + $cmd.="\n"; + + $cmd.=jailctl_initialize_jail($jail, $jstatus, $jconfig); + + $fd=fopen('/tmp/jcreate_'.$jail['jname'], 'w+'); + fwrite($fd, $cmd); + fclose($fd); + + exec("sh /tmp/jcreate_".$jail['jname']." 2>&1 >/var/log/jcreate_exec &"); +} + +function jailctl_find_if($ip) { + exec("ifconfig | grep -C 1 '".addcslashes($ip, ".")."'", $_ifconfig); + $if=explode(':', $_ifconfig[0]); + + return $if[0]; +} + +function jailctl_addinterfaces($config) { + $vips=$config['virtualip']['vip']; + ?> + <script type="text/javascript"> + function isValidIPAddress(ipaddr) { + var re = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; + if (re.test(ipaddr)) { + var parts = ipaddr.split("."); + if (parseInt(parseFloat(parts[0])) == 0) { return false; } + for (var i=0; i<parts.length; i++) { + if (parseInt(parseFloat(parts[i])) > 255) { return false; } + } + return true; + } else { + return false; + } + } + function addinterfaces() { + <?php + + foreach($vips as $vip) { + if($vip['mode']=='carp') { + echo("document.forms['iform'].jif.appendChild(new Option('".$vip['descr']." (".$vip['subnet'].")', '".$vip['subnet']."'));"); + } + } + + ?> + } + addinterfaces(); + + for (var i=0; i < document.forms['iform'].jif.length; i++) { + <?php + $jif=$config['installedpackages']['pfjailctl']['config'][$_GET['id']]['jif']; + echo('if (document.forms["iform"].jif[i].value == "'.$jif.'") {'); + ?> + document.forms['iform'].jif[i].selected = true; + } else { + document.forms['iform'].jif[i].selected = false; + } + } + if (isValidIPAddress(document.forms['iform'].jif.value)) { + document.forms['iform'].jip.disabled=true; + } + + function setdisableip() { + if (isValidIPAddress(document.forms['iform'].jif.value)) { + document.forms['iform'].jip.value=document.forms['iform'].jif.value; + document.forms['iform'].jip.disabled=true; + } else { + // document.forms['iform'].jip.value=''; + document.forms['iform'].jip.disabled=false; + } + } + document.forms['iform'].jif.addEventListener('change', setdisableip, true); + </script> + <?php +} + +function jailctl_addtemplates($config) { + $templates=$config['installedpackages']['pfjailctltemplates']['config'][0]['templates']; + ?> + <script type="text/javascript"> + function addtemplates() { + <?php + foreach($templates as $template) { + echo("document.forms['iform'].jtemplates.appendChild(new Option('".$template['name']."', '".$template['path']."'));"); + } + ?> + } + addtemplates(); + </script> + <?php +} + + +function jailctl_jailstatus($config, $jail) { + $jconfig=$config['installedpackages']['pfjailctlsettings']['config'][0]; + #echo("<pre>"); print_r($jail); echo("</pre>"); + + + $jname=$jail['jname']; + $jhostname=explode('.', $jname, 2); + $jpath=$jconfig['jstorage']."/".$jname; + $jip=$jail['jip']; + $jif=$jail['jif']; + + if(is_ipaddr($jif)) { + $jrealif=jailctl_find_if($jif); + #$jrealif=guess_interface_from_ip($jif); + #$jrealif=link_carp_interface_to_parent($jif); + } else { + $jrealif=$config['interfaces'][$jif]['if']; + } + + if($config['interfaces'][$jif]['descr']) { + $jifdesc=$config['interfaces'][$jif]['descr']; + } elseif(is_ipaddr($jif)) { + $vips=$config['virtualip']['vip']; + foreach($vips as $vip) { + if($vip['mode']=='carp' and $vip['subnet']==$jif) { + $jifdesc='CARP on '.strtoupper($vip['interface']); + } + } + } else { + $jifdesc=strtoupper($jail['jif']); + } + + $_out=Array(); + exec('ps axwww | grep "sysinstall.*'.$jname.'" | grep -v grep', $_out); + if(count($_out)) { + $jstate='Building'; + } else { + $_out=Array(); + exec('/usr/local/sbin/jailctl status '.$jname, $_out); + #echo("<pre>"); print_r($_out); echo("</pre>"); + if (substr($_out[0], 0, strlen($jname))==$jname) { + $_tmp=Array(); + ereg("is (.*)\.", array_shift($_out), $_tmp); + switch ($_tmp[1]) { + case 'down': + $jstate='Stopped'; + break; + case 'up': + $jstate='Running'; + break; + default: + $jstate='Undefined'; + break; + } + } else { + $jstate='New'; + } + } + + $jstatus['jstate']=$jstate; + $jstatus['jpath']=$jpath; + $jstatus['jrealif']=$jrealif; + $jstatus['jifdesc']=$jifdesc; + $jstatus['jhostname']=$jhostname; + + return $jstatus; +} + + +?>
\ No newline at end of file diff --git a/config/jailctl/jailctl.inc b/config/jailctl/jailctl.inc new file mode 100644 index 00000000..d6b7344c --- /dev/null +++ b/config/jailctl/jailctl.inc @@ -0,0 +1,217 @@ +<?php +/* $Id$ */ +include("jailctl-utils.inc"); + +if($_POST['xml']=='jailctl_settings.xml' && $_POST['jpasswd']) { + $_POST['jpasswd']=crypt($_POST['jpasswd']); +} elseif($_POST['xml']=='jailctl_settings.xml' && !$_POST['jpasswd']) { + $_POST['jpasswd']=$config['installedpackages']['pfjailctlsettings']['config'][0]['jpasswd']; +} + +if($_POST['xml']=='jailctl_settings.xml') { + $_count=0; + while($_count <= count(array_keys($_POST))) { + if(isset($_POST['rcconfline'.$_count])) { + $_POST['rcconfline'.$_count]=addcslashes($_POST['rcconfline'.$_count], '"'); + } + $_count++; + } +} elseif($_GET['xml']=='jailctl_settings.xml') { + $config['installedpackages']['pfjailctlsettings']['config'][0]['jpasswd']=''; +} elseif($_POST['xml']=='jailctl.xml' && is_ipaddr($_POST['jif'])) { + $_POST['jip']=$_POST['jif']; +} elseif($_POST['xml']=='jailctl.xml') { + # Stuff goes here? +} + + +function jailctl_create($config, $jail) { + $jstatus=jailctl_jailstatus($config, $jail); + $jconfig=$config['installedpackages']['pfjailctlsettings']['config'][0]; + if($jail['jtemplates']) { + jailctl_create_template($jail, $jstatus, $jconfig); + } else { + jailctl_create_sysinstall($jail, $jstatus, $jconfig); + } +} + +function jailctl_delete() { + global $config, $jconfig, $jails; + + $jpath=$jconfig['jstorage']."/".$jails[$_GET['id']]['jname']; + exec("rm -Rf '".$jpath."' >/dev/null 2>/dev/null &"); +# sync_package_jailctl(); +} + +function jailctl_deinstall() { +# unset($GLOBALS['config']['installedpackages']['pfjailctlsettings']); +# unset($GLOBALS['config']['installedpackages']['pfjailctl']); +} + +function jailctl_install() { + $jails=$GLOBALS['config']['installedpackages']['pfjailctl']['config']; + for($i=0;$i<=count($jails);$i++) { + if(is_array($jails[$i]) and ! $jails[$i]['jname']) + unset($GLOBALS['config']['installedpackages']['pfjailctl']['config'][$i]); + } + + if(!$GLOBALS['config']['installedpackages']['pfjailctlsettings']['config'][0]['jif']) { + $settings['jif']='lan'; + $settings['jdnsservers']=$GLOBALS['config']['interfaces']['lan']['ipaddr']; + $settings['jstorage']='/usr/local/jails'; + $settings['jbackup']=$settings['jstorage']; + $settings['jbackupexcludes']='--exclude ./usr/ports/* --exclude ./tmp/* --exclude ./var/tmp/* --exclude ./usr/src/*'; + $settings['jrcconf']='sshd_enable="YES"'; + $settings['jpasswd']='$1$e4.8A4lV$oU.OQciTOnonltQkK12ff0'; + + $GLOBALS['config']['installedpackages']['pfjailctlsettings']['config'][0]=$settings; + } +} + +function jailctl_servicestatus() { + global $config; + $jconfig=$config['installedpackages']['pfjailctlsettings']['config'][0]; + $jails=$config['installedpackages']['pfjailctl']['config']; + is_array($jails) ? $num_jails=count($jails) : $num_jails=0; + + if($num_jails) { + for ($i=0;$i<$num_jails;$i++) { + $jname=$jails[$i]['jname']; + $jstatus=Array(); + $_jcreate=Array(); + exec('/usr/local/sbin/jailctl status '.$jname, $jstatus); + + if (substr($jstatus[0], 0, strlen($jname))==$jname) { + $_tmp=Array(); + ereg("is (.*)\.", array_shift($jstatus), $_tmp); + switch ($_tmp[1]) { + case 'up': + break; + default: + return false; + } + } else { + return false; + } + } + } else { + return false; + } + return true; +} + +function jailctl_do_xmlrpc_sync($config) { + $jails=$config['installedpackages']['pfjailctl']['config'][0]; + $jconfig=$config['installedpackages']['pfjailctlsettings']['config'][0]; + $sync=$config['installedpackages']['carpsettings']['config'][0]; + + if(!$sync['synchronizetoip'] or !$sync['password']) + return; + + if($config['system']['webgui']['protocol'] != "") { + $synchronizetoip = $config['system']['webgui']['protocol']; + $synchronizetoip .= "://"; + } + $port = $config['system']['webgui']['port']; + /* if port is empty lets rely on the protocol selection */ + if($port == "") { + if($config['system']['webgui']['protocol'] == "http") + $port = "80"; + else + $port = "443"; + } + $synchronizetoip .= $sync['synchronizetoip']; + + /* xml will hold the sections to sync */ + $xml = array(); + $xml['pfjailctl'] = $config['installedpackages']['pfjailctl']; + $xml['pfjailctlsettings'] = $config['installedpackages']['pfjailctlsettings']; + + /* assemble xmlrpc payload */ + $params = array( + XML_RPC_encode($sync['password']), + XML_RPC_encode($xml) + ); + + /* set a few variables needed for sync code borrowed from filter.inc */ + $url = $synchronizetoip; + log_error("Beginning pfJailctl XMLRPC sync to {$url}:{$port}."); + $method = 'pfsense.merge_installedpackages_section_xmlrpc'; + $msg = new XML_RPC_Message($method, $params); + $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); + $cli->setCredentials('admin', $sync['password']); + /* send our XMLRPC message and timeout after 25 seconds */ + $resp = $cli->send($msg, "25"); + if(!$resp) { + $error = "A communications error occured while attempting pfJailctl XMLRPC sync with {$url}:{$port}."; + log_error($error); + file_notice("sync_settings", $error, "pfJailctl Settings Sync", ""); + } elseif($resp->faultCode()) { + $cli->setDebug(1); + $resp = $cli->send($msg, "250"); + $error = "An error code was received while attempting pfJailctl XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); + log_error($error); + file_notice("sync_settings", $error, "pfJailctl Settings Sync", ""); + } else { + log_error("pfJailctl XMLRPC sync successfully completed with {$url}:{$port}."); + } + #echo "done.<br>"; +} + +function sync_package_jailctl() { + global $config, $g; + $jconfig=$config['installedpackages']['pfjailctlsettings']['config'][0]; + $jails=$config['installedpackages']['pfjailctl']['config']; + is_array($jails) ? $num_jails=count($jails) : $num_jails=0; + + $jdefaultif=$config['interfaces']['lan']['if']; + + conf_mount_rw(); + config_lock(); + $fd = fopen("/usr/local/etc/jails.conf","w"); + + fwrite($fd, 'IF="'.$jdefaultif.'"'."\n"); + fwrite($fd, 'JAIL_HOME="'.$jconfig['jstorage'].'/"'."\n"); + fwrite($fd, 'BACKUPDIR="'.$jconfig['jbackup'].'"'."\n"); + fwrite($fd, 'BACKUP_EXCLUDE="'.$jconfig['jbackupexcludes'].'"'."\n"); + fwrite($fd, 'INSTALLWORLD_FLAGS="'.$jconfig['jinstallflags'].'"'."\n"); + fwrite($fd, 'BATCH="'.$jconfig['jbatchcreate'].'"'."\n"); + fwrite($fd, 'ROOT_PW="'.$jconfig['jpasswd'].'"'."\n"); + fwrite($fd, 'NAMESERVERS="'.$jconfig['jdnsservers'].'"'."\n"); + fwrite($fd, 'RC_CONF=\''.$jconfig['jrcconf'].'\''."\n"); + + fwrite($fd, "\nJAILS=''\n"); + + $_rcfile['file']='jails.sh'; + $_rcfile['start']=''; + $_rcfile['stop']=''; + if($num_jails) { + for ($i=0;$i<$num_jails;$i++) { + $jname=$jails[$i]['jname']; + $jpath=$jconfig['jstorage']."/".$jname."/"; + $jif=$jails[$i]['jif']; + if(is_ipaddr($jif)) { + $jip=$jif; + #$jif=guess_interface_from_ip($jif); + $jif=jailctl_find_if($jif); + } else { + $jif=$config['interfaces'][$jails[$i]['jif']]['if']; + $jip=$jails[$i]['jip']; + } + + $_cfg="JAILS=\"\$JAILS $jname:$jip;$jpath;$jif\"\n"; + fwrite($fd, $_cfg); + + if($jails[$i]['jautostart']=='on') { + $_rcfile['start'].="/usr/local/sbin/jailctl start $jname \n\t"; + $_rcfile['stop'].="/usr/local/sbin/jailctl stop $jname \n\t"; + } + } + } + + write_rcfile($_rcfile); + fclose($fd); + jailctl_do_xmlrpc_sync($config); +} + +?> diff --git a/config/jailctl/jailctl.xml b/config/jailctl/jailctl.xml new file mode 100644 index 00000000..079ddb6b --- /dev/null +++ b/config/jailctl/jailctl.xml @@ -0,0 +1,233 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?> +<packagegui> + <description>Jail management</description> + <requirements>Disk space...</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>pfJailctl</name> + <version>0.1</version> + <title>Jails</title> + <!-- Menu is where this packages menu will appear --> + <menu> + <name>Jails</name> + <tooltiptext>Jail management</tooltiptext> + <section>Services</section> + <configfile>jailctl.xml</configfile> + </menu> + <service> + <name>Jails</name> + <rcfile>jails.sh</rcfile> + <description>All jails with autostart enabled.</description> + <custom_php_service_status_command> + include("/usr/local/pkg/jailctl.inc"); + jailctl_servicestatus(); + </custom_php_service_status_command> + </service> + <!-- configpath gets expanded out automatically and config items will be + stored in that location --> + <configpath>['installedpackages']['$packagename']['config']</configpath> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0644</chmod> + <item>http://www.pfsense.com/packages/config/jailctl/jailctl_defaults.xml</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0644</chmod> + <item>http://www.pfsense.com/packages/config/jailctl/jailctl_settings.xml</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0644</chmod> + <item>http://www.pfsense.com/packages/config/jailctl/jailctl.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0644</chmod> + <item>http://www.pfsense.com/packages/config/jailctl/jailctl-utils.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0644</chmod> + <item>http://www.pfsense.com/packages/config/jailctl/jailctl_list.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/sbin/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/jailctl/jailctl</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/sbin/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/jailctl/sysinstall</item> + </additional_files_needed> + + <tabs> + <tab> + <text>Jails</text> + <url>/pkg.php?xml=jailctl.xml</url> + <active/> + </tab> + <tab> + <text>Global settings</text> + <url>/pkg_edit.php?xml=jailctl_settings.xml&id=0</url> + </tab> +<!-- <tab> + <text>Jail defaults</text> + <url>/pkg_edit.php?xml=jailctl_defaults.xml&id=0</url> + </tab> --> + </tabs> + + + <adddeleteeditpagefields> + <columnitem> + <fielddescr>State</fielddescr> + <fieldname>jstate</fieldname> + </columnitem> + <columnitem> + <fielddescr>Jail name</fielddescr> + <fieldname>jname</fieldname> + </columnitem> + <columnitem> + <fielddescr>Jail IF</fielddescr> + <fieldname>jifdesc</fieldname> + </columnitem> + <columnitem> + <fielddescr>Jail IP</fielddescr> + <fieldname>jip</fieldname> + </columnitem> + <columnitem> + <fielddescr>Jail path</fielddescr> + <fieldname>jpath</fieldname> + </columnitem> + <columnitem> + <fielddescr>Actions</fielddescr> + <fieldname>jactions</fieldname> + </columnitem> + + </adddeleteeditpagefields> + + <fields> + <field> + <fielddescr>Jail hostname</fielddescr> + <fieldname>jname</fieldname> + <description>FQDN of the jail</description> + <type>input</type> + </field> + <field> + <fielddescr>Network interface</fielddescr> + <fieldname>jif</fieldname> + <description>Jail will be bound to this interface</description> + <type>interfaces_selection</type> + </field> + <field> + <fielddescr>IP address</fielddescr> + <fieldname>jip</fieldname> + <description>Must be in the same subnet as the parent interface</description> + <type>input</type> + </field> + <field> + <fielddescr>Autostart jail on boot?</fielddescr> + <fieldname>jautostart</fieldname> + <description>Start this jail automatically when the system boots?</description> + <type>checkbox</type> + </field> + + + <field> + <fielddescr>Jail templates</fielddescr> + <fieldname>jselect_templates</fieldname> + <type>listtopic</type> + <name>Select a predefined template for your jail:</name> + </field> + <field> + <fielddescr>Templates</fielddescr> + <fieldname>jtemplates</fieldname> + <description>Files from the templates will be read-only inside the jail.</description> + <type>select</type> + <options> + <option><name> --- select --- </name><value></value></option> + </options> + <default_value>jtemplate_default</default_value> + </field> + <field> + <fielddescr>Use unionfs</fielddescr> + <fieldname>juse_unionfs</fieldname> + <description>Use unionfs instead of nullfs to mount the template contents into the jail</description> + <type>checkbox</type> + </field> + + <field> + <fielddescr>Package sets</fielddescr> + <fieldname>jselect_sets</fieldname> + <type>listtopic</type> + <name>OR select a distribution set to install:</name> + </field> + <field> + <fielddescr>Distribution sets</fielddescr> + <fieldname>jdistset</fieldname> + <description>Select a standard set of distributions to install</description> + <type>select</type> + <options> + <option><name> --- select --- </name><value></value></option> + <option><name>User (binaries only)</name><value>distSetUser</value></option> + <option><name>Developer (src/all, binaries)</name><value>distSetDeveloper</value></option> + <option><name>Kernel developer (src/kern, binaries)</name><value>distSetKernDeveloper</value></option> + <option><name>Minimum (minimal binaries)</name><value>distSet</value></option> + </options> + <default_value></default_value> + </field> + + <field> + <fielddescr>Individual packages</fielddescr> + <fieldname>jselect_individual</fieldname> + <type>listtopic</type> + <name>OR select individual distributions in addition to 'base':</name> + </field> + + <field> + <fielddescr>Individual distributions</fielddescr> + <fieldname>jdists</fieldname> + <description>Select individual distributions (multiple selection)</description> + <type>select</type> + <options> + <option><name>Manual pages</name><value>manpages</value></option> + <option><name>The Ports collection</name><value>ports</value></option> + <option><name>Miscellaneous documentation</name><value>doc</value></option> + <option><name>Local additions collection</name><value>local</value></option> + <option><name>X.org client binaries</name><value>Xbin</value></option> + <option><name>X.org libraries</name><value>Xlib</value></option> + <option><name>X.org manual pages</name><value>Xman</value></option> + <option><name>X.org imake distribution</name><value>Xprog</value></option> + <option><name>Games</name><value>games</value></option> + </options> + <multiple/> + </field> + + </fields> + + + <!-- php hooks --> + <include_file>/usr/local/pkg/jailctl_list.inc</include_file> + <custom_add_php_command> + sync_package_jailctl(); + </custom_add_php_command> + <custom_delete_php_command> + jailctl_delete(); + </custom_delete_php_command> + <custom_php_resync_config_command> + sync_package_jailctl(); + </custom_php_resync_config_command> + <custom_php_install_command> + jailctl_install(); + </custom_php_install_command> + <custom_php_deinstall_command> + jailctl_deinstall(); + </custom_php_deinstall_command> + <custom_php_after_form_command> + jailctl_addinterfaces($config); + jailctl_addtemplates($config); + </custom_php_after_form_command> +</packagegui> + diff --git a/config/jailctl/jailctl_defaults.xml b/config/jailctl/jailctl_defaults.xml new file mode 100644 index 00000000..c499abcb --- /dev/null +++ b/config/jailctl/jailctl_defaults.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?> +<packagegui> + <description>Jail management</description> + <requirements>Built world in /usr/obj</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>pfJailctl_Defaults</name> + <version>0.1</version> + <title>Jails: Jail building defaults</title> + <!-- configpath gets expanded out automatically and config items will be + stored in that location --> + <configpath>['installedpackages']['package']['$packagename']['config']</configpath> + + <tabs> + <tab> + <text>Jails</text> + <url>/pkg.php?xml=jailctl.xml</url> + </tab> + <tab> + <text>Global settings</text> + <url>/pkg_edit.php?xml=jailctl_settings.xml&id=0</url> + </tab> + <tab> + <text>Jail defaults</text> + <url>/pkg_edit.php?xml=jailctl_defaults.xml&id=0</url> + <active/> + </tab> + </tabs> + + <fields> + <field> + <fielddescr>Package sets</fielddescr> + <fieldname>jdist_select_sets</fieldname> + <type>listtopic</type> + <name>Select a distribution set:</name> + </field> + <field> + <fielddescr>Distribution set</fielddescr> + <fieldname>jdist_set</fieldname> + <description>Select a standard set of distributions to install</description> + <type>select</type> + <value>eng</value> + <options> + <option><name>Developer (src/all, binaries)</name><value>distSetDeveloper</value></option> + <option><name>Kernel developer (src/kern, binaries)</name><value>distSetKernDeveloper</value></option> + <option><name>User (binaries only)</name><value>distSetUser</value></option> + <option><name>Minimum (minimal binaries)</name><value>distSet</value></option> + </options> + <default_value>distSetUser</default_value> + </field> + <field> + <fielddescr>Individual packages</fielddescr> + <fieldname>jdist_select_individual</fieldname> + <type>listtopic</type> + <name>OR select individual distributions in addition to base:</name> + </field> + <field> + <fielddescr>Manual pages</fielddescr> + <fieldname>jdist_manpages</fieldname> + <type>checkbox</type> + </field> + <field> + <fielddescr>Games</fielddescr> + <fieldname>jdist_games</fieldname> + <type>checkbox</type> + </field> + <field> + <fielddescr>The Ports collection</fielddescr> + <fieldname>jdist_ports</fieldname> + <type>checkbox</type> + </field> + <field> + <fielddescr>Miscellaneous documentation</fielddescr> + <fieldname>jdist_doc</fieldname> + <type>checkbox</type> + </field> + <field> + <fielddescr>X.Org client binaries</fielddescr> + <fieldname>jdist_xbin</fieldname> + <type>checkbox</type> + </field> + <field> + <fielddescr>X.Org libraries</fielddescr> + <fieldname>jdist_xlib</fieldname> + <type>checkbox</type> + </field> + <field> + <fielddescr>X.Org manual pages</fielddescr> + <fieldname>jdist_xman</fieldname> + <type>checkbox</type> + </field> + <field> + <fielddescr>X.Org imake distribution</fielddescr> + <fieldname>jdist_xprog</fieldname> + <type>checkbox</type> + </field> + <field> + <fielddescr>Local additions collection</fielddescr> + <fieldname>jdist_local</fieldname> + <type>checkbox</type> + </field> + </fields> + + + <!-- php hooks --> + <include_file>/usr/local/pkg/jailctl.inc</include_file> + <custom_add_php_command> + sync_package_jailctl(); + </custom_add_php_command> + <custom_delete_php_command> + sync_package_jailctl(); + </custom_delete_php_command> + <custom_php_resync_config_command> + sync_package_jailctl(); + </custom_php_resync_config_command> + <custom_php_install_command> + </custom_php_install_command> + <custom_php_deinstall_command> + </custom_php_deinstall_command> +</packagegui> + diff --git a/config/jailctl/jailctl_list.inc b/config/jailctl/jailctl_list.inc new file mode 100644 index 00000000..d1869bd6 --- /dev/null +++ b/config/jailctl/jailctl_list.inc @@ -0,0 +1,112 @@ +<?php +include('/usr/local/pkg/jailctl.inc'); + +$jconfig=$config['installedpackages']['pfjailctlsettings']['config'][0]; +$jails=$config['installedpackages']['pfjailctl']['config']; +is_array($jails) ? $num_jails=count($jails) : $num_jails=0; + + +if($num_jails) { + for ($i=0;$i<$num_jails;$i++) { + $jail=$jails[$i]; + $jstatus=jailctl_jailstatus($config, $jail); + $_path=$jstatus['jpath']; + $_name=$jail['jname']; + $_ip=$jail['jip']; + $_hostname=$jstatus['jhostname']; + $_dnsservers=$jconfig['jdnsservers']; + $_passwd=$jconfig['jpasswd']; + $_template=$jail['jtemplates']; + $mounts=$GLOBALS['jailctl_tmp']['mounts']; + $unionmounts=$GLOBALS['jailctl_tmp']['unionmounts']; + $mount_unionfs=$GLOBALS['jailctl_tmp']['mount_unionfs']; + $mount_nullfs=$GLOBALS['jailctl_tmp']['mount_nullfs']; + + if($_GET['jaction'] && $_GET['id']==$i) { + switch ($_GET['jaction']) { + case 'create': +# if($jstate!='New') break; + jailctl_create($config, $jail); + if($jconfig['debug']) { + echo("Create script:<br><pre>"); + echo(file_get_contents("/tmp/jcreate_".$_name)); + echo("</pre>"); + } else { + header('Location: /pkg.php?xml=jailctl.xml'); + } + flush(); + exit; + + case 'start': +# if($jstate!='Stopped') break; + exec('umount -f '.$_path.'/dev'); + if($_template) { + $jail['juse_unionfs']=='on' ? $mount=$mount_unionfs : $mount=$mount_nullfs ; + foreach($mounts as $mp) { + exec($mount.' '.$_template.'/'.$mp.' '.$_path.'/'.$mp, $_cmd); + } + foreach($unionmounts as $mp) { + exec($mount_unionfs.' '.$_template.'/'.$mp.' '.$_path.'/'.$mp, $_cmd); + } + } + + $cmd='jailctl start '.$_name; + exec($cmd, $_cmd); + if($jconfig['debug']) { + echo("<script>alert('".addcslashes(implode("\\n", $_cmd), "'")."'); this.location.replace('/pkg.php?xml=jailctl.xml');</script>"); + } else { + header('Location: /pkg.php?xml=jailctl.xml'); + } + flush(); + exit; + + case 'stop': +# if($jstate!='Running') break; + $cmd='jailctl stop '.$_name; + exec($cmd, $_cmd); + if($_template) { + foreach($mounts as $mp) { + exec('umount -f '.$_template.'/'.$mp.' '.$_path.'/'.$mp, $_cmd); + } + foreach($unionmounts as $mp) { + exec('umount -f '.$_template.'/'.$mp.' '.$_path.'/'.$mp, $_cmd); + } + } + exec('umount -f '.$_path.'/dev'); + if($jconfig['debug']) { + echo("<script>alert('".addcslashes(implode("\\n", $_cmd), "'")."'); this.location.replace('/pkg.php?xml=jailctl.xml');</script>"); + } else { + header('Location: /pkg.php?xml=jailctl.xml'); + } + flush(); + exit; + } + } + + $config['installedpackages']['pfjailctl']['config'][$i]['jstate']=$jstatus['jstate']; + $config['installedpackages']['pfjailctl']['config'][$i]['jpath']=$jstatus['jpath']; + $config['installedpackages']['pfjailctl']['config'][$i]['jifdesc']= + $jstatus['jifdesc']." (".$jstatus['jrealif'].")"; + + $jactions=Array(); + switch ($jstatus['jstate']) { + case 'Building': + $jactions[]=""; + break; + case 'New': + $jactions[]="<a href='/pkg.php?xml=jailctl.xml&jaction=create&id=".$i."'>Create</a>"; + break; + case 'Stopped': + $jactions[]="<a href='/pkg.php?xml=jailctl.xml&jaction=start&id=".$i."'>Start</a>"; + #$jactions[]="<a href='/pkg.php?xml=jailctl.xml&jaction=upgrade&id=".$i."'>Upgrade</a>"; + break; + case 'Running': + $jactions[]="<a href='/pkg.php?xml=jailctl.xml&jaction=stop&id=".$i."'>Stop</a>"; + break; + } + $config['installedpackages']['pfjailctl']['config'][$i]['jactions']=implode(' | ', $jactions); + } +} + + +?>
\ No newline at end of file diff --git a/config/jailctl/jailctl_settings.xml b/config/jailctl/jailctl_settings.xml new file mode 100644 index 00000000..e82eea6c --- /dev/null +++ b/config/jailctl/jailctl_settings.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?> +<packagegui> + <description>Jail management</description> + <requirements>Built world in /usr/obj</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>pfJailctl_Settings</name> + <version>0.1</version> + <title>Jails: Settings</title> + <!-- configpath gets expanded out automatically and config items will be + stored in that location --> + <configpath>['installedpackages']['$packagename']['config']</configpath> + + <tabs> + <tab> + <text>Jails</text> + <url>/pkg.php?xml=jailctl.xml</url> + </tab> + <tab> + <text>Global settings</text> + <url>/pkg_edit.php?xml=jailctl_settings.xml&id=0</url> + <active/> + </tab> +<!-- <tab> + <text>Jail defaults</text> + <url>/pkg_edit.php?xml=jailctl_defaults.xml&id=0</url> + </tab> --> + </tabs> + + <fields> + <field> + <fielddescr>FTP mirror</fielddescr> + <fieldname>jftpmirror</fieldname> + <description>Select a FTP server (mirror) to use for sysinstall</description> + <type>select</type> + <options> + <option><name>ftp.FreeBSD.org</name><value>ftp://ftp.FreeBSD.org/pub/FreeBSD/</value></option> + <option><name>ftp.no.FreeBSD.org</name><value>ftp://ftp.no.FreeBSD.org/pub/FreeBSD/</value></option> + <option><name>ftp.de.FreeBSD.org</name><value>ftp://ftp.de.FreeBSD.org/pub/FreeBSD/</value></option> + <option><name>ftp.se.FreeBSD.org</name><value>ftp://ftp.se.FreeBSD.org/pub/FreeBSD/</value></option> + </options> + <default_value>ftp://ftp.FreeBSD.org/pub/FreeBSD/</default_value> + </field> + <field> + <fielddescr>DNS servers</fielddescr> + <description>DNS servers to be added to /etc/resolv.conf of jails, space separated IP addresses</description> + <fieldname>jdnsservers</fieldname> + <type>textarea</type> + </field> + <field> + <fielddescr>Location for jails</fielddescr> + <fieldname>jstorage</fieldname> + <description>Jails will be stored here</description> + <type>input</type> + <default>/usr/local/jails</default> + <default_value>/usr/local/jails</default_value> + </field> + <field> + <fielddescr>Location for jail backups</fielddescr> + <fieldname>jbackup</fieldname> + <description>Backups are .tgz files of the jail directory</description> + <type>input</type> + <default_value>/usr/local/jails</default_value> + </field> + <field> + <fielddescr>Files to exclude from backup</fielddescr> + <fieldname>jbackupexcludes</fieldname> + <description>Files to exclude from backup</description> + <type>input</type> + <default_value>--exclude ./usr/ports/* --exclude ./tmp/* --exclude ./var/tmp/* --exclude ./usr/src/*</default_value> + </field> + <field> + <fielddescr>System configuration</fielddescr> + <fieldname>jrcconf</fieldname> + <type>rowhelper</type> + <rowhelper> + <rowhelperfield> + <fielddescr>Lines to add to /etc/rc.conf</fielddescr> + <type>input</type> + <size>25</size> + <fieldname>rcconfline</fieldname> + </rowhelperfield> + </rowhelper> + </field> + <field> + <fielddescr>Default password for jails</fielddescr> + <fieldname>jpasswd</fieldname> + <description>Set to "system" by default.<br> + <b>NOTE: Only type here if you want to change the current default password!</b><br> + This field will show as empty even if a password has been set. Changing this will not affect existing jails.</description> + <type>password</type> + <default_value>system</default_value> + </field> + <field> + <fielddescr>Debug mode</fielddescr> + <fieldname>debug</fieldname> + <type>checkbox</type> + <description>Enable debug information do be shown by the GUI</description> + </field> + + </fields> + + + <!-- php hooks --> + <include_file>/usr/local/pkg/jailctl.inc</include_file> + <custom_add_php_command> + sync_package_jailctl(); + </custom_add_php_command> + <custom_delete_php_command> + sync_package_jailctl(); + </custom_delete_php_command> + <custom_php_resync_config_command> + sync_package_jailctl(); + </custom_php_resync_config_command> + <custom_php_install_command> + </custom_php_install_command> + <custom_php_deinstall_command> + </custom_php_deinstall_command> +</packagegui> + diff --git a/config/jailctl/sysinstall b/config/jailctl/sysinstall Binary files differnew file mode 100755 index 00000000..d4a05fb1 --- /dev/null +++ b/config/jailctl/sysinstall |