From 228bb3b8cef36c703f758a2a3de9e0caade11665 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 11 Jan 2025 16:44:01 -0700 Subject: [PATCH 01/24] cp: update to use new functions in common.sh --- usr/local/share/bastille/cp.sh | 80 ++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index d7fc174b..0dd0b0b0 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -34,49 +34,63 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille cp [OPTION] TARGET HOST_PATH CONTAINER_PATH" + error_notify "Usage: bastille cp [option(s)] TARGET HOST_PATH JAIL_PATH" + cat << EOF + Options: + + -q | --quiet Suppress output. + -x | --debug Enable debug mode. + +EOF + exit 1 } -CPSOURCE="${1}" -CPDEST="${2}" +# Handle options. +OPTION="-av" +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -q|--quiet) + OPTION="-a" + shift + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + q) OPTION="-a" ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift + ;; + *) + break + ;; + esac +done -# Handle special-case commands first. -case "$1" in -help|-h|--help) - usage - ;; --q|--quiet) - OPTION="${1}" - CPSOURCE="${2}" - CPDEST="${3}" - ;; -esac - -if [ $# -ne 2 ]; then +if [ "$#" -ne 3 ]; then usage fi -bastille_root_check +TARGET="${1}" +CPSOURCE="${2}" +CPDEST="${3}" -case "${OPTION}" in - -q|--quiet) - OPTION="-a" - ;; - *) - OPTION="-av" - ;; -esac +bastille_root_check +set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" bastille_jail_path="${bastille_jailsdir}/${_jail}/root" - cp "${OPTION}" "${CPSOURCE}" "${bastille_jail_path}/${CPDEST}" - RETURN="$?" - if [ "${TARGET}" = "ALL" ]; then - # Display the return status for reference - echo -e "Returned: ${RETURN}\n" - else - echo - return "${RETURN}" + if ! cp "${OPTION}" "${CPSOURCE}" "${bastille_jail_path}${CPDEST}"; then + error_continue "CP failed: ${CPSOURCE} -> ${bastille_jail_path}${CPDEST}" fi done From 6040308270b8d6c572a0c288d6422534e8ce80fe Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 11 Jan 2025 16:46:30 -0700 Subject: [PATCH 02/24] rcp: update to use new functions --- usr/local/share/bastille/rcp.sh | 79 ++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh index a3b1cda1..7b313577 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -34,46 +34,63 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille rcp [OPTION] TARGET CONTAINER_PATH HOST_PATH" + error_notify "Usage: bastille rcp [option(s)] TARGET JAIL_PATH HOST_PATH" + cat << EOF + Options: + + -q | --quiet Suppress output. + -x | --debug Enable debug mode. + +EOF + exit 1 } -CPSOURCE="${1}" -CPDEST="${2}" +# Handle options. +OPTION="-av" +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -q|--quiet) + OPTION="-a" + shift + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + q) OPTION="-a" ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift + ;; + *) + break + ;; + esac +done -# Handle special-case commands first. -case "$1" in -help|-h|--help) - usage - ;; --q|--quiet) - OPTION="${1}" - CPSOURCE="${2}" - CPDEST="${3}" - ;; -esac - -if [ $# -ne 2 ]; then +if [ "$#" -ne 3 ]; then usage fi -if [ "${TARGET}" = "ALL" ]; then - usage -fi +TARGET="${1}" +CPSOURCE="${2}" +CPDEST="${3}" -case "${OPTION}" in - -q|--quiet) - OPTION="-a" - ;; - *) - OPTION="-av" - ;; -esac +bastille_root_check +set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" bastille_jail_path="${bastille_jailsdir}/${_jail}/root" - cp "${OPTION}" "${bastille_jail_path}/${CPSOURCE}" "${CPDEST}" - RETURN="$?" - echo - return "${RETURN}" + if ! cp "${OPTION}" "${bastille_jail_path}${CPSOURCE}" "${CPDEST}"; then + error_continue "RCP failed: ${bastille_jail_path}${CPSOURCE} -> ${CPDEST}" + fi done From 14d7f4ae741c5b310d93f0914171845294da92de Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 11 Jan 2025 16:52:39 -0700 Subject: [PATCH 03/24] docs: cp documentation update for new functions --- docs/chapters/subcommands/cp.rst | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/docs/chapters/subcommands/cp.rst b/docs/chapters/subcommands/cp.rst index 88c69cfb..e551fb92 100644 --- a/docs/chapters/subcommands/cp.rst +++ b/docs/chapters/subcommands/cp.rst @@ -6,17 +6,27 @@ This command allows efficiently copying files from host to container(s). .. code-block:: shell - ishmael ~ # bastille cp ALL /tmp/resolv.conf-cf etc/resolv.conf + ishmael ~ # bastille cp ALL /tmp/resolv.conf-cf /etc/resolv.conf [bastion]: - + /tmp/resolv.conf-cf -> /usr/local/bastille/jails/bastion/root/etc/resolv.conf [unbound0]: - + /tmp/resolv.conf-cf -> /usr/local/bastille/jails/unbound0/root/etc/resolv.conf [unbound1]: - + /tmp/resolv.conf-cf -> /usr/local/bastille/jails/unbound1/root/etc/resolv.conf [squid]: - + /tmp/resolv.conf-cf -> /usr/local/bastille/jails/squid/root/etc/resolv.conf [nginx]: - + /tmp/resolv.conf-cf -> /usr/local/bastille/jails/nginx/root/etc/resolv.conf [folsom]: + /tmp/resolv.conf-cf -> /usr/local/bastille/jails/folsom/root/etc/resolv.conf Unless you see errors reported in the output the `cp` was successful. + +.. code-block:: shell + + ishmael ~ # bastille cp help + Usage: bastille cp [option(s)] TARGET HOST_PATH JAIL_PATH + Options: + + -q | --quiet Suppress output. + -x | --debug Enable debug mode. From c67ab1879c1e8d14defd6cbc74834099452ba6c9 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 11 Jan 2025 16:59:41 -0700 Subject: [PATCH 04/24] docs: add rcp documentation --- docs/chapters/subcommands/rcp.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 docs/chapters/subcommands/rcp.rst diff --git a/docs/chapters/subcommands/rcp.rst b/docs/chapters/subcommands/rcp.rst new file mode 100644 index 00000000..7b9945d7 --- /dev/null +++ b/docs/chapters/subcommands/rcp.rst @@ -0,0 +1,22 @@ +=== +rcp +=== + +This command allows copying files from a single jail to the host. + +.. code-block:: shell + + ishmael ~ # bastille rcp bastion /tmp/myfile /temp + [bastion]: + /usr/local/bastille/jails/bastion/root/tmp/myfile -> /temp/myfile + +Unless you see errors reported in the output the `rcp` was successful. + +.. code-block:: shell + + ishmael ~ # bastille rcp help + Usage: bastille rcp [option(s)] TARGET JAIL_PATH HOST_PATH + Options: + + -q | --quiet Suppress output. + -x | --debug Enable debug mode. From 816f24331af490eb5be856abbb6b3ace4e9e1159 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 11 Jan 2025 17:20:10 -0700 Subject: [PATCH 05/24] cp: trim double // to / --- usr/local/share/bastille/cp.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index 0dd0b0b0..a1dc0c15 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -89,8 +89,9 @@ set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" - bastille_jail_path="${bastille_jailsdir}/${_jail}/root" - if ! cp "${OPTION}" "${CPSOURCE}" "${bastille_jail_path}${CPDEST}"; then - error_continue "CP failed: ${CPSOURCE} -> ${bastille_jail_path}${CPDEST}" + host_path="${CPSOURCE}" + jail_path="$(echo ${bastille_jailsdir}/${_jail}/root/${CPDEST} | sed 's#//#/#g')" + if ! cp "${OPTION}" "${host_path}" "${jail_path}"; then + error_continue "CP failed: ${host_path} -> ${jail_path}" fi done From f65b8c3ebfb8a0e5e1fd828d2a4ed9aa611f71a5 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 11 Jan 2025 17:20:54 -0700 Subject: [PATCH 06/24] rcp: trim // to / and allow only single target --- usr/local/share/bastille/rcp.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh index 7b313577..ec1c5bd5 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -85,12 +85,13 @@ CPSOURCE="${2}" CPDEST="${3}" bastille_root_check -set_target "${TARGET}" +set_target_single "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" - bastille_jail_path="${bastille_jailsdir}/${_jail}/root" - if ! cp "${OPTION}" "${bastille_jail_path}${CPSOURCE}" "${CPDEST}"; then - error_continue "RCP failed: ${bastille_jail_path}${CPSOURCE} -> ${CPDEST}" + host_path="${CPDEST}" + jail_path="$(echo ${bastille_jailsdir}/${_jail}/root/${CPSOURCE} | sed 's#//#/#g')" + if ! cp "${OPTION}" "${jail_path}" "${host_path}"; then + error_continue "RCP failed: ${jail_path} -> ${host_path}" fi done From 8e73e6f18806e117636a2350de9a5a66b8920c1d Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Sun, 12 Jan 2025 11:16:51 -0700 Subject: [PATCH 07/24] cp: include rcp in cp and add jail mode --- README.md | 3 +- docs/chapters/subcommands/rcp.rst | 22 ------- usr/local/bin/bastille | 3 +- usr/local/share/bastille/cp.sh | 78 ++++++++++++++++++++----- usr/local/share/bastille/rcp.sh | 97 ------------------------------- 5 files changed, 65 insertions(+), 138 deletions(-) delete mode 100644 docs/chapters/subcommands/rcp.rst delete mode 100644 usr/local/share/bastille/rcp.sh diff --git a/README.md b/README.md index 21746469..1dcc5c7c 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Available Commands: config Get or set a config value for the targeted container(s). console Console into a running container. convert Convert a Thin container into a Thick container. - cp cp(1) files from host to targeted container(s). + cp cp(1) files from host or container to host or targeted container(s). 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). @@ -75,7 +75,6 @@ Available Commands: mount Mount a volume inside the targeted container(s). pkg Manipulate binary packages within targeted container(s). See pkg(8). rdr Redirect host port to container port. - rcp reverse cp(1) files from a single container to the host. rename Rename a container. restart Restart a running container. service Manage services within targeted container(s). diff --git a/docs/chapters/subcommands/rcp.rst b/docs/chapters/subcommands/rcp.rst deleted file mode 100644 index 7b9945d7..00000000 --- a/docs/chapters/subcommands/rcp.rst +++ /dev/null @@ -1,22 +0,0 @@ -=== -rcp -=== - -This command allows copying files from a single jail to the host. - -.. code-block:: shell - - ishmael ~ # bastille rcp bastion /tmp/myfile /temp - [bastion]: - /usr/local/bastille/jails/bastion/root/tmp/myfile -> /temp/myfile - -Unless you see errors reported in the output the `rcp` was successful. - -.. code-block:: shell - - ishmael ~ # bastille rcp help - Usage: bastille rcp [option(s)] TARGET JAIL_PATH HOST_PATH - Options: - - -q | --quiet Suppress output. - -x | --debug Enable debug mode. diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index c5442daf..3799429c 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -95,7 +95,7 @@ Available Commands: config Get or set a config value for the targeted container(s). console Console into a running container. convert Convert a Thin container into a Thick container. - cp cp(1) files from host to targeted container(s). + cp cp(1) files from host or container to host or targeted container(s). 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). @@ -107,7 +107,6 @@ Available Commands: list List containers (running). mount Mount a volume inside the targeted container(s). pkg Manipulate binary packages within targeted container(s). See pkg(8). - rcp reverse cp(1) files from a single container to the host. rdr Redirect host port to container port. rename Rename a container. restart Restart a running container. diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index a1dc0c15..b0141327 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -34,24 +34,37 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille cp [option(s)] TARGET HOST_PATH JAIL_PATH" + error_notify "Usage: bastille cp [option(s)] TARGET SOURCE DESTINATION" cat << EOF Options: - -q | --quiet Suppress output. - -x | --debug Enable debug mode. + -j | --jail Jail mode. Copy files from jail to jail(s). + Syntax is [-j jail:srcpath jail:dstpath] + -r | --reverse Reverse copy files from jail to host. + -q | --quiet Suppress output. + -x | --debug Enable debug mode. EOF exit 1 } # Handle options. +JAIL_MODE=0 OPTION="-av" +REVERSE_MODE=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; + -j|--jail) + JAIL_MODE=1 + shift + ;; + -r|--reverse) + REVERSE_MODE=1 + shift + ;; -q|--quiet) OPTION="-a" shift @@ -63,6 +76,8 @@ while [ "$#" -gt 0 ]; do -*) for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do case ${_opt} in + j) JAIL_MODE=1 ;; + r) REVERSE_MODE=1 ;; q) OPTION="-a" ;; x) enable_debug ;; *) error_exit "Unknown Option: \"${1}\"" ;; @@ -76,22 +91,55 @@ while [ "$#" -gt 0 ]; do esac done -if [ "$#" -ne 3 ]; then +if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then usage fi +if [ "${JAIL_MODE}" -eq 1 ]; then + SOURCE_TARGET="$(echo ${1} | awk -F":" '{print $1}')" + SOURCE_PATH="$(echo ${1} | awk -F":" '{print $2}')" + DEST_TARGET="$(echo ${2} | awk -F":" '{print $1}')" + DEST_PATH="$(echo ${2} | awk -F":" '{print $2}')" + set_target_single "${SOURCE_TARGET}" && SOURCE_TARGET="${TARGET}" + set_target "${DEST_TARGET}" && DEST_TARGET="${JAILS}" + for _jail in ${DEST_TARGET}; do + if [ "${_jail}" = "${SOURCE_TARGET}" ]; then + continue + fi + info "[${_jail}]:" + source_path="$(echo ${bastille_jailsdir}/${SOURCE_TARGET}/root/${SOURCE_PATH} | sed 's#//#/#g')" + dest_path="$(echo ${bastille_jailsdir}/${_jail}/root/${DEST_PATH} | sed 's#//#/#g')" + if ! cp "${OPTION}" "${source_path}" "${dest_path}"; then + error_continue "CP failed: ${source_path} -> ${dest_path}" + fi + done + exit +fi + TARGET="${1}" -CPSOURCE="${2}" -CPDEST="${3}" +SOURCE="${2}" +DEST="${3}" bastille_root_check -set_target "${TARGET}" -for _jail in ${JAILS}; do - info "[${_jail}]:" - host_path="${CPSOURCE}" - jail_path="$(echo ${bastille_jailsdir}/${_jail}/root/${CPDEST} | sed 's#//#/#g')" - if ! cp "${OPTION}" "${host_path}" "${jail_path}"; then - error_continue "CP failed: ${host_path} -> ${jail_path}" - fi -done +if [ "${REVERSE_MODE}" -eq 1 ]; then + set_target_single "${TARGET}" + for _jail in ${JAILS}; do + info "[${_jail}]:" + host_path="${DEST}" + jail_path="$(echo ${bastille_jailsdir}/${_jail}/root/${SOURCE} | sed 's#//#/#g')" + if ! cp "${OPTION}" "${jail_path}" "${host_path}"; then + error_exit "RCP failed: ${jail_path} -> ${host_path}" + fi + done +else + set_target "${TARGET}" + for _jail in ${JAILS}; do + info "[${_jail}]:" + host_path="${SOURCE}" + jail_path="$(echo ${bastille_jailsdir}/${_jail}/root/${DEST} | sed 's#//#/#g')" + if ! cp "${OPTION}" "${host_path}" "${jail_path}"; then + error_continue "CP failed: ${host_path} -> ${jail_path}" + fi + done +fi \ No newline at end of file diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh deleted file mode 100644 index ec1c5bd5..00000000 --- a/usr/local/share/bastille/rcp.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/sh -# -# SPDX-License-Identifier: BSD-3-Clause -# -# Copyright (c) 2018-2025, Christer Edwards -# 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 rcp [option(s)] TARGET JAIL_PATH HOST_PATH" - cat << EOF - Options: - - -q | --quiet Suppress output. - -x | --debug Enable debug mode. - -EOF - exit 1 -} - -# Handle options. -OPTION="-av" -while [ "$#" -gt 0 ]; do - case "${1}" in - -h|--help|help) - usage - ;; - -q|--quiet) - OPTION="-a" - shift - ;; - -x|--debug) - enable_debug - shift - ;; - -*) - for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do - case ${_opt} in - q) OPTION="-a" ;; - x) enable_debug ;; - *) error_exit "Unknown Option: \"${1}\"" ;; - esac - done - shift - ;; - *) - break - ;; - esac -done - -if [ "$#" -ne 3 ]; then - usage -fi - -TARGET="${1}" -CPSOURCE="${2}" -CPDEST="${3}" - -bastille_root_check -set_target_single "${TARGET}" - -for _jail in ${JAILS}; do - info "[${_jail}]:" - host_path="${CPDEST}" - jail_path="$(echo ${bastille_jailsdir}/${_jail}/root/${CPSOURCE} | sed 's#//#/#g')" - if ! cp "${OPTION}" "${jail_path}" "${host_path}"; then - error_continue "RCP failed: ${jail_path} -> ${host_path}" - fi -done From 628f0fac34fc2d743a24676a126aaa9131da57ae Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 13 Jan 2025 19:37:59 -0700 Subject: [PATCH 08/24] bastille: move cp to no action commands --- usr/local/bin/bastille | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index 3799429c..a01777e3 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -162,10 +162,10 @@ 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|cp|destroy|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) +clone|config|cmd|console|convert|edit|limits|pkg|rcp|rename|service|stop|sysrc|tags|template|zfs) # Parse the target and ensure it exists. -- cwells if [ $# -eq 0 ]; then # No target was given, so show the command's help. -- cwells PARAMS='help' From 1cfbe6b5e01aa8e618a4568156b1b4db06cd4749 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 13 Jan 2025 19:39:34 -0700 Subject: [PATCH 09/24] bastille: remove rcp --- usr/local/bin/bastille | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index a01777e3..14c9d927 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -165,7 +165,7 @@ help|-h|--help) bootstrap|create|cp|destroy|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|edit|limits|pkg|rcp|rename|service|stop|sysrc|tags|template|zfs) +clone|config|cmd|console|convert|edit|limits|pkg|rename|service|stop|sysrc|tags|template|zfs) # Parse the target and ensure it exists. -- cwells if [ $# -eq 0 ]; then # No target was given, so show the command's help. -- cwells PARAMS='help' From 22831e4b8296a83b4f36a3756c1bda8e09f7d264 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 20 Jan 2025 18:47:58 -0700 Subject: [PATCH 10/24] cp: Exit it -j and -r are both set --- usr/local/share/bastille/cp.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index b0141327..ac6d8c2d 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -39,7 +39,7 @@ usage() { Options: -j | --jail Jail mode. Copy files from jail to jail(s). - Syntax is [-j jail:srcpath jail:dstpath] + Syntax: [-j jail:srcpath jail:dstpath] -r | --reverse Reverse copy files from jail to host. -q | --quiet Suppress output. -x | --debug Enable debug mode. @@ -95,6 +95,10 @@ if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then usage fi +if [ "${JAIL_MODE}" -eq 1 ] && [ "${REVERSE_MODE}" -eq 1 ]; then + error_exit "[-j|--jail] cannot be used with [-r|reverse]" +fi + if [ "${JAIL_MODE}" -eq 1 ]; then SOURCE_TARGET="$(echo ${1} | awk -F":" '{print $1}')" SOURCE_PATH="$(echo ${1} | awk -F":" '{print $2}')" @@ -142,4 +146,4 @@ else error_continue "CP failed: ${host_path} -> ${jail_path}" fi done -fi \ No newline at end of file +fi From 5746af35816a0535ff7b822767db099df95bdab5 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 20 Jan 2025 18:50:06 -0700 Subject: [PATCH 11/24] common: Add debug mode --- usr/local/share/bastille/common.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 654ff026..dd8be78c 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -61,6 +61,12 @@ error_notify() { echo -e "${COLOR_RED}$*${COLOR_RESET}" 1>&2 } +enable_debug() { + # Enable debug mode. + warn "***DEBUG MODE***" + set -x +} + error_continue() { error_notify "$@" # Disabling this shellcheck as we only ever call it inside of a loop From 4c2539dd8d11c7861b5a688b5c24ec63bbaac0c3 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Tue, 21 Jan 2025 07:41:01 -0700 Subject: [PATCH 12/24] copy: Add jcp for jail to jail copy --- usr/local/share/bastille/cp.sh | 84 +++++--------------------- usr/local/share/bastille/jcp.sh | 102 ++++++++++++++++++++++++++++++++ usr/local/share/bastille/rcp.sh | 97 ++++++++++++++++++++++++++++++ 3 files changed, 215 insertions(+), 68 deletions(-) create mode 100644 usr/local/share/bastille/jcp.sh create mode 100644 usr/local/share/bastille/rcp.sh diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index ac6d8c2d..33436b34 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -34,36 +34,23 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille cp [option(s)] TARGET SOURCE DESTINATION" + error_notify "Usage: bastille cp [option(s)] TARGET HOST_PATH JAIL_PATH" cat << EOF Options: - -j | --jail Jail mode. Copy files from jail to jail(s). - Syntax: [-j jail:srcpath jail:dstpath] - -r | --reverse Reverse copy files from jail to host. - -q | --quiet Suppress output. - -x | --debug Enable debug mode. + -q | --quiet Suppress output. + -x | --debug Enable debug mode. EOF exit 1 } # Handle options. -JAIL_MODE=0 OPTION="-av" -REVERSE_MODE=0 while [ "$#" -gt 0 ]; do case "${1}" in - -h|--help|help) - usage - ;; - -j|--jail) - JAIL_MODE=1 - shift - ;; - -r|--reverse) - REVERSE_MODE=1 - shift + -h|--help|help) + usage ;; -q|--quiet) OPTION="-a" @@ -76,8 +63,6 @@ while [ "$#" -gt 0 ]; do -*) for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do case ${_opt} in - j) JAIL_MODE=1 ;; - r) REVERSE_MODE=1 ;; q) OPTION="-a" ;; x) enable_debug ;; *) error_exit "Unknown Option: \"${1}\"" ;; @@ -95,55 +80,18 @@ if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then usage fi -if [ "${JAIL_MODE}" -eq 1 ] && [ "${REVERSE_MODE}" -eq 1 ]; then - error_exit "[-j|--jail] cannot be used with [-r|reverse]" -fi - -if [ "${JAIL_MODE}" -eq 1 ]; then - SOURCE_TARGET="$(echo ${1} | awk -F":" '{print $1}')" - SOURCE_PATH="$(echo ${1} | awk -F":" '{print $2}')" - DEST_TARGET="$(echo ${2} | awk -F":" '{print $1}')" - DEST_PATH="$(echo ${2} | awk -F":" '{print $2}')" - set_target_single "${SOURCE_TARGET}" && SOURCE_TARGET="${TARGET}" - set_target "${DEST_TARGET}" && DEST_TARGET="${JAILS}" - for _jail in ${DEST_TARGET}; do - if [ "${_jail}" = "${SOURCE_TARGET}" ]; then - continue - fi - info "[${_jail}]:" - source_path="$(echo ${bastille_jailsdir}/${SOURCE_TARGET}/root/${SOURCE_PATH} | sed 's#//#/#g')" - dest_path="$(echo ${bastille_jailsdir}/${_jail}/root/${DEST_PATH} | sed 's#//#/#g')" - if ! cp "${OPTION}" "${source_path}" "${dest_path}"; then - error_continue "CP failed: ${source_path} -> ${dest_path}" - fi - done - exit -fi - TARGET="${1}" -SOURCE="${2}" -DEST="${3}" +HOST_PATH="${2}" +JAIL_PATH="${3}" bastille_root_check +set_target "${TARGET}" -if [ "${REVERSE_MODE}" -eq 1 ]; then - set_target_single "${TARGET}" - for _jail in ${JAILS}; do - info "[${_jail}]:" - host_path="${DEST}" - jail_path="$(echo ${bastille_jailsdir}/${_jail}/root/${SOURCE} | sed 's#//#/#g')" - if ! cp "${OPTION}" "${jail_path}" "${host_path}"; then - error_exit "RCP failed: ${jail_path} -> ${host_path}" - fi - done -else - set_target "${TARGET}" - for _jail in ${JAILS}; do - info "[${_jail}]:" - host_path="${SOURCE}" - jail_path="$(echo ${bastille_jailsdir}/${_jail}/root/${DEST} | sed 's#//#/#g')" - if ! cp "${OPTION}" "${host_path}" "${jail_path}"; then - error_continue "CP failed: ${host_path} -> ${jail_path}" - fi - done -fi +for _jail in ${JAILS}; do + info "[${_jail}]:" + host_path="${HOST_PATH}" + jail_path="$(echo ${bastille_jailsdir}/${_jail}/root/${JAIL_PATH} | sed 's#//#/#g')" + if ! cp "${OPTION}" "${host_path}" "${jail_path}"; then + error_continue "CP failed: ${host_path} -> ${jail_path}" + fi +done \ No newline at end of file diff --git a/usr/local/share/bastille/jcp.sh b/usr/local/share/bastille/jcp.sh new file mode 100644 index 00000000..bd0e4870 --- /dev/null +++ b/usr/local/share/bastille/jcp.sh @@ -0,0 +1,102 @@ +#!/bin/sh +# +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards +# 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 jcp [option(s)] SOURCE_JAIL JAIL_PATH DEST_JAIL JAIL_PATH" + cat << EOF + Options: + + -q | --quiet Suppress output. + -x | --debug Enable debug mode. + +EOF + exit 1 +} + +# Handle options. +OPTION="-av" +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -q|--quiet) + OPTION="-a" + shift + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + q) OPTION="-a" ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift + ;; + *) + break + ;; + esac +done + +if [ "$#" -ne 4 ]; then + usage +fi + +SOURCE_TARGET="${1}" +SOURCE_PATH="${2}" +DEST_TARGET="${3}" +DEST_PATH="${4}" + +bastille_root_check +set_target_single "${SOURCE_TARGET}" && SOURCE_TARGET="${TARGET}" +set_target "${DEST_TARGET}" && DEST_TARGET="${JAILS}" + +for _jail in ${DEST_TARGET}; do + if [ "${_jail}" = "${SOURCE_TARGET}" ]; then + continue + else + info "[${_jail}]:" + source_path="$(echo ${bastille_jailsdir}/${SOURCE_TARGET}/root/${SOURCE_PATH} | sed 's#//#/#g')" + dest_path="$(echo ${bastille_jailsdir}/${_jail}/root/${DEST_PATH} | sed 's#//#/#g')" + if ! cp "${OPTION}" "${source_path}" "${dest_path}"; then + error_continue "JCP failed: ${source_path} -> ${dest_path}" + fi +done \ No newline at end of file diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh new file mode 100644 index 00000000..c0828ecb --- /dev/null +++ b/usr/local/share/bastille/rcp.sh @@ -0,0 +1,97 @@ +#!/bin/sh +# +# SPDX-License-Identifier: BSD-3-Clause +# +# Copyright (c) 2018-2025, Christer Edwards +# 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 rcp [option(s)] TARGET JAIL_PATH HOST_PATH" + cat << EOF + Options: + + -q | --quiet Suppress output. + -x | --debug Enable debug mode. + +EOF + exit 1 +} + +# Handle options. +OPTION="-av" +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -q|--quiet) + OPTION="-a" + shift + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + q) OPTION="-a" ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift + ;; + *) + break + ;; + esac +done + +if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then + usage +fi + +TARGET="${1}" +JAIL_PATH="${2}" +HOST_PATH="${3}" + +bastille_root_check +set_target_single "${TARGET}" + +info "[${TARGET}]:" + +host_path="${HOST_PATH}" +jail_path="$(echo ${bastille_jailsdir}/${TARGET}/root/${JAIL_PATH} | sed 's#//#/#g')" + +if ! cp "${OPTION}" "${jail_path}" "${host_path}"; then + error_exit "RCP failed: ${jail_path} -> ${host_path}" +fi From 086f4a60a5d727643d0d0d5615706f7889b3beab Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 21 Jan 2025 07:42:41 -0700 Subject: [PATCH 13/24] jcp: Add missing fi --- usr/local/share/bastille/jcp.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/usr/local/share/bastille/jcp.sh b/usr/local/share/bastille/jcp.sh index bd0e4870..fc8cf05e 100644 --- a/usr/local/share/bastille/jcp.sh +++ b/usr/local/share/bastille/jcp.sh @@ -99,4 +99,5 @@ for _jail in ${DEST_TARGET}; do if ! cp "${OPTION}" "${source_path}" "${dest_path}"; then error_continue "JCP failed: ${source_path} -> ${dest_path}" fi + fi done \ No newline at end of file From 708c9c3b4d0e51db81d9bfe86676582ddae39313 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 21 Jan 2025 07:48:09 -0700 Subject: [PATCH 14/24] bastille: Add jcp/rcp to commands --- usr/local/bin/bastille | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index fe651702..e293d69d 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -95,7 +95,7 @@ Available Commands: config Get or set a config value for the targeted container(s). console Console into a running container. convert Convert a Thin container into a Thick container. - cp cp(1) files from host or container to host or targeted container(s). + cp cp(1) files from host to jail(s). 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). @@ -103,11 +103,13 @@ Available Commands: export Exports a specified container. help Help about any command. htop Interactive process viewer (requires htop). + jcp cp(1) files from a jail to jail(s). import Import a specified container. limits Apply resources limits to targeted container(s). See rctl(8). list List containers (running). mount Mount a volume inside the targeted container(s). pkg Manipulate binary packages within targeted container(s). See pkg(8). + rcp cp(1) files from a jail to host. rdr Redirect host port to container port. rename Rename a container. restart Restart a running container. @@ -163,7 +165,7 @@ version|-v|--version) help|-h|--help) usage ;; -bootstrap|create|cp|destroy|etcupdate|export|htop|import|list|mount|rdr|restart|setup|start|top|umount|update|upgrade|verify) +bootstrap|create|cp|destroy|etcupdate|export|htop|import|jcp|list|mount|rcp|rdr|restart|setup|start|top|umount|update|upgrade|verify) # Nothing "extra" to do for these commands. -- cwells ;; clone|config|cmd|console|convert|edit|limits|pkg|rename|service|stop|sysrc|tags|template|zfs) From 42d1c1305849d51c1ea67f65cbf5561874a4c7dd Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 21 Jan 2025 07:58:56 -0700 Subject: [PATCH 15/24] cp: Allow only 3 arcs --- usr/local/share/bastille/cp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index 33436b34..0d1b53a1 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -76,7 +76,7 @@ while [ "$#" -gt 0 ]; do esac done -if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then +if [ "$#" -ne 3 ]; then usage fi From 25cc612f46d8c9eb098efa2579a00f745e67deab Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 21 Jan 2025 07:59:55 -0700 Subject: [PATCH 16/24] rcp: Allow only 3 args --- usr/local/share/bastille/rcp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh index c0828ecb..f3880a0f 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -76,7 +76,7 @@ while [ "$#" -gt 0 ]; do esac done -if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then +if [ "$#" -ne 3 ]; then usage fi From 9c0b600bc59bf2b7eed476edab3e52b5ea426e5f Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Tue, 21 Jan 2025 08:14:09 -0700 Subject: [PATCH 17/24] docs: Document new jcp command --- docs/chapters/subcommands/cp.rst | 2 +- docs/chapters/subcommands/jcp.rst | 30 ++++++++++++++++++++++++++++++ docs/chapters/subcommands/rcp.rst | 22 ++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 docs/chapters/subcommands/jcp.rst create mode 100644 docs/chapters/subcommands/rcp.rst diff --git a/docs/chapters/subcommands/cp.rst b/docs/chapters/subcommands/cp.rst index e551fb92..57b610b9 100644 --- a/docs/chapters/subcommands/cp.rst +++ b/docs/chapters/subcommands/cp.rst @@ -2,7 +2,7 @@ cp == -This command allows efficiently copying files from host to container(s). +This command allows copying files from host to jail(s). .. code-block:: shell diff --git a/docs/chapters/subcommands/jcp.rst b/docs/chapters/subcommands/jcp.rst new file mode 100644 index 00000000..fbaeee05 --- /dev/null +++ b/docs/chapters/subcommands/jcp.rst @@ -0,0 +1,30 @@ +=== +jcp +=== + +This command allows copying files from jail to jail(s). + +.. code-block:: shell + + ishmael ~ # bastille cp bastion /tmp/resolv.conf-cf ALL /etc/resolv.conf + [unbound0]: + /usr/local/bastille/jails/bastion/root/tmp/resolv.conf-cf -> /usr/local/bastille/jails/unbound0/root/etc/resolv.conf + [unbound1]: + /usr/local/bastille/jails/bastion/root/tmp/resolv.conf-cf -> /usr/local/bastille/jails/unbound1/root/etc/resolv.conf + [squid]: + /usr/local/bastille/jails/bastion/root/tmp/resolv.conf-cf -> /usr/local/bastille/jails/squid/root/etc/resolv.conf + [nginx]: + /usr/local/bastille/jails/bastion/root/tmp/resolv.conf-cf -> /usr/local/bastille/jails/nginx/root/etc/resolv.conf + [folsom]: + /usr/local/bastille/jails/bastion/root/tmp/resolv.conf-cf -> /usr/local/bastille/jails/folsom/root/etc/resolv.conf + +Unless you see errors reported in the output the `jcp` was successful. + +.. code-block:: shell + + ishmael ~ # bastille cp help + Usage: bastille jcp [option(s)] SOURCE_JAIL JAIL_PATH DEST_JAIL JAIL_PATH + Options: + + -q | --quiet Suppress output. + -x | --debug Enable debug mode. diff --git a/docs/chapters/subcommands/rcp.rst b/docs/chapters/subcommands/rcp.rst new file mode 100644 index 00000000..fd4ab86f --- /dev/null +++ b/docs/chapters/subcommands/rcp.rst @@ -0,0 +1,22 @@ +=== +rcp +=== + +This command allows copying files from jail to host. + +.. code-block:: shell + + ishmael ~ # bastille rcp bastion /test/testfile.txt /tmp/testfile.txt + [bastion]: + /usr/local/bastille/jails/bastion/root/test/testfile.txt -> /tmp/testfile.txt + +Unless you see errors reported in the output the `rcp` was successful. + +.. code-block:: shell + + ishmael ~ # bastille rcp help + Usage: bastille rcp [option(s)] TARGET JAIL_PATH HOST_PATH + Options: + + -q | --quiet Suppress output. + -x | --debug Enable debug mode. From fe1eb18fbdf803c3ad4b7e2e82fac2539483390e Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 26 Jan 2025 12:53:49 -0700 Subject: [PATCH 18/24] docs: Typo in jcp --- docs/chapters/subcommands/jcp.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/chapters/subcommands/jcp.rst b/docs/chapters/subcommands/jcp.rst index fbaeee05..6dca3c3d 100644 --- a/docs/chapters/subcommands/jcp.rst +++ b/docs/chapters/subcommands/jcp.rst @@ -6,7 +6,7 @@ This command allows copying files from jail to jail(s). .. code-block:: shell - ishmael ~ # bastille cp bastion /tmp/resolv.conf-cf ALL /etc/resolv.conf + ishmael ~ # bastille jcp bastion /tmp/resolv.conf-cf ALL /etc/resolv.conf [unbound0]: /usr/local/bastille/jails/bastion/root/tmp/resolv.conf-cf -> /usr/local/bastille/jails/unbound0/root/etc/resolv.conf [unbound1]: @@ -22,7 +22,7 @@ Unless you see errors reported in the output the `jcp` was successful. .. code-block:: shell - ishmael ~ # bastille cp help + ishmael ~ # bastille jcp help Usage: bastille jcp [option(s)] SOURCE_JAIL JAIL_PATH DEST_JAIL JAIL_PATH Options: From bcf738b6eef71bf2939a6647056126000e24964e Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 26 Jan 2025 20:45:37 -0500 Subject: [PATCH 19/24] Revert "Merge pull request #823 from JRGTH/bastille_setup_initial" This reverts commit acc7bb9739d67e781b6f9c830c0e29f9cd84de63, reversing changes made to 05dc2b8d6a371ce3930ce502150293c18d7d1bea. --- usr/local/share/bastille/setup.sh | 974 +++--------------------------- 1 file changed, 72 insertions(+), 902 deletions(-) diff --git a/usr/local/share/bastille/setup.sh b/usr/local/share/bastille/setup.sh index 8e609d95..020d2cf4 100644 --- a/usr/local/share/bastille/setup.sh +++ b/usr/local/share/bastille/setup.sh @@ -1,5 +1,7 @@ #!/bin/sh # +# SPDX-License-Identifier: BSD-3-Clause +# # Copyright (c) 2018-2025, Christer Edwards # All rights reserved. # @@ -28,488 +30,41 @@ # 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. -# Let's set some predefined/fallback variables. -bastille_config_path="/usr/local/etc/bastille" -bastille_config="${bastille_config_path}/bastille.conf" -bastille_prefix_default="/usr/local/bastille" -bastille_zfsprefix_default="bastille" -bastille_ifbridge_name="bastille1" - +bastille_config="/usr/local/etc/bastille/bastille.conf" . /usr/local/share/bastille/common.sh # shellcheck source=/usr/local/etc/bastille/bastille.conf . ${bastille_config} usage() { - # Build an independent usage for the `setup` command. - # No short options here for the special purpose --long-options, - # so we can reserve short options for future adds, also the user - # must genuinely agreed on configuration reset/restore so let them type for it. - error_notify "Usage: bastille setup [option]" - - cat << EOF - Options: - - -p | --firewall -- Attempt to configure bastille PF firewall. - -n | --network -- Attempt to configure network loopback interface. - -e | --ethernet -- Attempt to configure the network shared interface. - -v | --vnet -- Attempt to configure VNET bridge interface [bastille1]. - -z | --zfs -- Activates ZFS storage features and benefits for bastille. - --conf-network-reset -- Restore bastille default Network options on the config file. - --conf-storage-reset -- Restore bastille default ZFS storage options on the config file. - --conf-restore-clean -- Restore bastille default config file from bastille.conf.sample file. - -EOF - exit 1 + error_exit "Usage: bastille setup [pf|network|zfs|vnet]" } -input_error() { - error_exit "Invalid user input, aborting!" -} - -config_runtime() { - # Run here variables considered to be required by bastille by default silently. - if ! sysrc -qn bastille_enable | grep -qi "yes"; then - sysrc bastille_enable="YES" >/dev/null 2>&1 - fi -} - -# Check for too many args. +# Check for too many args if [ $# -gt 1 ]; then usage fi -# Handle special-case commands first. -case "${1}" in - help|--help|-h) - usage - ;; -esac - -user_canceled() { - # Don't use 'error_exit' here as this only should inform the user, not panic them. - info "Cancelled by user, exiting!" - exit 1 -} - -config_backup() { - # Create bastille configuration backup with system time appended. - # This should be called each time `bastille setup` attempts to - # write to bastille configuration file. - BACKUP_DATE=$(date +%Y%m%d-%H%M%S) - cp "${bastille_config}" "${bastille_config}.${BACKUP_DATE}" - BACKUP_NAME="${bastille_config}.${BACKUP_DATE}" - info "Config backup created in: [${BACKUP_NAME}]" -} - -config_network_reset() { - # Restore bastille default network options. - warn "Performing Network configuration reset, requested by the user..." - warn "Do you really want to reset 'bastille' network configuration? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - config_backup - local VAR_ITEMS="bastille_network_loopback=bastille0 bastille_network_pf_ext_if=ext_if - bastille_network_pf_table=jails bastille_network_shared= bastille_network_gateway= bastille_network_gateway6=" - for _item in ${VAR_ITEMS}; do - sysrc -f "${bastille_config}" ${_item} - done - info "Network configuration has been reset successfully!" - exit 0 - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac -} - -config_storage_reset() { - # Restore bastille default ZFS storage options. - warn "Performing ZFS configuration reset, requested by the user..." - warn "Do you really want to reset 'bastille' ZFS configuration? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - config_backup - local VAR_ITEMS="bastille_zfs_enable= bastille_zfs_zpool= bastille_zfs_prefix=bastille" - for _item in ${VAR_ITEMS}; do - sysrc -f "${bastille_config}" ${_item} - done - - # Let's configure variables with complex values individually to keep it simple/readable for everyone. - sysrc -f "${bastille_config}" bastille_zfs_options="-o compress=lz4 -o atime=off" - sysrc -f "${bastille_config}" bastille_prefix="${bastille_prefix_default}" - info "ZFS configuration has been reset successfully!" - exit 0 - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac -} - -config_restore_global() { - local _response - # This will restore bastille default configuration file from the sample config file. - # Be aware that if the sample configuration file is missing, we can generate a new one, - # but that's highly unlikely to happen so will keep the code smaller here. - warn "Performing Bastille default configuration restore, requested by the user..." - warn "Do you really want to restore 'bastille' default configuration file and start over? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - config_backup - if [ -f "${bastille_config}.sample" ]; then - mv "${bastille_config}" "${bastille_config}.${BACKUP_DATE}" - cp "${bastille_config}.sample" "${bastille_config}" - else - error_exit "Bastille sample configuration file is missing, exiting." - fi - info "Bastille configuration file restored successfully!" - exit 0 - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac -} - -get_zfs_params() { - info "Reading on-disk and bastille ZFS config parameters..." - # Always try to detect and recover on-disk ZFS bastille configuration first. - # Bastille ZFS prefix is always set to "bastille" in the config file by default, - # so will keep things simple here, or considered custom setup if this variable is changed. - BARTILLE_ROOTFS=$(mount | awk '/ \/ / {print $1}') - BASTILLE_UFSBOOT= - BASTILLE_ZFSPOOL= - BASTILLE_PREFIXDEF= - BASTILLE_ZFSENABLE= - BASTILLE_PREFIX_MATCH= - - # Check if the system boots from ZFS. - if echo "${BARTILLE_ROOTFS}" | grep -q -m 1 -E "^/dev/"; then - # Assume the host is running from UFS. - info "This system doesn't boot from ZFS, looking for alternate configuration." - BASTILLE_UFSBOOT="1" - fi - - BASTILLE_PREFIXCONF=$(sysrc -qn -f "${bastille_config}" bastille_prefix) - BASTILLE_PREFIXZFS=$(sysrc -qn -f "${bastille_config}" bastille_zfs_prefix) - - if [ -z "${BASTILLE_PREFIXZFS}" ]; then - BASTILLE_PREFIXZFS="${bastille_zfsprefix_default}" - fi - - if [ -z "${BASTILLE_UFSBOOT}" ]; then - if [ "${BASTILLE_PREFIXZFS}" != "${bastille_zfsprefix_default}" ]; then - BASTILLE_CUSTOM_CONFIG="1" - fi - fi - - # Try to determine "zroot" pool name as it may happens that the user - # customized the "zroot" pool name during the initial FreeBSD installation. - if [ -z "${BASTILLE_UFSBOOT}" ]; then - #BASTILLE_ZFSPOOL=$(df ${bastille_config_path} 2>/dev/null | sed 1d | awk -F '/' '{print $1}') - BASTILLE_ZFSPOOL=$(zfs list -H ${bastille_config_path} 2>/dev/null | awk -F '/' '{print $1}') - fi - - if [ -z "${BASTILLE_UFSBOOT}" ]; then - BASTILLE_PREFIXDEF=$(zfs list -H "${BASTILLE_ZFSPOOL}/${BASTILLE_PREFIXZFS}" 2>/dev/null | awk '{print $5}') - fi - - if [ -n "${BASTILLE_UFSBOOT}" ]; then - # Make sure bastille_prefix is listed by ZFS then try to get bastille_zfs_pool from it. - # Make some additional checks for non ZFS boot systems, also rely on some 'bastille.conf' ZFS parameters. - BASTILLE_PREFIXLOOK=$(zfs list -H "${BASTILLE_PREFIXCONF}" 2>/dev/null | awk '{print $1}') - BASTILLE_ZFSPOOL=$(zfs list -H "${BASTILLE_PREFIXLOOK}" 2>/dev/null | awk -F '/' '{print $1}') - BASTILLE_PREFIXDEF=$(zfs list -H "${BASTILLE_PREFIXCONF}" 2>/dev/null | awk '{print $5}') - - else - # Fallback to default config. - if [ -z "${BASTILLE_PREFIXDEF}" ]; then - BASTILLE_PREFIXDEF="${bastille_prefix_default}" - fi - fi - - if [ "${BASTILLE_PREFIXDEF}" = "${BASTILLE_PREFIXCONF}" ]; then - BASTILLE_PREFIX_MATCH="1" - fi - - # Update 'bastille_prefix' if a custom dataset is detected while reading on-disk configuration. - if [ ! -d "${bastille_prefix}" ] || [ -n "${ZFS_DATASET_DETECT}" ] || [ -n "${BASTILLE_PREFIXDEF}" ]; then - BASTILLE_ZFSENABLE="YES" - bastille_prefix="${BASTILLE_PREFIXDEF}" - else - BASTILLE_ZFSENABLE="NO" - if [ -z "${BASTILLE_UFSBOOT}" ]; then - BASTILLE_PREFIXZFS="" - fi - fi -} - -config_validation(){ - # Perform a basic bastille ZFS configuration check, - if [ -d "${bastille_prefix}" ] && [ -n "${BASTILLE_PREFIX_MATCH}" ] && echo "${bastille_zfs_enable}" | grep -qi "yes" \ - && zfs list "${bastille_zfs_zpool}/${bastille_zfs_prefix}" >/dev/null 2>&1; then - info "Looks like Bastille ZFS storage features has been activated successfully!." - exit 0 - else - if [ ! -d "${bastille_prefix}" ] && [ -z "${BASTILLE_ZFSPOOL}" ]; then - zfs_initial_activation - else - if ! echo "${bastille_zfs_enable}" | grep -qi "no"; then - - # Inform the user bastille ZFS configuration has been tampered and/or on-disk ZFS config has changed. - error_exit "Bastille ZFS misconfiguration detected, please refer to 'bastille.conf' or see 'bastille setup --config-reset'." - fi - fi - fi -} - -show_zfs_params() { - # Show a brief info of the detected and/or pending bastille ZFS configuration parameters. - # Don't need to show bastille zfs enable as this will be enabled by default. - info "*************************************" - info "Bastille Storage Prefix: [${BASTILLE_PREFIXDEF}]" - info "Bastille ZFS Pool: [${BASTILLE_ZFSPOOL}]" - info "Bastille ZFS Prefix: [${BASTILLE_PREFIXZFS}]" - info "*************************************" -} - -write_zfs_opts() { - # Write/update to bastille config file the required and/or misssing parameters. - if [ -z "${bastille_prefix}" ] || [ "${BASTILLE_PREFIXDEF}" != "${bastille_prefix_default}" ]; then - if [ -z "${BASTILLE_PREFIX_MATCH}" ]; then - sysrc -f "${bastille_config}" bastille_prefix="${BASTILLE_PREFIXDEF}" - fi - else - if [ -z "${BASTILLE_PREFIXCONF}" ] && [ -n "${BASTILLE_PREFIXDEF}" ]; then - sysrc -f "${bastille_config}" bastille_prefix="${BASTILLE_PREFIXDEF}" - fi - fi - - if [ -z "${bastille_zfs_enable}" ]; then - sysrc -f "${bastille_config}" bastille_zfs_enable="${BASTILLE_ZFSENABLE}" - fi - if [ -z "${bastille_zfs_zpool}" ]; then - sysrc -f "${bastille_config}" bastille_zfs_zpool="${BASTILLE_ZFSPOOL}" - fi - if [ -z "${bastille_zfs_prefix}" ] || [ "${BASTILLE_PREFIXDEF}" != "${bastille_zfs_prefix}" ]; then - sysrc -f "${bastille_config}" bastille_zfs_prefix="${BASTILLE_PREFIXZFS}" - fi - info "ZFS has been enabled in bastille configuration successfully!" -} - -create_zfs_dataset(){ - info "Creating ZFS dataset [${BASTILLE_ZFSPOOL}/${BASTILLE_PREFIXZFS}] for bastille..." - - if [ -n "${BASTILLE_CONFIG_USER}" ]; then - bastille_prefix="${BASTILLE_PREFIXDEF}" - fi - - # shellcheck disable=SC1073 - if zfs list "${BASTILLE_ZFSPOOL}/${BASTILLE_PREFIXZFS}" >/dev/null 2>&1; then - info "Dataset ${BASTILLE_ZFSPOOL}/${BASTILLE_PREFIXZFS} already exist, skipping." - else - if ! zfs create -p "${bastille_zfs_options}" -o mountpoint="${bastille_prefix}" "${BASTILLE_ZFSPOOL}/${BASTILLE_PREFIXZFS}"; then - error_exit "Failed to create 'bastille_prefix' dataset, exiting." - fi - fi - chmod 0750 "${bastille_prefix}" - info "Bastille ZFS storage features has been activated successfully!" - exit 0 -} - -write_zfs_disable() { - # Explicitly disable ZFS in 'bastille_zfs_enable' - sysrc -f "${bastille_config}" bastille_zfs_enable="NO" - info "ZFS has been disabled in bastille configuration successfully!" -} - -write_zfs_enable() { - # Explicitly enable ZFS in 'bastille_zfs_enable' - # Just empty the 'bastille_zfs_enable' variable so the user can re-run the ZFS activation helper. - # Don't put "YES" here as it will trigger the ZFS validation and failing due missing and/or invalid configuration. - sysrc -f "${bastille_config}" bastille_zfs_enable="" - info "ZFS activation helper enabled!" -} - -zfs_initial_activation() { - local _response= - - # Just let the user interactively select the ZFS items manually from a list for the initial activation. - # This should be performed before `bastille bootstrap` as we already know. - info "Initial bastille ZFS activation helper invoked." - info "Would you like to configure the bastille ZFS options interactively? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - # Assume the user knows what hes/she doing and want to configure ZFS parameters interactively. - configure_zfs_manually - ;; - [Nn]|[Nn][Oo]) - # Assume the user will manually edit the ZFS parameters in the config file. - user_canceled - ;; - *) - input_error - ;; - esac -} - -configure_ethernet() { - # This will attempt to configure the physical ethernet interface for 'bastille_network_shared', - # commonly used with shared IP jails and/or simple jail network configurations. - - local ETHIF_COUNT="0" - local _ethernet_choice= - local _ethernet_select= - local _response= - - # Try to get a list of the available physical network/ethernet interfaces. - local ETHERNET_PHY_ADAPTERS="$(pciconf -lv | grep 'ethernet' -B4 | grep 'class=0x020000' | awk -F '@' '{print $1}')" - if [ -z "${ETHERNET_PHY_ADAPTERS}" ]; then - error_exit "Unable to detect for any physical ethernet interfaces, exiting." - fi - - info "This will attempt to configure the physical ethernet interface for [bastille_network_shared]." - warn "Would you like to configure the physical ethernet interface now? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - # shellcheck disable=SC2104 - break - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac - - info "Listing available physical ethernet interfaces..." - for _ethernetif in ${ETHERNET_PHY_ADAPTERS}; do - echo "[${ETHIF_COUNT}] ${_ethernetif}" - ETHIF_NUM="${ETHIF_NUM} [${ETHIF_COUNT}]${_ethernetif}" - ETHIF_COUNT=$(expr ${ETHIF_COUNT} + 1) - done - - info "Please select the wanted physical ethernet adapter [NUM] to be used as 'bastille_network_shared': " - read _ethernet_choice - if ! echo "${_ethernet_choice}" | grep -Eq "^[0-9]{1,3}$"; then - error_exit "Invalid input number, aborting!" - else - _ethernet_select=$(echo "${ETHIF_NUM}" | grep -wo "\[${_ethernet_choice}\][^ ]*" | sed 's/\[.*\]//g') - # If the user is unsure here, just abort as no input validation will be performed after. - if [ -z "${_ethernet_select}" ]; then - error_exit "No physical ethernet interface selected, aborting!" - else - info "Selected physical ethernet interface: [${_ethernet_select}]" - # Ask again to make sure the user is confident with the election. - warn "Are you sure '${_ethernet_select}' is the correct physical ethernet interface [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - if ! sysrc -f "${bastille_config}" bastille_network_shared | grep -qi "${_ethernet_select}"; then - config_backup - sysrc -f "${bastille_config}" bastille_network_shared="${_ethernet_select}" - fi - exit 0 - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac - fi - fi -} - +# Configure bastille loopback network interface configure_network() { - local _response + info "Configuring ${bastille_network_loopback} loopback interface" + sysrc cloned_interfaces+=lo1 + sysrc ifconfig_lo1_name="${bastille_network_loopback}" - # Configure bastille loopback network interface. - # This is an initial attempt to make this function interactive, - # however this may be enhanced in the future by advanced contributors in this topic. - info "This will attempt to configure the loopback network interface [${bastille_network_loopback}]." - warn "Would you like to configure the loopback network interface now? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - # shellcheck disable=SC2104 - break - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac - - info "Configuring ${bastille_network_loopback} loopback interface..." - if ! sysrc -qn cloned_interfaces | grep -qi "lo1"; then - sysrc cloned_interfaces+="lo1" - fi - if ! sysrc -qn ifconfig_lo1_name | grep -qi "${bastille_network_loopback}"; then - sysrc ifconfig_lo1_name="${bastille_network_loopback}" - fi - - info "Bringing up new interface: ${bastille_network_loopback}..." + info "Bringing up new interface: ${bastille_network_loopback}" service netif cloneup } configure_vnet() { - local _response + info "Configuring bridge interface" + sysrc cloned_interfaces+=bridge1 + sysrc ifconfig_bridge1_name=bastille1 - # This is an initial attempt to make this function interactive, - # however this may be enhanced in the future by advanced contributors in this topic. - info "This will attempt to configure the VNET bridge interface [${bastille_ifbridge_name}]." - warn "Would you like to configure the VNET bridge interface now? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - # shellcheck disable=SC2104 - break - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac - - info "Configuring bridge interface [${bastille_ifbridge_name}]..." - - if ! sysrc -qn cloned_interfaces | grep -qi "${bastille_ifbridge_name}"; then - sysrc cloned_interfaces+="${bastille_ifbridge_name}" - fi - if ! sysrc -qn ifconfig_bridge1_name | grep -qi "${bastille_ifbridge_name}"; then - sysrc ifconfig_bridge1_name="${bastille_ifbridge_name}" - fi - - info "Bringing up new interface: ${bastille_ifbridge_name}..." + info "Bringing up new interface: bastille1" service netif cloneup - if [ ! -f "/etc/devfs.rules" ]; then - info "Creating bastille_vnet devfs.rules..." + if [ ! -f /etc/devfs.rules ]; then + info "Creating bastille_vnet devfs.rules" cat << EOF > /etc/devfs.rules -# Auto-generated file from `bastille setup` -# devfs configuration information - [bastille_vnet=13] add include \$devfsrules_hide_all add include \$devfsrules_unhide_basic @@ -518,48 +73,22 @@ add include \$devfsrules_jail add include \$devfsrules_jail_vnet add path 'bpf*' unhide EOF - else - warn "File [/etc/devfs.rules] already exist, skipping." - exit 1 fi - exit 0 } +# Configure pf firewall configure_pf() { - local _response - - # Configure the PF firewall. - # This is an initial attempt to make this function interactive, - # however this may be enhanced in the future by advanced contributors in this topic. - info "This will attempt to configure the PF firewall parameters in [${bastille_pf_conf}]." - warn "Would you like to configure the PF firewall parameters now? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - # shellcheck disable=SC2104 - break - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac - - # shellcheck disable=SC2154 - if [ ! -f "${bastille_pf_conf}" ]; then - # shellcheck disable=SC3043 - local ext_if - ext_if=$(netstat -rn | awk '/default/ {print $4}' | head -n1) - info "Determined default network interface: ($ext_if)" - info "${bastille_pf_conf} does not exist: creating..." - - # Creating pf.conf file. - cat << EOF > "${bastille_pf_conf}" -# Auto-generated file from `bastille setup` -# packet filter configuration file +# shellcheck disable=SC2154 +if [ ! -f "${bastille_pf_conf}" ]; then + # shellcheck disable=SC3043 + local ext_if + ext_if=$(netstat -rn | awk '/default/ {print $4}' | head -n1) + info "Determined default network interface: ($ext_if)" + info "${bastille_pf_conf} does not exist: creating..." + ## creating pf.conf + cat << EOF > "${bastille_pf_conf}" +## generated by bastille setup ext_if="$ext_if" set block-policy return @@ -575,417 +104,58 @@ pass out quick keep state antispoof for \$ext_if inet pass in inet proto tcp from any to any port ssh flags S/SA keep state EOF - - if ! sysrc -qn pf_enable | grep -qi "yes"; then - sysrc pf_enable="YES" - fi - warn "The pf ruleset file has been created, please review '${bastille_pf_conf}' and enable it using 'service pf start'." - else - warn "${bastille_pf_conf} already exists, skipping." - exit 1 - fi - exit 0 + sysrc pf_enable=YES + warn "pf ruleset created, please review ${bastille_pf_conf} and enable it using 'service pf start'." +else + error_exit "${bastille_pf_conf} already exists. Exiting." +fi } +# Configure ZFS configure_zfs() { - # Attempt to detect and setup either new or an existing bastille ZFS on-disk configuration. - # This is useful for new users to easily activate the bastille ZFS parameters on a standard installation, - # or to recover an existing on-disk ZFS bastille configuration in case the config file has been borked/reset by the user, - # also a config backup will be created each time the config needs to be modified in the following format: bastille.conf.YYYYMMDD-HHMMSS - # Be aware that the users now need to explicitly enable ZFS in the config file due later config file changes, failing to do so - # before initial `bastille bootstrap` will private the user from activating ZFS storage features without manual intervention. - - ZFS_DATASET_DETECT= - BASTILLE_CUSTOM_CONFIG= - local _response= - - if ! kldstat -qm zfs; then - warn "Looks like the ZFS module is not loaded." - warn "If this is not a dedicated ZFS system you can ignore this warning." - exit 1 + if [ ! "$(kldstat -m zfs)" ]; then + info "ZFS module not loaded; skipping..." else - # If the below statement becomes true, will assume that the user do not want ZFS activation at all regardless of the - # host filesystem, or the default configuration file has been changed officially and set to "NO" by default. - if echo "${bastille_zfs_enable}" | grep -qi "no"; then - info "Looks like Bastille ZFS has been disabled in 'bastille.conf', ZFS activation helper disabled." - warn "Would you like to enable the ZFS activation helper now? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - # Assume the user wants to configure the ZFS parameters. - if config_backup; then - write_zfs_enable - warn "Please run 'bastille setup' again or consult bastille.conf for further configuration." - exit 0 - else - error_exit "Config backup creation failed, exiting." - fi - ;; - [Nn]|[Nn][Oo]) - # Assume the user will manually configure the ZFS parameters, or skip ZFS configuration. - user_canceled - ;; - esac - else - # Attempt to detect if bastille was installed with sane defaults(ports/pkg) and hasn't been bootstrapped yet, - # then offer the user initial ZFS activation option to gain all of the ZFS storage features and benefits. - # This should be performed before `bastille` initial bootstrap because several ZFS datasets will be - # created/configured during the bootstrap process by default. - get_zfs_params - if [ ! -d "${bastille_prefix}" ] && [ -n "${BASTILLE_ZFSPOOL}" ]; then - if [ "${bastille_prefix}" = "${bastille_prefix_default}" ] && [ -z "${BASTILLE_CUSTOM_CONFIG}" ]; then - show_zfs_params - info "Looks like bastille has been installed and hasn't been bootstrapped yet." - warn "Would you like to activate ZFS now to get the features and benefits? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - if [ -n "${BASTILLE_ZFSPOOL}" ]; then - info "Attempting to create a backup file of the current bastille.conf file..." - if config_backup; then - write_zfs_opts - create_zfs_dataset - else - error_exit "Config backup creation failed, exiting." - fi - else - error_exit "Unable to determine the [zroot] pool name, exiting" - fi - ;; - [Nn]|[Nn][Oo]) - info "Looks like you cancelled the ZFS activation." - # Offer the user option to disable ZFS in the configuration file. - # Maybe the user wants to use UFS or ZFS with legacy directories instead. - warn "Would you like to explicitly disable ZFS in the configuration file? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - if config_backup; then - # Assume the user want to skip ZFS configuration regardless. - write_zfs_disable - exit 0 - else - error_exit "Config backup creation failed, exiting." - fi - ;; - [Nn]|[Nn][Oo]) - # Assume the user will manually configure the ZFS parameters by itself. - user_canceled - ;; - *) - input_error - ;; - esac - ;; - *) - input_error - ;; - esac - else - config_validation - fi - else - if [ -d "${bastille_prefix}" ] && [ -z "${bastille_zfs_enable}" ] && [ -z "${bastille_zfs_zpool}" ] && [ -z "${BASTILLE_CUSTOM_CONFIG}" ] && [ -z "${BASTILLE_UFSBOOT}" ]; then - show_zfs_params - # This section is handy if the user has reset the bastille configuration file after a successful ZFS activation. - info "Looks like bastille has been bootstrapped already, but ZFS options are not configured." - info "Attempting to configure default ZFS options for you..." - if zfs list | grep -qw "${bastille_prefix}"; then - ZFS_DATASET_DETECT="1" - warn "Would you like to auto-configure the detected ZFS parameters now? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - if config_backup; then - write_zfs_opts - exit 0 - else - error_exit "Config backup creation failed, exiting." - fi - ;; - [Nn]|[Nn][Oo]) - # Assume the user will manually configure the ZFS parameters by itself. - user_canceled - ;; - *) - input_error - ;; - esac - else - if [ -d "${bastille_prefix}" ]; then - if [ ! "$(ls -A ${bastille_prefix})" ]; then - if ! zfs list | grep -qw "${bastille_prefix}"; then - # If the user want to use ZFS he/she need to remove/rename the existing 'bastille_prefix' directory manually. - # We do not want to cause existing data lost at all due end-user errors. - warn "Looks like bastille prefix is not a ZFS dataset, thus ZFS storage options are not required." - warn "Please refer to 'bastille.conf' and/or verify for alreay existing 'bastille_prefix' directory." - warn "Would you like to explicitly disable ZFS in the configuration file so we don't ask again? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - if config_backup; then - write_zfs_disable - exit 0 - else - error_exit "Config backup creation failed, exiting." - fi - ;; - [Nn]|[Nn][Oo]) - # Assume the user will manually configure the ZFS parameters by itself. - user_canceled - ;; - *) - input_error - ;; - esac - fi - else - error_exit "Looks like 'bastille_prefix' is not a ZFS dataset and is not empty, aborting." - fi - fi - fi - fi - if [ -n "${BASTILLE_CUSTOM_CONFIG}" ]; then - # Attempt to detect an existing on-disk bastille ZFS configuration and let the user interactively select the items manually from a list. - # This should be performed if the user has borked/reset the config file or in the event the setup detected an unusual/customized bastille install. - warn "A custom bastille ZFS configuration has been detected and/or unable to read ZFS configuration properly." - warn "Please refer to 'bastille.conf' config file and/or 'bastille setup -help' for additional info." - zfs_initial_activation - else - config_validation - fi - fi + ## attempt to determine bastille_zroot from `zpool list` + bastille_zroot=$(zpool list | grep -v NAME | awk '{print $1}') + if [ "$(echo "${bastille_zroot}" | wc -l)" -gt 1 ]; then + error_notify "Error: Multiple ZFS pools available:\n${bastille_zroot}" + error_notify "Set desired pool using \"sysrc -f ${bastille_config} bastille_zfs_zpool=ZPOOL_NAME\"" + error_exit "Don't forget to also enable ZFS using \"sysrc -f ${bastille_config} bastille_zfs_enable=YES\"" fi + sysrc -f "${bastille_config}" bastille_zfs_enable=YES + sysrc -f "${bastille_config}" bastille_zfs_zpool="${bastille_zroot}" fi } -configure_zfs_manually() { - BASTILLE_CONFIG_USER= - local ZFSPOOL_COUNT="0" - local ZFSDATA_COUNT="0" - local MPREFIX_COUNT="0" - local _zfsprefix_trim= - local _zfspool_choice= - local _zfspool_select= - local _zfsprefix_choice= - local _zfsprefix_select= - local _zfsmount_choice= - local _zfsmount_select= - local _response= +# Run all base functions (w/o vnet) if no args +if [ $# -eq 0 ]; then + sysrc bastille_enable=YES + configure_network + configure_pf + configure_zfs +fi - info "Would you like to configure the ZFS parameters entirely by hand? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - # We will assume the user knows what hes/she doing and want to configure ZFS parameters entirely by hand. - warn "Please enter the desired ZFS pool for bastille: " - read _zfspool_select - warn "Please enter the ZFS dataset for bastille: " - read _zfsprefix_select - warn "Please enter the ZFS mountpoint for bastille: " - read _zfsmount_select - - # Set the parameters and show the user a preview. - BASTILLE_PREFIXDEF="${_zfsmount_select}" - BASTILLE_ZFSPOOL="${_zfspool_select}" - BASTILLE_PREFIXZFS="${_zfsprefix_select}" - show_zfs_params - - # Ask again to make sure the user is confident with the entered parameters. - warn "Are you sure the above bastille ZFS configuration is correct?" - warn "Once bastille is activated it can't be easily undone, do you really want to activate ZFS now? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - BASTILLE_CONFIG_USER="1" - write_zfs_opts - create_zfs_dataset - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac - ;; - [Nn]|[Nn][Oo]) - # shellcheck disable=SC2104 - break - ;; - *) - input_error - ;; - esac - - # Ask here several times as we want the user to be really sure of what they doing, - # We do not want to cause existing data lost at all due end-user errors. - info "Listing available ZFS pools..." - bastille_zpool=$(zpool list -H | awk '{print $1}') - for _zpool in ${bastille_zpool}; do - echo "[${ZFSPOOL_COUNT}] ${_zpool}" - ZFSPOOL_NUM="${ZFSPOOL_NUM} [${ZFSPOOL_COUNT}]${_zpool}" - ZFSPOOL_COUNT=$(expr ${ZFSPOOL_COUNT} + 1) - done - - info "Please select the ZFS pool [NUM] for bastille: " - read _zfspool_choice - if ! echo "${_zfspool_choice}" | grep -Eq "^[0-9]{1,3}$"; then - error_exit "Invalid input number, aborting!" - else - _zfspool_select=$(echo "${ZFSPOOL_NUM}" | grep -wo "\[${_zfspool_choice}\][^ ]*" | sed 's/\[.*\]//g') - # If the user is unsure here, just abort as no input validation will be performed after. - if [ -z "${_zfspool_select}" ]; then - error_exit "No ZFS pool selected, aborting!" - else - info "Selected ZFS pool: [${_zfspool_select}]" - # Ask again to make sure the user is confident with the election. - warn "Are you sure '${_zfspool_select}' is the correct ZFS pool [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - # shellcheck disable=SC2104 - continue - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac - fi - fi - - # Ask on what zfs dataset `bastille` is installed. - info "Listing available ZFS datasets from the selected ZFS pool..." - bastille_zprefix=$(zfs list -H -r "${_zfspool_select}" | awk '{print $1}') - for _zprefix in ${bastille_zprefix}; do - echo "[${ZFSDATA_COUNT}] ${_zprefix}" - ZFSDATA_NUM="${ZFSDATA_NUM} [${ZFSDATA_COUNT}]${_zprefix}" - ZFSDATA_COUNT=$(expr ${ZFSDATA_COUNT} + 1) - done - info "Please select the ZFS dataset [NUM] for bastille: " - read _zfsprefix_choice - if ! echo "${_zfsprefix_choice}" | grep -Eq "^[0-9]{1,3}$"; then - error_exit "Invalid input number, aborting!" - else - _zfsprefix_select=$(echo "${ZFSDATA_NUM}" | grep -wo "\[${_zfsprefix_choice}\][^ ]*" | sed 's/\[.*\]//g') - if [ -z "${_zfsprefix_select}" ]; then - # If the user is unsure here, just abort as no input validation will be performed after. - error_exit "No ZFS dataset selected, aborting!" - else - _zfsprefix_select=$(echo ${ZFSDATA_NUM} | grep -wo "\[${_zfsprefix_choice}\][^ ]*" | sed 's/\[.*\]//g') - _zfsprefix_trim=$(echo ${ZFSDATA_NUM} | grep -wo "\[${_zfsprefix_choice}\][^ ]*" | awk -F "${_zfspool_select}/" 'NR==1{print $2}') - info "Selected ZFS prefix: [${_zfsprefix_select}]" - # Ask again to make sure the user is confident with the election. - warn "Are you sure '${_zfsprefix_select}' is the correct ZFS dataset [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - # shellcheck disable=SC2104 - continue - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac - fi - fi - - _zfsmount_select="${_zfsprefix_select}" - # Ask what zfs mountpoint `bastille` will use. - info "Listing ZFS mountpoints from the selected ZFS dataset: [${_zfsmount_select}]..." - bastille_prefix=$(zfs list -H "${_zfsmount_select}" | awk '{print $5}') - for _zfsmount_choice in ${bastille_prefix}; do - echo "[${MPREFIX_COUNT}] ${_zfsmount_choice}" - MPREFIX_NUM="${MPREFIX_NUM} [${MPREFIX_COUNT}]${_zfsmount_choice}" - MPREFIX_COUNT=$(expr ${MPREFIX_COUNT} + 1) - done - info "Please select the ZFS mountpoint [NUM] for bastille: " - read _zfsmount_choice - if ! echo "${_zfsmount_choice}" | grep -Eq "^[0-9]{1,3}$"; then - error_exit "Invalid input number, aborting!" - else - _zfsmount_select=$(echo ${MPREFIX_NUM} | grep -wo "\[${_zfsmount_choice}\][^ ]*" | sed 's/\[.*\]//g') - if [ -z "${_zfsmount_select}" ]; then - # If the user is unsure here, just abort as no input validation will be performed after. - error_exit "No ZFS mountpoint selected, aborting!" - else - info "Selected bastille storage mountpoint: [${_zfsmount_select}]" - # Ask again to make sure the user is confident with the election. - warn "Are you sure '${_zfsmount_select}' is the correct bastille prefix [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - # Set the parameters and show the user a preview. - BASTILLE_PREFIXDEF="${_zfsmount_select}" - BASTILLE_ZFSPOOL="${_zfspool_select}" - BASTILLE_PREFIXZFS="${_zfsprefix_trim}" - show_zfs_params - warn "Are you sure the above bastille ZFS configuration is correct?" - warn "Once bastille is activated it can't be easily undone, do you really want to activate ZFS now? [y/N]: " - read _response - case "${_response}" in - [Yy]|[Yy][Ee][Ss]) - write_zfs_opts - create_zfs_dataset - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac - ;; - [Nn]|[Nn][Oo]) - user_canceled - ;; - *) - input_error - ;; - esac - fi - fi -} - -# Runtime required variables. -config_runtime - -# Handle options one at a time per topic, we don't want users to select/process -# multiple options at once just to end with a broked and/or unwanted configuration. -case "${1}" in - --firewall|-p) - configure_pf - ;; - --ethernet|-e) - configure_ethernet - ;; - --network|-n|bastille0) - # TODO remove in future release 0.13 - warn "Notice: 'bastille setup bastille0' will be deprecated in the next 0.13 version." - configure_network - ;; - --vnet|-v|bridge) - configure_vnet - ;; - --zfs|-z) - configure_zfs - ;; - --conf-network-reset) - config_network_reset - ;; - --conf-storage-reset) - config_storage_reset - ;; - --conf-restore-clean) - config_restore_global - ;; - *) - usage - ;; +# Handle special-case commands first. +case "$1" in +help|-h|--help) + usage + ;; +pf|firewall) + configure_pf + ;; +bastille0) + # TODO remove in future release 0.13 + warn "'bastille setup bastille0' will be deprecated in the next 0.13 version." + configure_network + ;; +network|loopback) + configure_network + ;; +zfs|storage) + configure_zfs + ;; +bastille1|vnet|bridge) + configure_vnet + ;; esac From 43e186899dbfd3d6f30d06dbaa4d697898bec9eb Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 26 Jan 2025 19:40:07 -0700 Subject: [PATCH 20/24] README: Fix reference to rcp --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1dcc5c7c..4ce958c3 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ Available Commands: list List containers (running). mount Mount a volume inside the targeted container(s). pkg Manipulate binary packages within targeted container(s). See pkg(8). + rcp cp(1) files from a jail to host. rdr Redirect host port to container port. rename Rename a container. restart Restart a running container. From 6d033ab227bcab1a97d31bfe94169765dd5259d4 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 26 Jan 2025 21:56:26 -0500 Subject: [PATCH 21/24] readme: Adds jcp subcommand information --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4ce958c3..6605202f 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ Available Commands: help Help about any command. htop Interactive process viewer (requires htop). import Import a specified container. + jcp cp(1) files from a jail to jail(s). limits Apply resources limits to targeted container(s). See rctl(8). list List containers (running). mount Mount a volume inside the targeted container(s). From c21a2386071e55b6d486a261be9dad2920d926af Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 26 Jan 2025 22:13:10 -0500 Subject: [PATCH 22/24] authors: Add Victor Tschetter --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 3a777ac1..353f1961 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -28,6 +28,7 @@ Christer Edwards [christer.edwards@gmail.com] - Niketh Murali - Eric Borisch - Kevet Duncombe +- Victor Tschetter ### Special thanks Software doesn't happen in a vacuum. Thank you to the following people who may From 00f09ef7385d1c5c1ab0a010fe764b8eb1e0cef8 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 26 Jan 2025 22:15:08 -0500 Subject: [PATCH 23/24] version 0.13.20250126 --- README.md | 2 +- docs/chapters/installation.rst | 2 +- docs/conf.py | 4 ++-- usr/local/bin/bastille | 2 +- usr/local/share/bastille/etcupdate.sh | 2 +- usr/local/share/bastille/rename.sh | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6605202f..ca2d2d38 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ Use "bastille command -h|--help" for more information about a command. ``` -## 0.12-beta +## 0.13-beta This document outlines the basic usage of the Bastille container management framework. This release is still considered beta. diff --git a/docs/chapters/installation.rst b/docs/chapters/installation.rst index 232988c9..1596813b 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.20250111`. +Current version is `0.13.20250126`. To install from the FreeBSD package repository: diff --git a/docs/conf.py b/docs/conf.py index 96451510..c2f36b89 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,9 +12,9 @@ copyright = '2018-2025, Christer Edwards' author = 'Christer Edwards' # The short X.Y version -version = '0.12.20250111' +version = '0.13.20250126' # The full version, including alpha/beta/rc tags -release = '0.12.20250111-beta' +release = '0.13.20250126-beta' # -- General configuration --------------------------------------------------- diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index d89baf15..d8439beb 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -78,7 +78,7 @@ bastille_perms_check() { bastille_perms_check ## version -BASTILLE_VERSION="0.12.20250111" +BASTILLE_VERSION="0.13.20250126" usage() { cat << EOF diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh index 9e4f6c68..1f0979be 100644 --- a/usr/local/share/bastille/etcupdate.sh +++ b/usr/local/share/bastille/etcupdate.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2025, Christer Edwards # 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 52e206f7..7aa887b8 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2025, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without From 205be1afdd703a51e5b9fc6109e4e656112b605f Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 29 Jan 2025 07:59:47 -0700 Subject: [PATCH 24/24] console: Fix _jail > TARGET --- usr/local/share/bastille/console.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/usr/local/share/bastille/console.sh b/usr/local/share/bastille/console.sh index 96690b3d..33851a05 100644 --- a/usr/local/share/bastille/console.sh +++ b/usr/local/share/bastille/console.sh @@ -94,10 +94,10 @@ fi validate_user() { if jexec -l "${TARGET}" id "${USER}" >/dev/null 2>&1; then - USER_SHELL="$(jexec -l "${_jail}" getent passwd "${USER}" | cut -d: -f7)" + USER_SHELL="$(jexec -l "${TARGET}" getent passwd "${USER}" | cut -d: -f7)" if [ -n "${USER_SHELL}" ]; then - if jexec -l "${_jail}" grep -qwF "${USER_SHELL}" /etc/shells; then - jexec -l "${_jail}" $LOGIN -f "${USER}" + if jexec -l "${TARGET}" grep -qwF "${USER_SHELL}" /etc/shells; then + jexec -l "${TARGET}" $LOGIN -f "${USER}" else echo "Invalid shell for user ${USER}" fi