diff --git a/usr/local/etc/rc.d/bastille b/usr/local/etc/rc.d/bastille index 15420986..b8dd04eb 100755 --- a/usr/local/etc/rc.d/bastille +++ b/usr/local/etc/rc.d/bastille @@ -8,19 +8,13 @@ # Add the following to /etc/rc.conf[.local] to enable this service # -# bastille_enable (bool): Set to "NO" by default. -# Set it to "YES" to enable bastille. -# bastille_conf (bool): Set to "/usr/local/etc/bastille/bastille.conf" by default. -# Path to bastile.conf file. Used if bastille_rcorder="YES". -# bastille_list (string): Set to "ALL" by default. -# Space separated list of jails to start or "ALL" to start all -# jails. -# bastille_rcorder (bool): Set to "NO" by default. -# Set it to "YES" to start all jails in order, defined by -# rcorder(8). It starts all jails, except jails with "KEYWORD: -# nostart" in jail.conf. Value of bastille_list is ignored in this -# case, requires correct path to bastile.conf in bastille_conf -# var. +# bastille_enable (bool): Set to "NO" by default. +# Set to "YES" to enable bastille. +# bastille_conf (bool): Set to "/usr/local/etc/bastille/bastille.conf" by default. +# Path to bastile.conf file. +# bastille_startup_delay (bool): Set to 0 by default. +# Set to a numerical value. +# This is the delay between startup of each jail. # . /etc/rc.subr @@ -30,8 +24,6 @@ rcvar=${name}_enable : ${bastille_enable:="NO"} : ${bastille_conf:="/usr/local/etc/bastille/bastille.conf"} -: ${bastille_list:="ALL"} -: ${bastille_rcorder:="NO"} : ${bastille_startup_delay:=0} command=/usr/local/bin/${name} @@ -39,51 +31,14 @@ start_cmd="bastille_start" stop_cmd="bastille_stop" restart_cmd="bastille_stop && bastille_start" -rcordered_list() { - local _jailsdir - _jailsdir=$(. $bastille_conf; echo $bastille_jailsdir) - bastille_ordered_list=$(rcorder -s nostart ${_jailsdir}/*/jail.conf | xargs dirname | xargs basename -a | tr "\n" " ") -} - bastille_start() { - local _jail - - if checkyesno bastille_rcorder; then - rcordered_list - elif [ -z "${bastille_list}" ]; then - echo "bastille_list is undefined" - return 1 - else - bastille_ordered_list=${bastille_list} - fi - - for _jail in ${bastille_ordered_list}; do - sleep ${bastille_startup_delay} - echo "Starting Bastille Container: ${_jail}" - ${command} start ${_jail} - done + ${command} start --boot --delay ${bastille_startup_delay} ALL } bastille_stop() { - local _jail _revlist - - if checkyesno bastille_rcorder; then - rcordered_list - elif [ -z "${bastille_list}" ]; then - echo "bastille_list is undefined" - return 1 - else - bastille_ordered_list=${bastille_list} - fi - - ## reverse order of list for shutdown ## fixes #389 - _revlist=$(echo "${bastille_ordered_list}" | awk '{ for (i=NF; i>1; i--) printf("%s ",$i); print $1; }') - for _jail in ${_revlist}; do - echo "Stopping Bastille Container: ${_jail}" - ${command} stop ${_jail} - done + ${command} stop ALL } load_rc_config ${name} diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index fd43b015..0f4cb57f 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -144,8 +144,29 @@ jail_autocomplete() { fi } +list_jail_priority() { + local _jail_list="${1}" + if [ -d "${bastille_jailsdir}" ]; then + for _jail in ${_jail_list}; do + local _boot_file=${bastille_jailsdir}/${_jail}/boot.conf + # Set defaults if boot file does not exist + if [ ! -f ${_boot_file} ]; then + sysrc -f ${_boot_file} boot=on > /dev/null 2>&1 + sysrc -f ${_boot_file} priority=99 > /dev/null 2>&1 + fi + _priority="$(sysrc -f ${bastille_jailsdir}/${_jail}/boot.conf -n priority)" + echo "${_jail} ${_priority}" + done + fi +} + set_target() { local _TARGET=${1} + if [ "${2}" = "reverse" ]; then + local _order="${2}" + else + local _order="forward" + fi JAILS="" TARGET="" if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then @@ -170,6 +191,13 @@ set_target() { TARGET="${TARGET} ${_jail}" JAILS="${JAILS} ${_jail}" done + if [ "${_order}" = "forward" ]; then + TARGET="$(list_jail_priority "${TARGET}" | sort -k2 -n | awk '{print $1}')" + JAILS="$(list_jail_priority "${TARGET}" | sort -k2 -n | awk '{print $1}')" + elif [ "${_order}" = "reverse" ]; then + TARGET="$(list_jail_priority "${TARGET}" | sort -k2 -nr | awk '{print $1}')" + JAILS="$(list_jail_priority "${TARGET}" | sort -k2 -nr | awk '{print $1}')" + fi export TARGET export JAILS fi @@ -210,6 +238,11 @@ target_all_jails() { JAILS="${JAILS} ${_jail}" fi done + if [ "${_order}" = "forward" ]; then + JAILS="$(list_jail_priority "${JAILS}" | sort -k2 -n | awk '{print $1}')" + elif [ "${_order}" = "reverse" ]; then + JAILS="$(list_jail_priority "${JAILS}" | sort -k2 -nr | awk '{print $1}')" + fi export JAILS } diff --git a/usr/local/share/bastille/config.sh b/usr/local/share/bastille/config.sh index b15a03fb..3218f8bb 100644 --- a/usr/local/share/bastille/config.sh +++ b/usr/local/share/bastille/config.sh @@ -73,7 +73,7 @@ while [ "$#" -gt 0 ]; do esac done -if [ "$#" -lt 1 ] || [ "$#" -gt 3 ]; then +if [ "$#" -lt 1 ] || [ "$#" -gt 4 ]; then usage fi @@ -81,6 +81,7 @@ bastille_root_check TARGET="${1}" ACTION="${2}" +BASTILLE_PROPERTY="" shift 2 set_target "${TARGET}" @@ -113,98 +114,127 @@ print_jail_conf() { } for _jail in ${JAILS}; do - FILE="${bastille_jailsdir}/${_jail}/jail.conf" - if [ ! -f "${FILE}" ]; then - error_notify "jail.conf does not exist for jail: ${_jail}" - continue - fi - - if [ "${ACTION}" = 'get' ]; then - _output=$( - print_jail_conf "${FILE}" | awk -F= -v property="${PROPERTY}" ' - $1 == property { - # note that we have found the property - found = 1; - # check if there is a value for this property - if (NF == 2) { - # remove any quotes surrounding the string - #sub(",[^|]*\\|", ",", $2); - sub(/^"/, "", $2); - sub(/"$/, "", $2); - print $2; - } else { - # no value, just the property name - print "enabled"; - } - exit 0; - } - END { - # if we have not found anything we need to print a special - # string - if (! found) { - print("not set"); - # let the caller know that this is a warn condition - exit(120); - } - }' - ) - # check if our output is a warning or regular - if [ $? -eq 120 ]; then - warn "${_output}" - else - echo "${_output}" - fi - else # Setting the value. -- cwells - if [ -n "${VALUE}" ]; then - VALUE=$(echo "${VALUE}" | sed 's/\//\\\//g') - if echo "${VALUE}" | grep ' ' > /dev/null 2>&1; then # Contains a space, so wrap in quotes. -- cwells - VALUE="'${VALUE}'" + # Handle Bastille specific properties + if [ "${PROPERTY}" = "priority" ] || [ "${PROPERTY}" = "prio" ]; then + PROPERTY="priority" + BASTILLE_PROPERTY=1 + FILE="${bastille_jailsdir}/${_jail}/boot.conf" + info "[${_jail}]:" + if [ "${ACTION}" = "set" ]; then + if echo "${VALUE}" | grep -Eq '^[0-9]+$'; then + sysrc -f "${FILE}" "${PROPERTY}=${VALUE}" + else + error_exit "Priority value must be a number." fi - LINE=" ${PROPERTY} = ${VALUE};" else - LINE=" ${PROPERTY};" + sysrc -f "${FILE}" -n "${PROPERTY}" fi + elif [ "${PROPERTY}" = "boot" ]; then + BASTILLE_PROPERTY=1 + FILE="${bastille_jailsdir}/${_jail}/boot.conf" + info "[${_jail}]:" + if [ "${ACTION}" = "set" ]; then + if [ "${VALUE}" = "on" ] || [ "${VALUE}" = "off" ]; then + sysrc -f "${FILE}" "${PROPERTY}=${VALUE}" + else + error_exit "Boot value must be 'on' or 'off'." + fi + else + sysrc -f "${FILE}" -n "${PROPERTY}" + fi + else + FILE="${bastille_jailsdir}/${_jail}/jail.conf" + if [ ! -f "${FILE}" ]; then + error_notify "jail.conf does not exist for jail: ${_jail}" + continue + fi + if [ "${ACTION}" = 'get' ]; then + _output=$( + print_jail_conf "${FILE}" | awk -F= -v property="${PROPERTY}" ' + $1 == property { + # note that we have found the property + found = 1; + # check if there is a value for this property + if (NF == 2) { + # remove any quotes surrounding the string + #sub(",[^|]*\\|", ",", $2); + sub(/^"/, "", $2); + sub(/"$/, "", $2); + print $2; + } else { + # no value, just the property name + print "enabled"; + } + exit 0; + } + END { + # if we have not found anything we need to print a special + # string + if (! found) { + print("not set"); + # let the caller know that this is a warn condition + exit(120); + } + }' + ) + # check if our output is a warning or regular + if [ $? -eq 120 ]; then + warn "${_output}" + else + echo "${_output}" + fi + else # Setting the value. -- cwells + if [ -n "${VALUE}" ]; then + VALUE=$(echo "${VALUE}" | sed 's/\//\\\//g') + if echo "${VALUE}" | grep ' ' > /dev/null 2>&1; then # Contains a space, so wrap in quotes. -- cwells + VALUE="'${VALUE}'" + fi + LINE=" ${PROPERTY} = ${VALUE};" + else + LINE=" ${PROPERTY};" + fi - # add the value to the config file, replacing any existing value or, if - # there is none, at the end - # - # awk doesn't have "inplace" editing so we use a temp file - _tmpfile=$(mktemp) || error_exit "unable to set because mktemp failed" - cp "${FILE}" "${_tmpfile}" && \ - awk -F= -v line="${LINE}" -v property="${PROPERTY}" ' - BEGIN { - # build RE as string as we can not expand vars in RE literals - prop_re = "^[[:space:]]*" property "[[:space:]]*;?$"; - } - $1 ~ prop_re && !found { - # we already have an entry in the config for this property so - # we need to substitute our line here rather than keep the - # existing line - print(line); - # note we have already found the property - found = 1; - # move onto the next line - next; - } - $1 == "}" { - # reached the end of the stanza so if we have not already - # added our line we need to do so now - if (! found) { - print(line); + # add the value to the config file, replacing any existing value or, if + # there is none, at the end + # + # awk doesn't have "inplace" editing so we use a temp file + _tmpfile=$(mktemp) || error_exit "unable to set because mktemp failed" + cp "${FILE}" "${_tmpfile}" && \ + awk -F= -v line="${LINE}" -v property="${PROPERTY}" ' + BEGIN { + # build RE as string as we can not expand vars in RE literals + prop_re = "^[[:space:]]*" property "[[:space:]]*;?$"; } - } - { - # print each uninteresting line unchanged - print; - } - ' "${_tmpfile}" > "${FILE}" - rm "${_tmpfile}" + $1 ~ prop_re && !found { + # we already have an entry in the config for this property so + # we need to substitute our line here rather than keep the + # existing line + print(line); + # note we have already found the property + found = 1; + # move onto the next line + next; + } + $1 == "}" { + # reached the end of the stanza so if we have not already + # added our line we need to do so now + if (! found) { + print(line); + } + } + { + # print each uninteresting line unchanged + print; + } + ' "${_tmpfile}" > "${FILE}" + rm "${_tmpfile}" + fi fi done # Only display this message once at the end (not for every jail). -- cwells -if [ "${ACTION}" = 'set' ]; then - info "A restart is required for the changes to be applied. See 'bastille restart ${TARGET}'." +if [ "${ACTION}" = 'set' ] && [ -z "${BASTILLE_PROPERTY}" ]; then + info "A restart is required for the changes to be applied. See 'bastille restart'." fi exit 0 diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index aad6131a..4e5f5186 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -45,7 +45,9 @@ usage() { -E | --empty Creates an empty container, intended for custom jail builds (thin/thick/linux or unsupported). -L | --linux This option is intended for testing with Linux jails, this is considered experimental. -M | --static-mac Generate a static MAC address for jail (VNET only). + --no-boot Create jail with boot=off. --no-validate Do not validate the release when creating the jail. + -p | --priority VALUE Sets the priority value for jail startup and shutdown. -T | --thick Creates a thick container, they consume more space as they are self contained and independent. -V | --vnet Enables VNET, VNET containers are attached to a virtual bridge interface for connectivity. -v | --vlan VLANID Creates the jail with specified VLAN ID (VNET only). @@ -546,6 +548,10 @@ create_jail() { # Set strict permissions on the jail by default chmod 0700 "${bastille_jailsdir}/${NAME}" + # Apply priority and boot settings before starting jail + sysrc -f "${bastille_jailsdir}/${NAME}/boot.conf" boot=${BOOT} + sysrc -f "${bastille_jailsdir}/${NAME}/boot.conf" priority="${PRIORITY}" + # Jail must be started before applying the default template. -- cwells if [ -z "${EMPTY_JAIL}" ]; then bastille start "${NAME}" @@ -665,6 +671,7 @@ if echo "${3}" | grep '@'; then fi # Handle options. +BOOT="on" EMPTY_JAIL="" THICK_JAIL="" CLONE_JAIL="" @@ -674,6 +681,7 @@ LINUX_JAIL="" STATIC_MAC="" DUAL_STACK="" VALIDATE_RELEASE="1" +PRIORITY="99" while [ $# -gt 0 ]; do case "${1}" in -h|--help|help) @@ -704,6 +712,18 @@ while [ $# -gt 0 ]; do STATIC_MAC="1" shift ;; + -p|--priority) + if echo "${2}" | grep -Eoq "^[0-9]+$"; then + PRIORITY="${2}" + shift 2 + else + error_exit "Not a valid priority value: \"${2}\"" + fi + ;; + --no-boot) + BOOT="off" + shift + ;; --no-validate|no-validate) VALIDATE_RELEASE="" shift diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index 6c7902d7..f5c5ae4c 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -297,7 +297,7 @@ case "${TARGET}" in ;; *) ## just destroy a jail - set_target "${TARGET}" + set_target "${TARGET}" "reverse" destroy_jail "${JAILS}" ;; esac diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 4a12763c..238d6f1a 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -33,10 +33,12 @@ . /usr/local/share/bastille/common.sh usage() { - error_notify "Usage: bastille list [option(s)] [-j|-a] [RELEASE (-p)] [template] [JAIL|CONTAINER] [log] [limit] [import] [export] [backup]" + error_notify "Usage: bastille list [option(s)] [RELEASE (-p)] [template] [JAIL|CONTAINER] [log] [limit] [import] [export] [backup] [priority]" cat << EOF Options: + -a | --all List all jails, running and stopped, in BastilleBSD format. + -j | --json List jails in json format. -x | --debug Enable debug mode. EOF @@ -76,7 +78,7 @@ list_all(){ if [ "${MAX_LENGTH_THICK_JAIL_RELEASE}" -gt "${MAX_LENGTH_JAIL_RELEASE}" ]; then MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_THICK_JAIL_RELEASE}; fi if [ "${MAX_LENGTH_LINUX_JAIL_RELEASE}" -gt "${MAX_LENGTH_JAIL_RELEASE}" ]; then MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_LINUX_JAIL_RELEASE}; fi if [ "${MAX_LENGTH_JAIL_RELEASE}" -lt 7 ]; then MAX_LENGTH_JAIL_RELEASE=7; fi - printf " JID%*sState%*sIP Address%*sPublished Ports%*sHostname%*sRelease%*sPath\n" "$((${MAX_LENGTH_JID} + ${SPACER} - 3))" "" "$((${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} + ${SPACER} - 10))" "" "$((${MAX_LENGTH_JAIL_PORTS} + ${SPACER} - 15))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} + ${SPACER} - 8))" "" "$((${MAX_LENGTH_JAIL_RELEASE} + ${SPACER} - 7))" "" + printf " JID%*sBoot%*sPrio%*sState%*sIP Address%*sPublished Ports%*sHostname%*sRelease%*sPath\n" "$((${MAX_LENGTH_JID} + ${SPACER} - 3))" "" "$((${SPACER}))" "" "$((${SPACER}))" "" "$((${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} + ${SPACER} - 10))" "" "$((${MAX_LENGTH_JAIL_PORTS} + ${SPACER} - 15))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} + ${SPACER} - 8))" "" "$((${MAX_LENGTH_JAIL_RELEASE} + ${SPACER} - 7))" "" if [ -n "${TARGET}" ]; then # Query all info for a specific jail. JAIL_LIST="${TARGET}" @@ -88,6 +90,8 @@ list_all(){ if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then JAIL_NAME=$(grep -h -m 1 -e "^.* {$" "${bastille_jailsdir}/${_JAIL}/jail.conf" 2> /dev/null | awk '{ print $1 }') JID="$(jls -j ${_JAIL} jid 2>/dev/null)" + BOOT="$(sysrc -f ${bastille_jailsdir}/${_JAIL}/boot.conf -n boot)" + PRIORITY="$(sysrc -f ${bastille_jailsdir}/${_JAIL}/boot.conf -n priority)" IS_FREEBSD_JAIL=0 if [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/bin/freebsd-version" ] || [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/.bastille/bin/freebsd-version" ] || [ "$(grep -c "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_FREEBSD_JAIL=1; fi IS_FREEBSD_JAIL=${IS_FREEBSD_JAIL:-0} @@ -141,6 +145,8 @@ list_all(){ if [ "${#JAIL_PORTS}" -gt "${MAX_LENGTH_JAIL_PORTS}" ]; then JAIL_PORTS="$(echo ${JAIL_PORTS} | cut -c-$((${MAX_LENGTH_JAIL_PORTS} - 3)))..."; fi JAIL_NAME=${JAIL_NAME:-${DEFAULT_VALUE}} JID=${JID:-${DEFAULT_VALUE}} + BOOT=${BOOT:-${DEFAULT_VALUE}} + PRIORITY=${PRIORITY:-${DEFAULT_VALUE}} JAIL_STATE=${JAIL_STATE:-${DEFAULT_VALUE}} JAIL_IP=${JAIL_IP:-${DEFAULT_VALUE}} JAIL_PORTS=${JAIL_PORTS:-${DEFAULT_VALUE}} @@ -156,12 +162,15 @@ list_all(){ # 10.10.10.11 # 10.10.10.12 FIRST_IP="$(echo "${JAIL_IP}" | head -n 1)" - printf " ${JID}%*s${JAIL_STATE}%*s${FIRST_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JID} - ${#JID} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#FIRST_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" "" + if echo "${FIRST_IP}" | grep -q "|"; then FIRST_IP=$(echo ${FIRST_IP} | awk -F"|" '{print $2}'); fi + printf " ${JID}%*s${BOOT}%*s${PRIORITY}%*s${JAIL_STATE}%*s${FIRST_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JID} - ${#JID} + ${SPACER}))" "" "$((4 - ${#BOOT} + ${SPACER}))" "" "$((4 - ${#PRIORITY} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#FIRST_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" "" for IP in $(echo "${JAIL_IP}" | tail -n +2); do - printf " %*s%*s${IP}\n" "$((${MAX_LENGTH_JID} + ${SPACER}))" "" "$((5 + ${SPACER}))" "" + if echo "${IP}" | grep -q "|"; then IP=$(echo ${IP} | awk -F"|" '{print $2}'); fi + printf "%*s%*s%*s%*s ${IP}\n" "$((${MAX_LENGTH_JID} + ${SPACER}))" "" "$((4 + ${SPACER}))" "" "$((4 + ${SPACER}))" "" "$((5 + ${SPACER}))" "" done else - printf " ${JID}%*s${JAIL_STATE}%*s${JAIL_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JID} - ${#JID} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#JAIL_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" "" + if echo "${JAIL_IP}" | grep -q "|"; then JAIL_IP=$(echo ${JAIL_IP} | awk -F"|" '{print $2}'); fi + printf " ${JID}%*s${BOOT}%*s${PRIORITY}%*s${JAIL_STATE}%*s${JAIL_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JID} - ${#JID} + ${SPACER}))" "" "$((4 - ${#BOOT} + ${SPACER}))" "" "$((4 - ${#PRIORITY} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#JAIL_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" "" fi fi done @@ -321,4 +330,4 @@ if [ "$#" -gt 0 ]; then fi ;; esac -fi +fi \ No newline at end of file diff --git a/usr/local/share/bastille/restart.sh b/usr/local/share/bastille/restart.sh index ffdb1650..ebc70dd7 100644 --- a/usr/local/share/bastille/restart.sh +++ b/usr/local/share/bastille/restart.sh @@ -30,5 +30,26 @@ # 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. +usage() { + error_notify "Usage: bastille restart [option(s)] TARGET" + cat << EOF + Options: + + -b | --boot Respect jail boot setting. + -d | --delay VALUE Time to wait between starting/stopping each jail. + -v | --verbose Print every action on jail start. + -x | --debug Enable debug mode. + +EOF + exit 1 +} + +# Handle options. +case "${1}" in + -h|--help|help) + usage + ;; +esac + bastille stop "$@" bastille start "$@" diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index bdb2cc91..44f518b8 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -37,20 +37,36 @@ usage() { cat << EOF Options: - -v | --verbose Print every action on jail start. - -x | --debug Enable debug mode. + -b | --boot Respect jail boot setting. + -d | --delay VALUE Time to wait between starting each jail. + -v | --verbose Print every action on jail start. + -x | --debug Enable debug mode. EOF exit 1 } # Handle options. +BOOT=0 +DELAY_TIME=0 OPTION="" while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; + -b|--boot) + BOOT=1 + shift + ;; + -d|--delay) + if [ -z "${2}" ] && ! echo "${2}" | grep -Eq '^[0-9]+$'; then + error_exit "[-d|--delay] requires a value." + else + DELAY_TIME="${2}" + fi + shift 2 + ;; -v|--verbose) OPTION="-v" shift @@ -62,6 +78,7 @@ while [ "$#" -gt 0 ]; do -*) for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do case ${_opt} in + b) BOOT=1 ;; v) OPTION="-v" ;; x) enable_debug ;; *) error_exit "Unknown Option: \"${1}\"" ;; @@ -86,6 +103,14 @@ set_target "${TARGET}" for _jail in ${JAILS}; do + # Continue if '-b|--boot' is set and 'boot=off' + if [ "${BOOT}" -eq 1 ]; then + BOOT_ENABLED="$(sysrc -f ${bastille_jailsdir}/${_jail}/boot.conf -n boot)" + if [ "${BOOT_ENABLED}" = "off" ]; then + continue + fi + fi + info "[${_jail}]:" check_target_is_stopped "${_jail}" || error_continue "Jail is already running." @@ -157,4 +182,8 @@ for _jail in ${JAILS}; do bastille rdr ${_jail} ${_rules} done < "${bastille_jailsdir}/${_jail}/rdr.conf" fi + + # Delay between jail action + sleep "${DELAY_TIME}" + done diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index d8c7e73a..d7bb1350 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -37,20 +37,36 @@ usage() { cat << EOF Options: - -v | --verbose Print every action on jail stop. - -x | --debug Enable debug mode. + -b | --boot Respect jail boot setting. + -d | --delay VALUE Time to wait between stopping each jail. + -v | --verbose Print every action on jail stop. + -x | --debug Enable debug mode. EOF exit 1 } # Handle options. +BOOT=0 +DELAY_TIME=0 OPTION="" while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; + -b|--boot) + BOOT=1 + shift + ;; + -d|--delay) + if [ -z "${2}" ] && ! echo "${2}" | grep -Eq '^[0-9]+$'; then + error_exit "[-d|--delay] requires a value." + else + DELAY_TIME="${2}" + fi + shift 2 + ;; -v|--verbose) OPTION="-v" shift @@ -62,6 +78,7 @@ while [ "$#" -gt 0 ]; do -*) for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do case ${_opt} in + b) BOOT="1" ;; v) OPTION="-v" ;; x) enable_debug ;; *) error_exit "Unknown Option: \"${1}\"" ;; @@ -82,10 +99,18 @@ fi TARGET="${1}" bastille_root_check -set_target "${TARGET}" +set_target "${TARGET}" "reverse" for _jail in ${JAILS}; do + # Continue if '-b|--boot' is set and 'boot=off' + if [ "${BOOT}" -eq 1 ]; then + BOOT_ENABLED="$(sysrc -f ${bastille_jailsdir}/${_jail}/boot.conf -n boot)" + if [ "${BOOT_ENABLED}" = "off" ]; then + continue + fi + fi + info "[${_jail}]:" check_target_is_running "${_jail}" || error_continue "Jail is already stopped." @@ -133,4 +158,8 @@ for _jail in ${JAILS}; do pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" done fi + + # Delay between jail action + sleep "${DELAY_TIME}" + done