From f9a5fbfa1079f9a8dcfdfe4ad1bd50c1317ec8ac Mon Sep 17 00:00:00 2001 From: Eirik Oeverby Date: Sat, 14 Mar 2009 00:27:08 +0100 Subject: Added pfJailctl and jail_template packages See http://doc.pfsense.org/index.php/PfJailctl_package for details. --- config/jail_template/jail_template.img.uzip | Bin 0 -> 63200768 bytes config/jail_template/jail_template.inc | 32 + config/jailctl/jailctl | 1053 +++++++++++++++++++++++++++ config/jailctl/jailctl-utils.inc | 272 +++++++ config/jailctl/jailctl.inc | 217 ++++++ config/jailctl/jailctl.xml | 233 ++++++ config/jailctl/jailctl_defaults.xml | 122 ++++ config/jailctl/jailctl_list.inc | 112 +++ config/jailctl/jailctl_settings.xml | 121 +++ config/jailctl/sysinstall | Bin 0 -> 447888 bytes 10 files changed, 2162 insertions(+) create mode 100644 config/jail_template/jail_template.img.uzip create mode 100644 config/jail_template/jail_template.inc create mode 100755 config/jailctl/jailctl create mode 100644 config/jailctl/jailctl-utils.inc create mode 100644 config/jailctl/jailctl.inc create mode 100644 config/jailctl/jailctl.xml create mode 100644 config/jailctl/jailctl_defaults.xml create mode 100644 config/jailctl/jailctl_list.inc create mode 100644 config/jailctl/jailctl_settings.xml create mode 100755 config/jailctl/sysinstall (limited to 'config') diff --git a/config/jail_template/jail_template.img.uzip b/config/jail_template/jail_template.img.uzip new file mode 100644 index 00000000..1c92fb90 Binary files /dev/null and b/config/jail_template/jail_template.img.uzip differ diff --git a/config/jail_template/jail_template.inc b/config/jail_template/jail_template.inc new file mode 100644 index 00000000..f9c00b79 --- /dev/null +++ b/config/jail_template/jail_template.inc @@ -0,0 +1,32 @@ + \ No newline at end of file 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 []" >&2 + echo " = start|stop|status|create|delete|upgrade|backup|restore" >&2 + echo " = hostname|all" >&2 + echo " = 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 @@ +> ".$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."
"; +# } + + $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']; + ?> + + + + "); print_r($jail); echo(""); + + + $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("
"); print_r($_out); echo("
"); + 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 @@ +/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.
"; +} + +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 @@ + + + + + Jail management + Disk space... + Currently there are no FAQ items provided. + pfJailctl + 0.1 + Jails + + + Jails + Jail management +
Services
+ jailctl.xml +
+ + Jails + jails.sh + All jails with autostart enabled. + + include("/usr/local/pkg/jailctl.inc"); + jailctl_servicestatus(); + + + + ['installedpackages']['$packagename']['config'] + + /usr/local/pkg/ + 0644 + http://www.pfsense.com/packages/config/jailctl/jailctl_defaults.xml + + + /usr/local/pkg/ + 0644 + http://www.pfsense.com/packages/config/jailctl/jailctl_settings.xml + + + /usr/local/pkg/ + 0644 + http://www.pfsense.com/packages/config/jailctl/jailctl.inc + + + /usr/local/pkg/ + 0644 + http://www.pfsense.com/packages/config/jailctl/jailctl-utils.inc + + + /usr/local/pkg/ + 0644 + http://www.pfsense.com/packages/config/jailctl/jailctl_list.inc + + + /usr/local/sbin/ + 0755 + http://www.pfsense.com/packages/config/jailctl/jailctl + + + /usr/sbin/ + 0755 + http://www.pfsense.com/packages/config/jailctl/sysinstall + + + + + Jails + /pkg.php?xml=jailctl.xml + + + + Global settings + /pkg_edit.php?xml=jailctl_settings.xml&id=0 + + + + + + + + State + jstate + + + Jail name + jname + + + Jail IF + jifdesc + + + Jail IP + jip + + + Jail path + jpath + + + Actions + jactions + + + + + + + Jail hostname + jname + FQDN of the jail + input + + + Network interface + jif + Jail will be bound to this interface + interfaces_selection + + + IP address + jip + Must be in the same subnet as the parent interface + input + + + Autostart jail on boot? + jautostart + Start this jail automatically when the system boots? + checkbox + + + + + Jail templates + jselect_templates + listtopic + Select a predefined template for your jail: + + + Templates + jtemplates + Files from the templates will be read-only inside the jail. + select + + + + jtemplate_default + + + Use unionfs + juse_unionfs + Use unionfs instead of nullfs to mount the template contents into the jail + checkbox + + + + Package sets + jselect_sets + listtopic + OR select a distribution set to install: + + + Distribution sets + jdistset + Select a standard set of distributions to install + select + + + + + + + + + + + + Individual packages + jselect_individual + listtopic + OR select individual distributions in addition to 'base': + + + + Individual distributions + jdists + Select individual distributions (multiple selection) + select + + + + + + + + + + + + + + + + + + + /usr/local/pkg/jailctl_list.inc + + sync_package_jailctl(); + + + jailctl_delete(); + + + sync_package_jailctl(); + + + jailctl_install(); + + + jailctl_deinstall(); + + + jailctl_addinterfaces($config); + jailctl_addtemplates($config); + +
+ 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 @@ + + + + + Jail management + Built world in /usr/obj + Currently there are no FAQ items provided. + pfJailctl_Defaults + 0.1 + Jails: Jail building defaults + + ['installedpackages']['package']['$packagename']['config'] + + + + Jails + /pkg.php?xml=jailctl.xml + + + Global settings + /pkg_edit.php?xml=jailctl_settings.xml&id=0 + + + Jail defaults + /pkg_edit.php?xml=jailctl_defaults.xml&id=0 + + + + + + + Package sets + jdist_select_sets + listtopic + Select a distribution set: + + + Distribution set + jdist_set + Select a standard set of distributions to install + select + eng + + + + + + + distSetUser + + + Individual packages + jdist_select_individual + listtopic + OR select individual distributions in addition to base: + + + Manual pages + jdist_manpages + checkbox + + + Games + jdist_games + checkbox + + + The Ports collection + jdist_ports + checkbox + + + Miscellaneous documentation + jdist_doc + checkbox + + + X.Org client binaries + jdist_xbin + checkbox + + + X.Org libraries + jdist_xlib + checkbox + + + X.Org manual pages + jdist_xman + checkbox + + + X.Org imake distribution + jdist_xprog + checkbox + + + Local additions collection + jdist_local + checkbox + + + + + + /usr/local/pkg/jailctl.inc + + sync_package_jailctl(); + + + sync_package_jailctl(); + + + sync_package_jailctl(); + + + + + + + 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 @@ +
");
+						echo(file_get_contents("/tmp/jcreate_".$_name));
+						echo("
"); + } 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(""); + } 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(""); + } 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[]="Create"; + break; + case 'Stopped': + $jactions[]="Start"; + #$jactions[]="Upgrade"; + break; + case 'Running': + $jactions[]="Stop"; + 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 @@ + + + + + Jail management + Built world in /usr/obj + Currently there are no FAQ items provided. + pfJailctl_Settings + 0.1 + Jails: Settings + + ['installedpackages']['$packagename']['config'] + + + + Jails + /pkg.php?xml=jailctl.xml + + + Global settings + /pkg_edit.php?xml=jailctl_settings.xml&id=0 + + + + + + + + FTP mirror + jftpmirror + Select a FTP server (mirror) to use for sysinstall + select + + + + + + + ftp://ftp.FreeBSD.org/pub/FreeBSD/ + + + DNS servers + DNS servers to be added to /etc/resolv.conf of jails, space separated IP addresses + jdnsservers + textarea + + + Location for jails + jstorage + Jails will be stored here + input + /usr/local/jails + /usr/local/jails + + + Location for jail backups + jbackup + Backups are .tgz files of the jail directory + input + /usr/local/jails + + + Files to exclude from backup + jbackupexcludes + Files to exclude from backup + input + --exclude ./usr/ports/* --exclude ./tmp/* --exclude ./var/tmp/* --exclude ./usr/src/* + + + System configuration + jrcconf + rowhelper + + + Lines to add to /etc/rc.conf + input + 25 + rcconfline + + + + + Default password for jails + jpasswd + 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. + password + system + + + Debug mode + debug + checkbox + Enable debug information do be shown by the GUI + + + + + + + /usr/local/pkg/jailctl.inc + + sync_package_jailctl(); + + + sync_package_jailctl(); + + + sync_package_jailctl(); + + + + + + + diff --git a/config/jailctl/sysinstall b/config/jailctl/sysinstall new file mode 100755 index 00000000..d4a05fb1 Binary files /dev/null and b/config/jailctl/sysinstall differ -- cgit v1.2.3