diff --git a/LICENSE b/LICENSE index 7ccaf14b7..2f34d728e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/docs/chapters/installation.rst b/docs/chapters/installation.rst index 1a7b239af..232988c9c 100644 --- a/docs/chapters/installation.rst +++ b/docs/chapters/installation.rst @@ -4,7 +4,7 @@ Bastille is available in the official FreeBSD ports tree at `sysutils/bastille`. Binary packages available in `quarterly` and `latest` repositories. -Current version is `0.12.20241124`. +Current version is `0.12.20250111`. To install from the FreeBSD package repository: diff --git a/docs/chapters/subcommands/htop.rst b/docs/chapters/subcommands/htop.rst index d3493be23..1fcb8bdbe 100644 --- a/docs/chapters/subcommands/htop.rst +++ b/docs/chapters/subcommands/htop.rst @@ -2,8 +2,8 @@ htop ==== -This one runs `htop` inside the container. -note: won't work if you don't have htop installed in the container. +This command runs `htop` in the targeted jail. +Requires htop to be installed in the jail. .. image:: ../../images/htop.png diff --git a/docs/chapters/subcommands/top.rst b/docs/chapters/subcommands/top.rst index 16df8682a..77e7f831f 100644 --- a/docs/chapters/subcommands/top.rst +++ b/docs/chapters/subcommands/top.rst @@ -2,7 +2,7 @@ top === -This one runs `top` in that container. +This command runs `top` in the targeted jail. .. image:: ../../images/top.png diff --git a/docs/chapters/subcommands/umount.rst b/docs/chapters/subcommands/umount.rst index cdcdabdb3..2dbfdafa8 100644 --- a/docs/chapters/subcommands/umount.rst +++ b/docs/chapters/subcommands/umount.rst @@ -19,7 +19,7 @@ Syntax requires only the jail path to unmount. Usage: bastille umount TARGET JAIL_PATH -If the directory you are unmounting has spaces, make sure to escape them with a backslash \, and enclode the mount point in quotes "". +If the directory you are unmounting has spaces, make sure to escape them with a backslash \, and enclose the mount point in quotes "". .. code-block:: shell diff --git a/docs/conf.py b/docs/conf.py index 1c3f2c770..964515107 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,13 +8,13 @@ # -- Project information ----------------------------------------------------- project = 'Bastille' -copyright = '2018-2024, Christer Edwards' +copyright = '2018-2025, Christer Edwards' author = 'Christer Edwards' # The short X.Y version -version = '0.12.20241124' +version = '0.12.20250111' # The full version, including alpha/beta/rc tags -release = '0.12.20241124-beta' +release = '0.12.20250111-beta' # -- General configuration --------------------------------------------------- diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index 5c78318a7..ba831d07f 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -30,20 +32,23 @@ PATH=${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin -. /usr/local/share/bastille/common.sh - ## check for config existence bastille_conf_check() { if [ ! -r "/usr/local/etc/bastille/bastille.conf" ]; then - warn "Configuration file not found. Do yu want to create it with default values? [y/N]" + echo "[INFO] Configuration file not found. Do you want to create it with default values? [y/N]" read answer case "${answer}" in [Nn][Oo]|[Nn]|"") - error_exit "No configuration file has been generated. Exiting." + echo "[INFO] No configuration file has been generated. Exiting." + exit ;; [Yy][Ee][Ss]|[Yy]) cp /usr/local/etc/bastille/bastille.conf.sample /usr/local/etc/bastille/bastille.conf - info "Configuration file has been generated. Continuing with default values" + echo "[INFO] Configuration file has been generated. Continuing with default values" + ;; + *) + echo "[ERROR] Invalid option. Please answer with 'y' or 'N'." + exit 1 ;; esac fi @@ -51,7 +56,8 @@ bastille_conf_check() { bastille_conf_check -## we only load the config if conf_check passes +## we only load this if conf_check passes +. /usr/local/share/bastille/common.sh . /usr/local/etc/bastille/bastille.conf # Set default values for config properties added during the current major version: : "${bastille_network_pf_ext_if:=ext_if}" @@ -72,7 +78,7 @@ bastille_perms_check() { bastille_perms_check ## version -BASTILLE_VERSION="0.12.20241124" +BASTILLE_VERSION="0.12.20250111" usage() { cat << EOF @@ -93,6 +99,7 @@ Available Commands: create Create a new thin container or a thick container if -T|--thick option specified. destroy Destroy a stopped container or a FreeBSD release. edit Edit container configuration files (advanced). + etcupdate Update /etc directory to specified release. export Exports a specified container. help Help about any command. htop Interactive process viewer (requires htop). @@ -157,7 +164,7 @@ version|-v|--version) help|-h|--help) usage ;; -bootstrap|create|destroy|export|htop|import|list|mount|rdr|restart|setup|start|top|umount|update|upgrade|verify) +bootstrap|create|destroy|etcupdate|export|htop|import|list|mount|rdr|restart|setup|start|top|umount|update|upgrade|verify) # Nothing "extra" to do for these commands. -- cwells ;; clone|config|cmd|console|convert|cp|edit|limits|pkg|rcp|rename|service|stop|sysrc|tags|template|zfs) diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index 295ebf676..b981e9abb 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index e11bd701e..428bf9c80 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -103,47 +105,77 @@ update_jailconf() { update_jailconf_vnet() { bastille_jail_rc_conf="${bastille_jailsdir}/${NEWNAME}/root/etc/rc.conf" - - # Determine number of containers and define an uniq_epair - local list_jails_num="$(bastille list jails | wc -l | awk '{print $1}')" - local num_range="$(expr "${list_jails_num}" + 1)" - jail_list=$(bastille list jail) - for _num in $(seq 0 "${num_range}"); do - if [ -n "${jail_list}" ]; then - if ! grep -q "e0b_bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then - if ! grep -q "epair${_num}" "${bastille_jailsdir}"/*/jail.conf; then - local uniq_epair="bastille${_num}" + # Determine number of interfaces and define a uniq_epair + local _if_list="$(grep -Eo 'epair[0-9]+|bastille[0-9]+' ${JAIL_CONFIG} | sort -u)" + for _if in ${_if_list}; do + local _epair_if_count="$(grep -Eo 'epair[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')" + local _bastille_if_count="$(grep -Eo 'bastille[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')" + local epair_num_range=$((_epair_if_count + 1)) + local bastille_num_range=$((_bastille_if_count + 1)) + if echo ${_if} | grep -Eoq 'epair[0-9]+'; then + # Update bridged VNET config + for _num in $(seq 0 "${epair_num_range}"); do + if ! grep -oq "epair${_num}" ${bastille_jailsdir}/*/jail.conf; then + # Update jail.conf epair name local uniq_epair_bridge="${_num}" - # since we don't have access to the external_interface variable, we cat the jail.conf file to retrieve the mac prefix - # we also do not use the main generate_static_mac function here - local macaddr_prefix="$(cat ${JAIL_CONFIG} | grep -m 1 ether | grep -oE '([0-9a-f]{2}(:[0-9a-f]{2}){5})' | awk -F: '{print $1":"$2":"$3}')" - local macaddr_suffix="$(echo -n ${NEWNAME} | sha256 | cut -b -5 | sed 's/\([0-9a-fA-F][0-9a-fA-F]\)\([0-9a-fA-F][0-9a-fA-F]\)\([0-9a-fA-F]\)/\1:\2:\3/')" - local macaddr="${macaddr_prefix}:${macaddr_suffix}" - # Update the exec.* with uniq_epair when cloning jails. - # for VNET jails - sed -i '' "s|bastille\([0-9]\{1,\}\)|${uniq_epair}|g" "${JAIL_CONFIG}" - sed -i '' "s|e\([0-9]\{1,\}\)a_${NEWNAME}|e${uniq_epair_bridge}a_${NEWNAME}|g" "${JAIL_CONFIG}" - sed -i '' "s|e\([0-9]\{1,\}\)b_${NEWNAME}|e${uniq_epair_bridge}b_${NEWNAME}|g" "${JAIL_CONFIG}" - sed -i '' "s|epair\([0-9]\{1,\}\)|epair${uniq_epair_bridge}|g" "${JAIL_CONFIG}" - sed -i '' "s|exec.prestart += \"ifconfig e0a_bastille\([0-9]\{1,\}\).*description.*|exec.prestart += \"ifconfig e0a_${uniq_epair} description \\\\\"vnet host interface for Bastille jail ${NEWNAME}\\\\\"\";|" "${JAIL_CONFIG}" - sed -i '' "s|ether.*:.*:.*:.*:.*:.*a\";|ether ${macaddr}a\";|" "${JAIL_CONFIG}" - sed -i '' "s|ether.*:.*:.*:.*:.*:.*b\";|ether ${macaddr}b\";|" "${JAIL_CONFIG}" + local _if_epaira="${_if}a" + local _if_epairb="${_if}b" + local _if_vnet="$(grep ${_if_epairb} "${bastille_jail_rc_conf}" | grep -Eo -m 1 "vnet[0-9]+")" + sed -i '' "s|${_if}|epair${uniq_epair_bridge}|g" "${JAIL_CONFIG}" + # If jail had a static MAC, generate one for clone + if grep ether ${JAIL_CONFIG} | grep -qoc epair${uniq_epair_bridge}; then + local external_interface="$(grep "epair${uniq_epair_bridge}" ${JAIL_CONFIG} | grep -o '[^ ]* addm' | awk '{print $1}')" + generate_static_mac "${NEWNAME}" "${external_interface}" + sed -i '' "s|epair${uniq_epair_bridge}a ether.*:.*:.*:.*:.*:.*a\";|epair${uniq_epair_bridge}a ether ${macaddr}a\";|" "${JAIL_CONFIG}" + sed -i '' "s|epair${uniq_epair_bridge}b ether.*:.*:.*:.*:.*:.*b\";|epair${uniq_epair_bridge}b ether ${macaddr}b\";|" "${JAIL_CONFIG}" + fi + sed -i '' "s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|g" "${JAIL_CONFIG}" + # Update /etc/rc.conf + sed -i '' "s|${_if_epairb}_name|epair${uniq_epair_bridge}b_name|" "${bastille_jail_rc_conf}" + if grep "vnet0" "${bastille_jail_rc_conf}" | grep -q "epair${uniq_epair_bridge}b_name"; then + if [ "${IP}" = "0.0.0.0" ]; then + sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="SYNCDHCP" + else + sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}" + fi + else + sysrc -f "${bastille_jail_rc_conf}" ifconfig_${_if_vnet}="SYNCDHCP" + fi break fi - fi + done + elif echo ${_if} | grep -Eoq 'bastille[0-9]+'; then + # Update VNET config + for _num in $(seq 0 "${bastille_num_range}"); do + if ! grep -oq "bastille${_num}" ${bastille_jailsdir}/*/jail.conf; then + # Update jail.conf epair name + local uniq_epair="bastille${_num}" + local _if_vnet="$(grep ${_if} "${bastille_jail_rc_conf}" | grep -Eo -m 1 "vnet[0-9]+")" + sed -i '' "s|${_if}|${uniq_epair}|g" "${JAIL_CONFIG}" + # If jail had a static MAC, generate one for clone + if grep ether ${JAIL_CONFIG} | grep -qoc ${uniq_epair}; then + local external_interface="$(grep ${uniq_epair} ${JAIL_CONFIG} | grep -o 'addm.*' | awk '{print $3}' | sed 's/["|;]//g')" + generate_static_mac "${NEWNAME}" "${external_interface}" + sed -i '' "s|${uniq_epair} ether.*:.*:.*:.*:.*:.*a\";|${uniq_epair} ether ${macaddr}a\";|" "${JAIL_CONFIG}" + sed -i '' "s|${uniq_epair} ether.*:.*:.*:.*:.*:.*b\";|${uniq_epair} ether ${macaddr}b\";|" "${JAIL_CONFIG}" + fi + sed -i '' "s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|g" "${JAIL_CONFIG}" + # Update /etc/rc.conf + sed -i '' "s|ifconfig_e0b_${_if}_name|ifconfig_e0b_${uniq_epair}_name|" "${bastille_jail_rc_conf}" + if grep "vnet0" "${bastille_jail_rc_conf}" | grep -q ${uniq_epair}; then + if [ "${IP}" = "0.0.0.0" ]; then + sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="SYNCDHCP" + else + sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0=" inet ${IP} " + fi + else + sysrc -f "${bastille_jail_rc_conf}" ifconfig_${_if_vnet}="SYNCDHCP" + fi + break + fi + done fi done - - # Rename interface to new uniq_epair - sed -i '' "s|ifconfig_e0b_bastille.*_name|ifconfig_e0b_${uniq_epair}_name|" "${bastille_jail_rc_conf}" - sed -i '' "s|ifconfig_e.*b_${TARGET}_name|ifconfig_e${uniq_epair_bridge}b_${NEWNAME}_name|" "${bastille_jail_rc_conf}" - - # If 0.0.0.0 set DHCP, else set static IP address - if [ "${IP}" = "0.0.0.0" ]; then - sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="SYNCDHCP" - else - sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}" - fi } update_fstab() { diff --git a/usr/local/share/bastille/cmd.sh b/usr/local/share/bastille/cmd.sh index a1f423472..277791d13 100644 --- a/usr/local/share/bastille/cmd.sh +++ b/usr/local/share/bastille/cmd.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/colors.pre.sh b/usr/local/share/bastille/colors.pre.sh index 0d5614201..9074e2d15 100644 --- a/usr/local/share/bastille/colors.pre.sh +++ b/usr/local/share/bastille/colors.pre.sh @@ -1,5 +1,7 @@ #!/bin/sh # +# SPDX-License-Identifier: BSD-3-Clause +# # Copyright (c) 2014-2015 Bryan Drewery <bdrewery@FreeBSD.org> # All rights reserved. # diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index b9b0986fc..654ff026b 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -110,9 +112,11 @@ check_target_is_stopped() { generate_static_mac() { local jail_name="${1}" local external_interface="${2}" - local external_interface_mac="$(ifconfig ${external_interface} | grep ether | awk '{print $2}' | sed 's#:##g')" - local macaddr_prefix="$(echo -n "${external_interface_mac}" | sha256 | cut -b -6 | sed 's/\([0-9a-fA-F][0-9a-fA-F]\)\([0-9a-fA-F][0-9a-fA-F]\)\([0-9a-fA-F]\)/\1:\2:\3/')" - local macaddr_suffix="$(echo -n "${jail_name}" | sha256 | cut -b -5 | sed 's/\([0-9a-fA-F][0-9a-fA-F]\)\([0-9a-fA-F][0-9a-fA-F]\)\([0-9a-fA-F]\)/\1:\2:\3/')" + local external_interface_mac="$(ifconfig ${external_interface} | grep ether | awk '{print $2}')" + # Use the FreeBSD vendor MAC prefix for jail MAC prefix "58:9c:fc" + local macaddr_prefix="58:9c:fc" + # Hash interface+jailname for jail MAC suffix + local macaddr_suffix="$(echo -n "${external_interface_mac}${jail_name}" | sed 's#:##g' | sha256 | cut -b -5 | sed 's/\([0-9a-fA-F][0-9a-fA-F]\)\([0-9a-fA-F][0-9a-fA-F]\)\([0-9a-fA-F]\)/\1:\2:\3/')" if [ -z "${macaddr_prefix}" ] || [ -z "${macaddr_suffix}" ]; then error_notify "Failed to generate MAC address." fi @@ -121,47 +125,73 @@ generate_static_mac() { } generate_vnet_jail_netblock() { - local jail_name="$1" - local use_unique_bridge="$2" - local external_interface="$3" - generate_static_mac "${jail_name}" "${external_interface}" - ## determine number of containers + 1 + local jail_name="${1}" + local use_unique_bridge="${2}" + local external_interface="${3}" + local static_mac="${4}" + ## determine number of interfaces + 1 ## iterate num and grep all jail configs ## define uniq_epair - local jail_list="$(bastille list jails)" - if [ -n "${jail_list}" ]; then - local list_jails_num="$(echo "${jail_list}" | wc -l | awk '{print $1}')" - local num_range=$((list_jails_num + 1)) - for _num in $(seq 0 "${num_range}"); do - if ! grep -q "e[0-9]b_bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then - if ! grep -q "epair${_num}" "${bastille_jailsdir}"/*/jail.conf; then - local uniq_epair="bastille${_num}" + local _epair_if_count="$(grep -Eos 'epair[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')" + local _bastille_if_count="$(grep -Eos 'bastille[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')" + local epair_num_range=$((_epair_if_count + 1)) + local bastille_num_range=$((_bastille_if_count + 1)) + if [ -n "${use_unique_bridge}" ]; then + if [ "${_epair_if_count}" -gt 0 ]; then + for _num in $(seq 0 "${epair_num_range}"); do + if ! grep -Eosq "epair${_num}" ${bastille_jailsdir}/*/jail.conf; then local uniq_epair_bridge="${_num}" break fi - fi - done + done + else + local uniq_epair_bridge="0" + fi else - local uniq_epair="bastille0" - local uniq_epair_bridge="0" + if [ "${_bastille_if_count}" -gt 0 ]; then + for _num in $(seq 0 "${bastille_num_range}"); do + if ! grep -Eosq "bastille${_num}" ${bastille_jailsdir}/*/jail.conf; then + local uniq_epair="bastille${_num}" + break + fi + done + else + local uniq_epair="bastille0" + fi fi + ## If BRIDGE is enabled, generate bridge config, else generate VNET config if [ -n "${use_unique_bridge}" ]; then - ## generate bridge config - cat <<-EOF + if [ -n "${static_mac}" ]; then + ## Generate bridged VNET config with static MAC address + generate_static_mac "${jail_name}" "${external_interface}" + cat <<-EOF + vnet; + vnet.interface = epair${uniq_epair_bridge}b; + exec.prestart += "ifconfig epair${uniq_epair_bridge} create"; + exec.prestart += "ifconfig ${external_interface} addm epair${uniq_epair_bridge}a"; + exec.prestart += "ifconfig epair${uniq_epair_bridge}a ether ${macaddr}a"; + exec.prestart += "ifconfig epair${uniq_epair_bridge}b ether ${macaddr}b"; + exec.prestart += "ifconfig epair${uniq_epair_bridge}a description \"vnet host interface for Bastille jail ${jail_name}\""; + exec.poststop += "ifconfig ${external_interface} deletem epair${uniq_epair_bridge}a"; + exec.poststop += "ifconfig epair${uniq_epair_bridge}a destroy"; +EOF + else + ## Generate bridged VNET config without static MAC address + cat <<-EOF vnet; - vnet.interface = e${uniq_epair_bridge}b_${jail_name}; + vnet.interface = epair${uniq_epair_bridge}b; exec.prestart += "ifconfig epair${uniq_epair_bridge} create"; exec.prestart += "ifconfig ${external_interface} addm epair${uniq_epair_bridge}a"; - exec.prestart += "ifconfig epair${uniq_epair_bridge}a up name e${uniq_epair_bridge}a_${jail_name}"; - exec.prestart += "ifconfig epair${uniq_epair_bridge}b up name e${uniq_epair_bridge}b_${jail_name}"; - exec.prestart += "ifconfig e${uniq_epair_bridge}a_${jail_name} ether ${macaddr}a"; - exec.prestart += "ifconfig e${uniq_epair_bridge}b_${jail_name} ether ${macaddr}b"; - exec.poststop += "ifconfig ${external_interface} deletem e${uniq_epair_bridge}a_${jail_name}"; - exec.poststop += "ifconfig e${uniq_epair_bridge}a_${jail_name} destroy"; + exec.prestart += "ifconfig epair${uniq_epair_bridge}a description \"vnet host interface for Bastille jail ${jail_name}\""; + exec.poststop += "ifconfig ${external_interface} deletem epair${uniq_epair_bridge}a"; + exec.poststop += "ifconfig epair${uniq_epair_bridge}a destroy"; EOF + fi else - ## generate config - cat <<-EOF + if [ -n "${static_mac}" ]; then + ## Generate VNET config with static MAC address + generate_static_mac "${jail_name}" "${external_interface}" + cat <<-EOF vnet; vnet.interface = e0b_${uniq_epair}; exec.prestart += "jib addm ${uniq_epair} ${external_interface}"; @@ -170,6 +200,16 @@ EOF exec.prestart += "ifconfig e0a_${uniq_epair} description \"vnet host interface for Bastille jail ${jail_name}\""; exec.poststop += "jib destroy ${uniq_epair}"; EOF + else + ## Generate VNET config without static MAC address + cat <<-EOF + vnet; + vnet.interface = e0b_${uniq_epair}; + exec.prestart += "jib addm ${uniq_epair} ${external_interface}"; + exec.prestart += "ifconfig e0a_${uniq_epair} description \"vnet host interface for Bastille jail ${jail_name}\""; + exec.poststop += "jib destroy ${uniq_epair}"; +EOF + fi fi } @@ -190,13 +230,28 @@ set_target_single() { local _TARGET="${1}" if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then error_exit "[all|ALL] not supported with this command." - else - check_target_exists "${_TARGET}" || error_exit "Jail not found \"${_TARGET}\"" - JAILS="${_TARGET}" - TARGET="${_TARGET}" - export JAILS - export TARGET + elif [ "$(echo ${_TARGET} | wc -w)" -gt 1 ]; then + error_exit "Error: Command only supports a single TARGET." + elif echo "${_TARGET}" | grep -Eq '^[0-9]+$'; then + if get_jail_name "${_TARGET}" > /dev/null; then + _TARGET="$(get_jail_name ${_TARGET})" + else + error_exit "Error: JID \"${_TARGET}\" not found. Is jail running?" + fi + elif + ! check_target_exists "${_TARGET}"; then + if jail_autocomplete "${_TARGET}" > /dev/null; then + _TARGET="$(jail_autocomplete ${_TARGET})" + elif [ $? -eq 2 ]; then + error_exit "Jail not found \"${_TARGET}\"" + else + exit 1 + fi fi + TARGET="${_TARGET}" + JAILS="${_TARGET}" + export TARGET + export JAILS } target_all_jails() { diff --git a/usr/local/share/bastille/config.sh b/usr/local/share/bastille/config.sh index 9b39f6bce..68fe1135d 100644 --- a/usr/local/share/bastille/config.sh +++ b/usr/local/share/bastille/config.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/console.sh b/usr/local/share/bastille/console.sh index b15865cc9..9131b221b 100644 --- a/usr/local/share/bastille/console.sh +++ b/usr/local/share/bastille/console.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh index 0290f3553..d22c97083 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index 0d027f7d2..d7fc174bb 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index f0a1250fe..0f47f17c1 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -39,12 +41,13 @@ usage() { cat << EOF Options: - -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. - -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. - -C | --clone -- Creates a clone container, they are duplicates of the base release, consume low space and preserves changing data. - -B | --bridge -- Enables VNET, VNET containers are attached to a specified, already existing external bridge. + -M | --static-mac -- Generate a static MAC address for jail (VNET only). + -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. + -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. + -C | --clone -- Creates a clone container, they are duplicates of the base release, consume low space and preserves changing data. + -B | --bridge -- Enables VNET, VNET containers are attached to a specified, already existing external bridge. EOF exit 1 @@ -227,7 +230,7 @@ generate_vnet_jail_conf() { else devfs_ruleset_value=13 fi - NETBLOCK=$(generate_vnet_jail_netblock "$NAME" "${VNET_JAIL_BRIDGE}" "${bastille_jail_conf_interface}") + NETBLOCK=$(generate_vnet_jail_netblock "$NAME" "${VNET_JAIL_BRIDGE}" "${bastille_jail_conf_interface}" "${STATIC_MAC}") cat << EOF > "${bastille_jail_conf}" ${NAME} { enforce_statfs = 2; @@ -628,10 +631,15 @@ THICK_JAIL="" CLONE_JAIL="" VNET_JAIL="" LINUX_JAIL="" +STATIC_MAC="" # Handle and parse options while [ $# -gt 0 ]; do case "${1}" in + -M|--static-mac) + STATIC_MAC="1" + shift + ;; -E|--empty) EMPTY_JAIL="1" shift diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index d95a4429d..56d8d7f3e 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/edit.sh b/usr/local/share/bastille/edit.sh index 79677e5b9..4442cad0d 100644 --- a/usr/local/share/bastille/edit.sh +++ b/usr/local/share/bastille/edit.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh new file mode 100644 index 000000000..9e4f6c684 --- /dev/null +++ b/usr/local/share/bastille/etcupdate.sh @@ -0,0 +1,197 @@ +#!/bin/sh +# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# 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. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may 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 HOLDER 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. + +. /usr/local/share/bastille/common.sh +. /usr/local/etc/bastille/bastille.conf + +usage() { + error_notify "Usage: bastille etcupdate [option(s)] [bootstrap|TARGET] [diff|resolve|update RELEASE]" + cat << EOF + Options: + + -d | --dry-run Show output, but do not apply. + -f | --force Force a re-bootstrap of a RELEASE. + -x | --debug Enable debug mode. + +EOF + exit 1 +} + +bootstrap_etc_release() { + local _release="${1}" + local _current="$(sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives | awk -F': ' '{print $2}')" + if ! ls -A "${bastille_releasesdir}/${_release}/usr/src" 2>/dev/null; then + sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives=src + if ! bastille bootstrap "${_release}" > /dev/null; then + sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives="${_current}" + error_exit "Failed to bootstrap etcupdate: ${_release}" + else + sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives="${_current}" + fi + fi +} + +bootstrap_etc_tarball() { + local _release="${1}" + if [ ! -f ${bastille_cachedir}/${_release}.tbz2 ]; then + echo "Building tarball, please wait..." + if ! etcupdate build -d /tmp/etcupdate -s ${bastille_releasesdir}/${_release}/usr/src ${bastille_cachedir}/${_release}.tbz2; then + error_exit "Failed to build etcupdate tarball \"${_release}.tbz2\"" + else + info "Etcupdate bootstrap complete: ${_release}" + fi + elif [ -f ${bastille_cachedir}/${_release}.tbz2 ] && [ "${FORCE}" -eq 1 ]; then + rm -f "${bastille_cachedir}/${_release}.tbz2" + echo "Building tarball, please wait..." + if ! etcupdate build -d /tmp/etcupdate -s ${bastille_releasesdir}/${_release}/usr/src ${bastille_cachedir}/${_release}.tbz2; then + error_exit "Failed to build etcupdate tarball: ${_release}.tbz2" + else + info "Etcupdate bootstrap complete: ${_release}" + fi + else + info "Etcupdate release has already been prepared for application: ${_release}" + fi +} + +diff_review() { + local _jail="${1}" + if [ "${DRY_RUN}" -eq 1 ]; then + warn "Warning: diff mode does not support [-d|--dryrun]" + fi + info "[${_jail}]: etcupdate --diff mode" + etcupdate diff -D "${bastille_jailsdir}/${_jail}/root" +} + +resolve_conflicts() { + local _jail="${1}" + if [ "${DRY_RUN}" -eq 1 ]; then + warn "Warning: resolve mode does not support [-d|--dryrun]" + fi + info "[${_jail}]: etcupdate resolve" + etcupdate resolve -D "${bastille_jailsdir}/${_jail}/root" +} + +update_jail_etc() { + local _jail="${1}" + local _release="${2}" + if [ ! -f ${bastille_cachedir}/${_release}.tbz2 ]; then + error_exit "Error: Please run \"bastille etcupdate bootstrap RELEASE\" first." + fi + if [ "${DRY_RUN}" -eq 1 ]; then + info "[${_jail}]: etcupdate update --dry-run" + etcupdate -n -D "${bastille_jailsdir}/${_jail}/root" -t ${bastille_cachedir}/${_release}.tbz2 + else + info "[${_jail}]: etcupdate update" + etcupdate -D "${bastille_jailsdir}/${_jail}/root" -t ${bastille_cachedir}/${_release}.tbz2 + fi +} + +# Handle options. +DRY_RUN=0 +FORCE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -d|--dry-run) + DRY_RUN=1 + shift + ;; + -f|--force) + FORCE=1 + shift + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + d) DRY_RUN=1 ;; + f) FORCE=1 ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift + ;; + *) + break + ;; + esac +done + +if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then + usage +fi + +# Main commands +while [ "$#" -gt 0 ]; do + case "${1}" in + bootstrap) + if [ -z "${2}" ]; then + usage + else + RELEASE="${2}" + bootstrap_etc_release "${RELEASE}" + bootstrap_etc_tarball "${RELEASE}" + shift "$#" + fi + ;; + *) + TARGET="${1}" + ACTION="${2}" + RELEASE="${3}" + set_target_single "${TARGET}" + case "${ACTION}" in + diff) + diff_review "${TARGET}" + shift "$#" + ;; + resolve) + resolve_conflicts "${TARGET}" + shift "$#" + ;; + update) + if [ -z "${RELEASE}" ]; then + usage + else + update_jail_etc "${TARGET}" "${RELEASE}" + shift "$#" + fi + ;; + *) + error_exit "Unknown action: \"${ACTION}\"" + ;; + esac + ;; + esac +done diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index 123db04ba..86898b52c 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh index 10795da15..d6b108d89 100644 --- a/usr/local/share/bastille/htop.sh +++ b/usr/local/share/bastille/htop.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -32,29 +34,41 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille htop [option(s)] TARGET" + error_notify "Usage: bastille htop [option(s)] TARGET" cat << EOF Options: - -f | --force -- Start the jail if it is stopped. + -a | --auto Auto mode. Start/stop jail(s) if required. + -x | --debug Enable debug mode. EOF exit 1 } # Handle options. -FORCE=0 +AUTO=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; - -f|--force) - FORCE=1 + -a|--auto) + AUTO=1 + shift + ;; + -x|--debug) + enable_debug shift ;; -*) - error_exit "Unknown option: \"${1}\"" + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + a) AUTO=1 ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" + esac + done + shift ;; *) break @@ -72,15 +86,14 @@ bastille_root_check set_target_single "${TARGET}" info "[${TARGET}]:" -check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then +check_target_is_running "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then bastille start "${TARGET}" else error_notify "Jail is not running." - error_continue "Use [-f|--force] to force start the jail." + error_continue "Use [-a|--auto] to auto-start the jail." fi -bastille_jail_path="${bastille_jailsdir}/${TARGET}/root" -if [ ! -x "${bastille_jail_path}/usr/local/bin/htop" ]; then +if [ ! -x "${bastille_jailsdir}/${TARGET}/root/usr/local/bin/htop" ]; then error_notify "htop not found on ${TARGET}." elif [ -x "${bastille_jail_path}/usr/local/bin/htop" ]; then jexec -l ${TARGET} /usr/local/bin/htop diff --git a/usr/local/share/bastille/import.sh b/usr/local/share/bastille/import.sh index 34cda5fc0..ade9f648b 100644 --- a/usr/local/share/bastille/import.sh +++ b/usr/local/share/bastille/import.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/limits.sh b/usr/local/share/bastille/limits.sh index 29f631a17..03af4690d 100644 --- a/usr/local/share/bastille/limits.sh +++ b/usr/local/share/bastille/limits.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # Ressource limits added by Sven R github.com/hackacad # diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 49534e2df..23f13d071 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -62,7 +64,8 @@ list_all(){ MAX_LENGTH_JID=${MAX_LENGTH_JID:-3} MAX_LENGTH_JAIL_IP=$(find ${bastille_jailsdir}/*/jail.conf -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 sed -n "s/^[ ]*ip[4,6].addr[ ]*=[ ]*\(.*\);$/\1 /p" | sed 's/\// /g' | awk '{ print length($1) }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_IP=${MAX_LENGTH_JAIL_IP:-10} - MAX_LENGTH_JAIL_VNET_IP=$(find ${bastille_jailsdir}/*/jail.conf -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -l "vnet;" | grep -h "ifconfig_vnet0=" "$(sed -n "s/\(.*\)jail.conf$/\1root\/etc\/rc.conf/p")" | sed -n "s/^ifconfig_vnet0=\"\(.*\)\"$/\1/p"| sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print length($2); else print 15 }' | sort -nr | head -n 1) + # shellcheck disable=SC2046 + MAX_LENGTH_JAIL_VNET_IP="$(find ${bastille_jailsdir}/*/jail.conf -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -l "vnet;" | grep -h "ifconfig_vnet0=" $(sed -n "s/\(.*\)jail.conf$/\1root\/etc\/rc.conf/p") | sed -n "s/^ifconfig_vnet0=\"\(.*\)\"$/\1/p"| sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print length($2); else print 15 }' | sort -nr | head -n 1)" MAX_LENGTH_JAIL_VNET_IP=${MAX_LENGTH_JAIL_VNET_IP:-10} if [ "${MAX_LENGTH_JAIL_VNET_IP}" -gt "${MAX_LENGTH_JAIL_IP}" ]; then MAX_LENGTH_JAIL_IP=${MAX_LENGTH_JAIL_VNET_IP}; fi if [ "${MAX_LENGTH_JAIL_IP}" -lt 10 ]; then MAX_LENGTH_JAIL_IP=10; fi @@ -73,11 +76,13 @@ list_all(){ MAX_LENGTH_JAIL_PORTS=${MAX_LENGTH_JAIL_PORTS:-15} if [ "${MAX_LENGTH_JAIL_PORTS}" -lt 15 ]; then MAX_LENGTH_JAIL_PORTS=15; fi if [ "${MAX_LENGTH_JAIL_PORTS}" -gt 30 ]; then MAX_LENGTH_JAIL_PORTS=30; fi - MAX_LENGTH_JAIL_RELEASE=$(find ${bastille_jailsdir}/*/fstab -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/releases/.*/root/.bastille.*nullfs" | grep -hE "^USERLAND_VERSION=" "$(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++')" | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1) + # shellcheck disable=SC2046 + MAX_LENGTH_JAIL_RELEASE="$(find ${bastille_jailsdir}/*/fstab -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/releases/.*/root/.bastille.*nullfs" | grep -hE "^USERLAND_VERSION=" $(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++') | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1)" MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_JAIL_RELEASE:-7} MAX_LENGTH_THICK_JAIL_RELEASE=$(find ${bastille_jailsdir}/*/root/bin/freebsd-version -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -hE "^USERLAND_VERSION=" | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1) MAX_LENGTH_THICK_JAIL_RELEASE=${MAX_LENGTH_THICK_JAIL_RELEASE:-7} - MAX_LENGTH_LINUX_JAIL_RELEASE=$(find ${bastille_jailsdir}/*/fstab -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/jails/.*/root/proc.*linprocfs" | grep -hE "^NAME=|^VERSION_ID=|^VERSION_CODENAME=" "$(sed -n "s/^linprocfs *\(.*\)\/.*$/\1\/etc\/os-release/p")" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | sed "N;N;s/\n/;/g" | sed -n "s/^NAME=\(.*\);VERSION_ID=\(.*\);VERSION_CODENAME=\(.*\)$/\1 \2 (\3)/p" | awk '{ print length($0) }' | sort -nr | head -n 1) + # shellcheck disable=SC2046 + MAX_LENGTH_LINUX_JAIL_RELEASE="$(find ${bastille_jailsdir}/*/fstab -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/jails/.*/root/proc.*linprocfs" | grep -hE "^NAME=|^VERSION_ID=|^VERSION_CODENAME=" $(sed -n "s/^linprocfs *\(.*\)\/.*$/\1\/etc\/os-release/p") 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | sed "N;N;s/\n/;/g" | sed -n "s/^NAME=\(.*\);VERSION_ID=\(.*\);VERSION_CODENAME=\(.*\)$/\1 \2 (\3)/p" | awk '{ print length($0) }' | sort -nr | head -n 1)" MAX_LENGTH_LINUX_JAIL_RELEASE=${MAX_LENGTH_LINUX_JAIL_RELEASE:-7} 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 diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 604a70d7d..1c2a8efb1 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/pkg.sh b/usr/local/share/bastille/pkg.sh index 4e537a4d8..e7cf23d75 100644 --- a/usr/local/share/bastille/pkg.sh +++ b/usr/local/share/bastille/pkg.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh index fe3d48db9..a3b1cda1c 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 63df78394..f5f426d58 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index e83d22840..20fb80212 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/restart.sh b/usr/local/share/bastille/restart.sh index f443a7821..ffdb16506 100644 --- a/usr/local/share/bastille/restart.sh +++ b/usr/local/share/bastille/restart.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/service.sh b/usr/local/share/bastille/service.sh index 92fa4f272..76d1edadc 100644 --- a/usr/local/share/bastille/service.sh +++ b/usr/local/share/bastille/service.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/setup.sh b/usr/local/share/bastille/setup.sh index b069ea325..020d2cf4b 100644 --- a/usr/local/share/bastille/setup.sh +++ b/usr/local/share/bastille/setup.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index 2eeb9e497..375d49c22 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index 6c4b7c1d5..efec51e11 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/sysrc.sh b/usr/local/share/bastille/sysrc.sh index db1c8a01a..baf0d7ae1 100644 --- a/usr/local/share/bastille/sysrc.sh +++ b/usr/local/share/bastille/sysrc.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/tags.sh b/usr/local/share/bastille/tags.sh index 65ed802ff..4457f03d1 100644 --- a/usr/local/share/bastille/tags.sh +++ b/usr/local/share/bastille/tags.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # Ressource limits added by Lars Engels github.com/bsdlme # diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 203dc1092..3aed8664c 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh index 669c11646..ef2a8bcbf 100644 --- a/usr/local/share/bastille/top.sh +++ b/usr/local/share/bastille/top.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -36,25 +38,37 @@ usage() { cat << EOF Options: - -f | --force -- Start the jail if it is stopped. + -a | --auto Auto mode. Start/stop jail(s) if required. + -x | --debug Enable debug mode. EOF exit 1 } # Handle options. -FORCE=0 +AUTO=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; - -f|--force) - FORCE=1 + -a|--auto) + AUTO=1 + shift + ;; + -x|--debug) + enable_debug shift ;; -*) - error_exit "Unknown option: \"${1}\"" + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + a) AUTO=1 ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" + esac + done + shift ;; *) break @@ -72,10 +86,10 @@ bastille_root_check set_target_single "${TARGET}" info "[${TARGET}]:" -check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then +check_target_is_running "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then bastille start "${TARGET}" else error_notify "Jail is not running." - error_continue "Use [-f|--force] to force start the jail." + error_continue "Use [-a|--auto] to auto-start the jail." fi jexec -l "${TARGET}" /usr/bin/top diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index ebbb52c5a..f5d689699 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index 60458a811..85d632c03 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/upgrade.sh b/usr/local/share/bastille/upgrade.sh index 394225829..5aa06905c 100644 --- a/usr/local/share/bastille/upgrade.sh +++ b/usr/local/share/bastille/upgrade.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh index 8f50dffa4..ec8afa916 100644 --- a/usr/local/share/bastille/verify.sh +++ b/usr/local/share/bastille/verify.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 0bcedbecf..3ba507925 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -1,6 +1,8 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com> +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com> # All rights reserved. # # Redistribution and use in source and binary forms, with or without