From 000635e5bc3040f36c6716b3f14028010bc586e5 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:40:56 -0700 Subject: [PATCH 001/120] Update bootstrap.sh --- usr/local/share/bastille/bootstrap.sh | 271 +++++++++++++------------- 1 file changed, 135 insertions(+), 136 deletions(-) diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index 295ebf676..017c4aec5 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -32,14 +32,14 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille bootstrap [release|template] [update|arch]" + error_exit "Usage: bastille bootstrap [RELEASE|TEMPLATE] [update|arch]" } # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac bastille_root_check @@ -52,7 +52,8 @@ if [ "$(sysrc -n zfs_enable)" = "YES" ] && ! checkyesno bastille_zfs_enable; the no|No|n|N|"") error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_enable." ;; - yes|Yes|y|Y) ;; + yes|Yes|y|Y) + ;; esac fi @@ -216,8 +217,6 @@ bootstrap_release() { if [ -f "${bastille_releasesdir}/${RELEASE}/COPYRIGHT" ]; then ## check distfiles list and skip existing cached files bastille_bootstrap_archives=$(echo "${bastille_bootstrap_archives}" | sed "s/base//") - # TODO check how to handle this - # shellcheck disable=SC2010 bastille_cached_files=$(ls "${bastille_cachedir}/${RELEASE}" | grep -v "MANIFEST" | tr -d ".txz") for distfile in ${bastille_cached_files}; do bastille_bootstrap_archives=$(echo "${bastille_bootstrap_archives}" | sed "s/${distfile}//") @@ -348,7 +347,7 @@ debootstrap_release() { ;; esac else - # If already set in /boot/loader.conf, check and try to load the module. + # If already set in /boot/loader.conf, check and try to load the module. if ! kldstat -m ${_req_kmod} >/dev/null 2>&1; then info "Loading kernel module: ${_req_kmod}" kldload -v ${_req_kmod} @@ -454,7 +453,7 @@ HW_MACHINE_ARCH=$(sysctl hw.machine_arch | awk '{ print $2 }') # bootstrapping from aarch64/arm64 Debian or Ubuntu require a different value for ARCH # create a new variable -if [ "${HW_MACHINE_ARCH}" = "aarch64" ]; then +if [ "${HW_MACHINE_ARCH}" == "aarch64" ]; then HW_MACHINE_ARCH_LINUX="arm64" else HW_MACHINE_ARCH_LINUX=${HW_MACHINE_ARCH} @@ -482,133 +481,133 @@ fi ## Filter sane release names case "${1}" in -2.[0-9]*) - ## check for MidnightBSD releases name - NAME_VERIFY=$(echo "${RELEASE}") - UPSTREAM_URL="${bastille_url_midnightbsd}${HW_MACHINE_ARCH}/${NAME_VERIFY}" - PLATFORM_OS="MidnightBSD" - validate_release_url - ;; -*-CURRENT|*-current) - ## check for FreeBSD releases name - NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT)$' | tr '[:lower:]' '[:upper:]') - UPSTREAM_URL=$(echo "${bastille_url_freebsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_VERIFY}" | sed 's/releases/snapshots/') - PLATFORM_OS="FreeBSD" - validate_release_url - ;; -*-RELEASE|*-release|*-RC[1-9]|*-rc[1-9]|*-BETA[1-9]) - ## check for FreeBSD releases name - NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([0-9]{1,2})\.[0-9](-RELEASE|-RC[1-9]|-BETA[1-9])$' | tr '[:lower:]' '[:upper:]') - UPSTREAM_URL="${bastille_url_freebsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_VERIFY}" - PLATFORM_OS="FreeBSD" - validate_release_url - ;; -*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) - ## check for HardenedBSD releases name(previous infrastructure, keep for reference) - NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})(-stable-last)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g') - UPSTREAM_URL="${bastille_url_hardenedbsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/hardenedbsd-${NAME_VERIFY}" - PLATFORM_OS="HardenedBSD" - validate_release_url - ;; -*-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*) - ## check for HardenedBSD(specific stable build releases) - NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build)-([0-9]{1,3})$' | sed 's/BUILD/build/g' | sed 's/STABLE/stable/g') - NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/-build-[0-9]\{1,3\}//g') - NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/[0-9]\{1,2\}-stable-//g') - UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_BUILD}" - PLATFORM_OS="HardenedBSD" - validate_release_url - ;; -*-stable-build-latest|*-stable-BUILD-LATEST|*-STABLE-BUILD-LATEST) - ## check for HardenedBSD(latest stable build release) - NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build-latest)$' | sed 's/STABLE/stable/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') - NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/-BUILD-LATEST//g') - NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/[0-9]\{1,2\}-stable-BUILD-//g') - UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/installer/${NAME_BUILD}" - PLATFORM_OS="HardenedBSD" - validate_release_url - ;; -current-build-[0-9]*|CURRENT-BUILD-[0-9]*) - ## check for HardenedBSD(specific current build releases) - NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build)-([0-9]{1,3})' | sed 's/BUILD/build/g' | sed 's/CURRENT/current/g') - NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/current-.*/current/g') - NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/current-//g') - UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_BUILD}" - PLATFORM_OS="HardenedBSD" - validate_release_url - ;; -current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST) - ## check for HardenedBSD(latest current build release) - NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build-latest)' | sed 's/CURRENT/current/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') - NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/current-.*/current/g') - NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/current-BUILD-//g') - UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/installer/${NAME_BUILD}" - PLATFORM_OS="HardenedBSD" - validate_release_url - ;; -http?://*/*/*) - BASTILLE_TEMPLATE_URL=${1} - BASTILLE_TEMPLATE_USER=$(echo "${1}" | awk -F / '{ print $4 }') - BASTILLE_TEMPLATE_REPO=$(echo "${1}" | awk -F / '{ print $5 }') - bootstrap_template - ;; -git@*:*/*) - BASTILLE_TEMPLATE_URL=${1} - git_repository=$(echo "${1}" | awk -F : '{ print $2 }') - BASTILLE_TEMPLATE_USER=$(echo "${git_repository}" | awk -F / '{ print $1 }') - BASTILLE_TEMPLATE_REPO=$(echo "${git_repository}" | awk -F / '{ print $2 }') - bootstrap_template - ;; -#adding Ubuntu Bionic as valid "RELEASE" for POC @hackacad -ubuntu_bionic|bionic|ubuntu-bionic) - PLATFORM_OS="Ubuntu/Linux" - LINUX_FLAVOR="bionic" - DIR_BOOTSTRAP="Ubuntu_1804" - ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} - debootstrap_release - ;; -ubuntu_focal|focal|ubuntu-focal) - PLATFORM_OS="Ubuntu/Linux" - LINUX_FLAVOR="focal" - DIR_BOOTSTRAP="Ubuntu_2004" - ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} - debootstrap_release - ;; -ubuntu_jammy|jammy|ubuntu-jammy) - PLATFORM_OS="Ubuntu/Linux" - LINUX_FLAVOR="jammy" - DIR_BOOTSTRAP="Ubuntu_2204" - ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} - debootstrap_release - ;; -debian_buster|buster|debian-buster) - PLATFORM_OS="Debian/Linux" - LINUX_FLAVOR="buster" - DIR_BOOTSTRAP="Debian10" - ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} - debootstrap_release - ;; -debian_bullseye|bullseye|debian-bullseye) - PLATFORM_OS="Debian/Linux" - LINUX_FLAVOR="bullseye" - DIR_BOOTSTRAP="Debian11" - ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} - debootstrap_release - ;; -debian_bookworm|bookworm|debian-bookworm) - PLATFORM_OS="Debian/Linux" - LINUX_FLAVOR="bookworm" - DIR_BOOTSTRAP="Debian12" - ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} - debootstrap_release - ;; -*) - usage - ;; + 2.[0-9]*) + ## check for MidnightBSD releases name + NAME_VERIFY=$(echo "${RELEASE}") + UPSTREAM_URL="${bastille_url_midnightbsd}${HW_MACHINE_ARCH}/${NAME_VERIFY}" + PLATFORM_OS="MidnightBSD" + validate_release_url + ;; + *-CURRENT|*-current) + ## check for FreeBSD releases name + NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT)$' | tr '[:lower:]' '[:upper:]') + UPSTREAM_URL=$(echo "${bastille_url_freebsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_VERIFY}" | sed 's/releases/snapshots/') + PLATFORM_OS="FreeBSD" + validate_release_url + ;; + *-RELEASE|*-release|*-RC[1-9]|*-rc[1-9]|*-BETA[1-9]) + ## check for FreeBSD releases name + NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([0-9]{1,2})\.[0-9](-RELEASE|-RC[1-9]|-BETA[1-9])$' | tr '[:lower:]' '[:upper:]') + UPSTREAM_URL="${bastille_url_freebsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_VERIFY}" + PLATFORM_OS="FreeBSD" + validate_release_url + ;; + *-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) + ## check for HardenedBSD releases name(previous infrastructure, keep for reference) + NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})(-stable-last)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g') + UPSTREAM_URL="${bastille_url_hardenedbsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/hardenedbsd-${NAME_VERIFY}" + PLATFORM_OS="HardenedBSD" + validate_release_url + ;; + *-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*) + ## check for HardenedBSD(specific stable build releases) + NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build)-([0-9]{1,3})$' | sed 's/BUILD/build/g' | sed 's/STABLE/stable/g') + NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/-build-[0-9]\{1,3\}//g') + NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/[0-9]\{1,2\}-stable-//g') + UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_BUILD}" + PLATFORM_OS="HardenedBSD" + validate_release_url + ;; + *-stable-build-latest|*-stable-BUILD-LATEST|*-STABLE-BUILD-LATEST) + ## check for HardenedBSD(latest stable build release) + NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build-latest)$' | sed 's/STABLE/stable/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') + NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/-BUILD-LATEST//g') + NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/[0-9]\{1,2\}-stable-BUILD-//g') + UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/installer/${NAME_BUILD}" + PLATFORM_OS="HardenedBSD" + validate_release_url + ;; + current-build-[0-9]*|CURRENT-BUILD-[0-9]*) + ## check for HardenedBSD(specific current build releases) + NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build)-([0-9]{1,3})' | sed 's/BUILD/build/g' | sed 's/CURRENT/current/g') + NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/current-.*/current/g') + NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/current-//g') + UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_BUILD}" + PLATFORM_OS="HardenedBSD" + validate_release_url + ;; + current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST) + ## check for HardenedBSD(latest current build release) + NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build-latest)' | sed 's/CURRENT/current/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') + NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/current-.*/current/g') + NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/current-BUILD-//g') + UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/installer/${NAME_BUILD}" + PLATFORM_OS="HardenedBSD" + validate_release_url + ;; + http?://*/*/*) + BASTILLE_TEMPLATE_URL=${1} + BASTILLE_TEMPLATE_USER=$(echo "${1}" | awk -F / '{ print $4 }') + BASTILLE_TEMPLATE_REPO=$(echo "${1}" | awk -F / '{ print $5 }') + bootstrap_template + ;; + git@*:*/*) + BASTILLE_TEMPLATE_URL=${1} + git_repository=$(echo "${1}" | awk -F : '{ print $2 }') + BASTILLE_TEMPLATE_USER=$(echo "${git_repository}" | awk -F / '{ print $1 }') + BASTILLE_TEMPLATE_REPO=$(echo "${git_repository}" | awk -F / '{ print $2 }') + bootstrap_template + ;; + #adding Ubuntu Bionic as valid "RELEASE" for POC @hackacad + ubuntu_bionic|bionic|ubuntu-bionic) + PLATFORM_OS="Ubuntu/Linux" + LINUX_FLAVOR="bionic" + DIR_BOOTSTRAP="Ubuntu_1804" + ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} + debootstrap_release + ;; + ubuntu_focal|focal|ubuntu-focal) + PLATFORM_OS="Ubuntu/Linux" + LINUX_FLAVOR="focal" + DIR_BOOTSTRAP="Ubuntu_2004" + ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} + debootstrap_release + ;; + ubuntu_jammy|jammy|ubuntu-jammy) + PLATFORM_OS="Ubuntu/Linux" + LINUX_FLAVOR="jammy" + DIR_BOOTSTRAP="Ubuntu_2204" + ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} + debootstrap_release + ;; + debian_buster|buster|debian-buster) + PLATFORM_OS="Debian/Linux" + LINUX_FLAVOR="buster" + DIR_BOOTSTRAP="Debian10" + ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} + debootstrap_release + ;; + debian_bullseye|bullseye|debian-bullseye) + PLATFORM_OS="Debian/Linux" + LINUX_FLAVOR="bullseye" + DIR_BOOTSTRAP="Debian11" + ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} + debootstrap_release + ;; + debian_bookworm|bookworm|debian-bookworm) + PLATFORM_OS="Debian/Linux" + LINUX_FLAVOR="bookworm" + DIR_BOOTSTRAP="Debian12" + ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} + debootstrap_release + ;; + *) + usage + ;; esac case "${OPTION}" in -update) - bastille update "${RELEASE}" - ;; + update) + bastille update "${RELEASE}" + ;; esac From 2d4fc364b99372633047f99f3320336e410ba6c0 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:41:19 -0700 Subject: [PATCH 002/120] Update clone.sh --- usr/local/share/bastille/clone.sh | 40 +++++++++++++------------------ 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 3d1e2d3d0..1fb1505ad 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -32,24 +32,26 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille clone [TARGET] [NEW_NAME] [IPADDRESS]" + error_exit "Usage: bastille clone TARGET NEW_NAME IPADDRESS" } # Handle special-case commands first -case "$1" in -help|-h|--help) - usage - ;; +case "${1}" in + help|-h|--help) + usage + ;; esac -if [ $# -ne 2 ]; then +if [ $# -ne 3 ]; then usage fi -bastille_root_check +TARGET="${1}" +NEWNAME="${2}" +IP="${3}" -NEWNAME="${1}" -IP="${2}" +bastille_root_check +set_target_single "${TARGET}" validate_ip() { IPX_ADDR="ip4.addr" @@ -58,7 +60,6 @@ validate_ip() { if [ -n "${ip6}" ]; then info "Valid: (${ip6})." IPX_ADDR="ip6.addr" - # shellcheck disable=SC2034 IP6_MODE="new" else local IFS @@ -87,7 +88,7 @@ update_jailconf() { JAIL_CONFIG="${bastille_jailsdir}/${NEWNAME}/jail.conf" if [ -f "${JAIL_CONFIG}" ]; then if ! grep -qw "path = ${bastille_jailsdir}/${NEWNAME}/root;" "${JAIL_CONFIG}"; then - sed -i '' "s|host.hostname = ${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}" + sed -i '' "s|host.hostname = ${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}" sed -i '' "s|exec.consolelog = .*;|exec.consolelog = ${bastille_logsdir}/${NEWNAME}_console.log;|" "${JAIL_CONFIG}" sed -i '' "s|path = .*;|path = ${bastille_jailsdir}/${NEWNAME}/root;|" "${JAIL_CONFIG}" sed -i '' "s|mount.fstab = .*;|mount.fstab = ${bastille_jailsdir}/${NEWNAME}/fstab;|" "${JAIL_CONFIG}" @@ -105,8 +106,8 @@ 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)" + 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 @@ -138,7 +139,7 @@ update_jailconf_vnet() { 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 + 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}" @@ -165,7 +166,7 @@ update_fstab() { clone_jail() { # Attempt container clone - info "Attempting to clone '${TARGET}' to ${NEWNAME}..." + info "Attempting to clone "${TARGET}" to "${NEWNAME}"..." if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then @@ -213,11 +214,4 @@ if echo "${NEWNAME}" | grep -q "[.]"; then error_exit "Container names may not contain a dot(.)!" fi -## check if ip address is valid -if [ -n "${IP}" ]; then - validate_ip -else - usage -fi - clone_jail From 84eb497afa859f7f49deef2e3e09686569e04c13 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:41:30 -0700 Subject: [PATCH 003/120] Update clone.sh --- usr/local/share/bastille/clone.sh | 195 +++++------------------------- 1 file changed, 33 insertions(+), 162 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 1fb1505ad..4a5e42065 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -32,186 +32,57 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille clone TARGET NEW_NAME IPADDRESS" + error_exit "Usage: bastille cmd TARGET command" } -# Handle special-case commands first +# Handle special-case commands first. case "${1}" in help|-h|--help) usage ;; esac -if [ $# -ne 3 ]; then +if [ $# -eq 0 ]; then usage fi -TARGET="${1}" -NEWNAME="${2}" -IP="${3}" - bastille_root_check -set_target_single "${TARGET}" - -validate_ip() { - IPX_ADDR="ip4.addr" - IP6_MODE="disable" - ip6=$(echo "${IP}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))') - if [ -n "${ip6}" ]; then - info "Valid: (${ip6})." - IPX_ADDR="ip6.addr" - IP6_MODE="new" - else - local IFS - if echo "${IP}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then - TEST_IP=$(echo "${IP}" | cut -d / -f1) - IFS=. - set ${TEST_IP} - for quad in 1 2 3 4; do - if eval [ \$$quad -gt 255 ]; then - error_exit "Invalid: (${TEST_IP})" - fi - done - if ifconfig | grep -qwF "${TEST_IP}"; then - warn "Warning: IP address already in use (${TEST_IP})." - else - info "Valid: (${IP})." - fi - else - error_exit "Invalid: (${IP})." - fi - fi -} -update_jailconf() { - # Update jail.conf - JAIL_CONFIG="${bastille_jailsdir}/${NEWNAME}/jail.conf" - if [ -f "${JAIL_CONFIG}" ]; then - if ! grep -qw "path = ${bastille_jailsdir}/${NEWNAME}/root;" "${JAIL_CONFIG}"; then - sed -i '' "s|host.hostname = ${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}" - sed -i '' "s|exec.consolelog = .*;|exec.consolelog = ${bastille_logsdir}/${NEWNAME}_console.log;|" "${JAIL_CONFIG}" - sed -i '' "s|path = .*;|path = ${bastille_jailsdir}/${NEWNAME}/root;|" "${JAIL_CONFIG}" - sed -i '' "s|mount.fstab = .*;|mount.fstab = ${bastille_jailsdir}/${NEWNAME}/fstab;|" "${JAIL_CONFIG}" - sed -i '' "s|${TARGET} {|${NEWNAME} {|" "${JAIL_CONFIG}" - sed -i '' "s|${IPX_ADDR} = .*;|${IPX_ADDR} = ${IP};|" "${JAIL_CONFIG}" - fi - fi +COUNT=0 +RETURN=0 - if grep -qw "vnet;" "${JAIL_CONFIG}"; then - update_jailconf_vnet - fi -} - -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}" - 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 ${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 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|ether.*:.*:.*:.*:.*:.*a|ether ${macaddr}a|" "${JAIL_CONFIG}" - sed -i '' "s|ether.*:.*:.*:.*:.*:.*b|ether ${macaddr}b|" "${JAIL_CONFIG}" - break - fi - fi - 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() { - # Update fstab to use the new name - FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab" - if [ -f "${FSTAB_CONFIG}" ]; then - FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9]|-BETA[1-9]|-CURRENT)|([0-9]{1,2}(-stable-build-[0-9]{1,3}|-stable-LAST))|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)' "${FSTAB_CONFIG}" | uniq) - FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET}/root/.bastille" "${FSTAB_CONFIG}") - FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${NEWNAME}/root/.bastille nullfs ro 0 0" - if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then - # If both variables are set, update as needed - if ! grep -qw "${bastille_releasesdir}/${FSTAB_RELEASE}.*${bastille_jailsdir}/${NEWNAME}/root/.bastille" "${FSTAB_CONFIG}"; then - sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" "${FSTAB_CONFIG}" - fi - fi - # Update additional fstab paths with new jail path - sed -i '' "s|${bastille_jailsdir}/${TARGET}/root/|${bastille_jailsdir}/${NEWNAME}/root/|" "${FSTAB_CONFIG}" - fi -} - -clone_jail() { - # Attempt container clone - info "Attempting to clone "${TARGET}" to "${NEWNAME}"..." - if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then - if checkyesno bastille_zfs_enable; then - if [ -n "${bastille_zfs_zpool}" ]; then - # Replicate the existing container - DATE=$(date +%F-%H%M%S) - zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}" - zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}" | zfs recv "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}" - - # Cleanup source temporary snapshots - zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_clone_${DATE}" - zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}" - - # Cleanup target temporary snapshots - zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}/root@bastille_clone_${DATE}" - zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}@bastille_clone_${DATE}" - fi - else - # Just clone the jail directory - # Check if container is running - if [ -n "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then - error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'." - fi - - # Perform container file copy(archive mode) - cp -a "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}" - fi +TARGET="${1}" +shift 1 + +set_target "${TARGET}" +check_target_exists "${TARGET}" +check_target_is_running "${TARGET}" + +for _jail in ${JAILS}; do + COUNT=$(($COUNT+1)) + info "[${_jail}]:" + if grep -qw "linsysfs" "${bastille_jailsdir}/${_jail}/fstab"; then + # Allow executing commands on Linux jails. + jexec -l -u root "${_jail}" "$@" else - error_exit "${NEWNAME} already exists." + jexec -l -U root "${_jail}" "$@" fi - # Generate jail configuration files - update_jailconf - update_fstab - - # Display the exist status - if [ "$?" -ne 0 ]; then - error_exit "An error has occurred while attempting to clone '${TARGET}'." - else - info "Cloned '${TARGET}' to '${NEWNAME}' successfully." + ERROR_CODE=$? + info "[${_jail}]: ${ERROR_CODE}" + + if [ "$COUNT" -eq 1 ]; then + RETURN=${ERROR_CODE} + else + RETURN=$(($RETURN+$ERROR_CODE)) fi -} + + echo +done -## don't allow for dots(.) in container names -if echo "${NEWNAME}" | grep -q "[.]"; then - error_exit "Container names may not contain a dot(.)!" +# Check when a command is executed in all running jails. (bastille cmd ALL ...) +if [ "${COUNT}" -gt 1 ] && [ "${RETURN}" -gt 0 ]; then + RETURN=1 fi -clone_jail +return "${RETURN}" From 2e67d85a7296046a51f7fdd4bb1aa50b13c09d1e Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:41:45 -0700 Subject: [PATCH 004/120] Update clone.sh --- usr/local/share/bastille/clone.sh | 193 +++++++++++++++++++++++------- 1 file changed, 150 insertions(+), 43 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 4a5e42065..009551b74 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,61 +28,168 @@ # 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 +COLOR_RED= +COLOR_GREEN= +COLOR_YELLOW= +COLOR_RESET= -usage() { - error_exit "Usage: bastille cmd TARGET command" +bastille_root_check() { + if [ "$(id -u)" -ne 0 ]; then + ## permission denied + error_notify "Bastille: Permission Denied" + error_exit "root / sudo / doas required" + fi } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac +enable_color() { + . /usr/local/share/bastille/colors.pre.sh +} -if [ $# -eq 0 ]; then - usage +# If "NO_COLOR" environment variable is present, or we aren't speaking to a +# tty, disable output colors. +if [ -z "${NO_COLOR}" ] && [ -t 1 ]; then + enable_color fi -bastille_root_check +# Notify message on error, but do not exit +error_notify() { + echo -e "${COLOR_RED}$*${COLOR_RESET}" 1>&2 +} -COUNT=0 -RETURN=0 +# Notify message on error and exit +error_exit() { + error_notify "$@" + exit 1 +} -TARGET="${1}" -shift 1 +info() { + echo -e "${COLOR_GREEN}$*${COLOR_RESET}" +} -set_target "${TARGET}" -check_target_exists "${TARGET}" -check_target_is_running "${TARGET}" +warn() { + echo -e "${COLOR_YELLOW}$*${COLOR_RESET}" +} -for _jail in ${JAILS}; do - COUNT=$(($COUNT+1)) - info "[${_jail}]:" - if grep -qw "linsysfs" "${bastille_jailsdir}/${_jail}/fstab"; then - # Allow executing commands on Linux jails. - jexec -l -u root "${_jail}" "$@" +check_target_exists() { + local _TARGET="${1}" + if [ -d "${bastille_jailsdir}"/"${_TARGET}" ]; then + return 0 else - jexec -l -U root "${_jail}" "$@" + error_exit "Jail not found \"${_TARGET}\"" fi +} - ERROR_CODE=$? - info "[${_jail}]: ${ERROR_CODE}" - - if [ "$COUNT" -eq 1 ]; then - RETURN=${ERROR_CODE} - else - RETURN=$(($RETURN+$ERROR_CODE)) +check_target_is_running() { + local _TARGET="${1}" + if [ ! "$(/usr/sbin/jls name | awk "/^${_TARGET}$/")" ]; then + error_exit "[${_TARGET}]: Not started. See 'bastille start ${_TARGET}'." + fi +} + +check_target_is_stopped() { + local _TARGET="${1}" + if [ "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then + error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'." fi - - echo -done +} -# Check when a command is executed in all running jails. (bastille cmd ALL ...) -if [ "${COUNT}" -gt 1 ] && [ "${RETURN}" -gt 0 ]; then - RETURN=1 -fi +set_target() { + if [ "${1}" = ALL ] || [ "${1}" = all ]; then + target_all_jails + else + check_target_exists "${1}" + JAILS="${1}" + export JAILS + fi +} -return "${RETURN}" +set_target_single() { + if [ "${1}" = ALL ] || [ "${1}" = all ]; then + error_exit "[all|ALL] not supported with this command." + else + check_target_exists "${1}" + TARGET="${1}" + export TARGET + fi +} + +target_all_jails() { + local _JAILS=$(/usr/sbin/jls name) + JAILS="" + for _jail in ${_JAILS}; do + _JAILPATH=$(/usr/sbin/jls -j "${_jail}" path) + if [ -z ${_JAILPATH##${bastille_jailsdir}*} ]; then + JAILS="${JAILS} ${_jail}" + fi + export JAILS + done +} + +generate_vnet_jail_netblock() { + local jail_name="$1" + local use_unique_bridge="$2" + local external_interface="$3" + ## determine number of containers + 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 uniq_epair_bridge="${_num}" + break + fi + fi + done + else + local uniq_epair="bastille0" + local uniq_epair_bridge="0" + fi + if [ -n "${use_unique_bridge}" ]; then + ## generate bridge config + cat <<-EOF + vnet; + vnet.interface = "e${uniq_epair_bridge}b_${jail_name}"; + 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.poststop += "ifconfig ${external_interface} deletem e${uniq_epair_bridge}a_${jail_name}"; + exec.poststop += "ifconfig e${uniq_epair_bridge}a_${jail_name} destroy"; +EOF + else + ## generate config + 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 +} + +checkyesno() { + ## copied from /etc/rc.subr -- cedwards (20231125) + ## issue #368 (lowercase values should be parsed) + ## now used for all bastille_zfs_enable=YES|NO tests + ## example: if checkyesno bastille_zfs_enable; then ... + ## returns 0 for enabled; returns 1 for disabled + eval _value=\$${1} + case $_value in + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + return 0 + ;; + [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) + return 1 + ;; + *) + warn "\$${1} is not set properly - see rc.conf(5)." + return 1 + ;; + esac +} From 10b84bbe122ccd8c509124eea4661adea7079660 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:41:58 -0700 Subject: [PATCH 005/120] Update clone.sh --- usr/local/share/bastille/clone.sh | 281 ++++++++++++++---------------- 1 file changed, 131 insertions(+), 150 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 009551b74..37d03d948 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -1,6 +1,7 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +set -x +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,168 +29,148 @@ # 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. -COLOR_RED= -COLOR_GREEN= -COLOR_YELLOW= -COLOR_RESET= +. /usr/local/share/bastille/common.sh +. /usr/local/etc/bastille/bastille.conf -bastille_root_check() { - if [ "$(id -u)" -ne 0 ]; then - ## permission denied - error_notify "Bastille: Permission Denied" - error_exit "root / sudo / doas required" - fi +usage() { + error_exit "Usage: bastille config TARGET get|set propertyName [newValue]" } -enable_color() { - . /usr/local/share/bastille/colors.pre.sh -} +# we need jail(8) to parse the config file so it can expand variables etc +print_jail_conf() { -# If "NO_COLOR" environment variable is present, or we aren't speaking to a -# tty, disable output colors. -if [ -z "${NO_COLOR}" ] && [ -t 1 ]; then - enable_color -fi + # we need to pass a literal \n to jail to get each parameter on its own + # line + jail -f "$1" -e ' +' +} -# Notify message on error, but do not exit -error_notify() { - echo -e "${COLOR_RED}$*${COLOR_RESET}" 1>&2 -} +# Handle special-case commands first. +case "$1" in +help|-h|--help) + usage + ;; +esac -# Notify message on error and exit -error_exit() { - error_notify "$@" - exit 1 -} - -info() { - echo -e "${COLOR_GREEN}$*${COLOR_RESET}" -} - -warn() { - echo -e "${COLOR_YELLOW}$*${COLOR_RESET}" -} +if [ $# -eq 2 ] || [ $# -gt 4 ]; then + usage +fi -check_target_exists() { - local _TARGET="${1}" - if [ -d "${bastille_jailsdir}"/"${_TARGET}" ]; then - return 0 - else - error_exit "Jail not found \"${_TARGET}\"" - fi -} +bastille_root_check -check_target_is_running() { - local _TARGET="${1}" - if [ ! "$(/usr/sbin/jls name | awk "/^${_TARGET}$/")" ]; then - error_exit "[${_TARGET}]: Not started. See 'bastille start ${_TARGET}'." - fi -} +TARGET="${1}" +ACTION="${2}" +shift 2 -check_target_is_stopped() { - local _TARGET="${1}" - if [ "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then - error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'." - fi -} +set_target "${TARGET}" -set_target() { - if [ "${1}" = ALL ] || [ "${1}" = all ]; then - target_all_jails - else - check_target_exists "${1}" - JAILS="${1}" - export JAILS - fi -} - -set_target_single() { - if [ "${1}" = ALL ] || [ "${1}" = all ]; then - error_exit "[all|ALL] not supported with this command." - else - check_target_exists "${1}" - TARGET="${1}" - export TARGET +case ${ACTION} in + get) + if [ $# -ne 1 ]; then + error_notify 'Too many parameters for a "get" operation.' + usage + fi + ;; + set) ;; + *) error_exit 'Only get and set are supported.' ;; +esac + +PROPERTY=${1} +shift +VALUE="$@" + +for _jail in ${JAILS}; do + FILE="${bastille_jailsdir}/${_jail}/jail.conf" + if [ ! -f "${FILE}" ]; then + error_notify "jail.conf does not exist for jail: ${_jail}" + continue fi -} -target_all_jails() { - local _JAILS=$(/usr/sbin/jls name) - JAILS="" - for _jail in ${_JAILS}; do - _JAILPATH=$(/usr/sbin/jls -j "${_jail}" path) - if [ -z ${_JAILPATH##${bastille_jailsdir}*} ]; then - JAILS="${JAILS} ${_jail}" + if [ "${ACTION}" = 'get' ]; then + _output=$( + print_jail_conf "${FILE}" | awk -F= -v property="${PROPERTY}" ' + $1 == property { + # note that we have found the property + found = 1; + # check if there is a value for this property + if (NF == 2) { + # remove any quotes surrounding the string + sub(/^"/, "", $2); + sub(/"$/, "", $2); + print $2; + } else { + # no value, just the property name + print "enabled"; + } + exit 0; + } + END { + # if we have not found anything we need to print a special + # string + if (! found) { + print("not set"); + # let the caller know that this is a warn condition + exit(120); + } + }' + ) + # check if our output is a warning or regular + if [ $? -eq 120 ]; then + warn "${_output}" + else + echo "${_output}" fi - export JAILS - done -} - -generate_vnet_jail_netblock() { - local jail_name="$1" - local use_unique_bridge="$2" - local external_interface="$3" - ## determine number of containers + 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 uniq_epair_bridge="${_num}" - break - fi + else # Setting the value. -- cwells + if [ -n "${VALUE}" ]; then + VALUE=$(echo "${VALUE}" | sed 's/\//\\\//g') + if echo "${VALUE}" | grep ' ' > /dev/null 2>&1; then # Contains a space, so wrap in quotes. -- cwells + VALUE="'${VALUE}'" fi - done - else - local uniq_epair="bastille0" - local uniq_epair_bridge="0" - fi - if [ -n "${use_unique_bridge}" ]; then - ## generate bridge config - cat <<-EOF - vnet; - vnet.interface = "e${uniq_epair_bridge}b_${jail_name}"; - 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.poststop += "ifconfig ${external_interface} deletem e${uniq_epair_bridge}a_${jail_name}"; - exec.poststop += "ifconfig e${uniq_epair_bridge}a_${jail_name} destroy"; -EOF - else - ## generate config - 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 + LINE=" ${PROPERTY} = ${VALUE};" + else + LINE=" ${PROPERTY};" + fi + + # add the value to the config file, replacing any existing value or, if + # there is none, at the end + # + # awk doesn't have "inplace" editing so we use a temp file + _tmpfile=$(mktemp) || error_exit "unable to set because mktemp failed" + cp "${FILE}" "${_tmpfile}" && \ + awk -F= -v line="${LINE}" -v property="${PROPERTY}" ' + BEGIN { + # build RE as string as we can not expand vars in RE literals + prop_re = "^[[:space:]]*" property "[[:space:]]*$"; + } + $1 ~ prop_re && !found { + # we already have an entry in the config for this property so + # we need to substitute our line here rather than keep the + # existing line + print(line); + # note we have already found the property + found = 1; + # move onto the next line + next; + } + $1 == "}" { + # reached the end of the stanza so if we have not already + # added our line we need to do so now + if (! found) { + print(line); + } + } + { + # print each uninteresting line unchanged + print; + } + ' "${_tmpfile}" > "${FILE}" + rm "${_tmpfile}" fi -} +done -checkyesno() { - ## copied from /etc/rc.subr -- cedwards (20231125) - ## issue #368 (lowercase values should be parsed) - ## now used for all bastille_zfs_enable=YES|NO tests - ## example: if checkyesno bastille_zfs_enable; then ... - ## returns 0 for enabled; returns 1 for disabled - eval _value=\$${1} - case $_value in - [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) - return 0 - ;; - [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) - return 1 - ;; - *) - warn "\$${1} is not set properly - see rc.conf(5)." - return 1 - ;; - esac -} +# Only display this message once at the end (not for every jail). -- cwells +if [ "${ACTION}" = 'set' ]; then + info "A restart is required for the changes to be applied. See 'bastille restart ${TARGET}'." +fi + +exit 0 From 608d046475ff18d819b3c8c37d199a16d133afdf Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:42:28 -0700 Subject: [PATCH 006/120] Update clone.sh --- usr/local/share/bastille/clone.sh | 277 +++++++++++++++++------------- 1 file changed, 159 insertions(+), 118 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 37d03d948..1fb1505ad 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -1,6 +1,5 @@ #!/bin/sh # -set -x # Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # @@ -33,144 +32,186 @@ set -x . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille config TARGET get|set propertyName [newValue]" + error_exit "Usage: bastille clone TARGET NEW_NAME IPADDRESS" } -# we need jail(8) to parse the config file so it can expand variables etc -print_jail_conf() { - - # we need to pass a literal \n to jail to get each parameter on its own - # line - jail -f "$1" -e ' -' -} - -# Handle special-case commands first. -case "$1" in -help|-h|--help) - usage - ;; +# Handle special-case commands first +case "${1}" in + help|-h|--help) + usage + ;; esac -if [ $# -eq 2 ] || [ $# -gt 4 ]; then +if [ $# -ne 3 ]; then usage fi -bastille_root_check - TARGET="${1}" -ACTION="${2}" -shift 2 +NEWNAME="${2}" +IP="${3}" -set_target "${TARGET}" +bastille_root_check +set_target_single "${TARGET}" + +validate_ip() { + IPX_ADDR="ip4.addr" + IP6_MODE="disable" + ip6=$(echo "${IP}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))') + if [ -n "${ip6}" ]; then + info "Valid: (${ip6})." + IPX_ADDR="ip6.addr" + IP6_MODE="new" + else + local IFS + if echo "${IP}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then + TEST_IP=$(echo "${IP}" | cut -d / -f1) + IFS=. + set ${TEST_IP} + for quad in 1 2 3 4; do + if eval [ \$$quad -gt 255 ]; then + error_exit "Invalid: (${TEST_IP})" + fi + done + if ifconfig | grep -qwF "${TEST_IP}"; then + warn "Warning: IP address already in use (${TEST_IP})." + else + info "Valid: (${IP})." + fi + else + error_exit "Invalid: (${IP})." + fi + fi +} -case ${ACTION} in - get) - if [ $# -ne 1 ]; then - error_notify 'Too many parameters for a "get" operation.' - usage +update_jailconf() { + # Update jail.conf + JAIL_CONFIG="${bastille_jailsdir}/${NEWNAME}/jail.conf" + if [ -f "${JAIL_CONFIG}" ]; then + if ! grep -qw "path = ${bastille_jailsdir}/${NEWNAME}/root;" "${JAIL_CONFIG}"; then + sed -i '' "s|host.hostname = ${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}" + sed -i '' "s|exec.consolelog = .*;|exec.consolelog = ${bastille_logsdir}/${NEWNAME}_console.log;|" "${JAIL_CONFIG}" + sed -i '' "s|path = .*;|path = ${bastille_jailsdir}/${NEWNAME}/root;|" "${JAIL_CONFIG}" + sed -i '' "s|mount.fstab = .*;|mount.fstab = ${bastille_jailsdir}/${NEWNAME}/fstab;|" "${JAIL_CONFIG}" + sed -i '' "s|${TARGET} {|${NEWNAME} {|" "${JAIL_CONFIG}" + sed -i '' "s|${IPX_ADDR} = .*;|${IPX_ADDR} = ${IP};|" "${JAIL_CONFIG}" fi - ;; - set) ;; - *) error_exit 'Only get and set are supported.' ;; -esac + fi -PROPERTY=${1} -shift -VALUE="$@" + if grep -qw "vnet;" "${JAIL_CONFIG}"; then + update_jailconf_vnet + fi +} -for _jail in ${JAILS}; do - FILE="${bastille_jailsdir}/${_jail}/jail.conf" - if [ ! -f "${FILE}" ]; then - error_notify "jail.conf does not exist for jail: ${_jail}" - continue +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}" + 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 ${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 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|ether.*:.*:.*:.*:.*:.*a|ether ${macaddr}a|" "${JAIL_CONFIG}" + sed -i '' "s|ether.*:.*:.*:.*:.*:.*b|ether ${macaddr}b|" "${JAIL_CONFIG}" + break + fi + fi + 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 +} - if [ "${ACTION}" = 'get' ]; then - _output=$( - print_jail_conf "${FILE}" | awk -F= -v property="${PROPERTY}" ' - $1 == property { - # note that we have found the property - found = 1; - # check if there is a value for this property - if (NF == 2) { - # remove any quotes surrounding the string - sub(/^"/, "", $2); - sub(/"$/, "", $2); - print $2; - } else { - # no value, just the property name - print "enabled"; - } - exit 0; - } - END { - # if we have not found anything we need to print a special - # string - if (! found) { - print("not set"); - # let the caller know that this is a warn condition - exit(120); - } - }' - ) - # check if our output is a warning or regular - if [ $? -eq 120 ]; then - warn "${_output}" - else - echo "${_output}" +update_fstab() { + # Update fstab to use the new name + FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab" + if [ -f "${FSTAB_CONFIG}" ]; then + FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9]|-BETA[1-9]|-CURRENT)|([0-9]{1,2}(-stable-build-[0-9]{1,3}|-stable-LAST))|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)' "${FSTAB_CONFIG}" | uniq) + FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET}/root/.bastille" "${FSTAB_CONFIG}") + FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${NEWNAME}/root/.bastille nullfs ro 0 0" + if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then + # If both variables are set, update as needed + if ! grep -qw "${bastille_releasesdir}/${FSTAB_RELEASE}.*${bastille_jailsdir}/${NEWNAME}/root/.bastille" "${FSTAB_CONFIG}"; then + sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" "${FSTAB_CONFIG}" + fi fi - else # Setting the value. -- cwells - if [ -n "${VALUE}" ]; then - VALUE=$(echo "${VALUE}" | sed 's/\//\\\//g') - if echo "${VALUE}" | grep ' ' > /dev/null 2>&1; then # Contains a space, so wrap in quotes. -- cwells - VALUE="'${VALUE}'" + # Update additional fstab paths with new jail path + sed -i '' "s|${bastille_jailsdir}/${TARGET}/root/|${bastille_jailsdir}/${NEWNAME}/root/|" "${FSTAB_CONFIG}" + fi +} + +clone_jail() { + # Attempt container clone + info "Attempting to clone "${TARGET}" to "${NEWNAME}"..." + if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then + if checkyesno bastille_zfs_enable; then + if [ -n "${bastille_zfs_zpool}" ]; then + # Replicate the existing container + DATE=$(date +%F-%H%M%S) + zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}" + zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}" | zfs recv "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}" + + # Cleanup source temporary snapshots + zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_clone_${DATE}" + zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}" + + # Cleanup target temporary snapshots + zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}/root@bastille_clone_${DATE}" + zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}@bastille_clone_${DATE}" fi - LINE=" ${PROPERTY} = ${VALUE};" else - LINE=" ${PROPERTY};" + # Just clone the jail directory + # Check if container is running + if [ -n "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then + error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'." + fi + + # Perform container file copy(archive mode) + cp -a "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}" fi + else + error_exit "${NEWNAME} already exists." + fi + + # Generate jail configuration files + update_jailconf + update_fstab - # add the value to the config file, replacing any existing value or, if - # there is none, at the end - # - # awk doesn't have "inplace" editing so we use a temp file - _tmpfile=$(mktemp) || error_exit "unable to set because mktemp failed" - cp "${FILE}" "${_tmpfile}" && \ - awk -F= -v line="${LINE}" -v property="${PROPERTY}" ' - BEGIN { - # build RE as string as we can not expand vars in RE literals - prop_re = "^[[:space:]]*" property "[[:space:]]*$"; - } - $1 ~ prop_re && !found { - # we already have an entry in the config for this property so - # we need to substitute our line here rather than keep the - # existing line - print(line); - # note we have already found the property - found = 1; - # move onto the next line - next; - } - $1 == "}" { - # reached the end of the stanza so if we have not already - # added our line we need to do so now - if (! found) { - print(line); - } - } - { - # print each uninteresting line unchanged - print; - } - ' "${_tmpfile}" > "${FILE}" - rm "${_tmpfile}" + # Display the exist status + if [ "$?" -ne 0 ]; then + error_exit "An error has occurred while attempting to clone '${TARGET}'." + else + info "Cloned '${TARGET}' to '${NEWNAME}' successfully." fi -done +} -# Only display this message once at the end (not for every jail). -- cwells -if [ "${ACTION}" = 'set' ]; then - info "A restart is required for the changes to be applied. See 'bastille restart ${TARGET}'." +## don't allow for dots(.) in container names +if echo "${NEWNAME}" | grep -q "[.]"; then + error_exit "Container names may not contain a dot(.)!" fi -exit 0 +clone_jail From 5cbd3b41f0ca9b46208844e6cfe9fa2e7ee5272f Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:42:49 -0700 Subject: [PATCH 007/120] Update cmd.sh --- usr/local/share/bastille/cmd.sh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/usr/local/share/bastille/cmd.sh b/usr/local/share/bastille/cmd.sh index a1f423472..4a5e42065 100644 --- a/usr/local/share/bastille/cmd.sh +++ b/usr/local/share/bastille/cmd.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -36,10 +36,10 @@ usage() { } # Handle special-case commands first. -case "$1" in -help|-h|--help) - usage - ;; +case "${1}" in + help|-h|--help) + usage + ;; esac if [ $# -eq 0 ]; then @@ -51,10 +51,16 @@ bastille_root_check COUNT=0 RETURN=0 +TARGET="${1}" +shift 1 + +set_target "${TARGET}" +check_target_exists "${TARGET}" +check_target_is_running "${TARGET}" + for _jail in ${JAILS}; do COUNT=$(($COUNT+1)) info "[${_jail}]:" - if grep -qw "linsysfs" "${bastille_jailsdir}/${_jail}/fstab"; then # Allow executing commands on Linux jails. jexec -l -u root "${_jail}" "$@" From 8dd5128320c4ee07f59e3c94244fcd77fefc6006 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:43:09 -0700 Subject: [PATCH 008/120] Update common.sh --- usr/local/share/bastille/common.sh | 66 ++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index ed9e5a6ac..009551b74 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -70,19 +70,65 @@ warn() { echo -e "${COLOR_YELLOW}$*${COLOR_RESET}" } -generate_static_mac() { - local jail_name="${1}" - local external_interface="${2}" - local macaddr_prefix="$(ifconfig ${external_interface} | grep ether | awk '{print $2}' | cut -d':' -f1-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/')" - macaddr="${macaddr_prefix}:${macaddr_suffix}" +check_target_exists() { + local _TARGET="${1}" + if [ -d "${bastille_jailsdir}"/"${_TARGET}" ]; then + return 0 + else + error_exit "Jail not found \"${_TARGET}\"" + fi +} + +check_target_is_running() { + local _TARGET="${1}" + if [ ! "$(/usr/sbin/jls name | awk "/^${_TARGET}$/")" ]; then + error_exit "[${_TARGET}]: Not started. See 'bastille start ${_TARGET}'." + fi +} + +check_target_is_stopped() { + local _TARGET="${1}" + if [ "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then + error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'." + fi +} + +set_target() { + if [ "${1}" = ALL ] || [ "${1}" = all ]; then + target_all_jails + else + check_target_exists "${1}" + JAILS="${1}" + export JAILS + fi +} + +set_target_single() { + if [ "${1}" = ALL ] || [ "${1}" = all ]; then + error_exit "[all|ALL] not supported with this command." + else + check_target_exists "${1}" + TARGET="${1}" + export TARGET + fi +} + +target_all_jails() { + local _JAILS=$(/usr/sbin/jls name) + JAILS="" + for _jail in ${_JAILS}; do + _JAILPATH=$(/usr/sbin/jls -j "${_jail}" path) + if [ -z ${_JAILPATH##${bastille_jailsdir}*} ]; then + JAILS="${JAILS} ${_jail}" + fi + export JAILS + done } 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 ## iterate num and grep all jail configs ## define uniq_epair @@ -107,13 +153,11 @@ generate_vnet_jail_netblock() { ## generate bridge config cat <<-EOF vnet; - vnet.interface = e${uniq_epair_bridge}b_${jail_name}; + vnet.interface = "e${uniq_epair_bridge}b_${jail_name}"; 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"; EOF @@ -123,8 +167,6 @@ EOF vnet; vnet.interface = e0b_${uniq_epair}; exec.prestart += "jib addm ${uniq_epair} ${external_interface}"; - exec.prestart += "ifconfig e0a_${uniq_epair} ether ${macaddr}a"; - exec.prestart += "ifconfig e0b_${uniq_epair} ether ${macaddr}b"; exec.prestart += "ifconfig e0a_${uniq_epair} description \"vnet host interface for Bastille jail ${jail_name}\""; exec.poststop += "jib destroy ${uniq_epair}"; EOF From 86f6575e6cb0622424f0aff9d754659b24963d9a Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:43:31 -0700 Subject: [PATCH 009/120] Update config.sh --- usr/local/share/bastille/config.sh | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/usr/local/share/bastille/config.sh b/usr/local/share/bastille/config.sh index c22b6d52e..5fb14e164 100644 --- a/usr/local/share/bastille/config.sh +++ b/usr/local/share/bastille/config.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -51,16 +51,19 @@ help|-h|--help) ;; esac -if [ $# -eq 1 ] || [ $# -gt 3 ]; then +if [ $# -eq 2 ] || [ $# -gt 4 ]; then usage fi bastille_root_check -ACTION=$1 -shift +TARGET="${1}" +ACTION="${2}" +shift 2 + +set_target "${TARGET}" -case $ACTION in +case ${ACTION} in get) if [ $# -ne 1 ]; then error_notify 'Too many parameters for a "get" operation.' @@ -71,7 +74,7 @@ case $ACTION in *) error_exit 'Only get and set are supported.' ;; esac -PROPERTY=$1 +PROPERTY=${1} shift VALUE="$@" From 77cb14aa30b53306ecbedab12b41bab6ca34764c Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:43:46 -0700 Subject: [PATCH 010/120] Update console.sh --- usr/local/share/bastille/console.sh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/usr/local/share/bastille/console.sh b/usr/local/share/bastille/console.sh index b15865cc9..f272ebf24 100644 --- a/usr/local/share/bastille/console.sh +++ b/usr/local/share/bastille/console.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -37,18 +37,23 @@ usage() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; -esac + help|-h|--help) + usage + ;; + esac -if [ $# -gt 1 ]; then +if [ $# -gt 2 ]; then usage fi bastille_root_check -USER="${1}" +TARGET="${1}" +USER="${2}" + +set_target_single "${TARGET}" +check_target_exists "${TARGET}" +check_target_is_running "${TARGET}" validate_user() { if jexec -l "${_jail}" id "${USER}" >/dev/null 2>&1; then @@ -82,7 +87,6 @@ for _jail in ${JAILS}; do if [ -n "${USER}" ]; then validate_user else - check_fib LOGIN="$(jexec -l "${_jail}" which login)" ${_setfib} jexec -l "${_jail}" $LOGIN -f root fi From ff00e70ce1b2d5ee2f8bc0865333ca15e17d9605 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:44:04 -0700 Subject: [PATCH 011/120] Update convert.sh --- usr/local/share/bastille/convert.sh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh index 0290f3553..e21ea72b2 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -37,17 +37,23 @@ usage() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac -if [ $# -ne 0 ]; then +if [ $# -ne 1 ]; then usage fi bastille_root_check +TARGET="${1}" + +set_target_single "${TARGET}" +check_target_exists "${TARGET}" +check_target_is_stopped "${TARGET}" + convert_symlinks() { # Work with the symlinks, revert on first cp error if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then @@ -114,7 +120,7 @@ start_convert() { HASPORTS=$(grep -w ${bastille_releasesdir}/${RELEASE}/usr/ports ${bastille_jailsdir}/${TARGET}/fstab) if [ -n "${RELEASE}" ]; then - cd "${bastille_jailsdir}/${TARGET}/root" || error_exit "Failed to change directory to ${bastille_jailsdir}/${TARGET}/root" + cd "${bastille_jailsdir}/${TARGET}/root" # Work with the symlinks convert_symlinks @@ -149,8 +155,6 @@ fi # Be interactive here since this cannot be easily undone while :; do error_notify "Warning: container conversion from thin to thick can't be undone!" - # shellcheck disable=SC2162 - # shellcheck disable=SC3045 read -p "Do you really wish to convert '${TARGET}' into a thick container? [y/N]:" yn case ${yn} in [Yy]) start_convert;; From 35d138dfb3dd4b31c8509e82ce806c5894865e2b Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:44:18 -0700 Subject: [PATCH 012/120] Update cp.sh --- usr/local/share/bastille/cp.sh | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index 0d027f7d2..978c7c59c 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -35,34 +35,30 @@ usage() { error_exit "Usage: bastille cp [OPTION] TARGET HOST_PATH CONTAINER_PATH" } -CPSOURCE="${1}" -CPDEST="${2}" - # Handle special-case commands first. -case "$1" in -help|-h|--help) - usage - ;; --q|--quiet) - OPTION="${1}" - CPSOURCE="${2}" - CPDEST="${3}" - ;; +case "${1}" in + help|-h|--help) + usage + ;; esac if [ $# -ne 2 ]; then usage fi +TARGET="${1}" +CPSOURCE="${2}" +CPDEST="${3}" +OPTION="-av" + bastille_root_check +set_target_single "${TARGET}" +check_target_exists "${TARGET}" -case "${OPTION}" in +case "$@" in -q|--quiet) OPTION="-a" ;; - *) - OPTION="-av" - ;; esac for _jail in ${JAILS}; do From 0d4b8be91840be1037716f2151432541bbf7a924 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:44:34 -0700 Subject: [PATCH 013/120] Update create.sh --- usr/local/share/bastille/create.sh | 41 ++++++------------------------ 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index f0a1250fe..c26285c0a 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -60,7 +60,7 @@ running_jail() { validate_name() { local NAME_VERIFY=${NAME} - local NAME_SANITY="$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')" + local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_') if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then error_exit "Container names may not begin with (-|_) characters!" elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then @@ -123,7 +123,7 @@ validate_ips() { } validate_netif() { - local LIST_INTERFACES="$(ifconfig -l)" + local LIST_INTERFACES=$(ifconfig -l) if echo "${LIST_INTERFACES} VNET" | grep -qwo "${INTERFACE}"; then info "Valid: (${INTERFACE})." else @@ -165,15 +165,10 @@ EOF } generate_jail_conf() { - if [ "$(sysctl -n security.jail.jailed)" -eq 1 ]; then - devfs_ruleset_value=0 - else - devfs_ruleset_value=4 - fi cat << EOF > "${bastille_jail_conf}" ${NAME} { + devfs_ruleset = 4; enforce_statfs = 2; - devfs_ruleset = ${devfs_ruleset_value}; exec.clean; exec.consolelog = ${bastille_jail_log}; exec.start = '/bin/sh /etc/rc'; @@ -194,17 +189,12 @@ EOF } generate_linux_jail_conf() { - if [ "$(sysctl -n security.jail.jailed)" -eq 1 ]; then - devfs_ruleset_value=0 - else - devfs_ruleset_value=4 - fi cat << EOF > "${bastille_jail_conf}" ${NAME} { host.hostname = ${NAME}; mount.fstab = ${bastille_jail_fstab}; path = ${bastille_jail_path}; - devfs_ruleset = ${devfs_ruleset_value}; + devfs_ruleset = 4; enforce_statfs = 1; exec.start = '/bin/true'; @@ -222,16 +212,11 @@ EOF } generate_vnet_jail_conf() { - if [ "$(sysctl -n security.jail.jailed)" -eq 1 ]; then - devfs_ruleset_value=0 - else - devfs_ruleset_value=13 - fi NETBLOCK=$(generate_vnet_jail_netblock "$NAME" "${VNET_JAIL_BRIDGE}" "${bastille_jail_conf_interface}") cat << EOF > "${bastille_jail_conf}" ${NAME} { + devfs_ruleset = 13; enforce_statfs = 2; - devfs_ruleset = ${devfs_ruleset_value}; exec.clean; exec.consolelog = ${bastille_jail_log}; exec.start = '/bin/sh /etc/rc'; @@ -253,7 +238,7 @@ post_create_jail() { # Using relative paths here. # MAKE SURE WE'RE IN THE RIGHT PLACE. - cd "${bastille_jail_path}" || error_exit "Failed to change directory." + cd "${bastille_jail_path}" echo if [ ! -f "${bastille_jail_conf}" ]; then @@ -292,9 +277,7 @@ create_jail() { bastille_jail_fstab="${bastille_jailsdir}/${NAME}/fstab" ## file bastille_jail_conf="${bastille_jailsdir}/${NAME}/jail.conf" ## file bastille_jail_log="${bastille_logsdir}/${NAME}_console.log" ## file - # shellcheck disable=SC2034 bastille_jail_rc_conf="${bastille_jailsdir}/${NAME}/root/etc/rc.conf" ## file - # shellcheck disable=SC2034 bastille_jail_resolv_conf="${bastille_jailsdir}/${NAME}/root/etc/resolv.conf" ## file if [ ! -d "${bastille_jailsdir}/${NAME}" ]; then @@ -411,10 +394,8 @@ create_jail() { info "Creating a clonejail...\n" ## clone the release base to the new basejail SNAP_NAME="bastille-clone-$(date +%Y-%m-%d-%H%M%S)" - # shellcheck disable=SC2140 zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" - # shellcheck disable=SC2140 zfs clone -p "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" \ "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" @@ -429,20 +410,16 @@ create_jail() { ## take a temp snapshot of the base release SNAP_NAME="bastille-$(date +%Y-%m-%d-%H%M%S)" - # shellcheck disable=SC2140 zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" ## replicate the release base to the new thickjail and set the default mountpoint - # shellcheck disable=SC2140 zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" | \ zfs receive "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" zfs set ${ZFS_OPTIONS} mountpoint=none "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" zfs inherit mountpoint "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" ## cleanup temp snapshots initially - # shellcheck disable=SC2140 zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" - # shellcheck disable=SC2140 zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"@"${SNAP_NAME}" fi @@ -616,9 +593,7 @@ esac bastille_root_check if echo "$3" | grep '@'; then - # shellcheck disable=SC2034 BASTILLE_JAIL_IP=$(echo "$3" | awk -F@ '{print $2}') - # shellcheck disable=SC2034 BASTILLE_JAIL_INTERFACES=$( echo "$3" | awk -F@ '{print $1}') fi @@ -701,7 +676,7 @@ while [ $# -gt 0 ]; do VNET_JAIL_BRIDGE="1" shift ;; - --*|-*) + -*|--*) error_notify "Unknown Option." usage ;; From 70e8ec20f5e99c9268cc478c2f51569ca377b7b3 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:44:47 -0700 Subject: [PATCH 014/120] Update destroy.sh --- usr/local/share/bastille/destroy.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index 9bdb60574..5e3a95dc8 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -37,9 +37,10 @@ usage() { destroy_jail() { local OPTIONS + check_target_exists "${TARGET}" bastille_jail_base="${bastille_jailsdir}/${TARGET}" ## dir bastille_jail_log="${bastille_logsdir}/${TARGET}_console.log" ## file - + if [ "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then if [ "${FORCE}" = "1" ]; then bastille stop "${TARGET}" @@ -172,7 +173,7 @@ destroy_rel() { if [ "${FORCE}" = "1" ]; then ## remove cache on force if [ -d "${bastille_cachedir}/${TARGET}" ]; then - rm -rf "${bastille_cachedir:?}/${TARGET}" + rm -rf "${bastille_cachedir}/${TARGET}" fi fi echo From 4b735c041a2fae417ede1ed923695d07ef919c1c Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:45:02 -0700 Subject: [PATCH 015/120] Update edit.sh --- usr/local/share/bastille/edit.sh | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/usr/local/share/bastille/edit.sh b/usr/local/share/bastille/edit.sh index 79677e5b9..e81354eae 100644 --- a/usr/local/share/bastille/edit.sh +++ b/usr/local/share/bastille/edit.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -37,28 +37,29 @@ usage() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac -if [ $# -gt 1 ]; then +if [ $# -gt 2 ]; then usage -elif [ $# -eq 1 ]; then - TARGET_FILENAME="${1}" +elif [ $# -eq 2 ]; then + TARGET_FILENAME="${2}" +else + TARGET_FILENAME="jail.conf" fi +TARGET="${1}" + +set_target_single "${TARGET}" +check_target_exists "${TARGET}" +check_target_is_running "${TARGET}" + bastille_root_check if [ -z "${EDITOR}" ]; then - # shellcheck disable=SC2209 EDITOR=vi fi -for _jail in ${JAILS}; do - if [ -n "${TARGET_FILENAME}" ]; then - "${EDITOR}" "${bastille_jailsdir}/${_jail}/${TARGET_FILENAME}" - else - "${EDITOR}" "${bastille_jailsdir}/${_jail}/jail.conf" - fi -done +"${EDITOR}" "${bastille_jailsdir}/${_jail}/${TARGET_FILENAME}" From 572f3d02f056ecefaa3e9b0b7e70e50475d848df Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:45:45 -0700 Subject: [PATCH 016/120] Create etcupdate.sh --- usr/local/share/bastille/etcupdate.sh | 109 ++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 usr/local/share/bastille/etcupdate.sh diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh new file mode 100644 index 000000000..eec31bbee --- /dev/null +++ b/usr/local/share/bastille/etcupdate.sh @@ -0,0 +1,109 @@ +#!/bin/sh +# +# Copyright (c) 2018-2024, 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_exit "Usage: bastille etcupdate [option(s)] [update TARGET|bootstrap] RELEASE" + + cat << EOF + Options: + + -d | --dry-run | -- Only show output of what etcupdate will do. + +EOF + exit 1 +} + +# Handle special-case commands first. +case "$1" in + help|-h|--help) + usage + ;; + esac + +bastille_root_check + +bootstrap_etc_release() { + local _release="${1}" + local _release_version=$( echo "${1}" | awk -F "-" '{print $1}' ) + if [ ! -d /usr/local/bastille/source/"${_release}" ]; then + if ! git clone --branch releng/"${_release_version}" --depth 1 https://git.FreeBSD.org/src.git /usr/local/bastille/source/"${_release}" 2>/dev/null; then + error_exit "Failed to bootstrap etcupdate release \"${_release}\"" + fi + fi +} + +bootstrap_etc_tarball() { + local _release="${1}" + if [ ! -f /usr/local/bastille/source/"${_release}".tbz2 ]; then + if ! etcupdate build -d /tmp/etcupdate -s /usr/local/bastille/releases/"${_release}" "${_release}".tbz2; then + error_exit "Failed to build etcupdate tarball \"${_release}.tbz2\"" + fi + else + info "\"${_release}\" has already been bootstrapped." + fi +} + +update_jail_etc() { + local _jail="${1}" + local _release="${2}" + if [ "${DRY_RUN}" -eq 1 ]; then + info "[_jail]: --dry-run" + etcupdate -n -D "${bastille_jailsdir}"/"${_jail}"/root -t /usr/local/bastille/source/"${_release}".tbz2 + else + info "[_jail]:" + etcupdate -D "${bastille_jailsdir}"/"${_jail}"/root -t /usr/local/bastille/source/"${_release}".tbz2 + fi +} + +DRY_RUN=0 + +while [ $# -gt 0 ]; do + case "${1}" in + -d|--dry-run) + DRY_RUN=1 + shift 1 + ;; + bootstrap) + bootstrap_etc_release "${2}" + bootstrap_etc_tarball "${2}" + shift $# + ;; + update) + update_jail_etc "${2}" "${3}" + shift $# + ;; + *) + usage + ;; + esac +done From bf8aaf78d9ec0472cd87d79b1e3cf699a9e79204 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:45:57 -0700 Subject: [PATCH 017/120] Update export.sh --- usr/local/share/bastille/export.sh | 46 ++++++++++++------------------ 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index 123db04ba..423cc7e94 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -57,30 +57,17 @@ EOF # Handle special-case commands first case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac -# Check for unsupported actions -if [ "${TARGET}" = "ALL" ]; then - error_exit "Batch export is unsupported." -fi - if [ $# -gt 5 ] || [ $# -lt 1 ]; then usage fi bastille_root_check -zfs_enable_check() { - # Temporarily disable ZFS so we can create a standard backup archive - if checkyesno bastille_zfs_enable; then - # shellcheck disable=SC2034 - bastille_zfs_enable="NO" - fi -} - TARGET="${1}" GZIP_EXPORT= XZ_EXPORT= @@ -93,6 +80,16 @@ TGZ_EXPORT= OPT_ZSEND="-R" COMP_OPTION="0" +set_target_single "${TARGET}" +check_target_exists "${TARGET}" + +zfs_enable_check() { + # Temporarily disable ZFS so we can create a standard backup archive + if checkyesno bastille_zfs_enable; then + bastille_zfs_enable="NO" + fi +} + opt_count() { COMP_OPTION=$(expr ${COMP_OPTION} + 1) } @@ -136,7 +133,7 @@ if [ -n "${bastille_export_options}" ]; then --verbose) OPT_ZSEND="-Rv" shift;; - --*|-*) error_notify "Unknown Option." + -*|--*) error_notify "Unknown Option." usage;; esac done @@ -186,7 +183,7 @@ else TARGET="${2}" shift ;; - --*|-*) + -*|--*) error_notify "Unknown Option." usage ;; @@ -209,16 +206,12 @@ if [ "${COMP_OPTION}" -gt "1" ]; then error_exit "Error: Only one compression format can be used during export." fi -if { [ -n "${TXZ_EXPORT}" ] || [ -n "${TGZ_EXPORT}" ]; } && [ -n "${SAFE_EXPORT}" ]; then +if [ -n "${TXZ_EXPORT}" -o -n "${TGZ_EXPORT}" ] && [ -n "${SAFE_EXPORT}" ]; then error_exit "Error: Simple archive modes with safe ZFS export can't be used together." fi if ! checkyesno bastille_zfs_enable; then - if [ -n "${XZ_EXPORT}" ] || - [ -n "${GZIP_EXPORT}" ] || - [ -n "${RAW_EXPORT}" ] || - [ -n "${SAFE_EXPORT}" ] || - [ "${OPT_ZSEND}" = "-Rv" ]; then + if [ -n "${XZ_EXPORT}" -o -n "${GZIP_EXPORT}" -o -n "${RAW_EXPORT}" -o -n "${SAFE_EXPORT}" -o "${OPT_ZSEND}" = "-Rv" ]; then error_exit "Options --xz, --gz, --raw, --safe, --verbose are valid for ZFS configured systems only." fi fi @@ -275,7 +268,7 @@ export_check() { EXPORT_AS="Exporting" fi - if [ "${FILE_EXT}" = ".xz" ] || [ "${FILE_EXT}" = ".gz" ] || [ "${FILE_EXT}" = "" ]; then + if [ "${FILE_EXT}" = ".xz" -o "${FILE_EXT}" = ".gz" -o "${FILE_EXT}" = "" ]; then EXPORT_TYPE="image" else EXPORT_TYPE="archive" @@ -365,13 +358,12 @@ jail_export() { fi fi - # shellcheck disable=SC2181 if [ "$?" -ne 0 ]; then error_exit "Failed to export '${TARGET}' container." else if [ -z "${USER_EXPORT}" ]; then # Generate container checksum file - cd "${bastille_backupsdir}" || error_exit "Failed to change directory." + cd "${bastille_backupsdir}" sha256 -q "${TARGET}_${DATE}${FILE_EXT}" > "${TARGET}_${DATE}.sha256" info "Exported '${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}' successfully." fi From 5bc2c447b6a5dfff59e0906dbbdaf6bd25e0a25f Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:46:21 -0700 Subject: [PATCH 018/120] Update htop.sh --- usr/local/share/bastille/htop.sh | 33 +++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh index de82387b3..869b93219 100644 --- a/usr/local/share/bastille/htop.sh +++ b/usr/local/share/bastille/htop.sh @@ -36,25 +36,28 @@ usage() { } # Handle special-case commands first. -case "$1" in -help|-h|--help) - usage - ;; +case "${1}" in + help|-h|--help) + usage + ;; esac -if [ $# -ne 0 ]; then +if [ $# -ne 1 ]; then usage fi +TARGET="${1}" + bastille_root_check +set_target_single "${TARGET}" +check_target_exists "${TARGET}" +check_target_is_running "${TARGET}" -for _jail in ${JAILS}; do - bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path) - if [ ! -x "${bastille_jail_path}/usr/local/bin/htop" ]; then - error_notify "htop not found on ${_jail}." - elif [ -x "${bastille_jail_path}/usr/local/bin/htop" ]; then - info "[${_jail}]:" - jexec -l ${_jail} /usr/local/bin/htop - fi - echo -e "${COLOR_RESET}" -done +bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path) +if [ ! -x "${bastille_jail_path}/usr/local/bin/htop" ]; then + error_notify "htop not found on ${_jail}." +elif [ -x "${bastille_jail_path}/usr/local/bin/htop" ]; then + info "[${_jail}]:" + jexec -l ${_jail} /usr/local/bin/htop +fi +echo -e "${COLOR_RESET}" From 1e2936d1ea5cb5c847dbacf60d62583606bb25d7 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:46:35 -0700 Subject: [PATCH 019/120] Update import.sh --- usr/local/share/bastille/import.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/usr/local/share/bastille/import.sh b/usr/local/share/bastille/import.sh index 34cda5fc0..69b23055d 100644 --- a/usr/local/share/bastille/import.sh +++ b/usr/local/share/bastille/import.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -50,22 +50,22 @@ EOF # Handle special-case commands first case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac if [ $# -gt 3 ] || [ $# -lt 1 ]; then usage fi -bastille_root_check - TARGET="${1}" OPT_FORCE= USER_IMPORT= OPT_ZRECV="-u" +bastille_root_check + # Handle and parse option args while [ $# -gt 0 ]; do case "${1}" in @@ -79,7 +79,7 @@ while [ $# -gt 0 ]; do TARGET="${2}" shift ;; - --*|-*) + -*|--*) error_notify "Unknown Option." usage ;; @@ -281,7 +281,7 @@ EOF >> "${bastille_jailsdir}/${TARGET_TRIM}/fstab" # Work with the symlinks - cd "${bastille_jailsdir}/${TARGET_TRIM}/root" || error_exit "Failed to change directory." + cd "${bastille_jailsdir}/${TARGET_TRIM}/root" update_symlinks else # Generate new empty fstab file @@ -324,7 +324,7 @@ update_config() { >> "${bastille_jailsdir}/${TARGET_TRIM}/fstab" # Work with the symlinks - cd "${bastille_jailsdir}/${TARGET_TRIM}/root" || error_exit "Failed to change directory." + cd "${bastille_jailsdir}/${TARGET_TRIM}/root" update_symlinks } @@ -377,7 +377,7 @@ update_symlinks() { for _link in ${SYMLINKS}; do if [ -L "${_link}" ]; then ln -sf /.bastille/${_link} ${_link} - elif [ "${ALLOW_EMPTY_DIRS_TO_BE_SYMLINKED:-0}" = "1" ] && [ -d "${_link}" ]; then + elif [ "${ALLOW_EMPTY_DIRS_TO_BE_SYMLINKED:-0}" = "1" -a -d "${_link}" ]; then # -F will enforce that the directory is empty and replaced by the symlink ln -sfF /.bastille/${_link} ${_link} || EXIT_CODE=$? if [ "${EXIT_CODE:-0}" != "0" ]; then From 736e070da803dfa251d9f368fc1b2fe6ebd707f5 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:46:48 -0700 Subject: [PATCH 020/120] Update limits.sh --- usr/local/share/bastille/limits.sh | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/usr/local/share/bastille/limits.sh b/usr/local/share/bastille/limits.sh index 29f631a17..9da7725db 100644 --- a/usr/local/share/bastille/limits.sh +++ b/usr/local/share/bastille/limits.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # Ressource limits added by Sven R github.com/hackacad # @@ -40,25 +40,29 @@ usage() { RACCT_ENABLE=$(sysctl -n kern.racct.enable) if [ "${RACCT_ENABLE}" != '1' ]; then - echo "Racct not enabled. Append 'kern.racct.enable=1' to /boot/loader.conf and reboot" -# exit 1 + error_exit "Racct not enabled. Append 'kern.racct.enable=1' to /boot/loader.conf and reboot" fi # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac -if [ $# -ne 2 ]; then +if [ $# -ne 3 ]; then usage fi -bastille_root_check +TARGET="${1}" +OPTION="${2}" +VALUE="${3}" -OPTION="${1}" -VALUE="${2}" + +bastille_root_check +set_target "${TARGET}" +check_target_exists "${TARGET}" +check_target_is_running "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" From f992c188cc6685b0fa1160c3682d3603e639c9fd Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:47:05 -0700 Subject: [PATCH 021/120] Update list.sh --- usr/local/share/bastille/list.sh | 55 ++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index dee2b391b..20ba42056 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -35,17 +35,18 @@ usage() { error_exit "Usage: bastille list [-j|-a] [release [-p]|template|(jail|container)|log|limit|(import|export|backup)]" } -if [ "${1}" = help ] || [ "${1}" = "-h" ] || [ "${1}" = "--help" ]; then - usage -fi - -bastille_root_check +# Handle special-case commands first. +case "$1" in + help|-h|--help) + usage + ;; +esac if [ $# -eq 0 ]; then /usr/sbin/jls fi -if [ "${1}" = "-j" ]; then +if [ "${1}" == "-j" ]; then /usr/sbin/jls -N --libxo json exit 0 fi @@ -61,7 +62,7 @@ list_all(){ if [ "${MAX_LENGTH_JAIL_NAME}" -lt 3 ]; then MAX_LENGTH_JAIL_NAME=3; fi 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) + 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 @@ -72,11 +73,11 @@ 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) + 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=$(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) + 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 @@ -93,7 +94,7 @@ list_all(){ if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then JAIL_NAME=$(grep -h -m 1 -e "^.* {$" "${bastille_jailsdir}/${_JAIL}/jail.conf" 2> /dev/null | awk '{ print $1 }') IS_FREEBSD_JAIL=0 - if [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/bin/freebsd-version" ] || [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/.bastille/bin/freebsd-version" ] || [ "$(grep -c "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_FREEBSD_JAIL=1; fi + if [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/bin/freebsd-version" -o -f "${bastille_jailsdir}/${JAIL_NAME}/root/.bastille/bin/freebsd-version" -o "$(grep -c "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_FREEBSD_JAIL=1; fi IS_FREEBSD_JAIL=${IS_FREEBSD_JAIL:-0} IS_LINUX_JAIL=0 if [ "$(grep -c "^linprocfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_LINUX_JAIL=1; fi @@ -117,7 +118,7 @@ list_all(){ JAIL_RELEASE=$(grep -hE "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }') fi else - JAIL_STATE=$(if [ "$(sed -n "/^${JAIL_NAME} {$/,/^}$/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | awk '$0 ~ /^'${JAIL_NAME}' \{|\}/ { printf "%s",$0 }')" = "${JAIL_NAME} {}" ]; then echo "Down"; else echo "n/a"; fi) + JAIL_STATE=$(if [ "$(sed -n "/^${JAIL_NAME} {$/,/^}$/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | awk '$0 ~ /^'${JAIL_NAME}' \{|\}/ { printf "%s",$0 }')" == "${JAIL_NAME} {}" ]; then echo "Down"; else echo "n/a"; fi) if [ "$(awk '$1 == "vnet;" { print $1 }' "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)" ]; then JAIL_IP=$(sed -n 's/^ifconfig_vnet0="\(.*\)"$/\1/p' "${bastille_jailsdir}/${JAIL_NAME}/root/etc/rc.conf" 2> /dev/null | sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print $2; else print $1 }') else @@ -131,7 +132,7 @@ list_all(){ if [ -f "${JAIL_PATH}/bin/freebsd-version" ]; then JAIL_RELEASE=$(grep -hE "^USERLAND_VERSION=" "${JAIL_PATH}/bin/freebsd-version" 2> /dev/null | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") else - JAIL_RELEASE=$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | 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") + JAIL_RELEASE=$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | 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") fi fi if [ "${IS_LINUX_JAIL}" -eq 1 ]; then @@ -158,16 +159,12 @@ list_all(){ fi } -# TODO: Check the correct usage or arguments here. See SC2120. -# shellcheck disable=SC2120 list_release(){ if [ -d "${bastille_releasesdir}" ]; then - # TODO: Check if this can be changed to `find` as SC2012 suggests. - # shellcheck disable=SC2012 - REL_LIST="$(ls "${bastille_releasesdir}" | sed "s/\n//g")" + REL_LIST=$(ls "${bastille_releasesdir}" | sed "s/\n//g") for _REL in ${REL_LIST}; do - if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" ] || [ -d "${bastille_releasesdir}/${_REL}/debootstrap" ]; then - if [ "${1}" = "-p" ] && [ -f "${bastille_releasesdir}/${_REL}/bin/freebsd-version" ]; then + if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" -o -d "${bastille_releasesdir}/${_REL}/debootstrap" ]; then + if [ "${1}" == "-p" -a -f "${bastille_releasesdir}/${_REL}/bin/freebsd-version" ]; then REL_PATCH_LEVEL=$(sed -n "s/^USERLAND_VERSION=\"\(.*\)\"$/\1/p" "${bastille_releasesdir}/${_REL}/bin/freebsd-version" 2> /dev/null) REL_PATCH_LEVEL=${REL_PATCH_LEVEL:-${_REL}} echo "${REL_PATCH_LEVEL}" @@ -203,16 +200,32 @@ list_limit(){ } list_import(){ - # shellcheck disable=SC2010 ls "${bastille_backupsdir}" | grep -v ".sha256$" } +list_ports() { + if [ -d "${bastille_jailsdir}" ]; then + JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") + for _JAIL in ${JAIL_LIST}; do + if [ -f "${bastille_jailsdir}/${_JAIL}/rdr.conf" ]; then + _PORTS=$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf) + #_PORTS=$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf | awk '{print $1" "$2":"$5"//"$3":"$6" -> "$4":"$7}') + info "[$_JAIL]:" + echo "${_PORTS}" + fi + done + fi +} + if [ $# -gt 0 ]; then # Handle special-case commands first. case "${1}" in all|-a|--all) list_all ;; + port|ports) + list_ports + ;; release|releases) list_release "${2}" ;; From 897bd263919da14e609e61003449bc54279644e9 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:47:29 -0700 Subject: [PATCH 022/120] Update mount.sh --- usr/local/share/bastille/mount.sh | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index bb0e66154..36025ccd8 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -37,20 +37,24 @@ usage() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac -if [ $# -lt 2 ]; then +if [ $# -lt 3 ]; then usage -elif [ $# -eq 2 ]; then +elif [ $# -eq 3 ]; then _fstab="$@ nullfs ro 0 0" else _fstab="$@" fi +TARGET="${1}" + bastille_root_check +set_target "${TARGET}" +check_target_exists "${TARGET}" ## assign needed variables _hostpath=$(echo "${_fstab}" | awk '{print $1}') @@ -67,13 +71,8 @@ if [ -z "${_hostpath}" ] || [ -z "${_jailpath}" ] || [ -z "${_type}" ] || [ -z " exit 1 fi -# if host path doesn't exist, type is not "nullfs" or are using advanced mount type "tmpfs,linprocfs,linsysfs, fdescfs, -# procfs" -if { [ "${_hostpath}" = "tmpfs" ] && [ "$_type" = "tmpfs" ]; } || \ - { [ "${_hostpath}" = "linprocfs" ] && [ "${_type}" = "linprocfs" ]; } || \ - { [ "${_hostpath}" = "linsysfs" ] && [ "${_type}" = "linsysfs" ]; } || \ - { [ "${_hostpath}" = "proc" ] && [ "${_type}" = "procfs" ]; } || \ - { [ "${_hostpath}" = "fdesc" ] && [ "${_type}" = "fdescfs" ]; } then +## if host path doesn't exist, type is not "nullfs" or are using advanced mount type "tmpfs,linprocfs,linsysfs, fdescfs, procfs" +if [ "${_hostpath}" == "tmpfs" -a "$_type" == "tmpfs" ] || [ "${_hostpath}" == "linprocfs" -a "${_type}" == "linprocfs" ] || [ "${_hostpath}" == "linsysfs" -a "${_type}" == "linsysfs" ] || [ "${_hostpath}" == "proc" -a "${_type}" == "procfs" ] || [ "${_hostpath}" == "fdesc" -a "${_type}" == "fdescfs" ] ; then warn "Detected advanced mount type ${_hostpath}" elif [ ! -d "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then error_notify "Detected invalid host path or incorrect mount type in FSTAB." From a66f5255c41af943cd9983ab14507991a47271c3 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:47:41 -0700 Subject: [PATCH 023/120] Update pkg.sh --- usr/local/share/bastille/pkg.sh | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/usr/local/share/bastille/pkg.sh b/usr/local/share/bastille/pkg.sh index 4e537a4d8..3a102f8e2 100644 --- a/usr/local/share/bastille/pkg.sh +++ b/usr/local/share/bastille/pkg.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -36,16 +36,38 @@ usage() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac -if [ $# -lt 1 ]; then +if [ $# -lt 2 ]; then usage fi +TARGET="${1}" + +while [ $# -gt 0 ]; do + case "${1}" in + -H|--host) + USE_HOST_PKG=1 + TARGET="${2}" + shift + ;; + -*|--*) + error_notify ""Unknown option." + usage + ;; + *) + break + ;; + case +done + bastille_root_check +set_target "${TARGET}" +check_target_exists "${TARGET}" +check_target_is_running "${TARGET}" errors=0 From a40e861a0f2a068c15b3ced9adb2d4d73945a95d Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:47:57 -0700 Subject: [PATCH 024/120] Update rcp.sh --- usr/local/share/bastille/rcp.sh | 36 ++++++++++++++------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh index fe3d48db9..8f9e16767 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2022, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -35,36 +35,30 @@ usage() { error_exit "Usage: bastille rcp [OPTION] TARGET CONTAINER_PATH HOST_PATH" } -CPSOURCE="${1}" -CPDEST="${2}" - # Handle special-case commands first. -case "$1" in -help|-h|--help) - usage - ;; --q|--quiet) - OPTION="${1}" - CPSOURCE="${2}" - CPDEST="${3}" - ;; +case "${1}" in + help|-h|--help) + usage + ;; esac -if [ $# -ne 2 ]; then +if [ $# -lt 3 ]; then usage fi -if [ "${TARGET}" = "ALL" ]; then - usage -fi +TARGET="${1}" +CPSOURCE="${2}" +CPDEST="${3}" +OPTION="-av" + +bastille_root_check +set_target_single "${TARGET}" +check_target_exists "${TARGET}" -case "${OPTION}" in +case "$@" in -q|--quiet) OPTION="-a" ;; - *) - OPTION="-av" - ;; esac for _jail in ${JAILS}; do From 58ca2af840b06d443296c257121686af8ebed37c Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:48:09 -0700 Subject: [PATCH 025/120] Update rdr.sh --- usr/local/share/bastille/rdr.sh | 293 ++++++++++++++++++++++++++------ 1 file changed, 240 insertions(+), 53 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 63df78394..45a2cf605 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -32,14 +32,25 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille rdr TARGET [clear|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )]" + error_notify "Usage: bastille rdr TARGET [option(s)] [clear|reset|list|(tcp|udp)] host_port jail_port [log ['(' logopts ')'] ] )]" + + cat << EOF + Options: + + -i | --interface [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. + -s | --source [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. + -d | --destination [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + -t | --type [ipv4|ipv6] | -- Specify IP type. Must be used if -s or -d are used. Defaults to both. + +EOF + exit 1 } # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac if [ $# -lt 2 ]; then @@ -52,7 +63,6 @@ TARGET="${1}" JAIL_NAME="" JAIL_IP="" JAIL_IP6="" -EXT_IF="" shift check_jail_validity() { @@ -74,6 +84,7 @@ check_jail_validity() { error_exit "Jail IP not found: ${TARGET}" fi fi + # Check if jail ip6 address (ip6.addr) is valid (non-VNET only) if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then if [ "$(bastille config $TARGET get ip6)" != 'disable' ] && [ "$(bastille config $TARGET get ip6)" != 'not set' ]; then @@ -81,70 +92,198 @@ check_jail_validity() { fi fi - # Check if rdr-anchor is defined in pf.conf if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then error_exit "rdr-anchor not found in pf.conf" fi +} - # Check if ext_if is defined in pf.conf - if [ -n "${bastille_pf_conf}" ]; then - EXT_IF=$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf}) - if [ -z "${EXT_IF}" ]; then - error_exit "bastille_network_pf_ext_if (${bastille_network_pf_ext_if}) not defined in pf.conf" +# function: check if IP is valid +check_rdr_ip_validity() { + local ip="$1" + local ip6=$(echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)') + if [ -n "${ip6}" ]; then + info "Valid: (${ip6})." + else + local IFS + if echo "${ip}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then + TEST_IP=$(echo "${ip}" | cut -d / -f1) + IFS=. + set ${TEST_IP} + for quad in 1 2 3 4; do + if eval [ \$$quad -gt 255 ]; then + error_exit "Invalid: (${TEST_IP})" + fi + done + info "Valid: (${ip})." + else + error_exit "Invalid: (${ip})." fi fi } # function: write rule to rdr.conf persist_rdr_rule() { -if ! grep -qs "$1 $2 $3" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$1 $2 $3" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" -fi + local inet="${1}" + local if="${2}" + local src="${3}" + local dst="${4}" + local proto="${5}" + local host_port="${6}" + local jail_port="${7}" + if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then + echo "$inet $if $src $dst $proto $host_port $jail_port" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" + fi } persist_rdr_log_rule() { -proto=$1;host_port=$2;jail_port=$3; -shift 3; -log=$@; -if ! grep -qs "$proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" -fi + local inet="${1}" + local if="${2}" + local src="${3}" + local dst="${4}" + local proto="${5}" + local host_port="${6}" + local jail_port="${7}" + shift 7; + log=$@; + if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then + echo "$inet $if $src $dst $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" + fi } - # function: load rdr rule via pfctl load_rdr_rule() { -( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; - printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$2" "$JAIL_IP" "$3" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f- -if [ -n "$JAIL_IP6" ]; then - ( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; - printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$2" "$JAIL_IP6" "$3" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f- -fi + local inet="${1}" + local if_name="${2}" + local if=ext_if=\"${2}\" + local src="${3}" + local dst="${4}" + local proto="${5}" + local host_port="${6}" + local jail_port="${7}" + # Create IPv4 rdr rule + if [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; then + if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; + printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_exit "Failed to create IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + else + info "[${JAIL_NAME}]:" + echo "IPv4 ${proto}/${host_port}:${jail_port} on ${if_name}" + fi + fi + # Create IPv6 rdr rule (if ip6.addr is enabled) + if [ -n "$JAIL_IP6" ] && [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; then + if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + printf '%s\nrdr pass on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_exit "Failed to create IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + else + info "[${JAIL_NAME}]:" + echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + fi + fi } # function: load rdr rule with log via pfctl load_rdr_log_rule() { -proto=$1;host_port=$2;jail_port=$3; -shift 3; -log=$@ -( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; - printf '%s\nrdr pass %s on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "$log" "${bastille_network_pf_ext_if}" "$proto" "$host_port" "$JAIL_IP" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f- -if [ -n "$JAIL_IP6" ]; then - ( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; - printf '%s\nrdr pass %s on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "$log" "${bastille_network_pf_ext_if}" "$proto" "$host_port" "$JAIL_IP6" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f- -fi - + local inet="${1}" + local if_name="${2}" + local if=ext_if=\"${2}\" + local src="${3}" + local dst="${4}" + local proto="${5}" + local host_port="${6}" + local jail_port="${7}" + shift 7; + log=$@ + # Create IPv4 rule with log + if [ "${inet} = "ipv4" ] || [ "${inet} = "dual" ]; then + if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_exit "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + else + info "[${JAIL_NAME}]:" + echo "IPv4 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + fi + fi + # Create IPv6 rdr rule with log (if ip6.addr is enabled) + if [ -n "$JAIL_IP6" ] && [ "${inet} = "ipv6" ] || [ "${inet} = "dual" ]; then + if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + printf '%s\nrdr pass %s on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_exit "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + else + info "[${JAIL_NAME}]:" + echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + fi + fi } -while [ $# -gt 0 ]; do +# Set defaults +RDR_IF="$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf} | awk -F'"' '{print $2}')" +RDR_SRC="any" +RDR_DST="any" +OPTION="0" +RDR_INET="dual" +OPTION_IF=0 +OPTION_SRC=0 +OPTION_DST=0 +OPTION_INET_TYPE=0 + +# Check for options +while [ "$#" -gt 0 ]; do case "$1" in + -i|--interface) + if [ -z "${2}" ] || [ -z "${3}" ]; then + usage + elif ifconfig | grep -owq "${2}:"; then + OPTION_IF=1 + RDR_IF="${2}" + shift 2 + else + error_exit "${2} is not a valid interface." + fi + ;; + -s|--source) + if [ -z "${2}" ] || [ -z "${3}" ]; then + usage + else + check_rdr_ip_validity "${2}" + OPTION_SRC=1 + RDR_SRC="${2}" + shift 2 + fi + ;; + -d|--destination) + if [ -z "${2}" ] || [ -z "${3}" ]; then + usage + elif ifconfig | grep -owq "inet ${2}"; then + OPTION_DST=1 + RDR_DST="${2}" + shift 2 + else + error_exit "${2} is not an IP on this system." + fi + ;; + -t|--type) + if [ -z "${2}" ] || [ -z "${3}" ]; then + usage + elif [ "${2}" != "ipv4" ] && [ "${2}" != "ipv6" ]; then + usage + else + OPTION_INET_TYPE=1 + RDR_INET="${2}" + shift 2 + fi + ;; list) - if [ "${TARGET}" = 'ALL' ]; then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then + error_exit "Command \"${1}\" cannot be used with options." + elif [ -n "${2}" ]; then + usage + elif [ "${TARGET}" = 'ALL' ]; then for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do echo "${JAIL_NAME} redirects:" pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null @@ -156,7 +295,11 @@ while [ $# -gt 0 ]; do shift ;; clear) - if [ "${TARGET}" = 'ALL' ]; then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then + error_exit "Command \"${1}\" cannot be used with options." + elif [ -n "${2}" ]; then + usage + elif [ "${TARGET}" = 'ALL' ]; then for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do echo "${JAIL_NAME} redirects:" pfctl -a "rdr/${JAIL_NAME}" -Fn @@ -167,14 +310,38 @@ while [ $# -gt 0 ]; do fi shift ;; + reset) + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then + error_exit "Command \"${1}\" cannot be used with options." + elif [ -n "${2}" ]; then + usage + elif [ "${TARGET}" = 'ALL' ]; then + for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do + echo "${JAIL_NAME} redirects:" + pfctl -a "rdr/${JAIL_NAME}" -Fn + if rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf; then + info "[${JAIL_NAME}]: rdr.conf removed" + fi + done + else + check_jail_validity + pfctl -a "rdr/${JAIL_NAME}" -Fn + if rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf; then + info "[${JAIL_NAME}]: rdr.conf removed" + fi + fi + shift + ;; tcp|udp) if [ $# -lt 3 ]; then usage + elif [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] && [ "${OPTION_INET_TYPE}" -ne 1 ];then + error_exit "[-t|--type] must be set when using [-s|--source] or [-d|--destination]" elif [ $# -eq 3 ]; then check_jail_validity - persist_rdr_rule $1 $2 $3 - load_rdr_rule $1 $2 $3 - shift 3 + persist_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 + load_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 + shift "$#" else case "$4" in log) @@ -186,18 +353,18 @@ while [ $# -gt 0 ]; do for last in "$@"; do true done - if [ "$2" = "(" ] && [ "$last" = ")" ] ; then + if [ $2 == "(" ] && [ $last == ")" ] ; then check_jail_validity - persist_rdr_log_rule "$proto" "$host_port" "$jail_port" "$@" - load_rdr_log_rule "$proto" "$host_port" "$jail_port" "$@" + persist_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + load_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift $# else usage fi elif [ $# -eq 1 ]; then check_jail_validity - persist_rdr_log_rule $proto $host_port $jail_port "$@" - load_rdr_log_rule $proto $host_port $jail_port "$@" + persist_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + load_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift 1 else usage @@ -210,7 +377,27 @@ while [ $# -gt 0 ]; do fi ;; *) - usage + if [ "${OPTION}" -eq 1 ];then + usage + fi + if [ "${1}" = "dual" ] || [ "${1}" = "ipv4" ] || [ "${1}" = "ipv6" ]; then + RDR_INET="${1}" + else + usage + fi + if [ $# -eq 7 ] && [ "${5}" = "tcp" ] || [ "${5}" = "udp" ]; then + check_jail_validity + persist_rdr_rule "$@" + load_rdr_rule "$@" + shift $# + elif [ $# -ge 8 ] && [ "${8}" = "log" ]; then + check_jail_validity + persist_rdr_log_rule "$@" + load_rdr_log_rule "$@" + shift $# + else + usage + fi ;; esac done From b0b2d933530e5abc0ff5225841f00657b1dc74a1 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:48:28 -0700 Subject: [PATCH 026/120] Update rename.sh --- usr/local/share/bastille/rename.sh | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index b9197bc56..93dd4f542 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-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -35,16 +35,6 @@ usage() { error_exit "Usage: bastille rename TARGET NEW_NAME" } -validate_name() { - local NAME_VERIFY=${NEWNAME} - local NAME_SANITY="$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')" - if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then - error_exit "Container names may not begin with (-|_) characters!" - elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then - error_exit "Container names may not contain special characters!" - fi -} - # Handle special-case commands first case "$1" in help|-h|--help) @@ -52,13 +42,27 @@ help|-h|--help) ;; esac -if [ $# -ne 1 ]; then +if [ $# -ne 2 ]; then usage fi +TARGET="${1}" +NEWNAME="${2}" + bastille_root_check +set_target "${TARGET}" +check_target_exists "${TARGET}" +check_target_is_stopped "${TARGET}" -NEWNAME="${1}" +validate_name() { + local NAME_VERIFY=${NEWNAME} + local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_') + if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then + error_exit "Container names may not begin with (-|_) characters!" + elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then + error_exit "Container names may not contain special characters!" + fi +} update_jailconf() { # Update jail.conf From ca5febdb97f07163a0c6ad1ad2ae5ceff3223aef Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:48:46 -0700 Subject: [PATCH 027/120] Update service.sh --- usr/local/share/bastille/service.sh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/usr/local/share/bastille/service.sh b/usr/local/share/bastille/service.sh index 92fa4f272..825d83d50 100644 --- a/usr/local/share/bastille/service.sh +++ b/usr/local/share/bastille/service.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -29,6 +29,7 @@ # 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_exit "Usage: bastille service TARGET service_name action" @@ -36,18 +37,23 @@ usage() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; -esac + help|-h|--help) + usage + ;; + esac -if [ $# -lt 1 ] || [ $# -gt 2 ]; then +if [ $# -lt 2 ] || [ $# -gt 3 ]; then usage fi +TARGET="${1}" + bastille_root_check +set_target "${TARGET}" for _jail in ${JAILS}; do + check_target_exists "${_jail}" + check_target_is_running "${_jail}" info "[${_jail}]:" jexec -l "${_jail}" /usr/sbin/service "$@" echo From bd5d603b37d151258909ffef4bcc0bb6f30d1fa6 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:49:56 -0700 Subject: [PATCH 028/120] Update start.sh --- usr/local/share/bastille/start.sh | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index f9e5a180a..13afb2134 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -37,30 +37,19 @@ usage() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac -if [ $# -gt 1 ] || [ $# -lt 1 ]; then +if [ $# -ne 1 ]; then usage fi -bastille_root_check - TARGET="${1}" -shift -if [ "${TARGET}" = 'ALL' ]; then - JAILS=$(bastille list jails) -fi -if [ "${TARGET}" != 'ALL' ]; then - JAILS=$(bastille list jails | awk "/^${TARGET}$/") - ## check if exist - if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then - error_exit "[${TARGET}]: Not found." - fi -fi +bastille_root_check +set_target "${TARGET}" for _jail in ${JAILS}; do ## test if running From 1aa8e801cd8d8fca82b1152b417394b5c44988f1 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:50:09 -0700 Subject: [PATCH 029/120] Update stop.sh --- usr/local/share/bastille/stop.sh | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index 49cec54d1..05c0bdf7f 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -37,16 +37,19 @@ usage() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac -if [ $# -ne 0 ]; then +if [ $# -ne 1 ]; then usage fi +TARGET="${1}" + bastille_root_check +set_target "${TARGET}" for _jail in ${JAILS}; do ## test if running @@ -55,10 +58,13 @@ for _jail in ${JAILS}; do _ip="$(/usr/sbin/jls -j ${_jail} ip4.addr)" # Check if pfctl is present - if which -s pfctl; then + # Do not invoke pfctl if no ip4.addr found + if [ -n "${_ip}" ]; then + if which -s pfctl; then if [ "$(bastille rdr ${_jail} list)" ]; then - bastille rdr ${_jail} clear + bastille rdr ${_jail} clear fi + fi fi ## remove rctl limits @@ -73,7 +79,7 @@ for _jail in ${JAILS}; do jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" ## remove (captured above) ip4.addr from firewall table - if [ -n "${bastille_network_loopback}" ] && [ ! -z "${_ip}" ]; then + if [ -n "${bastille_network_loopback}" -a ! -z "${_ip}" ]; then if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" fi From 818beede644ba09f65473162e003ccc80a5c2b4a Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:50:23 -0700 Subject: [PATCH 030/120] Update sysrc.sh --- usr/local/share/bastille/sysrc.sh | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/usr/local/share/bastille/sysrc.sh b/usr/local/share/bastille/sysrc.sh index db1c8a01a..df17ad4af 100644 --- a/usr/local/share/bastille/sysrc.sh +++ b/usr/local/share/bastille/sysrc.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -36,18 +36,23 @@ usage() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; -esac + help|-h|--help) + usage + ;; + esac -if [ $# -lt 1 ]; then +if [ $# -lt 2 ]; then usage fi +TARGET="${1}" + bastille_root_check +set_target "${TARGET}" for _jail in ${JAILS}; do + check_target_exists "${_jail}" + check_target_is_running "${_jail}" info "[${_jail}]:" jexec -l "${_jail}" /usr/sbin/sysrc "$@" echo -e "${COLOR_RESET}" From 86561feace6c820fa2ffb62e7168d39b610b2cbe Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:50:42 -0700 Subject: [PATCH 031/120] Update tags.sh --- usr/local/share/bastille/tags.sh | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/usr/local/share/bastille/tags.sh b/usr/local/share/bastille/tags.sh index 65ed802ff..929809d8a 100644 --- a/usr/local/share/bastille/tags.sh +++ b/usr/local/share/bastille/tags.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # Ressource limits added by Lars Engels github.com/bsdlme # @@ -45,21 +45,24 @@ usage() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac -if [ $# -lt 1 ] || [ $# -gt 2 ]; then +if [ $# -lt 2 ] || [ $# -gt 3 ]; then usage fi -bastille_root_check +TARGET="${1}" +ACTION="${2}" +TAGS="${3}" -ACTION="${1}" -TAGS="${2}" +bastille_root_check +set_target "${TARGET}" for _jail in ${JAILS}; do + check_target_exists "${_jail}" bastille_jail_tags="${bastille_jailsdir}/${_jail}/tags" case ${ACTION} in add) From 948af9bc656987af9581977e37891a07aff782cb Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:50:58 -0700 Subject: [PATCH 032/120] Update template.sh --- usr/local/share/bastille/template.sh | 37 ++++++++++++++-------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 53f50bc0b..fbf2f936f 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -96,7 +96,7 @@ render() { if [ -d "${_file_path}" ]; then # Recursively render every file in this directory. -- cwells echo "Rendering Directory: ${_file_path}" find "${_file_path}" \( -type d -name .git -prune \) -o -type f - find "${_file_path}" \( -type d -name .git -prune \) -o -type f -print0 | eval "xargs -0 sed -i '' ${ARG_REPLACEMENTS}" + find "${_file_path}" \( -type d -name .git -prune \) -o -type f -print0 | $(eval "xargs -0 sed -i '' ${ARG_REPLACEMENTS}") elif [ -f "${_file_path}" ]; then echo "Rendering File: ${_file_path}" eval "sed -i '' ${ARG_REPLACEMENTS} '${_file_path}'" @@ -107,30 +107,31 @@ render() { # Handle special-case commands first. case "$1" in -help|-h|--help) - bastille_usage - ;; + help|-h|--help) + bastille_usage + ;; esac -if [ $# -lt 1 ]; then +if [ $# -lt 2 ]; then bastille_usage fi -bastille_root_check - -## global variables -TEMPLATE="${1}" +TARGET="${1}" +TEMPLATE="${2}" bastille_template=${bastille_templatesdir}/${TEMPLATE} if [ -z "${HOOKS}" ]; then HOOKS='LIMITS INCLUDE PRE FSTAB PF PKG OVERLAY CONFIG SYSRC SERVICE CMD RENDER' fi +bastille_root_check +set_target_single "${TARGET}" + # Special case conversion of hook-style template files into a Bastillefile. -- cwells if [ "${TARGET}" = '--convert' ]; then if [ -d "${TEMPLATE}" ]; then # A relative path was provided. -- cwells - cd "${TEMPLATE}" || error_exit "Failed to change to directory: ${TEMPLATE}" + cd "${TEMPLATE}" elif [ -d "${bastille_template}" ]; then - cd "${bastille_template}" || error_exit "Failed to change to directory: ${TEMPLATE}" + cd "${bastille_template}" else error_exit "Template not found: ${TEMPLATE}" fi @@ -232,7 +233,7 @@ for _jail in ${JAILS}; do if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then _jail_ip=$(/usr/sbin/jls -j "${_jail}" ip4.addr 2>/dev/null) _jail_ip6=$(/usr/sbin/jls -j "${_jail}" ip6.addr 2>/dev/null) - if [ -z "${_jail_ip}" ] || [ "${_jail_ip}" = "-" ]; then + if [ -z "${_jail_ip}" -o "${_jail_ip}" = "-" ]; then error_notify "Jail IP not found: ${_jail}" _jail_ip='' # In case it was -. -- cwells fi @@ -299,12 +300,12 @@ for _jail in ${JAILS}; do # Escape single-quotes in the command being executed. -- cwells _args=$(echo "${_args}" | sed "s/'/'\\\\''/g") # Allow redirection within the jail. -- cwells - _args="sh -c '${_args}'" + _args="sh -c \"${_args}\"" ;; cp|copy) _cmd='cp' # Convert relative "from" path into absolute path inside the template directory. -- cwells - if [ "${_args%"${_args#?}"}" != '/' ] && [ "${_args%"${_args#??}"}" != '"/' ]; then + if [ "${_args%${_args#?}}" != '/' ] && [ "${_args%${_args#??}}" != '"/' ]; then _args="${bastille_template}/${_args}" fi ;; @@ -368,9 +369,9 @@ for _jail in ${JAILS}; do info "[${_jail}]:${_hook} -- START" if [ "${_hook}" = 'CMD' ] || [ "${_hook}" = 'PRE' ]; then - bastille cmd "${_jail}" /bin/sh < "${bastille_template}/${_hook}" || error_exit "Failed to execute command." + bastille cmd "${_jail}" /bin/sh < "${bastille_template}/${_hook}" || exit 1 elif [ "${_hook}" = 'PKG' ]; then - bastille pkg "${_jail}" install -y "$(cat "${bastille_template}/PKG")" || error_exit "Failed to install packages." + bastille pkg "${_jail}" install -y $(cat "${bastille_template}/PKG") || exit 1 bastille pkg "${_jail}" audit -F else while read _line; do @@ -380,7 +381,7 @@ for _jail in ${JAILS}; do # Replace "arg" variables in this line with the provided values. -- cwells _line=$(echo "${_line}" | eval "sed ${ARG_REPLACEMENTS}") eval "_args=\"${_args_template}\"" - bastille "${_cmd}" "${_jail}" "${_args}" || error_exit "Failed to execute command." + bastille "${_cmd}" "${_jail}" ${_args} || exit 1 done < "${bastille_template}/${_hook}" fi info "[${_jail}]:${_hook} -- END" From 7a5223d8c9d04b8e94701680426bd14e6360f711 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:51:09 -0700 Subject: [PATCH 033/120] Update top.sh --- usr/local/share/bastille/top.sh | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh index 1e8cbb9c7..27617c849 100644 --- a/usr/local/share/bastille/top.sh +++ b/usr/local/share/bastille/top.sh @@ -29,26 +29,29 @@ # 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_exit "Usage: bastille top TARGET" } # Handle special-case commands first. -case "$1" in -help|-h|--help) - usage - ;; +case "${1}" in + help|-h|--help) + usage + ;; esac -if [ $# -ne 0 ]; then +if [ $# -ne 1 ]; then usage fi +TARGET="${1}" + bastille_root_check +set_target_single "${TARGET}" +check_target_is_running "${TARGET}" -for _jail in ${JAILS}; do - info "[${_jail}]:" - jexec -l "${_jail}" /usr/bin/top - echo -e "${COLOR_RESET}" -done +info "[${TARGET}]:" +jexec -l "${TARGET}" /usr/bin/top +echo -e "${COLOR_RESET}" From 37cf0180f8b8adab1f0ba6d7b132e5a34dfb6a3d Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:51:23 -0700 Subject: [PATCH 034/120] Update umount.sh --- usr/local/share/bastille/umount.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index dfd576647..f3b071c96 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -37,22 +37,23 @@ usage() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac -if [ $# -ne 1 ]; then +if [ $# -ne 2 ]; then usage fi -bastille_root_check +TARGET="${1}" +MOUNT_PATH="${2}" -MOUNT_PATH=$1 +bastille_root_check +set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" - _jailpath="${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH}" if [ ! -d "${_jailpath}" ]; then From 9030382197647ad98a933b5e49344dc12cbb7cfc Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:51:36 -0700 Subject: [PATCH 035/120] Update upgrade.sh --- usr/local/share/bastille/upgrade.sh | 37 +++++++++++++++-------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/usr/local/share/bastille/upgrade.sh b/usr/local/share/bastille/upgrade.sh index 394225829..4b5f6d0df 100644 --- a/usr/local/share/bastille/upgrade.sh +++ b/usr/local/share/bastille/upgrade.sh @@ -37,26 +37,37 @@ usage() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac if [ $# -gt 3 ] || [ $# -lt 2 ]; then usage fi -bastille_root_check +# Handle options +case "${1}" in + -f|--force) + OPTION="-F" + TARGET="${2}" + shift + ;; + *) + OPTION="" + ;; +esac -TARGET="$1" -NEWRELEASE="$2" -OPTION="$3" +TARGET="${1}" +NEWRELEASE="${2}" + +bastille_root_check # Check for unsupported actions if [ "${TARGET}" = "ALL" ]; then error_exit "Batch upgrade is unsupported." fi - + if [ -f "/bin/midnightbsd-version" ]; then echo -e "${COLOR_RED}Not yet supported on MidnightBSD.${COLOR_RESET}" exit 1 @@ -66,16 +77,6 @@ if freebsd-version | grep -qi HBSD; then error_exit "Not yet supported on HardenedBSD." fi -# Handle options -case "${OPTION}" in - -f|--force) - OPTION="-F" - ;; - *) - OPTION= - ;; -esac - jail_check() { # Check if the jail is thick and is running if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then From 8a57cb595e079db47463c1f39cf1e3a55d85be1d Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:51:50 -0700 Subject: [PATCH 036/120] Update update.sh --- usr/local/share/bastille/update.sh | 32 +++++++++++------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index 60458a811..06328ab6a 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -32,40 +32,33 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille update [release|container|template] | [force]" + error_exit "Usage: bastille update [option(s)] [release|container|template]" } # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac if [ $# -gt 2 ] || [ $# -lt 1 ]; then usage fi -bastille_root_check - TARGET="${1}" -OPTION="${2}" +OPTION="" + +bastille_root_check # Handle options -case "${OPTION}" in +case "${1}" in -f|--force) OPTION="-F" - ;; - *) - OPTION= + TARGET="${2}" ;; esac -# Check for unsupported actions -if [ "${TARGET}" = "ALL" ]; then - error_exit "Batch upgrade is unsupported." -fi - if [ -f "/bin/midnightbsd-version" ]; then echo -e "${COLOR_RED}Not yet supported on MidnightBSD.${COLOR_RESET}" exit 1 @@ -143,10 +136,9 @@ template_update() { templates_update() { # Update all templates _updated_templates=0 - if [ -d "${bastille_templatesdir}" ]; then - # shellcheck disable=SC2045 - for _template_path in $(ls -d "${bastille_templatesdir}"/*/*); do - if [ -d "$_template_path"/.git ]; then + if [ -d ${bastille_templatesdir} ]; then + for _template_path in $(ls -d ${bastille_templatesdir}/*/*); do + if [ -d $_template_path/.git ]; then BASTILLE_TEMPLATE=$(echo "$_template_path" | awk -F / '{ print $(NF-1) "/" $NF }') template_update From 2df124a33acb81a8cede2f17100f4e9f497e3f85 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:52:04 -0700 Subject: [PATCH 037/120] Update verify.sh --- usr/local/share/bastille/verify.sh | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh index 8f50dffa4..5c48ec271 100644 --- a/usr/local/share/bastille/verify.sh +++ b/usr/local/share/bastille/verify.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -78,8 +78,6 @@ verify_template() { info "Detected ${_hook} hook." ## line count must match newline count - # shellcheck disable=SC2046 - # shellcheck disable=SC3003 if [ $(wc -l "${_path}" | awk '{print $1}') -ne $(grep -c $'\n' "${_path}") ]; then info "[${_hook}]:" error_notify "${BASTILLE_TEMPLATE}:${_hook} [failed]." @@ -147,18 +145,18 @@ verify_template() { # Handle special-case commands first. case "$1" in -help|-h|--help) - bastille_usage - ;; + help|-h|--help) + bastille_usage + ;; esac -if [ $# -gt 1 ] || [ $# -lt 1 ]; then +if [ $# -ne 1 ]; then bastille_usage fi bastille_root_check -case "$1" in +case "${1}" in *-RELEASE|*-release|*-RC[1-9]|*-rc[1-9]) RELEASE=$1 verify_release From 734963831e239f866a212e6b9827bbacef0b39ee Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:52:16 -0700 Subject: [PATCH 038/120] Update zfs.sh --- usr/local/share/bastille/zfs.sh | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 0bcedbecf..344c00ac6 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -38,7 +38,6 @@ usage() { zfs_snapshot() { for _jail in ${JAILS}; do info "[${_jail}]:" - # shellcheck disable=SC2140 zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" echo done @@ -47,7 +46,6 @@ done zfs_destroy_snapshot() { for _jail in ${JAILS}; do info "[${_jail}]:" - # shellcheck disable=SC2140 zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" echo done @@ -84,7 +82,14 @@ help|-h|--help) ;; esac +if [ $# -lt 2 ]; then + usage +fi + +TARGET="${1}" + bastille_root_check +set_target_single "${TARGET}" ## check ZFS enabled if ! checkyesno bastille_zfs_enable; then @@ -96,25 +101,21 @@ if [ -z "${bastille_zfs_zpool}" ]; then error_exit "ZFS zpool not defined." fi -if [ $# -lt 1 ]; then - usage -fi - -case "$1" in +case "${2}" in set) - ATTRIBUTE=$2 + ATTRIBUTE=${3} zfs_set_value ;; get) - ATTRIBUTE=$2 + ATTRIBUTE=${3} zfs_get_value ;; snap|snapshot) - TAG=$2 + TAG=${3} zfs_snapshot ;; destroy_snap|destroy_snapshot) - TAG=$2 + TAG=${3} zfs_destroy_snapshot ;; df|usage) From 6ead2680ed144a3739b6558c34138a2a10243f30 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:05:07 -0700 Subject: [PATCH 039/120] final --- usr/local/bin/bastille | 167 ++++++++++++++--------------------------- 1 file changed, 57 insertions(+), 110 deletions(-) diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index dd9cbb256..400ef3abb 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -39,14 +39,6 @@ bastille_conf_check() { fi } -bastille_conf_check - -## we only load the config if conf_check passes -. /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}" -: "${bastille_network_pf_table:=jails}" - ## bastille_prefix should be 0750 ## this restricts file system access to privileged users bastille_perms_check() { @@ -59,6 +51,10 @@ bastille_perms_check() { fi } +## we only load the config if conf_check passes +. /usr/local/etc/bastille/bastille.conf + +bastille_conf_check bastille_perms_check ## version @@ -116,104 +112,61 @@ EOF exit 1 } -[ $# -lt 1 ] && usage - -CMD=$1 -shift - -target_all_jails() { - _JAILS=$(/usr/sbin/jls name) - JAILS="" - for _jail in ${_JAILS}; do - _JAILPATH=$(/usr/sbin/jls -j "${_jail}" path) - if [ -z ${_JAILPATH##${bastille_jailsdir}*} ]; then - JAILS="${JAILS} ${_jail}" - fi - done -} - -check_target_is_running() { - if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then - error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'." - fi -} +if [ $# -lt 1 ]; then + usage +else + CMD="${1}" + shift +fi # Handle special-case commands first. case "${CMD}" in -version|-v|--version) - info "${BASTILLE_VERSION}" - exit 0 - ;; -help|-h|--help) - usage - ;; -bootstrap|create|destroy|export|import|list|rdr|restart|setup|start|update|upgrade|verify) - # Nothing "extra" to do for these commands. -- cwells - ;; -clone|config|cmd|console|convert|cp|edit|htop|limits|mount|pkg|rcp|rename|service|stop|sysrc|tags|template|top|umount|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' - elif [ "${1}" != 'help' ] && [ "${1}" != '-h' ] && [ "${1}" != '--help' ]; then - TARGET="${1}" - shift - - # This is needed to handle the special case of 'bastille rcp' and 'bastille cp' with the '-q' or '--quiet' - # option specified before the TARGET. Also seems the cp and rcp commands does not support ALL as a target, so - # that's why is handled here. Maybe this behaviour needs an improvement later. -- yaazkal - if { [ "${CMD}" = 'rcp' ] || [ "${CMD}" = 'cp' ]; } && \ - { [ "${TARGET}" = '-q' ] || [ "${TARGET}" = '--quiet' ]; }; then - TARGET="${1}" - JAILS="${TARGET}" - OPTION="-q" - export OPTION - shift - fi - - if [ "${TARGET}" = 'ALL' ]; then - target_all_jails - elif [ "${CMD}" = "pkg" ] && [ "${TARGET}" = '-H' ] || [ "${TARGET}" = '--host' ]; then - TARGET="${1}" - USE_HOST_PKG=1 - if [ "${TARGET}" = 'ALL' ]; then - target_all_jails - else - JAILS="${TARGET}" - check_target_is_running - fi - shift - elif [ "${CMD}" = 'template' ] && [ "${TARGET}" = '--convert' ]; then - # This command does not act on a jail, so we are temporarily bypassing the presence/started - # checks. The command will simply convert a template from hooks to a Bastillefile. -- cwells - : - else - JAILS="${TARGET}" - - # Ensure the target exists. -- cwells - if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then - error_exit "[${TARGET}]: Not found." - fi - - case "${CMD}" in - cmd|console|htop|pkg|service|stop|sysrc|template|top) - check_target_is_running - ;; - convert|rename) - # Require the target to be stopped. -- cwells - if [ "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then - error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'." - fi - ;; - esac - fi - export USE_HOST_PKG - export TARGET - export JAILS - fi - ;; -*) # Filter out all non-commands - usage - ;; + version|-v|--version) + info "${BASTILLE_VERSION}" + exit 0 + ;; + help|-h|--help) + usage + ;; + bootstrap| \ + clone| \ + cmd| \ + config| \ + console| \ + convert| \ + cp| \ + create| \ + destroy| \ + edit| \ + etcupdate| \ + export| \ + htop| \ + import| \ + limits| \ + list| \ + mount| \ + pkg| \ + rcp| \ + rdr| \ + rename| \ + restart| \ + service| \ + setup| \ + start| \ + stop| \ + sysrc| \ + tags| \ + template| \ + top| \ + umount| \ + update| \ + upgrade| \ + verify| \ + zfs) + ;; + *) + usage + ;; esac # shellcheck disable=SC2154 @@ -221,14 +174,8 @@ SCRIPTPATH="${bastille_sharedir}/${CMD}.sh" if [ -f "${SCRIPTPATH}" ]; then : "${UMASK:=022}" umask "${UMASK}" - : "${SH:=sh}" - - if [ -n "${PARAMS}" ]; then - exec "${SH}" "${SCRIPTPATH}" "${PARAMS}" - else - exec "${SH}" "${SCRIPTPATH}" "$@" - fi + exec "${SH}" "${SCRIPTPATH}" "$@" else error_exit "${SCRIPTPATH} not found." fi From e5fd655cb81183864d364ae1f6246880b53f4589 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:07:41 -0700 Subject: [PATCH 040/120] Update Bastillefile --- usr/local/share/bastille/templates/default/base/Bastillefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/templates/default/base/Bastillefile b/usr/local/share/bastille/templates/default/base/Bastillefile index 7418fba64..7d99dfd42 100644 --- a/usr/local/share/bastille/templates/default/base/Bastillefile +++ b/usr/local/share/bastille/templates/default/base/Bastillefile @@ -8,4 +8,4 @@ SYSRC sendmail_outbound_enable="NO" SYSRC sendmail_msp_queue_enable="NO" SYSRC cron_flags="-J 60" -CP "${HOST_RESOLV_CONF}" etc/resolv.conf +CP "${HOST_RESOLV_CONF}" /etc/resolv.conf From 9073f752cfc1e476ab329407aac8154fad6a38a0 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:07:59 -0700 Subject: [PATCH 041/120] final --- usr/local/share/bastille/bootstrap.sh | 89 +++++++++++++-------------- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index 017c4aec5..9c3c57d32 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -35,47 +35,6 @@ usage() { error_exit "Usage: bastille bootstrap [RELEASE|TEMPLATE] [update|arch]" } -# Handle special-case commands first. -case "$1" in - help|-h|--help) - usage - ;; -esac - -bastille_root_check - -#Validate if ZFS is enabled in rc.conf and bastille.conf. -if [ "$(sysrc -n zfs_enable)" = "YES" ] && ! checkyesno bastille_zfs_enable; then - warn "ZFS is enabled in rc.conf but not bastille.conf. Do you want to continue? (N|y)" - read answer - case $answer in - no|No|n|N|"") - error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_enable." - ;; - yes|Yes|y|Y) - ;; - esac -fi - -# Validate ZFS parameters. -if checkyesno bastille_zfs_enable; then - ## check for the ZFS pool and bastille prefix - if [ -z "${bastille_zfs_zpool}" ]; then - error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_zpool." - elif [ -z "${bastille_zfs_prefix}" ]; then - error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_prefix." - elif ! zfs list "${bastille_zfs_zpool}" > /dev/null 2>&1; then - error_exit "ERROR: ${bastille_zfs_zpool} is not a ZFS pool." - fi - - ## check for the ZFS dataset prefix if already exist - if [ -d "/${bastille_zfs_zpool}/${bastille_zfs_prefix}" ]; then - if ! zfs list "${bastille_zfs_zpool}/${bastille_zfs_prefix}" > /dev/null 2>&1; then - error_exit "ERROR: ${bastille_zfs_zpool}/${bastille_zfs_prefix} is not a ZFS dataset." - fi - fi -fi - validate_release_url() { ## check upstream url, else warn user if [ -n "${NAME_VERIFY}" ]; then @@ -448,9 +407,53 @@ bootstrap_template() { bastille verify "${_user}/${_repo}" } +# Handle special-case commands first. +case "$1" in + help|-h|--help) + usage + ;; +esac + +RELEASE="${1}" +OPTION="${2}" +NOCACHEDIR= HW_MACHINE=$(sysctl hw.machine | awk '{ print $2 }') HW_MACHINE_ARCH=$(sysctl hw.machine_arch | awk '{ print $2 }') +bastille_root_check + +#Validate if ZFS is enabled in rc.conf and bastille.conf. +if [ "$(sysrc -n zfs_enable)" = "YES" ] && ! checkyesno bastille_zfs_enable; then + warn "ZFS is enabled in rc.conf but not bastille.conf. Do you want to continue? (N|y)" + read answer + case $answer in + no|No|n|N|"") + error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_enable." + ;; + yes|Yes|y|Y) + ;; + esac +fi + +# Validate ZFS parameters. +if checkyesno bastille_zfs_enable; then + ## check for the ZFS pool and bastille prefix + if [ -z "${bastille_zfs_zpool}" ]; then + error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_zpool." + elif [ -z "${bastille_zfs_prefix}" ]; then + error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_prefix." + elif ! zfs list "${bastille_zfs_zpool}" > /dev/null 2>&1; then + error_exit "ERROR: ${bastille_zfs_zpool} is not a ZFS pool." + fi + + ## check for the ZFS dataset prefix if already exist + if [ -d "/${bastille_zfs_zpool}/${bastille_zfs_prefix}" ]; then + if ! zfs list "${bastille_zfs_zpool}/${bastille_zfs_prefix}" > /dev/null 2>&1; then + error_exit "ERROR: ${bastille_zfs_zpool}/${bastille_zfs_prefix} is not a ZFS dataset." + fi + fi +fi + # bootstrapping from aarch64/arm64 Debian or Ubuntu require a different value for ARCH # create a new variable if [ "${HW_MACHINE_ARCH}" == "aarch64" ]; then @@ -459,10 +462,6 @@ else HW_MACHINE_ARCH_LINUX=${HW_MACHINE_ARCH} fi -NOCACHEDIR= -RELEASE="${1}" -OPTION="${2}" - # Alternate RELEASE/ARCH fetch support(experimental) if [ -n "${OPTION}" ] && [ "${OPTION}" != "${HW_MACHINE}" ] && [ "${OPTION}" != "update" ]; then # Supported architectures From 8c1e6ae143ff7017fff8a70cf095637c36b8eb75 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:08:29 -0700 Subject: [PATCH 042/120] final --- usr/local/share/bastille/clone.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 1fb1505ad..653027b08 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille clone TARGET NEW_NAME IPADDRESS" + error_exit "Usage: bastille clone TARGET NEW_NAME IP_ADDRESS" } # Handle special-case commands first @@ -53,6 +53,11 @@ IP="${3}" bastille_root_check set_target_single "${TARGET}" +## don't allow for dots(.) in container names +if echo "${NEWNAME}" | grep -q "[.]"; then + error_exit "Container names may not contain a dot(.)!" +fi + validate_ip() { IPX_ADDR="ip4.addr" IP6_MODE="disable" @@ -118,7 +123,7 @@ update_jailconf_vnet() { # 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 ${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 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 @@ -126,6 +131,7 @@ update_jailconf_vnet() { 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}" break @@ -209,9 +215,12 @@ clone_jail() { fi } -## don't allow for dots(.) in container names -if echo "${NEWNAME}" | grep -q "[.]"; then - error_exit "Container names may not contain a dot(.)!" +# Check if IP address is valid. +if [ -n "${IP}" ]; then + validate_ip +else + usage fi clone_jail + From 33c577ca509b0206aab5abacec5f59e250315131 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:08:44 -0700 Subject: [PATCH 043/120] final --- usr/local/share/bastille/cmd.sh | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/usr/local/share/bastille/cmd.sh b/usr/local/share/bastille/cmd.sh index 4a5e42065..f98b072ca 100644 --- a/usr/local/share/bastille/cmd.sh +++ b/usr/local/share/bastille/cmd.sh @@ -48,17 +48,16 @@ fi bastille_root_check -COUNT=0 -RETURN=0 - TARGET="${1}" shift 1 +COUNT=0 +RETURN=0 set_target "${TARGET}" -check_target_exists "${TARGET}" -check_target_is_running "${TARGET}" for _jail in ${JAILS}; do + # If target is stopped or not found, continue... + check_target_is_running "${_jail}" || continue COUNT=$(($COUNT+1)) info "[${_jail}]:" if grep -qw "linsysfs" "${bastille_jailsdir}/${_jail}/fstab"; then @@ -67,17 +66,15 @@ for _jail in ${JAILS}; do else jexec -l -U root "${_jail}" "$@" fi - ERROR_CODE=$? - info "[${_jail}]: ${ERROR_CODE}" - + if [ "${ERROR_CODE}" -ne 0 ]; then + warn "[${_jail}]: ${ERROR_CODE}" + fi if [ "$COUNT" -eq 1 ]; then RETURN=${ERROR_CODE} else RETURN=$(($RETURN+$ERROR_CODE)) fi - - echo done # Check when a command is executed in all running jails. (bastille cmd ALL ...) From d2ac0d06d6a58744bc944d98b80a965551e29db8 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:09:08 -0700 Subject: [PATCH 044/120] final --- usr/local/share/bastille/common.sh | 72 ++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 009551b74..25a342de1 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -28,6 +28,8 @@ # 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/etc/bastille/bastille.conf + COLOR_RED= COLOR_GREEN= COLOR_YELLOW= @@ -72,63 +74,84 @@ warn() { check_target_exists() { local _TARGET="${1}" - if [ -d "${bastille_jailsdir}"/"${_TARGET}" ]; then - return 0 + if [ ! -d "${bastille_jailsdir}"/"${_TARGET}" ]; then + error_notify "Jail not found \"${_TARGET}\"" + return 1 else - error_exit "Jail not found \"${_TARGET}\"" + return 0 fi } check_target_is_running() { local _TARGET="${1}" - if [ ! "$(/usr/sbin/jls name | awk "/^${_TARGET}$/")" ]; then - error_exit "[${_TARGET}]: Not started. See 'bastille start ${_TARGET}'." - fi + if [ ! "$(/usr/sbin/jls name | awk "/^${_TARGET}$/")" ]; then + error_notify "[${_TARGET}]: Not started. See 'bastille start ${_TARGET}'." + return 1 + else + return 0 + fi } check_target_is_stopped() { local _TARGET="${1}" - if [ "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then - error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'." + if [ "$(/usr/sbin/jls name | awk "/^${_TARGET}$/")" ]; then + error_notify "${_TARGET} is running. See 'bastille stop ${_TARGET}'." + return 1 + else + return 0 fi } set_target() { - if [ "${1}" = ALL ] || [ "${1}" = all ]; then + local _TARGET="${1}" + if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then target_all_jails else - check_target_exists "${1}" - JAILS="${1}" + check_target_exists "${_TARGET}" || exit + JAILS="${_TARGET}" + TARGET="${_TARGET}" export JAILS + export TARGET fi } set_target_single() { - if [ "${1}" = ALL ] || [ "${1}" = all ]; then + local _TARGET="${1}" + if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then error_exit "[all|ALL] not supported with this command." else - check_target_exists "${1}" - TARGET="${1}" + check_target_exists "${_TARGET}" || exit + JAILS="${_TARGET}" + TARGET="${_TARGET}" + export JAILS export TARGET fi } target_all_jails() { - local _JAILS=$(/usr/sbin/jls name) + local _JAILS="$(bastille list jails)" JAILS="" for _jail in ${_JAILS}; do - _JAILPATH=$(/usr/sbin/jls -j "${_jail}" path) - if [ -z ${_JAILPATH##${bastille_jailsdir}*} ]; then + if [ -d "${bastille_jailsdir}/${_jail}" ]; then JAILS="${JAILS} ${_jail}" fi - export JAILS done + export JAILS +} + +generate_static_mac() { + local jail_name="${1}" + local external_interface="${2}" + local macaddr_prefix="$(ifconfig ${external_interface} | grep ether | awk '{print $2}' | cut -d':' -f1-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/')" + macaddr="${macaddr_prefix}:${macaddr_suffix}" } generate_vnet_jail_netblock() { - local jail_name="$1" - local use_unique_bridge="$2" - local external_interface="$3" + 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 ## iterate num and grep all jail configs ## define uniq_epair @@ -153,11 +176,13 @@ generate_vnet_jail_netblock() { ## generate bridge config cat <<-EOF vnet; - vnet.interface = "e${uniq_epair_bridge}b_${jail_name}"; + vnet.interface = e${uniq_epair_bridge}b_${jail_name}; 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"; EOF @@ -167,12 +192,13 @@ EOF vnet; vnet.interface = e0b_${uniq_epair}; exec.prestart += "jib addm ${uniq_epair} ${external_interface}"; + exec.prestart += "ifconfig e0a_${uniq_epair} ether ${macaddr}a"; + exec.prestart += "ifconfig e0b_${uniq_epair} ether ${macaddr}b"; exec.prestart += "ifconfig e0a_${uniq_epair} description \"vnet host interface for Bastille jail ${jail_name}\""; exec.poststop += "jib destroy ${uniq_epair}"; EOF fi } - checkyesno() { ## copied from /etc/rc.subr -- cedwards (20231125) ## issue #368 (lowercase values should be parsed) From f5c7b43e5da1ea796cb9fbdd6dfb6d11b600cbc7 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:09:22 -0700 Subject: [PATCH 045/120] final --- usr/local/share/bastille/config.sh | 35 ++++++++++++++++-------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/usr/local/share/bastille/config.sh b/usr/local/share/bastille/config.sh index 5fb14e164..48a703719 100644 --- a/usr/local/share/bastille/config.sh +++ b/usr/local/share/bastille/config.sh @@ -32,26 +32,17 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille config TARGET get|set propertyName [newValue]" + error_exit "Usage: bastille config TARGET [get|set] PROPERTY_NAME NEW_VALUE" } -# we need jail(8) to parse the config file so it can expand variables etc -print_jail_conf() { - - # we need to pass a literal \n to jail to get each parameter on its own - # line - jail -f "$1" -e ' -' -} - # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; esac -if [ $# -eq 2 ] || [ $# -gt 4 ]; then +if [ $# -lt 3 ] || [ $# -gt 4 ]; then usage fi @@ -63,21 +54,33 @@ shift 2 set_target "${TARGET}" -case ${ACTION} in +case "${ACTION}" in get) if [ $# -ne 1 ]; then error_notify 'Too many parameters for a "get" operation.' usage fi ;; - set) ;; - *) error_exit 'Only get and set are supported.' ;; + set) + ;; + *) + error_exit 'Only get and set are supported.' + ;; esac -PROPERTY=${1} +PROPERTY="${1}" shift VALUE="$@" +# we need jail(8) to parse the config file so it can expand variables etc +print_jail_conf() { + + # we need to pass a literal \n to jail to get each parameter on its own + # line + jail -f "${1}" -e ' +' +} + for _jail in ${JAILS}; do FILE="${bastille_jailsdir}/${_jail}/jail.conf" if [ ! -f "${FILE}" ]; then From 0f708ccffd7b7f76837051884fc8e25140b1acfa Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:09:37 -0700 Subject: [PATCH 046/120] final --- usr/local/share/bastille/console.sh | 33 ++++++++++++----------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/usr/local/share/bastille/console.sh b/usr/local/share/bastille/console.sh index f272ebf24..e298e9cfd 100644 --- a/usr/local/share/bastille/console.sh +++ b/usr/local/share/bastille/console.sh @@ -36,27 +36,25 @@ usage() { } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; - esac +esac -if [ $# -gt 2 ]; then +if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then usage fi -bastille_root_check - TARGET="${1}" USER="${2}" +bastille_root_check set_target_single "${TARGET}" -check_target_exists "${TARGET}" -check_target_is_running "${TARGET}" +check_target_is_running "${TARGET}" || exit validate_user() { - if jexec -l "${_jail}" id "${USER}" >/dev/null 2>&1; then + if jexec -l "${TARGET}" id "${USER}" >/dev/null 2>&1; then USER_SHELL="$(jexec -l "${_jail}" getent passwd "${USER}" | cut -d: -f7)" if [ -n "${USER_SHELL}" ]; then if jexec -l "${_jail}" grep -qwF "${USER_SHELL}" /etc/shells; then @@ -81,14 +79,11 @@ check_fib() { fi } -for _jail in ${JAILS}; do - info "[${_jail}]:" - LOGIN="$(jexec -l "${_jail}" which login)" - if [ -n "${USER}" ]; then - validate_user - else - LOGIN="$(jexec -l "${_jail}" which login)" - ${_setfib} jexec -l "${_jail}" $LOGIN -f root - fi - echo -done +info "[${TARGET}]:" +LOGIN="$(jexec -l "${TARGET}" which login)" +if [ -n "${USER}" ]; then + validate_user +else + LOGIN="$(jexec -l "${TARGET}" which login)" + ${_setfib} jexec -l "${TARGET}" $LOGIN -f root +fi From 844674f51a43800fa107b16924fe40e8860ea40f Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:09:52 -0700 Subject: [PATCH 047/120] Update convert.sh --- usr/local/share/bastille/convert.sh | 40 ++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh index e21ea72b2..10e2d16d3 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -32,27 +32,55 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille convert TARGET" + error_exit "Usage: bastille convert [option(s)] TARGET" + + cat << EOF + Options: + + -f | --force -- Stop the jail if it is running. + +EOF + exit 1 } + # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; esac -if [ $# -ne 1 ]; then +if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then usage fi -bastille_root_check +# Handle options. +FORCE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -f|--force) + FORCE=1 + shift + ;; + -*|--*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done TARGET="${1}" +bastille_root_check set_target_single "${TARGET}" -check_target_exists "${TARGET}" -check_target_is_stopped "${TARGET}" +check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille stop "${TARGET}" +else + exit +fi convert_symlinks() { # Work with the symlinks, revert on first cp error From b89c96933534e1f909af1c708235207e085c768e Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:10:15 -0700 Subject: [PATCH 048/120] final --- usr/local/share/bastille/cp.sh | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index 978c7c59c..59d634839 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille cp [OPTION] TARGET HOST_PATH CONTAINER_PATH" + error_exit "Usage: bastille cp [option(s)] TARGET HOST_PATH CONTAINER_PATH" } # Handle special-case commands first. @@ -42,29 +42,38 @@ case "${1}" in ;; esac -if [ $# -ne 2 ]; then +if [ $# -lt 3 ] || [ $# -gt 4 ]; then usage fi +# Handle options. +OPTION="-av" +while [ "$#" -gt 0 ]; do + case "${1}" in + -q|--quiet) + OPTION="-a" + shift + ;; + -*|--*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done + TARGET="${1}" CPSOURCE="${2}" CPDEST="${3}" -OPTION="-av" bastille_root_check -set_target_single "${TARGET}" -check_target_exists "${TARGET}" - -case "$@" in - -q|--quiet) - OPTION="-a" - ;; -esac +set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" bastille_jail_path="${bastille_jailsdir}/${_jail}/root" - cp "${OPTION}" "${CPSOURCE}" "${bastille_jail_path}/${CPDEST}" + cp "${OPTION}" "${CPSOURCE}" "${bastille_jail_path}${CPDEST}" RETURN="$?" if [ "${TARGET}" = "ALL" ]; then # Display the return status for reference From 9a91b14eea7ed825a9bc57b28a35013a38cdb605 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:10:36 -0700 Subject: [PATCH 049/120] final --- usr/local/share/bastille/destroy.sh | 155 +++++++++++++++------------- 1 file changed, 82 insertions(+), 73 deletions(-) diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index 5e3a95dc8..e1d4a6dc5 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -32,12 +32,21 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille destroy [force] | [container|release]" + error_notify "Usage: bastille destroy [option(s)] [JAIL|RELEASE]" + + cat << EOF + Options: + + -f | --force -- Stop the jail if it is running. + +EOF + exit 1 } + destroy_jail() { - local OPTIONS - check_target_exists "${TARGET}" + local TARGET="${1}" + local OPTIONS bastille_jail_base="${bastille_jailsdir}/${TARGET}" ## dir bastille_jail_log="${bastille_logsdir}/${TARGET}_console.log" ## file @@ -50,10 +59,6 @@ destroy_jail() { fi fi - if [ ! -d "${bastille_jail_base}" ]; then - error_exit "Jail not found." - fi - if [ -d "${bastille_jail_base}" ]; then info "Deleting Jail: ${TARGET}." if checkyesno bastille_zfs_enable; then @@ -185,83 +190,87 @@ destroy_rel() { # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; -esac - -## reset this options -FORCE="" - -## handle additional options -case "${1}" in - -f|--force|force) - FORCE="1" - shift - ;; - -*) - error_notify "Unknown Option." + help|-h|--help) usage ;; esac -TARGET="${1}" +# Handle options. +FORCE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -f|--force|force) + FORCE="1" + shift + ;; + -*|--*) + error_exit "Unknown Option: \"${1}\"" + usage + ;; + *) + break + ;; + esac +done if [ $# -gt 1 ] || [ $# -lt 1 ]; then usage fi +TARGET="${1}" + bastille_root_check ## check what should we clean case "${TARGET}" in -*-CURRENT|*-CURRENT-I386|*-CURRENT-i386|*-current) - ## check for FreeBSD releases name - NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT|-CURRENT-i386)$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g') - destroy_rel - ;; -*-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC[1-9]|*-rc[1-9]|*-BETA[1-9]) - ## check for FreeBSD releases name - NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9]|-BETA[1-9])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g') - destroy_rel - ;; -*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) - ## check for HardenedBSD releases name - NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})(-stable-last)$' | sed 's/STABLE/stable/g;s/last/LAST/g') - destroy_rel - ;; -*-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*) - ## check for HardenedBSD(specific stable build releases) - NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '([0-9]{1,2})(-stable-build)-([0-9]{1,3})$' | sed 's/BUILD/build/g;s/STABLE/stable/g') - destroy_rel - ;; -*-stable-build-latest|*-stable-BUILD-LATEST|*-STABLE-BUILD-LATEST) - ## check for HardenedBSD(latest stable build release) - NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '([0-9]{1,2})(-stable-build-latest)$' | sed 's/STABLE/stable/;s/build/BUILD/g;s/latest/LATEST/g') - destroy_rel - ;; -current-build-[0-9]*|CURRENT-BUILD-[0-9]*) - ## check for HardenedBSD(specific current build releases) - NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(current-build)-([0-9]{1,3})' | sed 's/BUILD/build/g;s/CURRENT/current/g') - destroy_rel - ;; -current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST) - ## check for HardenedBSD(latest current build release) - NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(current-build-latest)$' | sed 's/CURRENT/current/;s/build/BUILD/g;s/latest/LATEST/g') - destroy_rel - ;; -Ubuntu_1804|Ubuntu_2004|Ubuntu_2204|UBUNTU_1804|UBUNTU_2004|UBUNTU_2204) - ## check for Linux releases - NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Ubuntu_1804)$|(Ubuntu_2004)$|(Ubuntu_2204)$' | sed 's/UBUNTU/Ubuntu/g;s/ubuntu/Ubuntu/g') - destroy_rel - ;; -Debian10|Debian11|Debian12|DEBIAN10|DEBIAN11|DEBIAN12) - ## check for Linux releases - NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Debian10)$|(Debian11)$|(Debian12)$' | sed 's/DEBIAN/Debian/g') - destroy_rel - ;; -*) - ## just destroy a jail - destroy_jail - ;; + *-CURRENT|*-CURRENT-I386|*-CURRENT-i386|*-current) + ## check for FreeBSD releases name + NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT|-CURRENT-i386)$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g') + destroy_rel + ;; + *-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC[1-9]|*-rc[1-9]|*-BETA[1-9]) + ## check for FreeBSD releases name + NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9]|-BETA[1-9])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g') + destroy_rel + ;; + *-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) + ## check for HardenedBSD releases name + NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})(-stable-last)$' | sed 's/STABLE/stable/g;s/last/LAST/g') + destroy_rel + ;; + *-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*) + ## check for HardenedBSD(specific stable build releases) + NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '([0-9]{1,2})(-stable-build)-([0-9]{1,3})$' | sed 's/BUILD/build/g;s/STABLE/stable/g') + destroy_rel + ;; + *-stable-build-latest|*-stable-BUILD-LATEST|*-STABLE-BUILD-LATEST) + ## check for HardenedBSD(latest stable build release) + NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '([0-9]{1,2})(-stable-build-latest)$' | sed 's/STABLE/stable/;s/build/BUILD/g;s/latest/LATEST/g') + destroy_rel + ;; + current-build-[0-9]*|CURRENT-BUILD-[0-9]*) + ## check for HardenedBSD(specific current build releases) + NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(current-build)-([0-9]{1,3})' | sed 's/BUILD/build/g;s/CURRENT/current/g') + destroy_rel + ;; + current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST) + ## check for HardenedBSD(latest current build release) + NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(current-build-latest)$' | sed 's/CURRENT/current/;s/build/BUILD/g;s/latest/LATEST/g') + destroy_rel + ;; + Ubuntu_1804|Ubuntu_2004|Ubuntu_2204|UBUNTU_1804|UBUNTU_2004|UBUNTU_2204) + ## check for Linux releases + NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Ubuntu_1804)$|(Ubuntu_2004)$|(Ubuntu_2204)$' | sed 's/UBUNTU/Ubuntu/g;s/ubuntu/Ubuntu/g') + destroy_rel + ;; + Debian10|Debian11|Debian12|DEBIAN10|DEBIAN11|DEBIAN12) + ## check for Linux releases + NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Debian10)$|(Debian11)$|(Debian12)$' | sed 's/DEBIAN/Debian/g') + destroy_rel + ;; + *) + ## just destroy a jail + set_target_single "${TARGET}" + destroy_jail "${TARGET}" + ;; esac From a06fbf6bd702ae95d8d51f26732a1751158ddba9 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:10:49 -0700 Subject: [PATCH 050/120] final --- usr/local/share/bastille/edit.sh | 41 ++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/usr/local/share/bastille/edit.sh b/usr/local/share/bastille/edit.sh index e81354eae..3efdabd20 100644 --- a/usr/local/share/bastille/edit.sh +++ b/usr/local/share/bastille/edit.sh @@ -42,24 +42,45 @@ case "$1" in ;; esac -if [ $# -gt 2 ]; then +if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then usage -elif [ $# -eq 2 ]; then +fi + +# Handle options. +FORCE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -f|--force|force) + FORCE="1" + shift + ;; + -*|--*) + error_exit "Unknown Option: \"${1}\"" + usage + ;; + *) + break + ;; + esac +done + +TARGET="${1}" +if [ "$#" -eq 2 ]; then TARGET_FILENAME="${2}" else TARGET_FILENAME="jail.conf" fi -TARGET="${1}" - -set_target_single "${TARGET}" -check_target_exists "${TARGET}" -check_target_is_running "${TARGET}" - bastille_root_check +set_target_single "${TARGET}" +check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${TARGET}" +else + exit +fi if [ -z "${EDITOR}" ]; then - EDITOR=vi + EDITOR=nano fi -"${EDITOR}" "${bastille_jailsdir}/${_jail}/${TARGET_FILENAME}" +"${EDITOR}" "${bastille_jailsdir}/${TARGET}/${TARGET_FILENAME}" From 6e6cc3105db6adf6c0476dca364e0c863fe1556e Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:11:07 -0700 Subject: [PATCH 051/120] final --- usr/local/share/bastille/etcupdate.sh | 70 +++++++++++++++++++-------- 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh index eec31bbee..c21fa8892 100644 --- a/usr/local/share/bastille/etcupdate.sh +++ b/usr/local/share/bastille/etcupdate.sh @@ -1,8 +1,9 @@ -#!/bin/sh -# +#!/bin # Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # +set -x + # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # @@ -32,7 +33,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille etcupdate [option(s)] [update TARGET|bootstrap] RELEASE" + error_exit "Usage: bastille etcupdate [option(s)] [TARGET|bootstrap RELEASE]" cat << EOF Options: @@ -44,19 +45,21 @@ EOF } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; - esac +esac -bastille_root_check +if [ $# -lt 2 ] || [ $# -gt 3 ]; then + usage +fi bootstrap_etc_release() { local _release="${1}" local _release_version=$( echo "${1}" | awk -F "-" '{print $1}' ) if [ ! -d /usr/local/bastille/source/"${_release}" ]; then - if ! git clone --branch releng/"${_release_version}" --depth 1 https://git.FreeBSD.org/src.git /usr/local/bastille/source/"${_release}" 2>/dev/null; then + if ! git clone --branch releng/"${_release_version}" --depth 1 https://git.FreeBSD.org/src.git /usr/local/bastille/source/"${_release}"; then error_exit "Failed to bootstrap etcupdate release \"${_release}\"" fi fi @@ -65,7 +68,7 @@ bootstrap_etc_release() { bootstrap_etc_tarball() { local _release="${1}" if [ ! -f /usr/local/bastille/source/"${_release}".tbz2 ]; then - if ! etcupdate build -d /tmp/etcupdate -s /usr/local/bastille/releases/"${_release}" "${_release}".tbz2; then + if ! etcupdate build -d /tmp/etcupdate -s /usr/local/bastille/source/"${_release}" "${_release}".tbz2; then error_exit "Failed to build etcupdate tarball \"${_release}.tbz2\"" fi else @@ -85,25 +88,50 @@ update_jail_etc() { fi } -DRY_RUN=0 - -while [ $# -gt 0 ]; do +# Handle options. +while [ "$#" -gt 0 ]; do case "${1}" in -d|--dry-run) - DRY_RUN=1 - shift 1 + if [ -z "${2}" ] || [ -z "${3}" ]; then + usage + else + DRY_RUN=1 + shift + fi ;; - bootstrap) - bootstrap_etc_release "${2}" - bootstrap_etc_tarball "${2}" - shift $# + -m|--mode) + if [ -z "${2}" ] || [ -z "${3}" ]; then + usage + else + MODE="${2}" + shift 2 + fi + ;; + -*|--*) + error_exit "Unknown option: \"${1}\"" ;; - update) - update_jail_etc "${2}" "${3}" - shift $# + bootstrap) + if [ -z "${2}" ]; then + usage + else + RELEASE="${2}" + bootstrap_etc_release "${RELEASE}" + bootstrap_etc_tarball "${RELEASE}" + shift $# + fi ;; *) - usage + if [ -z "${2}" ]; then + usage + else + TARGET="${1}" + RELEASE="${2}" + fi + if [ -z "${DRY_RUN}" ]; then + DRY_RUN=0 + fi + update_jail_etc "${TARGET}" "${RELEASE}" + shift "$#" ;; esac done From deb2f559c87a619c885eedfeacb2bf398541c35e Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:11:19 -0700 Subject: [PATCH 052/120] final --- usr/local/share/bastille/export.sh | 32 ++++++++++++++---------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index 423cc7e94..dfa80ffa2 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -66,23 +66,6 @@ if [ $# -gt 5 ] || [ $# -lt 1 ]; then usage fi -bastille_root_check - -TARGET="${1}" -GZIP_EXPORT= -XZ_EXPORT= -SAFE_EXPORT= -USER_EXPORT= -RAW_EXPORT= -DIR_EXPORT= -TXZ_EXPORT= -TGZ_EXPORT= -OPT_ZSEND="-R" -COMP_OPTION="0" - -set_target_single "${TARGET}" -check_target_exists "${TARGET}" - zfs_enable_check() { # Temporarily disable ZFS so we can create a standard backup archive if checkyesno bastille_zfs_enable; then @@ -201,6 +184,21 @@ else done fi +TARGET="${1}" +GZIP_EXPORT= +XZ_EXPORT= +SAFE_EXPORT= +USER_EXPORT= +RAW_EXPORT= +DIR_EXPORT= +TXZ_EXPORT= +TGZ_EXPORT= +OPT_ZSEND="-R" +COMP_OPTION="0" + +bastille_root_check +set_target_single "${TARGET}" + # Validate for combined options if [ "${COMP_OPTION}" -gt "1" ]; then error_exit "Error: Only one compression format can be used during export." From d3f82bcbad20715d22b21bb496cfcb3c16d272fb Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:11:32 -0700 Subject: [PATCH 053/120] final --- usr/local/share/bastille/htop.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh index 869b93219..d9741d151 100644 --- a/usr/local/share/bastille/htop.sh +++ b/usr/local/share/bastille/htop.sh @@ -50,8 +50,7 @@ TARGET="${1}" bastille_root_check set_target_single "${TARGET}" -check_target_exists "${TARGET}" -check_target_is_running "${TARGET}" +check_target_is_running "${TARGET}" || exit bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path) if [ ! -x "${bastille_jail_path}/usr/local/bin/htop" ]; then From 715db6113e9ddbbb5d4f46742fdb0cd83e19a10c Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:12:04 -0700 Subject: [PATCH 054/120] final --- usr/local/share/bastille/limits.sh | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/usr/local/share/bastille/limits.sh b/usr/local/share/bastille/limits.sh index 9da7725db..d8bde4ab6 100644 --- a/usr/local/share/bastille/limits.sh +++ b/usr/local/share/bastille/limits.sh @@ -33,16 +33,11 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille limits TARGET option value" + error_notify "Usage: bastille limits TARGET OPTION VALUE" echo -e "Example: bastille limits JAILNAME memoryuse 1G" exit 1 } -RACCT_ENABLE=$(sysctl -n kern.racct.enable) -if [ "${RACCT_ENABLE}" != '1' ]; then - error_exit "Racct not enabled. Append 'kern.racct.enable=1' to /boot/loader.conf and reboot" -fi - # Handle special-case commands first. case "$1" in help|-h|--help) @@ -57,12 +52,14 @@ fi TARGET="${1}" OPTION="${2}" VALUE="${3}" - +RACCT_ENABLE=$(sysctl -n kern.racct.enable) +if [ "${RACCT_ENABLE}" != '1' ]; then + error_exit "Racct not enabled. Append 'kern.racct.enable=1' to /boot/loader.conf and reboot" +fi bastille_root_check set_target "${TARGET}" -check_target_exists "${TARGET}" -check_target_is_running "${TARGET}" +check_target_is_running "${TARGET}" || exit for _jail in ${JAILS}; do info "[${_jail}]:" From d563d888b15f72b9c397915c490941e6a89d1715 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:12:29 -0700 Subject: [PATCH 055/120] final --- usr/local/share/bastille/mount.sh | 34 ++++++++++++++++--------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 36025ccd8..fb4c3cb86 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -32,11 +32,11 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille mount TARGET host_path container_path [filesystem_type options dump pass_number]" + error_exit "Usage: bastille mount TARGET HOST_PATH JAIL_PATH [filesystem_type options dump pass_number]" } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; @@ -44,17 +44,19 @@ esac if [ $# -lt 3 ]; then usage -elif [ $# -eq 3 ]; then +fi + +TARGET="${1}" +shift + +if [ $# -eq 2 ]; then _fstab="$@ nullfs ro 0 0" else _fstab="$@" fi -TARGET="${1}" - bastille_root_check set_target "${TARGET}" -check_target_exists "${TARGET}" ## assign needed variables _hostpath=$(echo "${_fstab}" | awk '{print $1}') @@ -66,7 +68,7 @@ _checks=$(echo "${_fstab}" | awk '{print $5" "$6}') ## if any variables are empty, bail out if [ -z "${_hostpath}" ] || [ -z "${_jailpath}" ] || [ -z "${_type}" ] || [ -z "${_perms}" ] || [ -z "${_checks}" ]; then error_notify "FSTAB format not recognized." - warn "Format: /host/path jail/path nullfs ro 0 0" + warn "Format: /host/path /jail/path nullfs ro 0 0" warn "Read: ${_fstab}" exit 1 fi @@ -76,7 +78,7 @@ if [ "${_hostpath}" == "tmpfs" -a "$_type" == "tmpfs" ] || [ "${_hostpath}" == " warn "Detected advanced mount type ${_hostpath}" elif [ ! -d "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then error_notify "Detected invalid host path or incorrect mount type in FSTAB." - warn "Format: /host/path jail/path nullfs ro 0 0" + warn "Format: /host/path /jail/path nullfs ro 0 0" warn "Read: ${_fstab}" exit 1 fi @@ -84,7 +86,7 @@ fi ## if mount permissions are not "ro" or "rw" if [ "${_perms}" != "ro" ] && [ "${_perms}" != "rw" ]; then error_notify "Detected invalid mount permissions in FSTAB." - warn "Format: /host/path jail/path nullfs ro 0 0" + warn "Format: /host/path /jail/path nullfs ro 0 0" warn "Read: ${_fstab}" exit 1 fi @@ -92,7 +94,7 @@ fi ## if check & pass are not "0 0 - 1 1"; bail out if [ "${_checks}" != "0 0" ] && [ "${_checks}" != "1 0" ] && [ "${_checks}" != "0 1" ] && [ "${_checks}" != "1 1" ]; then error_notify "Detected invalid fstab options in FSTAB." - warn "Format: /host/path jail/path nullfs ro 0 0" + warn "Format: /host/path /jail/path nullfs ro 0 0" warn "Read: ${_fstab}" exit 1 fi @@ -101,7 +103,7 @@ for _jail in ${JAILS}; do info "[${_jail}]:" ## aggregate variables into FSTAB entry - _fullpath="${bastille_jailsdir}/${_jail}/root/${_jailpath}" + _fullpath="${bastille_jailsdir}${_jail}/root/${_jailpath}" _fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}" ## Create mount point if it does not exist. -- cwells @@ -112,15 +114,15 @@ for _jail in ${JAILS}; do fi ## if entry doesn't exist, add; else show existing entry - if ! egrep -q "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" 2> /dev/null; then - if ! echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab"; then + if ! egrep -q "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}${_jail}/fstab" 2> /dev/null; then + if ! echo "${_fstab_entry}" >> "${bastille_jailsdir}${_jail}/fstab"; then error_exit "Failed to create fstab entry: ${_fstab_entry}" fi echo "Added: ${_fstab_entry}" else - warn "Mountpoint already present in ${bastille_jailsdir}/${_jail}/fstab" - egrep "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" + warn "Mountpoint already present in ${bastille_jailsdir}${_jail}/fstab" + egrep "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}${_jail}/fstab" fi - mount -F "${bastille_jailsdir}/${_jail}/fstab" -a + mount -F "${bastille_jailsdir}${_jail}/fstab" -a echo done From c34a299d6f8822290a4922123d986409975d662f Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:12:48 -0700 Subject: [PATCH 056/120] final --- usr/local/share/bastille/pkg.sh | 41 ++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/usr/local/share/bastille/pkg.sh b/usr/local/share/bastille/pkg.sh index 3a102f8e2..c4203f53c 100644 --- a/usr/local/share/bastille/pkg.sh +++ b/usr/local/share/bastille/pkg.sh @@ -29,11 +29,22 @@ # 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_exit "Usage: bastille pkg [-H|--host] TARGET command [args]" + error_exit "Usage: bastille pkg [option(s)] TARGET COMMAND [args]" + + cat << EOF + Options: + + -f | --force -- Start the jail if it is stopped. + -h | --host -- Use the hosts pkg command. + +EOF + exit 1 } + # Handle special-case commands first. case "$1" in help|-h|--help) @@ -45,33 +56,41 @@ if [ $# -lt 2 ]; then usage fi -TARGET="${1}" - -while [ $# -gt 0 ]; do +# Handle options. +FORCE=0 +USE_HOST_PKG=0 +while [ "$#" -gt 0 ]; do case "${1}" in - -H|--host) + -h|--host) USE_HOST_PKG=1 - TARGET="${2}" + shift + ;; + -f|--force) + FORCE=1 shift ;; -*|--*) - error_notify ""Unknown option." - usage + error_exit "Unknown option: \"${1}\"" ;; *) break ;; - case + esac done + +TARGET="${1}" bastille_root_check set_target "${TARGET}" -check_target_exists "${TARGET}" -check_target_is_running "${TARGET}" errors=0 for _jail in ${JAILS}; do + check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${_jail}" + else + continue + fi info "[${_jail}]:" bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path) if [ -f "/usr/sbin/mport" ]; then From 6958f375df1d8c6a88ae600ef4e9e49a519af54a Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:13:01 -0700 Subject: [PATCH 057/120] final --- usr/local/share/bastille/rcp.sh | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh index 8f9e16767..01f75ac2f 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille rcp [OPTION] TARGET CONTAINER_PATH HOST_PATH" + error_exit "Usage: bastille rcp [option(s)] TARGET JAIL_PATH HOST_PATH" } # Handle special-case commands first. @@ -42,24 +42,33 @@ case "${1}" in ;; esac -if [ $# -lt 3 ]; then +if [ $# -lt 3 ] || [ $# -gt 4 ]; then usage fi +# Handle options. +OPTION="-av" +while [ "$#" -gt 0 ]; do + case "${1}" in + -q|--quiet) + OPTION="-a" + shift + ;; + -*|--*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done + TARGET="${1}" CPSOURCE="${2}" CPDEST="${3}" -OPTION="-av" bastille_root_check -set_target_single "${TARGET}" -check_target_exists "${TARGET}" - -case "$@" in - -q|--quiet) - OPTION="-a" - ;; -esac +set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" From d18eae5ee9c93c0fb37a70269e187560208c3465 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:13:14 -0700 Subject: [PATCH 058/120] final --- usr/local/share/bastille/rdr.sh | 45 +++++++++++++++------------------ 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 45a2cf605..2063832a9 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -46,31 +46,7 @@ EOF exit 1 } -# Handle special-case commands first. -case "$1" in - help|-h|--help) - usage - ;; -esac - -if [ $# -lt 2 ]; then - usage -fi - -bastille_root_check - -TARGET="${1}" -JAIL_NAME="" -JAIL_IP="" -JAIL_IP6="" -shift - check_jail_validity() { - # Can only redirect to single jail - if [ "${TARGET}" = 'ALL' ]; then - error_exit "Can only redirect to a single jail." - fi - # Check if jail name is valid JAIL_NAME=$(/usr/sbin/jls -j "${TARGET}" name 2>/dev/null) if [ -z "${JAIL_NAME}" ]; then @@ -221,6 +197,26 @@ load_rdr_log_rule() { fi } +# Handle special-case commands first. +case "$1" in + help|-h|--help) + usage + ;; +esac + +if [ $# -lt 2 ]; then + usage +fi + +TARGET="${1}" +JAIL_NAME="" +JAIL_IP="" +JAIL_IP6="" +shift + +bastille_root_check +set_target_single "${TARGET}" + # Set defaults RDR_IF="$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf} | awk -F'"' '{print $2}')" RDR_SRC="any" @@ -232,7 +228,6 @@ OPTION_SRC=0 OPTION_DST=0 OPTION_INET_TYPE=0 -# Check for options while [ "$#" -gt 0 ]; do case "$1" in -i|--interface) From 50f86ead65a583a8160c6782a99af0d606b55968 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:13:27 -0700 Subject: [PATCH 059/120] final --- usr/local/share/bastille/rename.sh | 45 ++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index 93dd4f542..1f11dfc08 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -33,26 +33,55 @@ usage() { error_exit "Usage: bastille rename TARGET NEW_NAME" + + cat << EOF + Options: + + -f | --force -- Stop the jail if it is running. + +EOF + exit 1 } + # Handle special-case commands first case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac -if [ $# -ne 2 ]; then +if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then usage fi +# Handle options. +FORCE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -f|--force) + FORCE=1 + shift + ;; + -*|--*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done + TARGET="${1}" NEWNAME="${2}" bastille_root_check -set_target "${TARGET}" -check_target_exists "${TARGET}" -check_target_is_stopped "${TARGET}" +set_target_single "${TARGET}" +check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille stop "${TARGET}" +else + usage +fi validate_name() { local NAME_VERIFY=${NEWNAME} @@ -155,7 +184,7 @@ change_name() { fi } -## validate jail name +## Validate new name. if [ -n "${NEWNAME}" ]; then validate_name fi From 7d02dd980f5b29265cd77e72adc42a18f37fb3e4 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:14:07 -0700 Subject: [PATCH 060/120] final --- usr/local/share/bastille/service.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/usr/local/share/bastille/service.sh b/usr/local/share/bastille/service.sh index 825d83d50..b1028eb0d 100644 --- a/usr/local/share/bastille/service.sh +++ b/usr/local/share/bastille/service.sh @@ -32,28 +32,28 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille service TARGET service_name action" + error_exit "Usage: bastille service TARGET SERVICE_NAME ACTION" } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; - esac +esac if [ $# -lt 2 ] || [ $# -gt 3 ]; then usage fi TARGET="${1}" +shift bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do - check_target_exists "${_jail}" - check_target_is_running "${_jail}" + check_target_is_running "${_jail}" || continue info "[${_jail}]:" jexec -l "${_jail}" /usr/sbin/service "$@" echo From acae6733e78db8f2b61d9daa5b95d5094f9eec11 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:14:28 -0700 Subject: [PATCH 061/120] final --- usr/local/share/bastille/start.sh | 67 ++++++++++++++----------------- 1 file changed, 30 insertions(+), 37 deletions(-) diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index 13afb2134..ede1986f6 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -53,48 +53,41 @@ set_target "${TARGET}" for _jail in ${JAILS}; do ## test if running - if [ "$(/usr/sbin/jls name | awk "/^${_jail}$/")" ]; then - error_notify "[${_jail}]: Already started." - - ## test if not running - elif [ ! "$(/usr/sbin/jls name | awk "/^${_jail}$/")" ]; then - # Verify that the configured interface exists. -- cwells - if [ "$(bastille config $_jail get vnet)" != 'enabled' ]; then - _interface=$(bastille config $_jail get interface) - if ! ifconfig | grep "^${_interface}:" >/dev/null; then - error_notify "Error: ${_interface} interface does not exist." - continue - fi + check_target_is_stopped "${_jail}" || continue + if [ "$(bastille config $_jail get vnet)" != 'enabled' ]; then + _interface=$(bastille config $_jail get interface) + if ! ifconfig | grep "^${_interface}:" >/dev/null; then + error_notify "Error: ${_interface} interface does not exist." + continue fi + fi - ## warn if matching configured (but not online) ip4.addr, ignore if there's no ip4.addr entry - ip=$(bastille config "${_jail}" get ip4.addr) - if [ -n "${ip}" ]; then - if ifconfig | grep -wF "${ip}" >/dev/null; then - error_notify "Error: IP address (${ip}) already in use." - continue - fi - ## add ip4.addr to firewall table - pfctl -q -t "${bastille_network_pf_table}" -T add "${ip}" + ## warn if matching configured (but not online) ip4.addr, ignore if there's no ip4.addr entry + _ip="$(bastille config "${_jail}" get ip4.addr)" + if [ "${_ip}" != "not set" ]; then + if ifconfig | grep -wF "${_ip}" >/dev/null; then + error_notify "Error: IP address (${_ip}) already in use." + continue fi + ## add ip4.addr to firewall table + pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip}" + fi - ## start the container - info "[${_jail}]:" - jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -c "${_jail}" + ## start the container + info "[${_jail}]:" + jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -c "${_jail}" - ## add rctl limits - if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then - while read _limits; do - rctl -a "${_limits}" - done < "${bastille_jailsdir}/${_jail}/rctl.conf" - fi + ## add rctl limits + if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then + while read _limits; do + rctl -a "${_limits}" + done < "${bastille_jailsdir}/${_jail}/rctl.conf" + fi - ## add rdr rules - if [ -s "${bastille_jailsdir}/${_jail}/rdr.conf" ]; then - while read _rules; do - bastille rdr "${_jail}" ${_rules} - done < "${bastille_jailsdir}/${_jail}/rdr.conf" - fi + ## add rdr rules + if [ -s "${bastille_jailsdir}/${_jail}/rdr.conf" ]; then + while read _rules; do + bastille rdr "${_jail}" ${_rules} + done < "${bastille_jailsdir}/${_jail}/rdr.conf" fi - echo done From 807b11c147a3ddc439a39151f1cb1f3f909d2f42 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:14:42 -0700 Subject: [PATCH 062/120] final --- usr/local/share/bastille/stop.sh | 47 ++++++++++++++++---------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index 05c0bdf7f..65c9c9d4f 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -52,38 +52,37 @@ bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do - ## test if running - if [ "$(/usr/sbin/jls name | awk "/^${_jail}$/")" ]; then - ## Capture ip4.addr address while still running + check_target_is_running "${_jail}" || continue + ## Capture ip4.addr address while still running + if [ "$(bastille config "${_jail}" get ip4.addr)" != "not set" ]; then _ip="$(/usr/sbin/jls -j ${_jail} ip4.addr)" + fi - # Check if pfctl is present - # Do not invoke pfctl if no ip4.addr found - if [ -n "${_ip}" ]; then - if which -s pfctl; then + # Check if pfctl is present + # Do not invoke pfctl if no ip4.addr found + if [ -n "${_ip}" ]; then + if which -s pfctl; then if [ "$(bastille rdr ${_jail} list)" ]; then - bastille rdr ${_jail} clear + bastille rdr ${_jail} clear fi - fi fi + fi - ## remove rctl limits - if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then - while read _limits; do - rctl -r "${_limits}" - done < "${bastille_jailsdir}/${_jail}/rctl.conf" - fi + ## remove rctl limits + if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then + while read _limits; do + rctl -r "${_limits}" + done < "${bastille_jailsdir}/${_jail}/rctl.conf" + fi - ## stop container - info "[${_jail}]:" - jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" + ## stop container + info "[${_jail}]:" + jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" - ## remove (captured above) ip4.addr from firewall table - if [ -n "${bastille_network_loopback}" -a ! -z "${_ip}" ]; then - if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then - pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" - fi + ## remove (captured above) ip4.addr from firewall table + if [ -n "${bastille_network_loopback}" -a ! -z "${_ip}" ]; then + if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then + pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" fi fi - echo done From 42450cb7fd8635d7b4fff6825891febbc4e6b4e2 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:14:54 -0700 Subject: [PATCH 063/120] final --- usr/local/share/bastille/sysrc.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/usr/local/share/bastille/sysrc.sh b/usr/local/share/bastille/sysrc.sh index df17ad4af..e696332ec 100644 --- a/usr/local/share/bastille/sysrc.sh +++ b/usr/local/share/bastille/sysrc.sh @@ -29,30 +29,31 @@ # 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_exit "Usage: bastille sysrc TARGET args" } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; - esac +esac if [ $# -lt 2 ]; then usage fi TARGET="${1}" +shift bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do - check_target_exists "${_jail}" - check_target_is_running "${_jail}" + check_target_is_running "${_jail}" || continue info "[${_jail}]:" jexec -l "${_jail}" /usr/sbin/sysrc "$@" echo -e "${COLOR_RESET}" From 6ea187ac31f14cc6509b64ecb8fc4fe45e275ae0 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:15:11 -0700 Subject: [PATCH 064/120] final --- usr/local/share/bastille/tags.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/usr/local/share/bastille/tags.sh b/usr/local/share/bastille/tags.sh index 929809d8a..0dca190c1 100644 --- a/usr/local/share/bastille/tags.sh +++ b/usr/local/share/bastille/tags.sh @@ -62,7 +62,6 @@ bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do - check_target_exists "${_jail}" bastille_jail_tags="${bastille_jailsdir}/${_jail}/tags" case ${ACTION} in add) From 50b8a2c7dd916f3426486240808b3f1546cfe165 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:15:23 -0700 Subject: [PATCH 065/120] final --- usr/local/share/bastille/template.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index fbf2f936f..7088c4470 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -124,7 +124,8 @@ if [ -z "${HOOKS}" ]; then fi bastille_root_check -set_target_single "${TARGET}" +set_target "${TARGET}" +check_target_is_running "${TARGET}" # Special case conversion of hook-style template files into a Bastillefile. -- cwells if [ "${TARGET}" = '--convert' ]; then @@ -226,7 +227,7 @@ fi for _jail in ${JAILS}; do info "[${_jail}]:" - info "Applying template: ${TEMPLATE}..." + echo "Applying template: ${TEMPLATE}..." ## jail-specific variables. bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path) From fc85e1e928526acfa4331516ac454b575a0c0009 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:15:36 -0700 Subject: [PATCH 066/120] final --- usr/local/share/bastille/top.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh index 27617c849..f7d97ee67 100644 --- a/usr/local/share/bastille/top.sh +++ b/usr/local/share/bastille/top.sh @@ -50,7 +50,8 @@ TARGET="${1}" bastille_root_check set_target_single "${TARGET}" -check_target_is_running "${TARGET}" +check_target_is_running "${TARGET}" || exit + info "[${TARGET}]:" jexec -l "${TARGET}" /usr/bin/top From ce1e3381f80d2da2c952348a721c0056731b543d Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:15:55 -0700 Subject: [PATCH 067/120] final --- usr/local/share/bastille/umount.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index f3b071c96..939b9562d 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille umount TARGET container_path" + error_exit "Usage: bastille umount TARGET JAIL_PATH" } # Handle special-case commands first. @@ -54,7 +54,7 @@ set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" - _jailpath="${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH}" + _jailpath="${bastille_jailsdir}${_jail}/root${MOUNT_PATH}" if [ ! -d "${_jailpath}" ]; then error_exit "The specified mount point does not exist inside the jail." From 0727798f14e70741159e28feb55d089124d54011 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:16:05 -0700 Subject: [PATCH 068/120] final --- usr/local/share/bastille/update.sh | 37 ++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index 06328ab6a..13ac0f7f2 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -32,9 +32,18 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille update [option(s)] [release|container|template]" + error_exit "Usage: bastille update [option(s)] [RELEASE|JAIL|TEMPLATE]" + + cat << EOF + Options: + + -f | --force -- Force update a release. + +EOF + exit 1 } + # Handle special-case commands first. case "$1" in help|-h|--help) @@ -46,18 +55,26 @@ if [ $# -gt 2 ] || [ $# -lt 1 ]; then usage fi -TARGET="${1}" +# Handle options. OPTION="" +while [ "$#" -gt 0 ]; do + case "${1}" in + -f|--force) + OPTION="-F" + shift + ;; + -*|--*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done -bastille_root_check +TARGET="${1}" -# Handle options -case "${1}" in - -f|--force) - OPTION="-F" - TARGET="${2}" - ;; -esac +bastille_root_check if [ -f "/bin/midnightbsd-version" ]; then echo -e "${COLOR_RED}Not yet supported on MidnightBSD.${COLOR_RESET}" From fb09f0f7aefa685ce7cd60e014842f662d748ba6 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:16:19 -0700 Subject: [PATCH 069/120] final --- usr/local/share/bastille/upgrade.sh | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/usr/local/share/bastille/upgrade.sh b/usr/local/share/bastille/upgrade.sh index 4b5f6d0df..7d668a92f 100644 --- a/usr/local/share/bastille/upgrade.sh +++ b/usr/local/share/bastille/upgrade.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille upgrade release newrelease | target newrelease | target install | [force]" + error_exit "Usage: bastille upgrade [option(s)] [RELEASE NEW_RELEASE (install)] [TARGET NEW_RELEASE (install)]" } # Handle special-case commands first. @@ -46,17 +46,22 @@ if [ $# -gt 3 ] || [ $# -lt 2 ]; then usage fi -# Handle options -case "${1}" in - -f|--force) - OPTION="-F" - TARGET="${2}" - shift - ;; - *) - OPTION="" - ;; -esac +# Handle options. +OPTION="" +while [ "$#" -gt 0 ]; do + case "${1}" in + -f|--force) + OPTION="-F" + shift + ;; + -*|--*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done TARGET="${1}" NEWRELEASE="${2}" From 1c5930c62c158a81ff43fae5d817493eb91937e6 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:16:32 -0700 Subject: [PATCH 070/120] final --- usr/local/share/bastille/verify.sh | 36 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh index 5c48ec271..4f56bf4d2 100644 --- a/usr/local/share/bastille/verify.sh +++ b/usr/local/share/bastille/verify.sh @@ -157,22 +157,22 @@ fi bastille_root_check case "${1}" in -*-RELEASE|*-release|*-RC[1-9]|*-rc[1-9]) - RELEASE=$1 - verify_release - ;; -*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) - RELEASE=$1 - verify_release - ;; -http?*) - bastille_usage - ;; -*/*) - BASTILLE_TEMPLATE=$1 - verify_template - ;; -*) - bastille_usage - ;; + *-RELEASE|*-release|*-RC[1-9]|*-rc[1-9]) + RELEASE="${1}" + verify_release + ;; + *-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) + RELEASE="${1}" + verify_release + ;; + http?*) + bastille_usage + ;; + */*) + BASTILLE_TEMPLATE="${1}" + verify_template + ;; + *) + bastille_usage + ;; esac From ec5fdb4fe5c68a124811b154c7c114053f3e2f12 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:16:47 -0700 Subject: [PATCH 071/120] final --- usr/local/share/bastille/zfs.sh | 46 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 344c00ac6..ec4a98ee8 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille zfs TARGET [set|get|snap] [key=value|date]'" + error_exit "Usage: bastille zfs TARGET [set|get|snap] [key=value|date]" } zfs_snapshot() { @@ -77,9 +77,9 @@ done # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac if [ $# -lt 2 ]; then @@ -102,23 +102,23 @@ if [ -z "${bastille_zfs_zpool}" ]; then fi case "${2}" in -set) - ATTRIBUTE=${3} - zfs_set_value - ;; -get) - ATTRIBUTE=${3} - zfs_get_value - ;; -snap|snapshot) - TAG=${3} - zfs_snapshot - ;; -destroy_snap|destroy_snapshot) - TAG=${3} - zfs_destroy_snapshot - ;; -df|usage) - zfs_disk_usage - ;; + set) + ATTRIBUTE=${3} + zfs_set_value + ;; + get) + ATTRIBUTE=${3} + zfs_get_value + ;; + snap|snapshot) + TAG=${3} + zfs_snapshot + ;; + destroy_snap|destroy_snapshot) + TAG=${3} + zfs_destroy_snapshot + ;; + df|usage) + zfs_disk_usage + ;; esac From 4640cae825bc938f247ad8aedea5131708f22858 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Fri, 20 Dec 2024 17:56:21 -0700 Subject: [PATCH 072/120] first go at shellcheck correction --- usr/local/share/bastille/convert.sh | 6 +++--- usr/local/share/bastille/cp.sh | 2 +- usr/local/share/bastille/edit.sh | 4 ++-- usr/local/share/bastille/export.sh | 11 ++++++----- usr/local/share/bastille/rdr.sh | 14 +++++++++----- usr/local/share/bastille/stop.sh | 2 +- usr/local/share/bastille/upgrade.sh | 2 +- 7 files changed, 23 insertions(+), 18 deletions(-) diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh index 10e2d16d3..080497d4e 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -63,7 +63,7 @@ while [ "$#" -gt 0 ]; do FORCE=1 shift ;; - -*|--*) + -*) error_exit "Unknown option: \"${1}\"" ;; *) @@ -148,7 +148,7 @@ start_convert() { HASPORTS=$(grep -w ${bastille_releasesdir}/${RELEASE}/usr/ports ${bastille_jailsdir}/${TARGET}/fstab) if [ -n "${RELEASE}" ]; then - cd "${bastille_jailsdir}/${TARGET}/root" + cd "${bastille_jailsdir}/${TARGET}/root" || error_exit "Could not cd to "${bastille_jailsdir}"/"${TARGET}"/root" # Work with the symlinks convert_symlinks @@ -183,7 +183,7 @@ fi # Be interactive here since this cannot be easily undone while :; do error_notify "Warning: container conversion from thin to thick can't be undone!" - read -p "Do you really wish to convert '${TARGET}' into a thick container? [y/N]:" yn + read "Do you really wish to convert '${TARGET}' into a thick container? [y/N]:" yn case ${yn} in [Yy]) start_convert;; [Nn]) exit 0;; diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index 59d634839..8b9e101cd 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -54,7 +54,7 @@ while [ "$#" -gt 0 ]; do OPTION="-a" shift ;; - -*|--*) + -*) error_exit "Unknown option: \"${1}\"" ;; *) diff --git a/usr/local/share/bastille/edit.sh b/usr/local/share/bastille/edit.sh index 3efdabd20..30b8cf671 100644 --- a/usr/local/share/bastille/edit.sh +++ b/usr/local/share/bastille/edit.sh @@ -54,8 +54,8 @@ while [ "$#" -gt 0 ]; do FORCE="1" shift ;; - -*|--*) - error_exit "Unknown Option: \"${1}\"" + -*) + error_notify "Unknown Option: \"${1}\"" usage ;; *) diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index dfa80ffa2..5a5d8074f 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -68,6 +68,7 @@ fi zfs_enable_check() { # Temporarily disable ZFS so we can create a standard backup archive + # shellcheck disable=SC2034 if checkyesno bastille_zfs_enable; then bastille_zfs_enable="NO" fi @@ -116,7 +117,7 @@ if [ -n "${bastille_export_options}" ]; then --verbose) OPT_ZSEND="-Rv" shift;; - -*|--*) error_notify "Unknown Option." + -*) error_notify "Unknown Option." usage;; esac done @@ -166,7 +167,7 @@ else TARGET="${2}" shift ;; - -*|--*) + -*) error_notify "Unknown Option." usage ;; @@ -209,7 +210,7 @@ if [ -n "${TXZ_EXPORT}" -o -n "${TGZ_EXPORT}" ] && [ -n "${SAFE_EXPORT}" ]; then fi if ! checkyesno bastille_zfs_enable; then - if [ -n "${XZ_EXPORT}" -o -n "${GZIP_EXPORT}" -o -n "${RAW_EXPORT}" -o -n "${SAFE_EXPORT}" -o "${OPT_ZSEND}" = "-Rv" ]; then + if [ -n "${XZ_EXPORT}" ] || [ -n "${GZIP_EXPORT}" ] || [ -n "${RAW_EXPORT}" ] || [ -n "${SAFE_EXPORT}" ] || [ "${OPT_ZSEND}" = "-Rv" ]; then error_exit "Options --xz, --gz, --raw, --safe, --verbose are valid for ZFS configured systems only." fi fi @@ -266,7 +267,7 @@ export_check() { EXPORT_AS="Exporting" fi - if [ "${FILE_EXT}" = ".xz" -o "${FILE_EXT}" = ".gz" -o "${FILE_EXT}" = "" ]; then + if [ "${FILE_EXT}" = ".xz" ] || [ "${FILE_EXT}" = ".gz" ] || [ "${FILE_EXT}" = "" ]; then EXPORT_TYPE="image" else EXPORT_TYPE="archive" @@ -361,7 +362,7 @@ jail_export() { else if [ -z "${USER_EXPORT}" ]; then # Generate container checksum file - cd "${bastille_backupsdir}" + cd "${bastille_backupsdir}" || error_exit "Could not cd to "${bastille_backupsdir}"" sha256 -q "${TARGET}_${DATE}${FILE_EXT}" > "${TARGET}_${DATE}.sha256" info "Exported '${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}' successfully." fi diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 2063832a9..f3ea6f2d0 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -77,7 +77,7 @@ check_jail_validity() { # function: check if IP is valid check_rdr_ip_validity() { local ip="$1" - local ip6=$(echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)') + local ip6="$(echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)')" if [ -n "${ip6}" ]; then info "Valid: (${ip6})." else @@ -138,6 +138,7 @@ load_rdr_rule() { local host_port="${6}" local jail_port="${7}" # Create IPv4 rdr rule + # shellcheck disable=SC2193 if [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ @@ -149,6 +150,7 @@ load_rdr_rule() { fi fi # Create IPv6 rdr rule (if ip6.addr is enabled) + # shellcheck disable=SC2193 if [ -n "$JAIL_IP6" ] && [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ @@ -174,7 +176,8 @@ load_rdr_log_rule() { shift 7; log=$@ # Create IPv4 rule with log - if [ "${inet} = "ipv4" ] || [ "${inet} = "dual" ]; then + # shellcheck disable=SC2193 + if [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then @@ -185,7 +188,8 @@ load_rdr_log_rule() { fi fi # Create IPv6 rdr rule with log (if ip6.addr is enabled) - if [ -n "$JAIL_IP6" ] && [ "${inet} = "ipv6" ] || [ "${inet} = "dual" ]; then + # shellcheck disable=SC2193 + if [ -n "${JAIL_IP6}" ] && [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass %s on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then @@ -344,11 +348,11 @@ while [ "$#" -gt 0 ]; do host_port=$2 jail_port=$3 shift 3 - if [ $# -gt 3 ]; then + if [ "$#" -gt 3 ]; then for last in "$@"; do true done - if [ $2 == "(" ] && [ $last == ")" ] ; then + if [ "${2}" = "(" ] && [ "${last}" == ")" ] ; then check_jail_validity persist_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" load_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index 65c9c9d4f..adf10c918 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -80,7 +80,7 @@ for _jail in ${JAILS}; do jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" ## remove (captured above) ip4.addr from firewall table - if [ -n "${bastille_network_loopback}" -a ! -z "${_ip}" ]; then + if [ -n "${bastille_network_loopback}" ] && [ ! -z "${_ip}" ]; then if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" fi diff --git a/usr/local/share/bastille/upgrade.sh b/usr/local/share/bastille/upgrade.sh index 7d668a92f..489f053eb 100644 --- a/usr/local/share/bastille/upgrade.sh +++ b/usr/local/share/bastille/upgrade.sh @@ -54,7 +54,7 @@ while [ "$#" -gt 0 ]; do OPTION="-F" shift ;; - -*|--*) + -*) error_exit "Unknown option: \"${1}\"" ;; *) From fccf4b5358fb6dc711cd3eaf0f1f19cddb794500 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Fri, 20 Dec 2024 18:23:33 -0700 Subject: [PATCH 073/120] next attempt at shellcheck --- usr/local/share/bastille/bootstrap.sh | 5 +++-- usr/local/share/bastille/clone.sh | 11 ++++++----- usr/local/share/bastille/convert.sh | 2 +- usr/local/share/bastille/create.sh | 15 +++++++++------ usr/local/share/bastille/destroy.sh | 4 ++-- usr/local/share/bastille/etcupdate.sh | 14 ++------------ usr/local/share/bastille/export.sh | 4 ++-- usr/local/share/bastille/import.sh | 6 +++--- usr/local/share/bastille/list.sh | 17 +++++++++-------- usr/local/share/bastille/mount.sh | 11 ++++++++--- usr/local/share/bastille/pkg.sh | 2 +- usr/local/share/bastille/rcp.sh | 2 +- usr/local/share/bastille/rdr.sh | 2 +- usr/local/share/bastille/rename.sh | 4 ++-- usr/local/share/bastille/template.sh | 14 +++++++------- usr/local/share/bastille/update.sh | 3 ++- usr/local/share/bastille/verify.sh | 3 ++- usr/local/share/bastille/zfs.sh | 2 ++ 18 files changed, 63 insertions(+), 58 deletions(-) diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index 9c3c57d32..97d878fd6 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -172,11 +172,12 @@ bootstrap_directories() { } bootstrap_release() { + # shellcheck disable=SC2010 ## if release exists quit, else bootstrap additional distfiles if [ -f "${bastille_releasesdir}/${RELEASE}/COPYRIGHT" ]; then ## check distfiles list and skip existing cached files bastille_bootstrap_archives=$(echo "${bastille_bootstrap_archives}" | sed "s/base//") - bastille_cached_files=$(ls "${bastille_cachedir}/${RELEASE}" | grep -v "MANIFEST" | tr -d ".txz") + bastille_cached_files="$(ls "${bastille_cachedir}/${RELEASE}" | grep -v "MANIFEST" | tr -d ".txz")" for distfile in ${bastille_cached_files}; do bastille_bootstrap_archives=$(echo "${bastille_bootstrap_archives}" | sed "s/${distfile}//") done @@ -456,7 +457,7 @@ fi # bootstrapping from aarch64/arm64 Debian or Ubuntu require a different value for ARCH # create a new variable -if [ "${HW_MACHINE_ARCH}" == "aarch64" ]; then +if [ "${HW_MACHINE_ARCH}" = "aarch64" ]; then HW_MACHINE_ARCH_LINUX="arm64" else HW_MACHINE_ARCH_LINUX=${HW_MACHINE_ARCH} diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 653027b08..de2545ff1 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -59,6 +59,7 @@ if echo "${NEWNAME}" | grep -q "[.]"; then fi validate_ip() { + # shellcheck disable=SC2034 IPX_ADDR="ip4.addr" IP6_MODE="disable" ip6=$(echo "${IP}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))') @@ -111,9 +112,9 @@ 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) + local list_jails_num="$(bastille list jails | wc -l | awk '{print $1}')" + local num_range="$(expr "${list_jails_num}" + 1)" + jail_list="$(bastille list jails)" for _num in $(seq 0 "${num_range}"); do if [ -n "${jail_list}" ]; then if ! grep -q "e0b_bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then @@ -145,7 +146,7 @@ update_jailconf_vnet() { 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 + 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}" @@ -172,7 +173,7 @@ update_fstab() { clone_jail() { # Attempt container clone - info "Attempting to clone "${TARGET}" to "${NEWNAME}"..." + info "Attempting to clone ${TARGET} to ${NEWNAME}..." if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh index 080497d4e..b1f11f076 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -148,7 +148,7 @@ start_convert() { HASPORTS=$(grep -w ${bastille_releasesdir}/${RELEASE}/usr/ports ${bastille_jailsdir}/${TARGET}/fstab) if [ -n "${RELEASE}" ]; then - cd "${bastille_jailsdir}/${TARGET}/root" || error_exit "Could not cd to "${bastille_jailsdir}"/"${TARGET}"/root" + cd "${bastille_jailsdir}/${TARGET}/root" || error_exit "Could not cd to ${bastille_jailsdir}/${TARGET}/root" # Work with the symlinks convert_symlinks diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index c26285c0a..0876924d2 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -60,7 +60,7 @@ running_jail() { validate_name() { local NAME_VERIFY=${NAME} - local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_') + local NAME_SANITY="$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')" if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then error_exit "Container names may not begin with (-|_) characters!" elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then @@ -123,7 +123,7 @@ validate_ips() { } validate_netif() { - local LIST_INTERFACES=$(ifconfig -l) + local LIST_INTERFACES="$(ifconfig -l)" if echo "${LIST_INTERFACES} VNET" | grep -qwo "${INTERFACE}"; then info "Valid: (${INTERFACE})." else @@ -238,7 +238,7 @@ post_create_jail() { # Using relative paths here. # MAKE SURE WE'RE IN THE RIGHT PLACE. - cd "${bastille_jail_path}" + cd "${bastille_jail_path}" || error_exit "Could not cd to ${bastille_jail_path}" echo if [ ! -f "${bastille_jail_conf}" ]; then @@ -271,6 +271,7 @@ post_create_jail() { } create_jail() { + # shellcheck disable=SC2034 bastille_jail_base="${bastille_jailsdir}/${NAME}/root/.bastille" ## dir bastille_jail_template="${bastille_jailsdir}/${NAME}/root/.template" ## dir bastille_jail_path="${bastille_jailsdir}/${NAME}/root" ## dir @@ -394,9 +395,10 @@ create_jail() { info "Creating a clonejail...\n" ## clone the release base to the new basejail SNAP_NAME="bastille-clone-$(date +%Y-%m-%d-%H%M%S)" + # shellcheck disable=SC2140 zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" - - zfs clone -p "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" \ + + zfs clone -p "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" \ "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" # Check and apply required settings. @@ -593,6 +595,7 @@ esac bastille_root_check if echo "$3" | grep '@'; then + # shellcheck disable=SC2034 BASTILLE_JAIL_IP=$(echo "$3" | awk -F@ '{print $2}') BASTILLE_JAIL_INTERFACES=$( echo "$3" | awk -F@ '{print $1}') fi @@ -676,7 +679,7 @@ while [ $# -gt 0 ]; do VNET_JAIL_BRIDGE="1" shift ;; - -*|--*) + -*) error_notify "Unknown Option." usage ;; diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index e1d4a6dc5..f0519b658 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -178,7 +178,7 @@ destroy_rel() { if [ "${FORCE}" = "1" ]; then ## remove cache on force if [ -d "${bastille_cachedir}/${TARGET}" ]; then - rm -rf "${bastille_cachedir}/${TARGET}" + rm -rf "${bastille_cachedir:?}/${TARGET:?}" fi fi echo @@ -203,7 +203,7 @@ while [ "$#" -gt 0 ]; do FORCE="1" shift ;; - -*|--*) + -*) error_exit "Unknown Option: \"${1}\"" usage ;; diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh index c21fa8892..890758b04 100644 --- a/usr/local/share/bastille/etcupdate.sh +++ b/usr/local/share/bastille/etcupdate.sh @@ -1,9 +1,7 @@ -#!/bin +#!/bin/sh # Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # -set -x - # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # @@ -99,15 +97,7 @@ while [ "$#" -gt 0 ]; do shift fi ;; - -m|--mode) - if [ -z "${2}" ] || [ -z "${3}" ]; then - usage - else - MODE="${2}" - shift 2 - fi - ;; - -*|--*) + -*) error_exit "Unknown option: \"${1}\"" ;; bootstrap) diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index 5a5d8074f..52a3ece1f 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -205,7 +205,7 @@ if [ "${COMP_OPTION}" -gt "1" ]; then error_exit "Error: Only one compression format can be used during export." fi -if [ -n "${TXZ_EXPORT}" -o -n "${TGZ_EXPORT}" ] && [ -n "${SAFE_EXPORT}" ]; then +if [ -n "${TXZ_EXPORT}" ] || [ -n "${TGZ_EXPORT}" ] && [ -n "${SAFE_EXPORT}" ]; then error_exit "Error: Simple archive modes with safe ZFS export can't be used together." fi @@ -362,7 +362,7 @@ jail_export() { else if [ -z "${USER_EXPORT}" ]; then # Generate container checksum file - cd "${bastille_backupsdir}" || error_exit "Could not cd to "${bastille_backupsdir}"" + cd "${bastille_backupsdir}" || error_exit "Could not cd to ${bastille_backupsdir}" sha256 -q "${TARGET}_${DATE}${FILE_EXT}" > "${TARGET}_${DATE}.sha256" info "Exported '${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}' successfully." fi diff --git a/usr/local/share/bastille/import.sh b/usr/local/share/bastille/import.sh index 69b23055d..2c7e49b08 100644 --- a/usr/local/share/bastille/import.sh +++ b/usr/local/share/bastille/import.sh @@ -79,7 +79,7 @@ while [ $# -gt 0 ]; do TARGET="${2}" shift ;; - -*|--*) + -*) error_notify "Unknown Option." usage ;; @@ -281,7 +281,7 @@ EOF >> "${bastille_jailsdir}/${TARGET_TRIM}/fstab" # Work with the symlinks - cd "${bastille_jailsdir}/${TARGET_TRIM}/root" + cd "${bastille_jailsdir}/${TARGET_TRIM}/root" || error_exit "Could not cd to ${bastille_jailsdir}/${TARGET_TRIM}/root" update_symlinks else # Generate new empty fstab file @@ -377,7 +377,7 @@ update_symlinks() { for _link in ${SYMLINKS}; do if [ -L "${_link}" ]; then ln -sf /.bastille/${_link} ${_link} - elif [ "${ALLOW_EMPTY_DIRS_TO_BE_SYMLINKED:-0}" = "1" -a -d "${_link}" ]; then + elif [ "${ALLOW_EMPTY_DIRS_TO_BE_SYMLINKED:-0}" = "1" ] && [ -d "${_link}" ]; then # -F will enforce that the directory is empty and replaced by the symlink ln -sfF /.bastille/${_link} ${_link} || EXIT_CODE=$? if [ "${EXIT_CODE:-0}" != "0" ]; then diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 20ba42056..b6a741873 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -46,7 +46,7 @@ if [ $# -eq 0 ]; then /usr/sbin/jls fi -if [ "${1}" == "-j" ]; then +if [ "${1}" = "-j" ]; then /usr/sbin/jls -N --libxo json exit 0 fi @@ -62,7 +62,7 @@ list_all(){ if [ "${MAX_LENGTH_JAIL_NAME}" -lt 3 ]; then MAX_LENGTH_JAIL_NAME=3; fi 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) + 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 +73,11 @@ 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) + 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="$(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) + 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 @@ -94,7 +94,7 @@ list_all(){ if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then JAIL_NAME=$(grep -h -m 1 -e "^.* {$" "${bastille_jailsdir}/${_JAIL}/jail.conf" 2> /dev/null | awk '{ print $1 }') IS_FREEBSD_JAIL=0 - if [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/bin/freebsd-version" -o -f "${bastille_jailsdir}/${JAIL_NAME}/root/.bastille/bin/freebsd-version" -o "$(grep -c "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_FREEBSD_JAIL=1; fi + if [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/bin/freebsd-version" ] || [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/.bastille/bin/freebsd-version" ] || [ "$(grep -c "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_FREEBSD_JAIL=1; fi IS_FREEBSD_JAIL=${IS_FREEBSD_JAIL:-0} IS_LINUX_JAIL=0 if [ "$(grep -c "^linprocfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_LINUX_JAIL=1; fi @@ -163,8 +163,8 @@ list_release(){ if [ -d "${bastille_releasesdir}" ]; then REL_LIST=$(ls "${bastille_releasesdir}" | sed "s/\n//g") for _REL in ${REL_LIST}; do - if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" -o -d "${bastille_releasesdir}/${_REL}/debootstrap" ]; then - if [ "${1}" == "-p" -a -f "${bastille_releasesdir}/${_REL}/bin/freebsd-version" ]; then + if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" ] || [ -d "${bastille_releasesdir}/${_REL}/debootstrap" ]; then + if [ "${1}" = "-p" ] && [ -f "${bastille_releasesdir}/${_REL}/bin/freebsd-version" ]; then REL_PATCH_LEVEL=$(sed -n "s/^USERLAND_VERSION=\"\(.*\)\"$/\1/p" "${bastille_releasesdir}/${_REL}/bin/freebsd-version" 2> /dev/null) REL_PATCH_LEVEL=${REL_PATCH_LEVEL:-${_REL}} echo "${REL_PATCH_LEVEL}" @@ -200,6 +200,7 @@ list_limit(){ } list_import(){ + # shellcheck disable=SC2010 ls "${bastille_backupsdir}" | grep -v ".sha256$" } diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index fb4c3cb86..6153e2406 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -73,12 +73,17 @@ if [ -z "${_hostpath}" ] || [ -z "${_jailpath}" ] || [ -z "${_type}" ] || [ -z " exit 1 fi -## if host path doesn't exist, type is not "nullfs" or are using advanced mount type "tmpfs,linprocfs,linsysfs, fdescfs, procfs" -if [ "${_hostpath}" == "tmpfs" -a "$_type" == "tmpfs" ] || [ "${_hostpath}" == "linprocfs" -a "${_type}" == "linprocfs" ] || [ "${_hostpath}" == "linsysfs" -a "${_type}" == "linsysfs" ] || [ "${_hostpath}" == "proc" -a "${_type}" == "procfs" ] || [ "${_hostpath}" == "fdesc" -a "${_type}" == "fdescfs" ] ; then +# if host path doesn't exist, type is not "nullfs" or are using advanced mount type "tmpfs,linprocfs,linsysfs, fdescfs, +# procfs" +if { [ "${_hostpath}" = "tmpfs" ] && [ "$_type" = "tmpfs" ]; } || \ + { [ "${_hostpath}" = "linprocfs" ] && [ "${_type}" = "linprocfs" ]; } || \ + { [ "${_hostpath}" = "linsysfs" ] && [ "${_type}" = "linsysfs" ]; } || \ + { [ "${_hostpath}" = "proc" ] && [ "${_type}" = "procfs" ]; } || \ + { [ "${_hostpath}" = "fdesc" ] && [ "${_type}" = "fdescfs" ]; } then warn "Detected advanced mount type ${_hostpath}" elif [ ! -d "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then error_notify "Detected invalid host path or incorrect mount type in FSTAB." - warn "Format: /host/path /jail/path nullfs ro 0 0" + warn "Format: /host/path jail/path nullfs ro 0 0" warn "Read: ${_fstab}" exit 1 fi diff --git a/usr/local/share/bastille/pkg.sh b/usr/local/share/bastille/pkg.sh index c4203f53c..2567234e6 100644 --- a/usr/local/share/bastille/pkg.sh +++ b/usr/local/share/bastille/pkg.sh @@ -69,7 +69,7 @@ while [ "$#" -gt 0 ]; do FORCE=1 shift ;; - -*|--*) + -*) error_exit "Unknown option: \"${1}\"" ;; *) diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh index 01f75ac2f..4fdee02ef 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -54,7 +54,7 @@ while [ "$#" -gt 0 ]; do OPTION="-a" shift ;; - -*|--*) + -*) error_exit "Unknown option: \"${1}\"" ;; *) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index f3ea6f2d0..9f85f83fb 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -352,7 +352,7 @@ while [ "$#" -gt 0 ]; do for last in "$@"; do true done - if [ "${2}" = "(" ] && [ "${last}" == ")" ] ; then + if [ "${2}" = "(" ] && [ "${last}" = ")" ] ; then check_jail_validity persist_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" load_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index 1f11dfc08..e3f24d3be 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -63,7 +63,7 @@ while [ "$#" -gt 0 ]; do FORCE=1 shift ;; - -*|--*) + -*) error_exit "Unknown option: \"${1}\"" ;; *) @@ -85,7 +85,7 @@ fi validate_name() { local NAME_VERIFY=${NEWNAME} - local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_') + local NAME_SANITY="$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')" if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then error_exit "Container names may not begin with (-|_) characters!" elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 7088c4470..3aa03b7ec 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -96,7 +96,7 @@ render() { if [ -d "${_file_path}" ]; then # Recursively render every file in this directory. -- cwells echo "Rendering Directory: ${_file_path}" find "${_file_path}" \( -type d -name .git -prune \) -o -type f - find "${_file_path}" \( -type d -name .git -prune \) -o -type f -print0 | $(eval "xargs -0 sed -i '' ${ARG_REPLACEMENTS}") + find "${_file_path}" \( -type d -name .git -prune \) -o -type f -print0 | "$(eval "xargs -0 sed -i '' ${ARG_REPLACEMENTS}")" elif [ -f "${_file_path}" ]; then echo "Rendering File: ${_file_path}" eval "sed -i '' ${ARG_REPLACEMENTS} '${_file_path}'" @@ -130,9 +130,9 @@ check_target_is_running "${TARGET}" # Special case conversion of hook-style template files into a Bastillefile. -- cwells if [ "${TARGET}" = '--convert' ]; then if [ -d "${TEMPLATE}" ]; then # A relative path was provided. -- cwells - cd "${TEMPLATE}" + cd "${TEMPLATE}" || error_exit "Could not cd to ${TEMPLATE}" elif [ -d "${bastille_template}" ]; then - cd "${bastille_template}" + cd "${bastille_template}" || error_exit "Could not cd to ${bastille_template}" else error_exit "Template not found: ${TEMPLATE}" fi @@ -234,7 +234,7 @@ for _jail in ${JAILS}; do if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then _jail_ip=$(/usr/sbin/jls -j "${_jail}" ip4.addr 2>/dev/null) _jail_ip6=$(/usr/sbin/jls -j "${_jail}" ip6.addr 2>/dev/null) - if [ -z "${_jail_ip}" -o "${_jail_ip}" = "-" ]; then + if [ -z "${_jail_ip}" ] || [ "${_jail_ip}" = "-" ]; then error_notify "Jail IP not found: ${_jail}" _jail_ip='' # In case it was -. -- cwells fi @@ -301,7 +301,7 @@ for _jail in ${JAILS}; do # Escape single-quotes in the command being executed. -- cwells _args=$(echo "${_args}" | sed "s/'/'\\\\''/g") # Allow redirection within the jail. -- cwells - _args="sh -c \"${_args}\"" + _args="sh -c ${_args}" ;; cp|copy) _cmd='cp' @@ -372,7 +372,7 @@ for _jail in ${JAILS}; do if [ "${_hook}" = 'CMD' ] || [ "${_hook}" = 'PRE' ]; then bastille cmd "${_jail}" /bin/sh < "${bastille_template}/${_hook}" || exit 1 elif [ "${_hook}" = 'PKG' ]; then - bastille pkg "${_jail}" install -y $(cat "${bastille_template}/PKG") || exit 1 + bastille pkg "${_jail}" install -y "$(cat "${bastille_template}/PKG")" || exit 1 bastille pkg "${_jail}" audit -F else while read _line; do @@ -382,7 +382,7 @@ for _jail in ${JAILS}; do # Replace "arg" variables in this line with the provided values. -- cwells _line=$(echo "${_line}" | eval "sed ${ARG_REPLACEMENTS}") eval "_args=\"${_args_template}\"" - bastille "${_cmd}" "${_jail}" ${_args} || exit 1 + bastille "${_cmd}" "${_jail}" "${_args}" || exit 1 done < "${bastille_template}/${_hook}" fi info "[${_jail}]:${_hook} -- END" diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index 13ac0f7f2..d17fd7ca1 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -63,7 +63,7 @@ while [ "$#" -gt 0 ]; do OPTION="-F" shift ;; - -*|--*) + -*) error_exit "Unknown option: \"${1}\"" ;; *) @@ -152,6 +152,7 @@ template_update() { templates_update() { # Update all templates + # shellcheck disable=SC2045 _updated_templates=0 if [ -d ${bastille_templatesdir} ]; then for _template_path in $(ls -d ${bastille_templatesdir}/*/*); do diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh index 4f56bf4d2..91eb2495b 100644 --- a/usr/local/share/bastille/verify.sh +++ b/usr/local/share/bastille/verify.sh @@ -78,7 +78,8 @@ verify_template() { info "Detected ${_hook} hook." ## line count must match newline count - if [ $(wc -l "${_path}" | awk '{print $1}') -ne $(grep -c $'\n' "${_path}") ]; then + # shellcheck disable=SC3003 + if [ "$(wc -l "${_path}" | awk '{print $1}')" -ne "$(grep -c $'\n' "${_path}")" ]; then info "[${_hook}]:" error_notify "${BASTILLE_TEMPLATE}:${_hook} [failed]." error_notify "Line numbers don't match line breaks." diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index ec4a98ee8..441a10511 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -37,6 +37,7 @@ usage() { zfs_snapshot() { for _jail in ${JAILS}; do + # shellcheck disable=SC2140 info "[${_jail}]:" zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" echo @@ -45,6 +46,7 @@ done zfs_destroy_snapshot() { for _jail in ${JAILS}; do + # shellcheck disable=SC2140 info "[${_jail}]:" zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" echo From 3b38f8f8d9cf9f0a15ed2eb4863b9cea40dbea07 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Fri, 20 Dec 2024 18:32:36 -0700 Subject: [PATCH 074/120] next try --- usr/local/share/bastille/clone.sh | 2 +- usr/local/share/bastille/create.sh | 9 ++++++++- usr/local/share/bastille/etcupdate.sh | 2 +- usr/local/share/bastille/import.sh | 2 +- usr/local/share/bastille/list.sh | 14 +++++++------- usr/local/share/bastille/update.sh | 4 ++-- usr/local/share/bastille/zfs.sh | 4 ++-- 7 files changed, 22 insertions(+), 15 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index de2545ff1..9fa166c0c 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -59,13 +59,13 @@ if echo "${NEWNAME}" | grep -q "[.]"; then fi validate_ip() { - # shellcheck disable=SC2034 IPX_ADDR="ip4.addr" IP6_MODE="disable" ip6=$(echo "${IP}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))') if [ -n "${ip6}" ]; then info "Valid: (${ip6})." IPX_ADDR="ip6.addr" + # shellcheck disable=SC2034 IP6_MODE="new" else local IFS diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index 0876924d2..2e7d2c5dd 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -271,14 +271,15 @@ post_create_jail() { } create_jail() { - # shellcheck disable=SC2034 bastille_jail_base="${bastille_jailsdir}/${NAME}/root/.bastille" ## dir bastille_jail_template="${bastille_jailsdir}/${NAME}/root/.template" ## dir bastille_jail_path="${bastille_jailsdir}/${NAME}/root" ## dir bastille_jail_fstab="${bastille_jailsdir}/${NAME}/fstab" ## file bastille_jail_conf="${bastille_jailsdir}/${NAME}/jail.conf" ## file bastille_jail_log="${bastille_logsdir}/${NAME}_console.log" ## file + # shellcheck disable=SC2034 bastille_jail_rc_conf="${bastille_jailsdir}/${NAME}/root/etc/rc.conf" ## file + # shellcheck disable=SC2034 bastille_jail_resolv_conf="${bastille_jailsdir}/${NAME}/root/etc/resolv.conf" ## file if [ ! -d "${bastille_jailsdir}/${NAME}" ]; then @@ -398,6 +399,7 @@ create_jail() { # shellcheck disable=SC2140 zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" + # shellcheck disable=SC2140 zfs clone -p "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" \ "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" @@ -412,16 +414,20 @@ create_jail() { ## take a temp snapshot of the base release SNAP_NAME="bastille-$(date +%Y-%m-%d-%H%M%S)" + # shellcheck disable=SC2140 zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" ## replicate the release base to the new thickjail and set the default mountpoint + # shellcheck disable=SC2140 zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" | \ zfs receive "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" zfs set ${ZFS_OPTIONS} mountpoint=none "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" zfs inherit mountpoint "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" ## cleanup temp snapshots initially + # shellcheck disable=SC2140 zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" + # shellcheck disable=SC2140 zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"@"${SNAP_NAME}" fi @@ -597,6 +603,7 @@ bastille_root_check if echo "$3" | grep '@'; then # shellcheck disable=SC2034 BASTILLE_JAIL_IP=$(echo "$3" | awk -F@ '{print $2}') + # shellcheck disable=SC2034 BASTILLE_JAIL_INTERFACES=$( echo "$3" | awk -F@ '{print $1}') fi diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh index 890758b04..8b7588ae7 100644 --- a/usr/local/share/bastille/etcupdate.sh +++ b/usr/local/share/bastille/etcupdate.sh @@ -55,7 +55,7 @@ fi bootstrap_etc_release() { local _release="${1}" - local _release_version=$( echo "${1}" | awk -F "-" '{print $1}' ) + local _release_version="$( echo "${1}" | awk -F "-" '{print $1}' )" if [ ! -d /usr/local/bastille/source/"${_release}" ]; then if ! git clone --branch releng/"${_release_version}" --depth 1 https://git.FreeBSD.org/src.git /usr/local/bastille/source/"${_release}"; then error_exit "Failed to bootstrap etcupdate release \"${_release}\"" diff --git a/usr/local/share/bastille/import.sh b/usr/local/share/bastille/import.sh index 2c7e49b08..5e8e29a01 100644 --- a/usr/local/share/bastille/import.sh +++ b/usr/local/share/bastille/import.sh @@ -324,7 +324,7 @@ update_config() { >> "${bastille_jailsdir}/${TARGET_TRIM}/fstab" # Work with the symlinks - cd "${bastille_jailsdir}/${TARGET_TRIM}/root" + cd "${bastille_jailsdir}/${TARGET_TRIM}/root" || error_exit "Could not cd to ${bastille_jailsdir}/${TARGET_TRIM}/root" update_symlinks } diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index b6a741873..293970fe8 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -57,12 +57,12 @@ list_all(){ if [ -d "${bastille_jailsdir}" ]; then DEFAULT_VALUE="-" SPACER=2 - MAX_LENGTH_JAIL_NAME=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h -m 1 -e "^.* {$" | awk '{ print length($1) }' | sort -nr | head -n 1) + MAX_LENGTH_JAIL_NAME="$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h -m 1 -e "^.* {$" | awk '{ print length($1) }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_NAME=${MAX_LENGTH_JAIL_NAME:-3} if [ "${MAX_LENGTH_JAIL_NAME}" -lt 3 ]; then MAX_LENGTH_JAIL_NAME=3; fi 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)" + 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 +73,11 @@ 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)" + 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)" + 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 @@ -118,7 +118,7 @@ list_all(){ JAIL_RELEASE=$(grep -hE "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }') fi else - JAIL_STATE=$(if [ "$(sed -n "/^${JAIL_NAME} {$/,/^}$/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | awk '$0 ~ /^'${JAIL_NAME}' \{|\}/ { printf "%s",$0 }')" == "${JAIL_NAME} {}" ]; then echo "Down"; else echo "n/a"; fi) + JAIL_STATE=$(if [ "$(sed -n "/^${JAIL_NAME} {$/,/^}$/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | awk '$0 ~ /^'${JAIL_NAME}' \{|\}/ { printf "%s",$0 }')" = "${JAIL_NAME} {}" ]; then echo "Down"; else echo "n/a"; fi) if [ "$(awk '$1 == "vnet;" { print $1 }' "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)" ]; then JAIL_IP=$(sed -n 's/^ifconfig_vnet0="\(.*\)"$/\1/p' "${bastille_jailsdir}/${JAIL_NAME}/root/etc/rc.conf" 2> /dev/null | sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print $2; else print $1 }') else @@ -130,9 +130,9 @@ list_all(){ if [ "${JAIL_PATH}" ]; then if [ "${IS_FREEBSD_JAIL}" -eq 1 ]; then if [ -f "${JAIL_PATH}/bin/freebsd-version" ]; then - JAIL_RELEASE=$(grep -hE "^USERLAND_VERSION=" "${JAIL_PATH}/bin/freebsd-version" 2> /dev/null | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") + JAIL_RELEASE="$(grep -hE "^USERLAND_VERSION=" "${JAIL_PATH}/bin/freebsd-version" 2> /dev/null | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p")" else - JAIL_RELEASE=$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | 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") + JAIL_RELEASE="$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | 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")" fi fi if [ "${IS_LINUX_JAIL}" -eq 1 ]; then diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index d17fd7ca1..61c189db6 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -152,10 +152,10 @@ template_update() { templates_update() { # Update all templates - # shellcheck disable=SC2045 _updated_templates=0 if [ -d ${bastille_templatesdir} ]; then - for _template_path in $(ls -d ${bastille_templatesdir}/*/*); do + # shellcheck disable=SC2045 + for _template_path in "$(ls -d ${bastille_templatesdir}/*/*)"; do if [ -d $_template_path/.git ]; then BASTILLE_TEMPLATE=$(echo "$_template_path" | awk -F / '{ print $(NF-1) "/" $NF }') template_update diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 441a10511..309f00986 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -37,8 +37,8 @@ usage() { zfs_snapshot() { for _jail in ${JAILS}; do - # shellcheck disable=SC2140 info "[${_jail}]:" + # shellcheck disable=SC2140 zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" echo done @@ -46,8 +46,8 @@ done zfs_destroy_snapshot() { for _jail in ${JAILS}; do - # shellcheck disable=SC2140 info "[${_jail}]:" + # shellcheck disable=SC2140 zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" echo done From 99830d2fb0e2ffd055a0d5054c02f5ff3b2582ea Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Fri, 20 Dec 2024 18:36:35 -0700 Subject: [PATCH 075/120] next --- usr/local/share/bastille/list.sh | 40 +++++++++++++++++--------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 293970fe8..d2d8d7168 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -35,12 +35,11 @@ usage() { error_exit "Usage: bastille list [-j|-a] [release [-p]|template|(jail|container)|log|limit|(import|export|backup)]" } -# Handle special-case commands first. -case "$1" in - help|-h|--help) - usage - ;; -esac +if [ "${1}" = help ] || [ "${1}" = "-h" ] || [ "${1}" = "--help" ]; then + usage +fi + +bastille_root_check if [ $# -eq 0 ]; then /usr/sbin/jls @@ -57,12 +56,12 @@ list_all(){ if [ -d "${bastille_jailsdir}" ]; then DEFAULT_VALUE="-" SPACER=2 - MAX_LENGTH_JAIL_NAME="$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h -m 1 -e "^.* {$" | awk '{ print length($1) }' | sort -nr | head -n 1) + MAX_LENGTH_JAIL_NAME=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h -m 1 -e "^.* {$" | awk '{ print length($1) }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_NAME=${MAX_LENGTH_JAIL_NAME:-3} if [ "${MAX_LENGTH_JAIL_NAME}" -lt 3 ]; then MAX_LENGTH_JAIL_NAME=3; fi 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)" + 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 +72,11 @@ 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)" + 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=$(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)" + 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 @@ -130,9 +129,9 @@ list_all(){ if [ "${JAIL_PATH}" ]; then if [ "${IS_FREEBSD_JAIL}" -eq 1 ]; then if [ -f "${JAIL_PATH}/bin/freebsd-version" ]; then - JAIL_RELEASE="$(grep -hE "^USERLAND_VERSION=" "${JAIL_PATH}/bin/freebsd-version" 2> /dev/null | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p")" + JAIL_RELEASE=$(grep -hE "^USERLAND_VERSION=" "${JAIL_PATH}/bin/freebsd-version" 2> /dev/null | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") else - JAIL_RELEASE="$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | 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")" + JAIL_RELEASE=$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | 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") fi fi if [ "${IS_LINUX_JAIL}" -eq 1 ]; then @@ -159,9 +158,13 @@ list_all(){ fi } +# TODO: Check the correct usage or arguments here. See SC2120. +# shellcheck disable=SC2120 list_release(){ if [ -d "${bastille_releasesdir}" ]; then - REL_LIST=$(ls "${bastille_releasesdir}" | sed "s/\n//g") + # TODO: Check if this can be changed to `find` as SC2012 suggests. + # shellcheck disable=SC2012 + REL_LIST="$(ls "${bastille_releasesdir}" | sed "s/\n//g")" for _REL in ${REL_LIST}; do if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" ] || [ -d "${bastille_releasesdir}/${_REL}/debootstrap" ]; then if [ "${1}" = "-p" ] && [ -f "${bastille_releasesdir}/${_REL}/bin/freebsd-version" ]; then @@ -206,11 +209,10 @@ list_import(){ list_ports() { if [ -d "${bastille_jailsdir}" ]; then - JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") + JAIL_LIST="$(ls "${bastille_jailsdir}" | sed "s/\n//g")" for _JAIL in ${JAIL_LIST}; do if [ -f "${bastille_jailsdir}/${_JAIL}/rdr.conf" ]; then - _PORTS=$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf) - #_PORTS=$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf | awk '{print $1" "$2":"$5"//"$3":"$6" -> "$4":"$7}') + _PORTS="$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf)" info "[$_JAIL]:" echo "${_PORTS}" fi @@ -224,7 +226,7 @@ if [ $# -gt 0 ]; then all|-a|--all) list_all ;; - port|ports) + port|ports) list_ports ;; release|releases) @@ -256,4 +258,4 @@ if [ $# -gt 0 ]; then fi ;; esac -fi +fi \ No newline at end of file From c7f744f65ecaf864fa9ba056d3fb315ab22fe6c4 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Fri, 20 Dec 2024 18:37:22 -0700 Subject: [PATCH 076/120] next --- usr/local/share/bastille/update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index 61c189db6..c7be8029e 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -155,7 +155,7 @@ templates_update() { _updated_templates=0 if [ -d ${bastille_templatesdir} ]; then # shellcheck disable=SC2045 - for _template_path in "$(ls -d ${bastille_templatesdir}/*/*)"; do + for _template_path in $(ls -d ${bastille_templatesdir}/*/*); do if [ -d $_template_path/.git ]; then BASTILLE_TEMPLATE=$(echo "$_template_path" | awk -F / '{ print $(NF-1) "/" $NF }') template_update From 8b4871c60e1ca5518db1b7f98f3c61caf44d6610 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Fri, 20 Dec 2024 18:54:08 -0700 Subject: [PATCH 077/120] copyright year --- usr/local/share/bastille/bootstrap.sh | 2 +- usr/local/share/bastille/clone.sh | 2 +- usr/local/share/bastille/cmd.sh | 2 +- usr/local/share/bastille/config.sh | 2 +- usr/local/share/bastille/console.sh | 2 +- usr/local/share/bastille/convert.sh | 2 +- usr/local/share/bastille/cp.sh | 2 +- usr/local/share/bastille/create.sh | 2 +- usr/local/share/bastille/edit.sh | 2 +- usr/local/share/bastille/import.sh | 4 ++-- usr/local/share/bastille/limits.sh | 4 ++-- usr/local/share/bastille/mount.sh | 2 +- usr/local/share/bastille/pkg.sh | 2 +- usr/local/share/bastille/rcp.sh | 2 +- usr/local/share/bastille/rename.sh | 4 ++-- usr/local/share/bastille/service.sh | 2 +- usr/local/share/bastille/start.sh | 2 +- usr/local/share/bastille/stop.sh | 4 ++-- usr/local/share/bastille/sysrc.sh | 2 +- usr/local/share/bastille/tags.sh | 4 ++-- usr/local/share/bastille/template.sh | 2 +- usr/local/share/bastille/umount.sh | 4 ++-- usr/local/share/bastille/update.sh | 2 +- usr/local/share/bastille/upgrade.sh | 2 +- usr/local/share/bastille/verify.sh | 2 +- usr/local/share/bastille/zfs.sh | 2 +- 26 files changed, 32 insertions(+), 32 deletions(-) diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index 97d878fd6..d7c937747 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # 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 9fa166c0c..20fecec2a 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/cmd.sh b/usr/local/share/bastille/cmd.sh index f98b072ca..8b6660974 100644 --- a/usr/local/share/bastille/cmd.sh +++ b/usr/local/share/bastille/cmd.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/config.sh b/usr/local/share/bastille/config.sh index 48a703719..a878fca9f 100644 --- a/usr/local/share/bastille/config.sh +++ b/usr/local/share/bastille/config.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # 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 e298e9cfd..367988dd9 100644 --- a/usr/local/share/bastille/console.sh +++ b/usr/local/share/bastille/console.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # 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 b1f11f076..5a0a41df7 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # 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 8b9e101cd..45bf3a4ec 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # 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 2e7d2c5dd..d6832e47f 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # 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 30b8cf671..b14d5273b 100644 --- a/usr/local/share/bastille/edit.sh +++ b/usr/local/share/bastille/edit.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/import.sh b/usr/local/share/bastille/import.sh index 5e8e29a01..09437eb02 100644 --- a/usr/local/share/bastille/import.sh +++ b/usr/local/share/bastille/import.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -49,7 +49,7 @@ EOF } # Handle special-case commands first -case "$1" in +case "${1}" in help|-h|--help) usage ;; diff --git a/usr/local/share/bastille/limits.sh b/usr/local/share/bastille/limits.sh index d8bde4ab6..e1ca91ab2 100644 --- a/usr/local/share/bastille/limits.sh +++ b/usr/local/share/bastille/limits.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # Ressource limits added by Sven R github.com/hackacad # @@ -39,7 +39,7 @@ usage() { } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 6153e2406..dc84480a5 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # 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 2567234e6..ff442fd4c 100644 --- a/usr/local/share/bastille/pkg.sh +++ b/usr/local/share/bastille/pkg.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # 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 4fdee02ef..ee0894ce1 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2024, 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 e3f24d3be..f4381b59b 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -45,7 +45,7 @@ EOF # Handle special-case commands first -case "$1" in +case "${1}" in help|-h|--help) usage ;; diff --git a/usr/local/share/bastille/service.sh b/usr/local/share/bastille/service.sh index b1028eb0d..71de29ce7 100644 --- a/usr/local/share/bastille/service.sh +++ b/usr/local/share/bastille/service.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # 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 ede1986f6..72103ad3b 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -36,7 +36,7 @@ usage() { } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index adf10c918..a35176842 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -36,7 +36,7 @@ usage() { } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; diff --git a/usr/local/share/bastille/sysrc.sh b/usr/local/share/bastille/sysrc.sh index e696332ec..92f2939f0 100644 --- a/usr/local/share/bastille/sysrc.sh +++ b/usr/local/share/bastille/sysrc.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # 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 0dca190c1..1b2835884 100644 --- a/usr/local/share/bastille/tags.sh +++ b/usr/local/share/bastille/tags.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # Ressource limits added by Lars Engels github.com/bsdlme # @@ -44,7 +44,7 @@ usage() { } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 3aa03b7ec..8ffd1bfa4 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index 939b9562d..60dfc295c 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -36,7 +36,7 @@ usage() { } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index c7be8029e..cc5b9b81e 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -45,7 +45,7 @@ EOF # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; diff --git a/usr/local/share/bastille/upgrade.sh b/usr/local/share/bastille/upgrade.sh index 489f053eb..9179bba91 100644 --- a/usr/local/share/bastille/upgrade.sh +++ b/usr/local/share/bastille/upgrade.sh @@ -36,7 +36,7 @@ usage() { } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh index 91eb2495b..7470b1211 100644 --- a/usr/local/share/bastille/verify.sh +++ b/usr/local/share/bastille/verify.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # 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 309f00986..aa7c4d1e7 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2023, Christer Edwards +# Copyright (c) 2018-2024, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without From 5cb69993a54f85c4276c7a71e9bda5038d5ee449 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Sat, 21 Dec 2024 16:47:18 -0700 Subject: [PATCH 078/120] rename fixes --- usr/local/share/bastille/rename.sh | 31 +++++++++--------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index f4381b59b..681200d77 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille rename TARGET NEW_NAME" + error_exit "Usage: bastille rename [option(s)] TARGET NEW_NAME" cat << EOF Options: @@ -96,6 +96,7 @@ validate_name() { update_jailconf() { # Update jail.conf JAIL_CONFIG="${bastille_jailsdir}/${NEWNAME}/jail.conf" + BASTILLE_JAIL_RC_CONF="${bastille_jailsdir}/${NEWNAME}/root/etc/rc.conf" if [ -f "${JAIL_CONFIG}" ]; then if ! grep -qw "path = ${bastille_jailsdir}/${NEWNAME}/root;" "${JAIL_CONFIG}"; then sed -i '' "s|host.hostname.*=.*${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}" @@ -103,9 +104,11 @@ update_jailconf() { sed -i '' "s|path.*=.*;|path = ${bastille_jailsdir}/${NEWNAME}/root;|" "${JAIL_CONFIG}" sed -i '' "s|mount.fstab.*=.*;|mount.fstab = ${bastille_jailsdir}/${NEWNAME}/fstab;|" "${JAIL_CONFIG}" sed -i '' "s|${TARGET}.*{|${NEWNAME} {|" "${JAIL_CONFIG}" - # Rename vnet interface - sed -i '' "/vnet.interface/s|_${TARGET}\";|_${NEWNAME}\";|" "${JAIL_CONFIG}" + # update vnet config + sed -i '' "s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|" "${JAIL_CONFIG}" + sed -i '' "/vnet.interface/s|_${TARGET};|_${NEWNAME};|" "${JAIL_CONFIG}" sed -i '' "/ifconfig/s|_${TARGET}|_${NEWNAME}|" "${JAIL_CONFIG}" + sed -i '' "/ifconfig/s|_${TARGET}_name=|_${NEWNAME}_name=|" "${BASTILLE_JAIL_RC_CONF}" fi fi } @@ -113,25 +116,9 @@ update_jailconf() { update_fstab() { # Update fstab to use the new name FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab" - if [ -f "${FSTAB_CONFIG}" ]; then - # Skip if fstab is empty, e.g newly created thick or clone jails - if [ -s "${FSTAB_CONFIG}" ]; then - FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-9])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}") - FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET}/root/.bastille" "${FSTAB_CONFIG}") - FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${NEWNAME}/root/.bastille nullfs ro 0 0" - if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then - # If both variables are set, update as needed - if ! grep -qw "${bastille_releasesdir}/${FSTAB_RELEASE}.*${bastille_jailsdir}/${NEWNAME}/root/.bastille" "${FSTAB_CONFIG}"; then - sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" "${FSTAB_CONFIG}" - fi - fi - - # Update linuxjail fstab name entries - # Search for either linprocfs/linsysfs, if true assume is a linux jail - if grep -qwE "linprocfs|linsysfs" "${FSTAB_CONFIG}"; then - sed -i '' "s|.${bastille_jailsdir}/${TARGET}/|${bastille_jailsdir}/${NEWNAME}/|" "${FSTAB_CONFIG}" - fi - fi + if [ -f "${FSTAB_CONFIG}" ] && [ -s "${FSTAB_CONFIG}" ]; then + # Update fstab paths with new jail path + sed -i '' "s|\ ${bastille_jailsdir}/${TARGET}/root/|\ ${bastille_jailsdir}/${NEWNAME}/root/|g" "${FSTAB_CONFIG}" fi } From 7c0acb1ba0c6518351080d5887707152083f741b Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Sat, 21 Dec 2024 18:41:05 -0700 Subject: [PATCH 079/120] integrate latest PRs --- usr/local/share/bastille/destroy.sh | 6 ++++++ usr/local/share/bastille/mount.sh | 14 +++++++------- usr/local/share/bastille/start.sh | 10 +++++----- usr/local/share/bastille/stop.sh | 10 ++++------ usr/local/share/bastille/template.sh | 8 ++++++-- usr/local/share/bastille/umount.sh | 2 +- 6 files changed, 29 insertions(+), 21 deletions(-) diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index f0519b658..2b81138a2 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -60,6 +60,12 @@ destroy_jail() { fi if [ -d "${bastille_jail_base}" ]; then + ## make sure no filesystem is currently mounted in the jail directory + mount_points="$(mount | cut -d ' ' -f 3 | grep "${bastille_jail_base}"/root/)" + if [ "$?" -eq 0 ]; then + error_notify "Failed to destroy jail: ${TARGET}" + error_exit "Jail has mounted filesystems:\n$mount_points" + fi info "Deleting Jail: ${TARGET}." if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index dc84480a5..fe5b377ae 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -83,7 +83,7 @@ if { [ "${_hostpath}" = "tmpfs" ] && [ "$_type" = "tmpfs" ]; } || \ warn "Detected advanced mount type ${_hostpath}" elif [ ! -d "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then error_notify "Detected invalid host path or incorrect mount type in FSTAB." - warn "Format: /host/path jail/path nullfs ro 0 0" + warn "Format: /host/path /jail/path nullfs ro 0 0" warn "Read: ${_fstab}" exit 1 fi @@ -108,7 +108,7 @@ for _jail in ${JAILS}; do info "[${_jail}]:" ## aggregate variables into FSTAB entry - _fullpath="${bastille_jailsdir}${_jail}/root/${_jailpath}" + _fullpath="${bastille_jailsdir}/${_jail}/root${_jailpath}" _fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}" ## Create mount point if it does not exist. -- cwells @@ -119,15 +119,15 @@ for _jail in ${JAILS}; do fi ## if entry doesn't exist, add; else show existing entry - if ! egrep -q "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}${_jail}/fstab" 2> /dev/null; then - if ! echo "${_fstab_entry}" >> "${bastille_jailsdir}${_jail}/fstab"; then + if ! egrep -q "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" 2> /dev/null; then + if ! echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab"; then error_exit "Failed to create fstab entry: ${_fstab_entry}" fi echo "Added: ${_fstab_entry}" else - warn "Mountpoint already present in ${bastille_jailsdir}${_jail}/fstab" - egrep "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}${_jail}/fstab" + warn "Mountpoint already present in ${bastille_jailsdir}/${_jail}/fstab" + egrep "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" fi - mount -F "${bastille_jailsdir}${_jail}/fstab" -a + mount -F "${bastille_jailsdir}/${_jail}/fstab" -a echo done diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index 72103ad3b..d06a26f93 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -63,14 +63,14 @@ for _jail in ${JAILS}; do fi ## warn if matching configured (but not online) ip4.addr, ignore if there's no ip4.addr entry - _ip="$(bastille config "${_jail}" get ip4.addr)" - if [ "${_ip}" != "not set" ]; then - if ifconfig | grep -wF "${_ip}" >/dev/null; then - error_notify "Error: IP address (${_ip}) already in use." + _ip4="$(bastille config "${_jail}" get ip4.addr)" + if [ "${_ip4}" != "not set" ]; then + if ifconfig | grep -wF "${_ip4}" >/dev/null; then + error_notify "Error: IP address (${_ip4}) already in use." continue fi ## add ip4.addr to firewall table - pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip}" + pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip4}" fi ## start the container diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index a35176842..c40de8a13 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -54,13 +54,11 @@ set_target "${TARGET}" for _jail in ${JAILS}; do check_target_is_running "${_jail}" || continue ## Capture ip4.addr address while still running - if [ "$(bastille config "${_jail}" get ip4.addr)" != "not set" ]; then - _ip="$(/usr/sbin/jls -j ${_jail} ip4.addr)" - fi + _ip4="$(bastille config ${_jail} get ip4.addr)" # Check if pfctl is present # Do not invoke pfctl if no ip4.addr found - if [ -n "${_ip}" ]; then + if [ "${_ip4}" != "not set" ]; then if which -s pfctl; then if [ "$(bastille rdr ${_jail} list)" ]; then bastille rdr ${_jail} clear @@ -80,9 +78,9 @@ for _jail in ${JAILS}; do jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" ## remove (captured above) ip4.addr from firewall table - if [ -n "${bastille_network_loopback}" ] && [ ! -z "${_ip}" ]; then + if [ -n "${bastille_network_loopback}" ] && [ "${_ip4}" != "not set" ]; then if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then - pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" + pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip4}" fi fi done diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 8ffd1bfa4..2184e24d5 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -198,7 +198,11 @@ case ${TEMPLATE} in fi ;; *) - error_exit "Template name/URL not recognized." + if [ ! -f ${TEMPLATE}/Bastillefile ]; then + error_exit "${TEMPLATE} not found." + else + bastille_template=${TEMPLATE} + fi esac if [ -z "${JAILS}" ]; then @@ -301,7 +305,7 @@ for _jail in ${JAILS}; do # Escape single-quotes in the command being executed. -- cwells _args=$(echo "${_args}" | sed "s/'/'\\\\''/g") # Allow redirection within the jail. -- cwells - _args="sh -c ${_args}" + _args="sh -c \"${_args}\"" ;; cp|copy) _cmd='cp' diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index 60dfc295c..13166060d 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -54,7 +54,7 @@ set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" - _jailpath="${bastille_jailsdir}${_jail}/root${MOUNT_PATH}" + _jailpath="${bastille_jailsdir}/${_jail}/root${MOUNT_PATH}" if [ ! -d "${_jailpath}" ]; then error_exit "The specified mount point does not exist inside the jail." From 53f64f6012882f2ab2a085b9ba35e2ae6973638a Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 22 Dec 2024 12:43:21 -0700 Subject: [PATCH 080/120] Allow file mounting --- usr/local/share/bastille/mount.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index fe5b377ae..df702fc2b 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -112,10 +112,11 @@ for _jail in ${JAILS}; do _fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}" ## Create mount point if it does not exist. -- cwells - if [ ! -d "${_fullpath}" ]; then - if ! mkdir -p "${_fullpath}"; then - error_exit "Failed to create mount point inside jail." - fi + if [ -d "${_hostpath}" ] && [ ! -d "${_fullpath}" ]; then + mkdir -p "${_fullpath}" || error_exit "Failed to create mount point inside jail." + elif [ -f "${_hostpath}" ] && [ ! -f "${_fullpath}" ]; then + mkdir -p "$( dirname ${_fullpath} )" || error_exit "Failed to create mount point inside jail." + touch "${_fullpath}" || error_exit "Failed to create mount point inside jail." fi ## if entry doesn't exist, add; else show existing entry From 4d051740acfd03c4c3fc3902e0cea1f688378ab9 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 22 Dec 2024 12:43:48 -0700 Subject: [PATCH 081/120] Update mount.sh --- usr/local/share/bastille/mount.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index df702fc2b..5ffe6d0a5 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -81,7 +81,7 @@ if { [ "${_hostpath}" = "tmpfs" ] && [ "$_type" = "tmpfs" ]; } || \ { [ "${_hostpath}" = "proc" ] && [ "${_type}" = "procfs" ]; } || \ { [ "${_hostpath}" = "fdesc" ] && [ "${_type}" = "fdescfs" ]; } then warn "Detected advanced mount type ${_hostpath}" -elif [ ! -d "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then +elif [ ! -e "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then error_notify "Detected invalid host path or incorrect mount type in FSTAB." warn "Format: /host/path /jail/path nullfs ro 0 0" warn "Read: ${_fstab}" From 72cceba55fc169781a9fe3843f6cfa7f22f1f1e4 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 22 Dec 2024 12:47:05 -0700 Subject: [PATCH 082/120] Strip // to / --- usr/local/share/bastille/mount.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 5ffe6d0a5..ce08f83d5 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -108,7 +108,7 @@ for _jail in ${JAILS}; do info "[${_jail}]:" ## aggregate variables into FSTAB entry - _fullpath="${bastille_jailsdir}/${_jail}/root${_jailpath}" + _fullpath="$( echo ${bastille_jailsdir}/${_jail}/root${_jailpath} 2>/dev/null | sed 's#//#/#' )" _fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}" ## Create mount point if it does not exist. -- cwells From f623d2554e835842690b16ff68e95bb2ce0c6d11 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 22 Dec 2024 12:48:33 -0700 Subject: [PATCH 083/120] Strip // to / --- usr/local/share/bastille/umount.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index 13166060d..0c37791b5 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -54,9 +54,9 @@ set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" - _jailpath="${bastille_jailsdir}/${_jail}/root${MOUNT_PATH}" + _jailpath="$( echo ${bastille_jailsdir}/${_jail}/root${MOUNT_PATH}" 2>/dev/null | sed '#//#/#' )" - if [ ! -d "${_jailpath}" ]; then + if [ ! -e "${_jailpath}" ]; then error_exit "The specified mount point does not exist inside the jail." fi From 138414d1bd43912b17a0cfbf0762397d93495dc1 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 22 Dec 2024 13:59:30 -0700 Subject: [PATCH 084/120] Update umount.sh --- usr/local/share/bastille/umount.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index 0c37791b5..5926e8463 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -54,7 +54,7 @@ set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" - _jailpath="$( echo ${bastille_jailsdir}/${_jail}/root${MOUNT_PATH}" 2>/dev/null | sed '#//#/#' )" + _jailpath="$( echo "${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH}" 2>/dev/null | sed '#//#/#' )" if [ ! -e "${_jailpath}" ]; then error_exit "The specified mount point does not exist inside the jail." From 16c9ac97615cf17c251990cc9d0bf808ea268c90 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Sun, 22 Dec 2024 19:20:35 -0700 Subject: [PATCH 085/120] fix mounting and unmounting --- usr/local/share/bastille/htop.sh | 30 +++++++++++++++++- usr/local/share/bastille/mount.sh | 51 +++++++++++++++--------------- usr/local/share/bastille/top.sh | 32 +++++++++++++++++-- usr/local/share/bastille/umount.sh | 26 +++++++++------ 4 files changed, 100 insertions(+), 39 deletions(-) diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh index d9741d151..62c93070b 100644 --- a/usr/local/share/bastille/htop.sh +++ b/usr/local/share/bastille/htop.sh @@ -33,6 +33,13 @@ usage() { error_exit "Usage: bastille htop TARGET" + cat << EOF + Options: + + -f | --force -- Start the jail if it is stopped. + +EOF + exit 1 } # Handle special-case commands first. @@ -46,11 +53,32 @@ if [ $# -ne 1 ]; then usage fi +# Handle options. +FORCE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -f|--force) + FORCE=1 + shift + ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done + TARGET="${1}" bastille_root_check set_target_single "${TARGET}" -check_target_is_running "${TARGET}" || exit +check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${TARGET}" +else + exit +fi bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path) if [ ! -x "${bastille_jail_path}/usr/local/bin/htop" ]; then diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index fe5b377ae..843d198fc 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -42,14 +42,14 @@ case "${1}" in ;; esac -if [ $# -lt 3 ]; then +if [ "$#" -lt 3 ]; then usage fi TARGET="${1}" shift -if [ $# -eq 2 ]; then +if [ "$#" -eq 2 ]; then _fstab="$@ nullfs ro 0 0" else _fstab="$@" @@ -58,76 +58,75 @@ fi bastille_root_check set_target "${TARGET}" -## assign needed variables +# Assign variables _hostpath=$(echo "${_fstab}" | awk '{print $1}') _jailpath=$(echo "${_fstab}" | awk '{print $2}') _type=$(echo "${_fstab}" | awk '{print $3}') _perms=$(echo "${_fstab}" | awk '{print $4}') _checks=$(echo "${_fstab}" | awk '{print $5" "$6}') -## if any variables are empty, bail out +## Exit if any variables are empty if [ -z "${_hostpath}" ] || [ -z "${_jailpath}" ] || [ -z "${_type}" ] || [ -z "${_perms}" ] || [ -z "${_checks}" ]; then error_notify "FSTAB format not recognized." warn "Format: /host/path /jail/path nullfs ro 0 0" warn "Read: ${_fstab}" - exit 1 + usage fi -# if host path doesn't exist, type is not "nullfs" or are using advanced mount type "tmpfs,linprocfs,linsysfs, fdescfs, -# procfs" +# Exit if host path doesn't exist, type is not "nullfs", or mount is an advanced mount type "tmpfs,linprocfs,linsysfs,fdescfs,procfs" if { [ "${_hostpath}" = "tmpfs" ] && [ "$_type" = "tmpfs" ]; } || \ { [ "${_hostpath}" = "linprocfs" ] && [ "${_type}" = "linprocfs" ]; } || \ { [ "${_hostpath}" = "linsysfs" ] && [ "${_type}" = "linsysfs" ]; } || \ { [ "${_hostpath}" = "proc" ] && [ "${_type}" = "procfs" ]; } || \ { [ "${_hostpath}" = "fdesc" ] && [ "${_type}" = "fdescfs" ]; } then warn "Detected advanced mount type ${_hostpath}" -elif [ ! -d "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then - error_notify "Detected invalid host path or incorrect mount type in FSTAB." +elif [ ! -e "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then + error_notify "Invalid host path or incorrect mount type in FSTAB." warn "Format: /host/path /jail/path nullfs ro 0 0" warn "Read: ${_fstab}" - exit 1 + usage fi -## if mount permissions are not "ro" or "rw" +## Mount permission need to be "ro" or "rw" if [ "${_perms}" != "ro" ] && [ "${_perms}" != "rw" ]; then error_notify "Detected invalid mount permissions in FSTAB." warn "Format: /host/path /jail/path nullfs ro 0 0" warn "Read: ${_fstab}" - exit 1 + usage fi -## if check & pass are not "0 0 - 1 1"; bail out +## Dump and pass need to be "0 0 - 1 1" if [ "${_checks}" != "0 0" ] && [ "${_checks}" != "1 0" ] && [ "${_checks}" != "0 1" ] && [ "${_checks}" != "1 1" ]; then error_notify "Detected invalid fstab options in FSTAB." warn "Format: /host/path /jail/path nullfs ro 0 0" warn "Read: ${_fstab}" - exit 1 + usage fi for _jail in ${JAILS}; do info "[${_jail}]:" ## aggregate variables into FSTAB entry - _fullpath="${bastille_jailsdir}/${_jail}/root${_jailpath}" + _fullpath="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath} 2>/dev/null | sed 's#//#/#' )" _fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}" - ## Create mount point if it does not exist. -- cwells - if [ ! -d "${_fullpath}" ]; then - if ! mkdir -p "${_fullpath}"; then - error_exit "Failed to create mount point inside jail." - fi - fi - - ## if entry doesn't exist, add; else show existing entry - if ! egrep -q "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" 2> /dev/null; then + ## Create mount point if it does not exist + if [ -d "${_hostpath}" ] && [ ! -d "${_fullpath}" ]; then + mkdir -p "${_fullpath}" || error_exit "Failed to create mount point inside jail." + elif [ -f "${_hostpath}" ] && [ ! -f "${_fullpath}" ]; then + mkdir -p "$( dirname ${_fullpath} )" || error_exit "Failed to create mount point inside jail." + touch "${_fullpath}" || error_exit "Failed to create mount point inside jail." + fi + + ## If entry doesn't exist, add, else show existing entry + if ! grep -Eq "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" 2> /dev/null; then if ! echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab"; then error_exit "Failed to create fstab entry: ${_fstab_entry}" fi echo "Added: ${_fstab_entry}" else warn "Mountpoint already present in ${bastille_jailsdir}/${_jail}/fstab" - egrep "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" + grep -E "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" fi mount -F "${bastille_jailsdir}/${_jail}/fstab" -a - echo done diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh index f7d97ee67..69a4cca30 100644 --- a/usr/local/share/bastille/top.sh +++ b/usr/local/share/bastille/top.sh @@ -33,6 +33,13 @@ usage() { error_exit "Usage: bastille top TARGET" + cat << EOF + Options: + + -f | --force -- Start the jail if it is stopped. + +EOF + exit 1 } # Handle special-case commands first. @@ -42,15 +49,36 @@ case "${1}" in ;; esac -if [ $# -ne 1 ]; then +if [ "$#" -ne 1 ]; then usage fi +# Handle options. +FORCE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -f|--force) + FORCE=1 + shift + ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done + TARGET="${1}" bastille_root_check set_target_single "${TARGET}" -check_target_is_running "${TARGET}" || exit +check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${TARGET}" +else + exit +fi info "[${TARGET}]:" diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index 13166060d..2dc31014a 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -42,7 +42,7 @@ case "${1}" in ;; esac -if [ $# -ne 2 ]; then +if [ "$#" -ne 2 ]; then usage fi @@ -54,22 +54,28 @@ set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" - _jailpath="${bastille_jailsdir}/${_jail}/root${MOUNT_PATH}" + _jailpath="$( echo ${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH} 2>/dev/null | sed 's#//#/#' )" + _mount="$( mount | grep -o ${_jailpath} )" + _fstab_entry="$( cat ${bastille_jailsdir}/${_jail}/fstab | grep -o ${_jailpath} )" - if [ ! -d "${_jailpath}" ]; then + # Exit if mount point non-existent + if [ -z "${_mount}" ] && [ -z "${_fstab_entry}" ]; then error_exit "The specified mount point does not exist inside the jail." fi - # Unmount the volume. -- cwells - if ! umount "${_jailpath}"; then - error_exit "Failed to unmount volume: ${MOUNT_PATH}" + # Unmount + if [ -n "${_mount}" ]; then + if ! umount "${_jailpath}"; then + error_exit "Failed to unmount volume: ${MOUNT_PATH}" + fi fi - # Remove the entry from fstab so it is not automounted in the future. -- cwells - if ! sed -E -i '' "\, +${_jailpath} +,d" "${bastille_jailsdir}/${_jail}/fstab"; then - error_exit "Failed to delete fstab entry: ${_fstab_entry}" + # Remove entry from fstab + if [ -n "${_fstab_entry}" ]; then + if ! sed -E -i '' "\, +${_jailpath} +,d" "${bastille_jailsdir}/${_jail}/fstab"; then + error_exit "Failed to delete fstab entry: ${MOUNT_PATH}" + fi fi echo "Unmounted: ${MOUNT_PATH}" - echo done From fff6a0373cf874700c0165af9edb4e7ee7e25300 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 22 Dec 2024 20:28:40 -0700 Subject: [PATCH 086/120] Spacing --- usr/local/share/bastille/umount.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index 2dc31014a..2ce1a70d4 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -53,11 +53,12 @@ bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do - info "[${_jail}]:" _jailpath="$( echo ${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH} 2>/dev/null | sed 's#//#/#' )" _mount="$( mount | grep -o ${_jailpath} )" _fstab_entry="$( cat ${bastille_jailsdir}/${_jail}/fstab | grep -o ${_jailpath} )" + info "[${_jail}]:" + # Exit if mount point non-existent if [ -z "${_mount}" ] && [ -z "${_fstab_entry}" ]; then error_exit "The specified mount point does not exist inside the jail." From b3a042c3d96d89ec5550007a2539b96709b632e9 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 22 Dec 2024 20:29:36 -0700 Subject: [PATCH 087/120] Spacing --- usr/local/share/bastille/mount.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 843d198fc..0de54ebc9 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -104,12 +104,11 @@ if [ "${_checks}" != "0 0" ] && [ "${_checks}" != "1 0" ] && [ "${_checks}" != " fi for _jail in ${JAILS}; do - info "[${_jail}]:" - - ## aggregate variables into FSTAB entry _fullpath="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath} 2>/dev/null | sed 's#//#/#' )" _fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}" + info "[${_jail}]:" + ## Create mount point if it does not exist if [ -d "${_hostpath}" ] && [ ! -d "${_fullpath}" ]; then mkdir -p "${_fullpath}" || error_exit "Failed to create mount point inside jail." From d2d176d36dabfc4f094ffaf1ed3b4956ba2719a2 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 22 Dec 2024 20:30:59 -0700 Subject: [PATCH 088/120] More spacing --- usr/local/share/bastille/mount.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 0de54ebc9..42fa4424f 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -65,7 +65,7 @@ _type=$(echo "${_fstab}" | awk '{print $3}') _perms=$(echo "${_fstab}" | awk '{print $4}') _checks=$(echo "${_fstab}" | awk '{print $5" "$6}') -## Exit if any variables are empty +# Exit if any variables are empty if [ -z "${_hostpath}" ] || [ -z "${_jailpath}" ] || [ -z "${_type}" ] || [ -z "${_perms}" ] || [ -z "${_checks}" ]; then error_notify "FSTAB format not recognized." warn "Format: /host/path /jail/path nullfs ro 0 0" @@ -87,7 +87,7 @@ elif [ ! -e "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then usage fi -## Mount permission need to be "ro" or "rw" +## Mount permissions need to be "ro" or "rw" if [ "${_perms}" != "ro" ] && [ "${_perms}" != "rw" ]; then error_notify "Detected invalid mount permissions in FSTAB." warn "Format: /host/path /jail/path nullfs ro 0 0" From 4ec894f5c1224e62fe261ff7afd7a9dec872809e Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Mon, 23 Dec 2024 15:00:38 -0700 Subject: [PATCH 089/120] imporve mounting and add error_continue function --- usr/local/share/bastille/common.sh | 6 +++ usr/local/share/bastille/mount.sh | 61 ++++++++++++++++++++---------- usr/local/share/bastille/umount.sh | 17 ++++++--- 3 files changed, 59 insertions(+), 25 deletions(-) diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 25a342de1..7988eeb86 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -53,6 +53,12 @@ if [ -z "${NO_COLOR}" ] && [ -t 1 ]; then enable_color fi +# Notify message on error, and continue to next jail +error_continue() { + error_notify "$@" + continue +fi + # Notify message on error, but do not exit error_notify() { echo -e "${COLOR_RED}$*${COLOR_RESET}" 1>&2 diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 843d198fc..5527948fe 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -42,7 +42,7 @@ case "${1}" in ;; esac -if [ "$#" -lt 3 ]; then +if [ "$#" -lt 3 ] || [ "$#" -gt 6 ]; then usage fi @@ -87,7 +87,7 @@ elif [ ! -e "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then usage fi -## Mount permission need to be "ro" or "rw" +# Mount permission need to be "ro" or "rw" if [ "${_perms}" != "ro" ] && [ "${_perms}" != "rw" ]; then error_notify "Detected invalid mount permissions in FSTAB." warn "Format: /host/path /jail/path nullfs ro 0 0" @@ -95,7 +95,7 @@ if [ "${_perms}" != "ro" ] && [ "${_perms}" != "rw" ]; then usage fi -## Dump and pass need to be "0 0 - 1 1" +# Dump and pass need to be "0 0 - 1 1" if [ "${_checks}" != "0 0" ] && [ "${_checks}" != "1 0" ] && [ "${_checks}" != "0 1" ] && [ "${_checks}" != "1 1" ]; then error_notify "Detected invalid fstab options in FSTAB." warn "Format: /host/path /jail/path nullfs ro 0 0" @@ -104,29 +104,52 @@ if [ "${_checks}" != "0 0" ] && [ "${_checks}" != "1 0" ] && [ "${_checks}" != " fi for _jail in ${JAILS}; do - info "[${_jail}]:" - ## aggregate variables into FSTAB entry _fullpath="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath} 2>/dev/null | sed 's#//#/#' )" _fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}" + info "[${_jail}]:" + + # Check if mount point has already been added + if grep -Eq "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" 2> /dev/null; then + warn "Mountpoint already present in ${bastille_jailsdir}/${_jail}/fstab" + grep -E "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" + continue + fi + ## Create mount point if it does not exist if [ -d "${_hostpath}" ] && [ ! -d "${_fullpath}" ]; then - mkdir -p "${_fullpath}" || error_exit "Failed to create mount point inside jail." - elif [ -f "${_hostpath}" ] && [ ! -f "${_fullpath}" ]; then - mkdir -p "$( dirname ${_fullpath} )" || error_exit "Failed to create mount point inside jail." - touch "${_fullpath}" || error_exit "Failed to create mount point inside jail." - fi - - ## If entry doesn't exist, add, else show existing entry - if ! grep -Eq "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" 2> /dev/null; then - if ! echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab"; then - error_exit "Failed to create fstab entry: ${_fstab_entry}" + mkdir -p "${_fullpath}" || error_continue "Failed to create mount point inside jail." + elif [ -f "${_hostpath}" ] ; then + _filename="$( basename ${_hostpath} )" + if echo "${_fullpath}" 2>/dev/null | grep -qo "${_filename}"; then + mkdir -p "$( dirname ${_fullpath} )" || error_continue "Failed to create mount point inside jail." + if [ ! -f "${_fullpath}" ]; then + touch "${_fullpath}" || error_continue "Failed to create mount point inside jail." + else + error_notify "Failed. File exists at mount point." + warn "${_fullpath}" + continue + fi + else + _fullpath="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath}/${_filename} 2>/dev/null | sed 's#//#/#' )" + _fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}" + mkdir -p "$( dirname ${_fullpath} )" || error_continue "Failed to create mount point inside jail." + if [ ! -f "${_fullpath}" ]; then + touch "${_fullpath}" || error_continue "Failed to create mount point inside jail." + else + error_notify "Failed. File exists at mount point." + warn "${_fullpath}" + continue + fi fi - echo "Added: ${_fstab_entry}" + fi + + # Add entry to fstab and mount + if ! echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab"; then + error_continue "Failed to create fstab entry: ${_fstab_entry}" else - warn "Mountpoint already present in ${bastille_jailsdir}/${_jail}/fstab" - grep -E "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" + mount -F "${bastille_jailsdir}/${_jail}/fstab" -a + echo "Added: ${_fstab_entry}" fi - mount -F "${bastille_jailsdir}/${_jail}/fstab" -a done diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index 2dc31014a..9cd31a207 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -53,29 +53,34 @@ bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do - info "[${_jail}]:" + _jailpath="$( echo ${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH} 2>/dev/null | sed 's#//#/#' )" _mount="$( mount | grep -o ${_jailpath} )" _fstab_entry="$( cat ${bastille_jailsdir}/${_jail}/fstab | grep -o ${_jailpath} )" + info "[${_jail}]:" + # Exit if mount point non-existent if [ -z "${_mount}" ] && [ -z "${_fstab_entry}" ]; then - error_exit "The specified mount point does not exist inside the jail." + error_continue "The specified mount point does not exist inside the jail." fi # Unmount if [ -n "${_mount}" ]; then - if ! umount "${_jailpath}"; then - error_exit "Failed to unmount volume: ${MOUNT_PATH}" - fi + umount "${_jailpath}" || error_continue "Failed to unmount volume: ${MOUNT_PATH}" fi # Remove entry from fstab if [ -n "${_fstab_entry}" ]; then if ! sed -E -i '' "\, +${_jailpath} +,d" "${bastille_jailsdir}/${_jail}/fstab"; then - error_exit "Failed to delete fstab entry: ${MOUNT_PATH}" + error_continue "Failed to delete fstab entry: ${MOUNT_PATH}" fi fi + # Delete if mount point was a file + if [ -f "${_jailpath}" ]; then + rm -f "${_jailpath}" || error_continue "Failed to unmount volume: ${MOUNT_PATH}" + fi + echo "Unmounted: ${MOUNT_PATH}" done From 17f52a174fab08e97cca7a12a36c08231395d98d Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 23 Dec 2024 15:05:20 -0700 Subject: [PATCH 090/120] fix brace --- usr/local/share/bastille/common.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 7988eeb86..e06806986 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -56,8 +56,8 @@ fi # Notify message on error, and continue to next jail error_continue() { error_notify "$@" - continue -fi + continue +} # Notify message on error, but do not exit error_notify() { From 484be5a296289c0b663a1969c66fd64cc6dace6e Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 23 Dec 2024 15:08:57 -0700 Subject: [PATCH 091/120] disable shellcheck 2104 as this is a special function --- usr/local/share/bastille/common.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index e06806986..3bddafb81 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -56,6 +56,7 @@ fi # Notify message on error, and continue to next jail error_continue() { error_notify "$@" + # shellcheck disable=SC2104 continue } From d5f03c6136a613d4b7208102415805211f820ab5 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 23 Dec 2024 15:12:54 -0700 Subject: [PATCH 092/120] spacing --- usr/local/share/bastille/top.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh index 69a4cca30..49c5503da 100644 --- a/usr/local/share/bastille/top.sh +++ b/usr/local/share/bastille/top.sh @@ -80,7 +80,6 @@ else exit fi - info "[${TARGET}]:" jexec -l "${TARGET}" /usr/bin/top echo -e "${COLOR_RESET}" From bcf16345db7b4e47d1210efaa32cd07a76d26bdc Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Mon, 23 Dec 2024 17:23:35 -0700 Subject: [PATCH 093/120] mount and umount bug fixes --- usr/local/share/bastille/mount.sh | 29 +++++++++++++---------------- usr/local/share/bastille/umount.sh | 10 +++++----- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index d73ee0601..3ca8a8cdb 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -105,27 +105,27 @@ fi for _jail in ${JAILS}; do + info "[${_jail}]:" + _fullpath="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath} 2>/dev/null | sed 's#//#/#' )" _fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}" - info "[${_jail}]:" - # Check if mount point has already been added - if grep -Eq "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" 2> /dev/null; then + if grep -Eq "[[:blank:]]${_fullpath}" "${bastille_jailsdir}/${_jail}/fstab"; then warn "Mountpoint already present in ${bastille_jailsdir}/${_jail}/fstab" - grep -E "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" + grep -E "[[:blank:]]${_fullpath}" "${bastille_jailsdir}/${_jail}/fstab" continue fi ## Create mount point if it does not exist if [ -d "${_hostpath}" ] && [ ! -d "${_fullpath}" ]; then - mkdir -p "${_fullpath}" || error_continue "Failed to create mount point inside jail." + mkdir -p "${_fullpath}" || error_continue"Failed to create mount point." elif [ -f "${_hostpath}" ] ; then _filename="$( basename ${_hostpath} )" - if echo "${_fullpath}" 2>/dev/null | grep -qo "${_filename}"; then - mkdir -p "$( dirname ${_fullpath} )" || error_continue "Failed to create mount point inside jail." + if echo "${_fullpath}" 2>/dev/null | grep -qow "${_filename}"; then + mkdir -p "$( dirname ${_fullpath} )" || error_continue "Failed to create mount point." if [ ! -f "${_fullpath}" ]; then - touch "${_fullpath}" || error_continue "Failed to create mount point inside jail." + touch "${_fullpath}" || error_continue "Failed to create mount point." else error_notify "Failed. File exists at mount point." warn "${_fullpath}" @@ -134,9 +134,9 @@ for _jail in ${JAILS}; do else _fullpath="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath}/${_filename} 2>/dev/null | sed 's#//#/#' )" _fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}" - mkdir -p "$( dirname ${_fullpath} )" || error_continue "Failed to create mount point inside jail." + mkdir -p "$( dirname ${_fullpath} )" || error_continue "Failed to create mount point." if [ ! -f "${_fullpath}" ]; then - touch "${_fullpath}" || error_continue "Failed to create mount point inside jail." + touch "${_fullpath}" || error_continue "Failed to create mount point." else error_notify "Failed. File exists at mount point." warn "${_fullpath}" @@ -146,10 +146,7 @@ for _jail in ${JAILS}; do fi # Add entry to fstab and mount - if ! echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab"; then - error_continue "Failed to create fstab entry: ${_fstab_entry}" - else - mount -F "${bastille_jailsdir}/${_jail}/fstab" -a - echo "Added: ${_fstab_entry}" - fi + echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab" || error_continue "Failed to create fstab entry: ${_fstab_entry}" + mount -F "${bastille_jailsdir}/${_jail}/fstab" -a || error_continue "Failed to mount volume: ${_fullpath}" + echo "Added: ${_fstab_entry}" done diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index 9cd31a207..b7f61e986 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -54,15 +54,15 @@ set_target "${TARGET}" for _jail in ${JAILS}; do - _jailpath="$( echo ${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH} 2>/dev/null | sed 's#//#/#' )" - _mount="$( mount | grep -o ${_jailpath} )" - _fstab_entry="$( cat ${bastille_jailsdir}/${_jail}/fstab | grep -o ${_jailpath} )" - info "[${_jail}]:" +set -x + _jailpath="$( echo ${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH} 2>/dev/null | sed 's#//#/#' )" + _mount="$( mount | grep -ow ${_jailpath} )" + _fstab_entry="$( cat ${bastille_jailsdir}/${_jail}/fstab | grep -ow ${_jailpath} )" # Exit if mount point non-existent if [ -z "${_mount}" ] && [ -z "${_fstab_entry}" ]; then - error_continue "The specified mount point does not exist inside the jail." + error_continue "The specified mount point does not exist." fi # Unmount From 87323098a0d899b1762036411c8d47542251d072 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Mon, 23 Dec 2024 17:27:19 -0700 Subject: [PATCH 094/120] spacing fix --- usr/local/share/bastille/mount.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 3ca8a8cdb..11480edb1 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -119,7 +119,7 @@ for _jail in ${JAILS}; do ## Create mount point if it does not exist if [ -d "${_hostpath}" ] && [ ! -d "${_fullpath}" ]; then - mkdir -p "${_fullpath}" || error_continue"Failed to create mount point." + mkdir -p "${_fullpath}" || error_continue "Failed to create mount point." elif [ -f "${_hostpath}" ] ; then _filename="$( basename ${_hostpath} )" if echo "${_fullpath}" 2>/dev/null | grep -qow "${_filename}"; then From 8be23eadaeba98a63a1ac4c77991a2bc5a3dc032 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Tue, 24 Dec 2024 07:42:27 -0700 Subject: [PATCH 095/120] more fixes and improvements --- usr/local/share/bastille/htop.sh | 29 ++-- usr/local/share/bastille/rdr.sh | 207 ++++++++++++++-------------- usr/local/share/bastille/service.sh | 35 ++++- usr/local/share/bastille/start.sh | 22 +-- usr/local/share/bastille/stop.sh | 13 +- usr/local/share/bastille/sysrc.sh | 35 ++++- usr/local/share/bastille/top.sh | 20 ++- 7 files changed, 205 insertions(+), 156 deletions(-) diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh index 62c93070b..c706cf176 100644 --- a/usr/local/share/bastille/htop.sh +++ b/usr/local/share/bastille/htop.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille htop TARGET" + error_exit "Usage: bastille htop [option(s)] TARGET" cat << EOF Options: @@ -42,21 +42,13 @@ EOF exit 1 } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac - -if [ $# -ne 1 ]; then - usage -fi - # Handle options. FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -f|--force) FORCE=1 shift @@ -70,6 +62,10 @@ while [ "$#" -gt 0 ]; do esac done +if [ $# -ne 1 ]; then + usage +fi + TARGET="${1}" bastille_root_check @@ -80,11 +76,10 @@ else exit fi -bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path) +bastille_jail_path="${bastille_jailsdir}/${TARGET}/root" if [ ! -x "${bastille_jail_path}/usr/local/bin/htop" ]; then - error_notify "htop not found on ${_jail}." + error_notify "htop not found on ${TARGET}." elif [ -x "${bastille_jail_path}/usr/local/bin/htop" ]; then - info "[${_jail}]:" - jexec -l ${_jail} /usr/local/bin/htop + info "[${TARGET}]:" + jexec -l ${TARGET} /usr/local/bin/htop fi -echo -e "${COLOR_RESET}" diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 9f85f83fb..6c54e6dc7 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -32,39 +32,32 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille rdr TARGET [option(s)] [clear|reset|list|(tcp|udp)] host_port jail_port [log ['(' logopts ')'] ] )]" - + error_notify "Usage: bastille rdr TARGET [option(s)] [clear|reset|list|(tcp|udp)] HOST_PORT JAIL_PORT [log ['(' logopts ')'] ] )]" cat << EOF Options: - -i | --interface [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. - -s | --source [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. - -d | --destination [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. - -t | --type [ipv4|ipv6] | -- Specify IP type. Must be used if -s or -d are used. Defaults to both. + -i | --interface [interface] -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. + -s | --source [source ip] -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. + -d | --destination [destination ip] -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + -t | --type [ipv4|ipv6] -- Specify IP type. Must be used if -s or -d are used. Defaults to both. EOF exit 1 } check_jail_validity() { - # Check if jail name is valid - JAIL_NAME=$(/usr/sbin/jls -j "${TARGET}" name 2>/dev/null) - if [ -z "${JAIL_NAME}" ]; then - error_exit "Jail not found: ${TARGET}" - fi # Check if jail ip4 address (ip4.addr) is valid (non-VNET only) - if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then - JAIL_IP=$(/usr/sbin/jls -j "${TARGET}" ip4.addr 2>/dev/null) - if [ -z "${JAIL_IP}" ] || [ "${JAIL_IP}" = "-" ]; then - error_exit "Jail IP not found: ${TARGET}" + if [ "$( bastille config ${TARGET} get vnet )" != 'enabled' ]; then + if [ "$( bastille config ${TARGET} get ip4.addr )" != 'disable' ] && [ "$( bastille config ${TARGET} get ip4.addr )" != 'not set' ]; then + JAIL_IP="$( bastille config ${TARGET} get ip4.addr )" fi fi # Check if jail ip6 address (ip6.addr) is valid (non-VNET only) - if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then - if [ "$(bastille config $TARGET get ip6)" != 'disable' ] && [ "$(bastille config $TARGET get ip6)" != 'not set' ]; then - JAIL_IP6=$(/usr/sbin/jls -j "${TARGET}" ip6.addr 2>/dev/null) + if [ "$( bastille config $TARGET get vnet )" != 'enabled' ]; then + if [ "$( bastille config $TARGET get ip6 )" != 'disable' ] && [ "$( bastille config $TARGET get ip6 )" != 'not set' ]; then + JAIL_IP6="$( bastille config ${TARGET} get ip6 )" fi fi @@ -76,8 +69,8 @@ check_jail_validity() { # function: check if IP is valid check_rdr_ip_validity() { - local ip="$1" - local ip6="$(echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)')" + local ip="${1}" + local ip6="$( echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )" if [ -n "${ip6}" ]; then info "Valid: (${ip6})." else @@ -107,8 +100,13 @@ persist_rdr_rule() { local proto="${5}" local host_port="${6}" local jail_port="${7}" - if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$inet $if $src $dst $proto $host_port $jail_port" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" + if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then + echo "$inet $if $src $dst $proto $host_port $jail_port" >> "${bastille_jailsdir}/${TARGET}/rdr.conf" + else + info "[${TARGET}]:" + warn "Rule already exists in rdr.conf" + echo "$inet $if $src $dst $proto $host_port $jail_port" + exit 1 fi } @@ -122,8 +120,13 @@ persist_rdr_log_rule() { local jail_port="${7}" shift 7; log=$@; - if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$inet $if $src $dst $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" + if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port $log" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then + echo "$inet $if $src $dst $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${TARGET}/rdr.conf" + else + info "[${TARGET}]:" + warn "Rule already exists in rdr.conf" + echo "$inet $if $src $dst $proto $host_port $jail_port $log" + exit 1 fi } @@ -138,26 +141,26 @@ load_rdr_rule() { local host_port="${6}" local jail_port="${7}" # Create IPv4 rdr rule - # shellcheck disable=SC2193 - if [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; then - if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; + # shellcheck disable=SC2193 + if { [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; } then + if ! ( pfctl -a "rdr/${TARGET}" -Psn 2>/dev/null; printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then + | pfctl -a "rdr/${TARGET}" -f-; then error_exit "Failed to create IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else - info "[${JAIL_NAME}]:" + info "[${TARGET}]:" echo "IPv4 ${proto}/${host_port}:${jail_port} on ${if_name}" fi fi # Create IPv6 rdr rule (if ip6.addr is enabled) - # shellcheck disable=SC2193 - if [ -n "$JAIL_IP6" ] && [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; then - if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + # shellcheck disable=SC2193 + if [ -n "${JAIL_IP6}" ] && { [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; } then + if ! ( pfctl -a "rdr/${TARGET}" -Psn; printf '%s\nrdr pass on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then + | pfctl -a "rdr/${TARGET}" -f-; then error_exit "Failed to create IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else - info "[${JAIL_NAME}]:" + info "[${TARGET}]:" echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" fi fi @@ -176,68 +179,51 @@ load_rdr_log_rule() { shift 7; log=$@ # Create IPv4 rule with log - # shellcheck disable=SC2193 - if [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; then - if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + # shellcheck disable=SC2193 + if { [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; } then + if ! ( pfctl -a "rdr/${TARGET}" -Psn; printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then + | pfctl -a "rdr/${TARGET}" -f-; then error_exit "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else - info "[${JAIL_NAME}]:" + info "[${TARGET}]:" echo "IPv4 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" fi fi # Create IPv6 rdr rule with log (if ip6.addr is enabled) - # shellcheck disable=SC2193 - if [ -n "${JAIL_IP6}" ] && [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; then - if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + # shellcheck disable=SC2193 + if [ -n "${JAIL_IP6}" ] && { [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; } then + if ! ( pfctl -a "rdr/${TARGET}" -Psn; printf '%s\nrdr pass %s on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then + | pfctl -a "rdr/${TARGET}" -f-; then error_exit "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else - info "[${JAIL_NAME}]:" + info "[${TARGET}]:" echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" fi fi } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) usage ;; esac -if [ $# -lt 2 ]; then - usage -fi - -TARGET="${1}" -JAIL_NAME="" -JAIL_IP="" -JAIL_IP6="" -shift - -bastille_root_check -set_target_single "${TARGET}" - -# Set defaults +# Handle options. RDR_IF="$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf} | awk -F'"' '{print $2}')" RDR_SRC="any" RDR_DST="any" -OPTION="0" RDR_INET="dual" OPTION_IF=0 OPTION_SRC=0 OPTION_DST=0 OPTION_INET_TYPE=0 - while [ "$#" -gt 0 ]; do - case "$1" in + case "${1}" in -i|--interface) - if [ -z "${2}" ] || [ -z "${3}" ]; then - usage - elif ifconfig | grep -owq "${2}:"; then + if ifconfig | grep -owq "${2}:"; then OPTION_IF=1 RDR_IF="${2}" shift 2 @@ -246,19 +232,13 @@ while [ "$#" -gt 0 ]; do fi ;; -s|--source) - if [ -z "${2}" ] || [ -z "${3}" ]; then - usage - else - check_rdr_ip_validity "${2}" - OPTION_SRC=1 - RDR_SRC="${2}" - shift 2 - fi + check_rdr_ip_validity "${2}" + OPTION_SRC=1 + RDR_SRC="${2}" + shift 2 ;; -d|--destination) - if [ -z "${2}" ] || [ -z "${3}" ]; then - usage - elif ifconfig | grep -owq "inet ${2}"; then + if ifconfig | grep -owq "inet ${2}"; then OPTION_DST=1 RDR_DST="${2}" shift 2 @@ -267,29 +247,50 @@ while [ "$#" -gt 0 ]; do fi ;; -t|--type) - if [ -z "${2}" ] || [ -z "${3}" ]; then - usage - elif [ "${2}" != "ipv4" ] && [ "${2}" != "ipv6" ]; then - usage + if [ "${2}" != "ipv4" ] && [ "${2}" != "ipv6" ]; then + error_exit "[-t|--type] must be [ipv4|ipv6]" else OPTION_INET_TYPE=1 RDR_INET="${2}" shift 2 fi ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done + +if [ "$#" -lt 2 ]; then + usage +fi + +TARGET="${1}" +JAIL_IP="" +JAIL_IP6="" +shift + +bastille_root_check +set_target_single "${TARGET}" + +while [ "$#" -gt 0 ]; do + case "$1" in list) if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage elif [ "${TARGET}" = 'ALL' ]; then - for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do - echo "${JAIL_NAME} redirects:" - pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null + for _jail in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do + echo "${_jail} redirects:" + pfctl -a "rdr/${_jail}" -Psn 2>/dev/null done else check_jail_validity - pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null + pfctl -a "rdr/${TARGET}" -Psn 2>/dev/null fi shift ;; @@ -299,13 +300,13 @@ while [ "$#" -gt 0 ]; do elif [ -n "${2}" ]; then usage elif [ "${TARGET}" = 'ALL' ]; then - for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do - echo "${JAIL_NAME} redirects:" - pfctl -a "rdr/${JAIL_NAME}" -Fn + for _jail in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do + echo "${_jail} redirects:" + pfctl -a "rdr/${_jail}" -Fn done else check_jail_validity - pfctl -a "rdr/${JAIL_NAME}" -Fn + pfctl -a "rdr/${TARGET}" -Fn fi shift ;; @@ -315,34 +316,34 @@ while [ "$#" -gt 0 ]; do elif [ -n "${2}" ]; then usage elif [ "${TARGET}" = 'ALL' ]; then - for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do - echo "${JAIL_NAME} redirects:" - pfctl -a "rdr/${JAIL_NAME}" -Fn - if rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf; then - info "[${JAIL_NAME}]: rdr.conf removed" + for _jail in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do + echo "${_jail} redirects:" + pfctl -a "rdr/${_jail}" -Fn + if rm -f "${bastille_jailsdir}"/"${_jail}"/rdr.conf; then + info "[${_jail}]: rdr.conf removed" fi done else check_jail_validity - pfctl -a "rdr/${JAIL_NAME}" -Fn - if rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf; then - info "[${JAIL_NAME}]: rdr.conf removed" + pfctl -a "rdr/${TARGET}" -Fn + if rm -f "${bastille_jailsdir}"/"${_jail}"/rdr.conf; then + info "[${TARGET}]: rdr.conf removed" fi fi shift ;; tcp|udp) - if [ $# -lt 3 ]; then + if [ "$#" -lt 3 ]; then usage elif [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] && [ "${OPTION_INET_TYPE}" -ne 1 ];then error_exit "[-t|--type] must be set when using [-s|--source] or [-d|--destination]" - elif [ $# -eq 3 ]; then + elif [ "$#" -eq 3 ]; then check_jail_validity persist_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 load_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 shift "$#" else - case "$4" in + case "${4}" in log) proto=$1 host_port=$2 @@ -384,16 +385,16 @@ while [ "$#" -gt 0 ]; do else usage fi - if [ $# -eq 7 ] && [ "${5}" = "tcp" ] || [ "${5}" = "udp" ]; then + if [ "$#" -eq 7 ] && [ "${5}" = "tcp" ] || [ "${5}" = "udp" ]; then check_jail_validity persist_rdr_rule "$@" load_rdr_rule "$@" - shift $# - elif [ $# -ge 8 ] && [ "${8}" = "log" ]; then + shift "$#" + elif [ "$#" -ge 8 ] && [ "${8}" = "log" ]; then check_jail_validity persist_rdr_log_rule "$@" load_rdr_log_rule "$@" - shift $# + shift "$#" else usage fi diff --git a/usr/local/share/bastille/service.sh b/usr/local/share/bastille/service.sh index 71de29ce7..f651388b5 100644 --- a/usr/local/share/bastille/service.sh +++ b/usr/local/share/bastille/service.sh @@ -32,7 +32,14 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille service TARGET SERVICE_NAME ACTION" + error_exit "Usage: bastille service [options(s)] TARGET SERVICE_NAME ACTION" + cat << EOF + Options: + + -f | --force -- Start the jail if it is stopped. + +EOF + exit 1 } # Handle special-case commands first. @@ -42,10 +49,27 @@ case "${1}" in ;; esac -if [ $# -lt 2 ] || [ $# -gt 3 ]; then +if [ "$#" -lt 3 ] || [ "$#" -gt 4 ]; then usage fi +# Handle options. +FORCE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -f|--force) + FORCE=1 + shift + ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done + TARGET="${1}" shift @@ -53,8 +77,11 @@ bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do - check_target_is_running "${_jail}" || continue + check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${_jail}" + else + continue + fi info "[${_jail}]:" jexec -l "${_jail}" /usr/sbin/service "$@" - echo done diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index d06a26f93..5134f3fe9 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -42,7 +42,7 @@ case "${1}" in ;; esac -if [ $# -ne 1 ]; then +if [ "$#" -ne 1 ]; then usage fi @@ -52,39 +52,41 @@ bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do - ## test if running + + # test if running check_target_is_stopped "${_jail}" || continue if [ "$(bastille config $_jail get vnet)" != 'enabled' ]; then - _interface=$(bastille config $_jail get interface) + _interface="$(bastille config ${_jail} get interface)" if ! ifconfig | grep "^${_interface}:" >/dev/null; then error_notify "Error: ${_interface} interface does not exist." continue fi fi - ## warn if matching configured (but not online) ip4.addr, ignore if there's no ip4.addr entry + # warn if matching configured (but not online) ip4.addr, ignore if there's no ip4.addr entry _ip4="$(bastille config "${_jail}" get ip4.addr)" if [ "${_ip4}" != "not set" ]; then if ifconfig | grep -wF "${_ip4}" >/dev/null; then error_notify "Error: IP address (${_ip4}) already in use." continue - fi - ## add ip4.addr to firewall table - pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip4}" + else + ## add ip4.addr to firewall table + pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip4}" + fi fi - ## start the container + # Start jail info "[${_jail}]:" jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -c "${_jail}" - ## add rctl limits + # Add rctl limits if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then while read _limits; do rctl -a "${_limits}" done < "${bastille_jailsdir}/${_jail}/rctl.conf" fi - ## add rdr rules + # Add rdr rules if [ -s "${bastille_jailsdir}/${_jail}/rdr.conf" ]; then while read _rules; do bastille rdr "${_jail}" ${_rules} diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index c40de8a13..12e9a9955 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -42,7 +42,7 @@ case "${1}" in ;; esac -if [ $# -ne 1 ]; then +if [ "$#" -ne 1 ]; then usage fi @@ -52,8 +52,9 @@ bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do + check_target_is_running "${_jail}" || continue - ## Capture ip4.addr address while still running + # Capture ip4.addr address while still running _ip4="$(bastille config ${_jail} get ip4.addr)" # Check if pfctl is present @@ -61,23 +62,23 @@ for _jail in ${JAILS}; do if [ "${_ip4}" != "not set" ]; then if which -s pfctl; then if [ "$(bastille rdr ${_jail} list)" ]; then - bastille rdr ${_jail} clear + bastille rdr "${_jail}" clear fi fi fi - ## remove rctl limits + # Remove rctl limits if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then while read _limits; do rctl -r "${_limits}" done < "${bastille_jailsdir}/${_jail}/rctl.conf" fi - ## stop container + # Stop jail info "[${_jail}]:" jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" - ## remove (captured above) ip4.addr from firewall table + # Remove (captured above) ip4.addr from firewall table if [ -n "${bastille_network_loopback}" ] && [ "${_ip4}" != "not set" ]; then if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip4}" diff --git a/usr/local/share/bastille/sysrc.sh b/usr/local/share/bastille/sysrc.sh index 92f2939f0..ce61581bb 100644 --- a/usr/local/share/bastille/sysrc.sh +++ b/usr/local/share/bastille/sysrc.sh @@ -32,7 +32,14 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille sysrc TARGET args" + error_exit "Usage: bastille sysrc [option(s)] TARGET ARGS" + cat << EOF + Options: + + -f | --force -- Start the jail if it is stopped. + +EOF + exit 1 } # Handle special-case commands first. @@ -42,10 +49,27 @@ case "${1}" in ;; esac -if [ $# -lt 2 ]; then +if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then usage fi +# Handle options. +FORCE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -f|--force) + FORCE=1 + shift + ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done + TARGET="${1}" shift @@ -53,8 +77,11 @@ bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do - check_target_is_running "${_jail}" || continue + check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${_jail}" + else + continue + fi info "[${_jail}]:" jexec -l "${_jail}" /usr/sbin/sysrc "$@" - echo -e "${COLOR_RESET}" done diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh index 49c5503da..d787ead25 100644 --- a/usr/local/share/bastille/top.sh +++ b/usr/local/share/bastille/top.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille top TARGET" + error_exit "Usage: bastille top [options(s)] TARGET" cat << EOF Options: @@ -42,21 +42,13 @@ EOF exit 1 } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac - -if [ "$#" -ne 1 ]; then - usage -fi - # Handle options. FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -f|--force) FORCE=1 shift @@ -70,6 +62,10 @@ while [ "$#" -gt 0 ]; do esac done +if [ "$#" -ne 1 ]; then + usage +fi + TARGET="${1}" bastille_root_check From 6f055fe7fc7ba1eee37c6cbbd56921424e0fa922 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Tue, 24 Dec 2024 07:58:18 -0700 Subject: [PATCH 096/120] more improvements and code cleanup --- usr/local/share/bastille/cp.sh | 29 ++++++++++------------------- usr/local/share/bastille/htop.sh | 2 +- usr/local/share/bastille/mount.sh | 2 +- usr/local/share/bastille/rcp.sh | 18 +++++++----------- usr/local/share/bastille/rdr.sh | 14 +++----------- usr/local/share/bastille/service.sh | 18 +++++++----------- usr/local/share/bastille/start.sh | 2 +- usr/local/share/bastille/sysrc.sh | 18 +++++++----------- usr/local/share/bastille/top.sh | 1 - usr/local/share/bastille/umount.sh | 3 ++- 10 files changed, 39 insertions(+), 68 deletions(-) diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index 45bf3a4ec..cdf1aa65f 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -32,24 +32,16 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille cp [option(s)] TARGET HOST_PATH CONTAINER_PATH" + error_exit "Usage: bastille cp [option(s)] TARGET HOST_PATH JAIL_PATH" } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac - -if [ $# -lt 3 ] || [ $# -gt 4 ]; then - usage -fi - # Handle options. OPTION="-av" while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -q|--quiet) OPTION="-a" shift @@ -63,6 +55,10 @@ while [ "$#" -gt 0 ]; do esac done +if [ "$#" -ne 3 ]; then + usage +fi + TARGET="${1}" CPSOURCE="${2}" CPDEST="${3}" @@ -75,11 +71,6 @@ for _jail in ${JAILS}; do 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}" - fi + echo + return "${RETURN}" done diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh index c706cf176..5582a8899 100644 --- a/usr/local/share/bastille/htop.sh +++ b/usr/local/share/bastille/htop.sh @@ -62,7 +62,7 @@ while [ "$#" -gt 0 ]; do esac done -if [ $# -ne 1 ]; then +if [ "$#" -ne 1 ]; then usage fi diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 11480edb1..318937e8f 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -117,7 +117,7 @@ for _jail in ${JAILS}; do continue fi - ## Create mount point if it does not exist + # Create mount point if it does not exist if [ -d "${_hostpath}" ] && [ ! -d "${_fullpath}" ]; then mkdir -p "${_fullpath}" || error_continue "Failed to create mount point." elif [ -f "${_hostpath}" ] ; then diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh index ee0894ce1..c15d22b5f 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -35,21 +35,13 @@ usage() { error_exit "Usage: bastille rcp [option(s)] TARGET JAIL_PATH HOST_PATH" } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac - -if [ $# -lt 3 ] || [ $# -gt 4 ]; then - usage -fi - # Handle options. OPTION="-av" while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -q|--quiet) OPTION="-a" shift @@ -63,6 +55,10 @@ while [ "$#" -gt 0 ]; do esac done +if [ "$#" -ne 3 ]; then + usage +fi + TARGET="${1}" CPSOURCE="${2}" CPDEST="${3}" diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 6c54e6dc7..c3487cfce 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -67,7 +67,6 @@ check_jail_validity() { fi } -# function: check if IP is valid check_rdr_ip_validity() { local ip="${1}" local ip6="$( echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )" @@ -91,7 +90,6 @@ check_rdr_ip_validity() { fi } -# function: write rule to rdr.conf persist_rdr_rule() { local inet="${1}" local if="${2}" @@ -130,7 +128,6 @@ persist_rdr_log_rule() { fi } -# function: load rdr rule via pfctl load_rdr_rule() { local inet="${1}" local if_name="${2}" @@ -166,7 +163,6 @@ load_rdr_rule() { fi } -# function: load rdr rule with log via pfctl load_rdr_log_rule() { local inet="${1}" local if_name="${2}" @@ -204,13 +200,6 @@ load_rdr_log_rule() { fi } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac - # Handle options. RDR_IF="$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf} | awk -F'"' '{print $2}')" RDR_SRC="any" @@ -222,6 +211,9 @@ OPTION_DST=0 OPTION_INET_TYPE=0 while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -i|--interface) if ifconfig | grep -owq "${2}:"; then OPTION_IF=1 diff --git a/usr/local/share/bastille/service.sh b/usr/local/share/bastille/service.sh index f651388b5..c9808a808 100644 --- a/usr/local/share/bastille/service.sh +++ b/usr/local/share/bastille/service.sh @@ -42,21 +42,13 @@ EOF exit 1 } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac - -if [ "$#" -lt 3 ] || [ "$#" -gt 4 ]; then - usage -fi - # Handle options. FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -f|--force) FORCE=1 shift @@ -70,6 +62,10 @@ while [ "$#" -gt 0 ]; do esac done +if [ "$#" -lt 3 ] || [ "$#" -gt 4 ]; then + usage +fi + TARGET="${1}" shift diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index 5134f3fe9..42bf2f9da 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -53,7 +53,7 @@ set_target "${TARGET}" for _jail in ${JAILS}; do - # test if running + # Check if jail is running check_target_is_stopped "${_jail}" || continue if [ "$(bastille config $_jail get vnet)" != 'enabled' ]; then _interface="$(bastille config ${_jail} get interface)" diff --git a/usr/local/share/bastille/sysrc.sh b/usr/local/share/bastille/sysrc.sh index ce61581bb..96f0fc20e 100644 --- a/usr/local/share/bastille/sysrc.sh +++ b/usr/local/share/bastille/sysrc.sh @@ -42,21 +42,13 @@ EOF exit 1 } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac - -if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then - usage -fi - # Handle options. FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -f|--force) FORCE=1 shift @@ -70,6 +62,10 @@ while [ "$#" -gt 0 ]; do esac done +if [ "$#" -lt 2 ]; then + usage +fi + TARGET="${1}" shift diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh index d787ead25..ec30311b5 100644 --- a/usr/local/share/bastille/top.sh +++ b/usr/local/share/bastille/top.sh @@ -78,4 +78,3 @@ fi info "[${TARGET}]:" jexec -l "${TARGET}" /usr/bin/top -echo -e "${COLOR_RESET}" diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index b7f61e986..8a0e78fc7 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -55,7 +55,7 @@ set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" -set -x + _jailpath="$( echo ${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH} 2>/dev/null | sed 's#//#/#' )" _mount="$( mount | grep -ow ${_jailpath} )" _fstab_entry="$( cat ${bastille_jailsdir}/${_jail}/fstab | grep -ow ${_jailpath} )" @@ -83,4 +83,5 @@ set -x fi echo "Unmounted: ${MOUNT_PATH}" + done From 697c81dc4a0bbe94d651e9800d52b830b5120495 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Tue, 24 Dec 2024 08:14:38 -0700 Subject: [PATCH 097/120] more code cleanup --- usr/local/share/bastille/convert.sh | 1 - usr/local/share/bastille/cp.sh | 7 +++ usr/local/share/bastille/destroy.sh | 26 ++++------ usr/local/share/bastille/edit.sh | 30 +++-------- usr/local/share/bastille/list.sh | 80 ++++++++++++++--------------- usr/local/share/bastille/rcp.sh | 7 +++ usr/local/share/bastille/rename.sh | 24 ++++----- usr/local/share/bastille/zfs.sh | 14 ++--- 8 files changed, 87 insertions(+), 102 deletions(-) diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh index 5a0a41df7..086490d28 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -43,7 +43,6 @@ EOF exit 1 } - # Handle special-case commands first. case "${1}" in help|-h|--help) diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index cdf1aa65f..03e6fd3bd 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -33,6 +33,13 @@ usage() { error_exit "Usage: bastille cp [option(s)] TARGET HOST_PATH JAIL_PATH" + cat << EOF + Options: + + -q | -- quiet -- Suppress output. + +EOF + exit 1 } # Handle options. diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index 2b81138a2..e18d1df6e 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -33,7 +33,6 @@ usage() { error_notify "Usage: bastille destroy [option(s)] [JAIL|RELEASE]" - cat << EOF Options: @@ -50,19 +49,16 @@ destroy_jail() { bastille_jail_base="${bastille_jailsdir}/${TARGET}" ## dir bastille_jail_log="${bastille_logsdir}/${TARGET}_console.log" ## file - if [ "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then - if [ "${FORCE}" = "1" ]; then - bastille stop "${TARGET}" - else - error_notify "Jail running." - error_exit "See 'bastille stop ${TARGET}'." - fi + check_target_is_running "${TARGET}" || if [ "${FORCE}" = "1" ]; then + bastille stop "${TARGET}" + else + exit fi if [ -d "${bastille_jail_base}" ]; then ## make sure no filesystem is currently mounted in the jail directory mount_points="$(mount | cut -d ' ' -f 3 | grep "${bastille_jail_base}"/root/)" - if [ "$?" -eq 0 ]; then + if [ -n "${mount_points}" ]; then error_notify "Failed to destroy jail: ${TARGET}" error_exit "Jail has mounted filesystems:\n$mount_points" fi @@ -194,17 +190,13 @@ destroy_rel() { fi } -# Handle special-case commands first. -case "$1" in - help|-h|--help) - usage - ;; -esac - # Handle options. FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -f|--force|force) FORCE="1" shift @@ -219,7 +211,7 @@ while [ "$#" -gt 0 ]; do esac done -if [ $# -gt 1 ] || [ $# -lt 1 ]; then +if [ "$#" -ne 1 ]; then usage fi diff --git a/usr/local/share/bastille/edit.sh b/usr/local/share/bastille/edit.sh index b14d5273b..caacdc13d 100644 --- a/usr/local/share/bastille/edit.sh +++ b/usr/local/share/bastille/edit.sh @@ -32,28 +32,15 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille edit TARGET [filename]" + error_exit "Usage: bastille edit [option(s)] TARGET [filename]" } -# Handle special-case commands first. -case "$1" in - help|-h|--help) - usage - ;; -esac - -if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then - usage -fi - # Handle options. -FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in - -f|--force|force) - FORCE="1" - shift - ;; + -h|--help|help) + usage + ;; -*) error_notify "Unknown Option: \"${1}\"" usage @@ -64,6 +51,10 @@ while [ "$#" -gt 0 ]; do esac done +if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then + usage +fi + TARGET="${1}" if [ "$#" -eq 2 ]; then TARGET_FILENAME="${2}" @@ -73,11 +64,6 @@ fi bastille_root_check set_target_single "${TARGET}" -check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then - bastille start "${TARGET}" -else - exit -fi if [ -z "${EDITOR}" ]; then EDITOR=nano diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index d2d8d7168..23350e56c 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -35,13 +35,9 @@ usage() { error_exit "Usage: bastille list [-j|-a] [release [-p]|template|(jail|container)|log|limit|(import|export|backup)]" } -if [ "${1}" = help ] || [ "${1}" = "-h" ] || [ "${1}" = "--help" ]; then - usage -fi - bastille_root_check -if [ $# -eq 0 ]; then +if [ "$#" -eq 0 ]; then /usr/sbin/jls fi @@ -220,42 +216,46 @@ list_ports() { fi } -if [ $# -gt 0 ]; then - # Handle special-case commands first. +if [ "$#" -gt 0 ]; then case "${1}" in - all|-a|--all) - list_all - ;; - port|ports) - list_ports - ;; - release|releases) - list_release "${2}" - ;; - template|templates) - list_template - ;; - jail|jails|container|containers) - list_jail - ;; - log|logs) - list_log - ;; - limit|limits) - list_limit - ;; - import|imports|export|exports|backup|backups) - list_import - exit 0 - ;; - *) - # Check if we want to query all info for a specific jail instead. - if [ -f "${bastille_jailsdir}/${1}/jail.conf" ]; then - TARGET="${1}" - list_all - else + -h|--help|help) usage - fi - ;; + ;; + all|-a|--all) + list_all + ;; + port|ports) + list_ports + ;; + release|releases) + list_release "${2}" + ;; + template|templates) + list_template + ;; + jail|jails|container|containers) + list_jail + ;; + log|logs) + list_log + ;; + limit|limits) + list_limit + ;; + import|imports|export|exports|backup|backups) + list_import + exit 0 + ;; + -*) + error_exit "Unknown option: \"${1}\"" + *) + # Check if we want to query all info for a specific jail instead. + if [ -f "${bastille_jailsdir}/${1}/jail.conf" ]; then + TARGET="${1}" + list_all + else + usage + fi + ;; esac fi \ No newline at end of file diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh index c15d22b5f..59cc5c98b 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -33,6 +33,13 @@ usage() { error_exit "Usage: bastille rcp [option(s)] TARGET JAIL_PATH HOST_PATH" + cat << EOF + Options: + + -q | -- quiet -- Suppress output. + +EOF + exit 1 } # Handle options. diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index 681200d77..6343e1cbc 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -33,7 +33,6 @@ usage() { error_exit "Usage: bastille rename [option(s)] TARGET NEW_NAME" - cat << EOF Options: @@ -43,22 +42,13 @@ EOF exit 1 } - -# Handle special-case commands first -case "${1}" in - help|-h|--help) - usage - ;; -esac - -if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then - usage -fi - # Handle options. FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -f|--force) FORCE=1 shift @@ -72,6 +62,10 @@ while [ "$#" -gt 0 ]; do esac done +if [ "$#" -ne 2 ]; then + usage +fi + TARGET="${1}" NEWNAME="${2}" @@ -84,7 +78,7 @@ else fi validate_name() { - local NAME_VERIFY=${NEWNAME} + local NAME_VERIFY="${NEWNAME}" local NAME_SANITY="$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')" if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then error_exit "Container names may not begin with (-|_) characters!" @@ -118,7 +112,7 @@ update_fstab() { FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab" if [ -f "${FSTAB_CONFIG}" ] && [ -s "${FSTAB_CONFIG}" ]; then # Update fstab paths with new jail path - sed -i '' "s|\ ${bastille_jailsdir}/${TARGET}/root/|\ ${bastille_jailsdir}/${NEWNAME}/root/|g" "${FSTAB_CONFIG}" + sed -i '' "s|${bastille_jailsdir}/${TARGET}/root/|${bastille_jailsdir}/${NEWNAME}/root/|g" "${FSTAB_CONFIG}" fi } diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index aa7c4d1e7..374824aa0 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -84,7 +84,7 @@ case "$1" in ;; esac -if [ $# -lt 2 ]; then +if [ "$#" -lt 2 ]; then usage fi @@ -93,31 +93,31 @@ TARGET="${1}" bastille_root_check set_target_single "${TARGET}" -## check ZFS enabled +# Check if ZFS is enabled if ! checkyesno bastille_zfs_enable; then error_exit "ZFS not enabled." fi -## check zpool defined +# Check if zpool is defined if [ -z "${bastille_zfs_zpool}" ]; then error_exit "ZFS zpool not defined." fi case "${2}" in set) - ATTRIBUTE=${3} + ATTRIBUTE="${3}" zfs_set_value ;; get) - ATTRIBUTE=${3} + ATTRIBUTE="${3}" zfs_get_value ;; snap|snapshot) - TAG=${3} + TAG="${3}" zfs_snapshot ;; destroy_snap|destroy_snapshot) - TAG=${3} + TAG="${3}" zfs_destroy_snapshot ;; df|usage) From 891a847c4f03f47f205526ce60aa850f1f4e9e11 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Tue, 24 Dec 2024 08:17:01 -0700 Subject: [PATCH 098/120] fix case --- usr/local/share/bastille/list.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 23350e56c..9632c31ee 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -248,6 +248,7 @@ if [ "$#" -gt 0 ]; then ;; -*) error_exit "Unknown option: \"${1}\"" + ;; *) # Check if we want to query all info for a specific jail instead. if [ -f "${bastille_jailsdir}/${1}/jail.conf" ]; then From a953fb7c8ab0abb10af92f827cf6bf06122304e1 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Tue, 24 Dec 2024 16:03:55 -0700 Subject: [PATCH 099/120] close to final arrangement of code --- usr/local/share/bastille/clone.sh | 57 +++++++++++++++++------ usr/local/share/bastille/cmd.sh | 42 ++++++++++++++--- usr/local/share/bastille/console.sh | 40 ++++++++++++++--- usr/local/share/bastille/convert.sh | 18 +++----- usr/local/share/bastille/cp.sh | 10 ++--- usr/local/share/bastille/create.sh | 26 +++++------ usr/local/share/bastille/destroy.sh | 21 +++++---- usr/local/share/bastille/edit.sh | 6 +-- usr/local/share/bastille/etcupdate.sh | 18 +++----- usr/local/share/bastille/export.sh | 4 +- usr/local/share/bastille/htop.sh | 1 + usr/local/share/bastille/limits.sh | 9 +++- usr/local/share/bastille/list.sh | 6 +-- usr/local/share/bastille/pkg.sh | 27 +++++------ usr/local/share/bastille/rcp.sh | 10 ++--- usr/local/share/bastille/rdr.sh | 3 +- usr/local/share/bastille/rename.sh | 14 +++--- usr/local/share/bastille/service.sh | 9 ++-- usr/local/share/bastille/setup.sh | 2 +- usr/local/share/bastille/start.sh | 4 +- usr/local/share/bastille/sysrc.sh | 7 +-- usr/local/share/bastille/template.sh | 22 +++++---- usr/local/share/bastille/top.sh | 1 + usr/local/share/bastille/update.sh | 45 +++++++++---------- usr/local/share/bastille/upgrade.sh | 65 ++++++++++++++------------- usr/local/share/bastille/verify.sh | 10 ++--- usr/local/share/bastille/zfs.sh | 7 +-- 27 files changed, 285 insertions(+), 199 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 20fecec2a..43046a68e 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -33,14 +33,42 @@ usage() { error_exit "Usage: bastille clone TARGET NEW_NAME IP_ADDRESS" + + cat << EOF + Options: + + -f | --force -- Start the jail if it is stopped. + -u | --unsafe -- Force clone even if the jail is running. + Only works with ZFS for now. + +EOF + exit 1 } -# Handle special-case commands first -case "${1}" in - help|-h|--help) - usage - ;; -esac +# Handle options. +FORCE=0 +UNSAFE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -u|--unsafe) + UNSAFE=1 + shift + ;; + -f|--force) + FORCE=1 + shift + ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done if [ $# -ne 3 ]; then usage @@ -172,8 +200,15 @@ update_fstab() { } clone_jail() { - # Attempt container clone + info "Attempting to clone ${TARGET} to ${NEWNAME}..." + + check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille stop "${TARGET}" + elif [ "${UNSAFE}" -ne 1 ] || [ ! checkyesno bastille_zfs_enable ]; then + exit + fi + if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then @@ -191,13 +226,7 @@ clone_jail() { zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}@bastille_clone_${DATE}" fi else - # Just clone the jail directory - # Check if container is running - if [ -n "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then - error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'." - fi - - # Perform container file copy(archive mode) + # Perform container file copy (archive mode) cp -a "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}" fi else diff --git a/usr/local/share/bastille/cmd.sh b/usr/local/share/bastille/cmd.sh index 8b6660974..245ad7022 100644 --- a/usr/local/share/bastille/cmd.sh +++ b/usr/local/share/bastille/cmd.sh @@ -33,14 +33,35 @@ usage() { error_exit "Usage: bastille cmd TARGET command" + + cat << EOF + Options: + + -f | --force -- Start the jail if it is stopped. + +EOF + exit 1 } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac +# Handle options. +FORCE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -f|--force) + FORCE=1 + shift + ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done if [ $# -eq 0 ]; then usage @@ -57,14 +78,21 @@ set_target "${TARGET}" for _jail in ${JAILS}; do # If target is stopped or not found, continue... - check_target_is_running "${_jail}" || continue + check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${_jail}" + else + continue + fi + COUNT=$(($COUNT+1)) info "[${_jail}]:" if grep -qw "linsysfs" "${bastille_jailsdir}/${_jail}/fstab"; then # Allow executing commands on Linux jails. jexec -l -u root "${_jail}" "$@" + echo "$@" else jexec -l -U root "${_jail}" "$@" + echo "$@" fi ERROR_CODE=$? if [ "${ERROR_CODE}" -ne 0 ]; then diff --git a/usr/local/share/bastille/console.sh b/usr/local/share/bastille/console.sh index 367988dd9..0bbce64a4 100644 --- a/usr/local/share/bastille/console.sh +++ b/usr/local/share/bastille/console.sh @@ -33,14 +33,36 @@ usage() { error_exit "Usage: bastille console TARGET [user]" + + cat << EOF + Options: + + -f | --force -- Start the jail if it is stopped. + +EOF + exit 1 } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac +# Handle options. +FORCE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -f|--force) + FORCE=1 + shift + ;; + -*) + error_notify "Unknown Option: \"${1}\"" + usage + ;; + *) + break + ;; + esac +done if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then usage @@ -51,7 +73,11 @@ USER="${2}" bastille_root_check set_target_single "${TARGET}" -check_target_is_running "${TARGET}" || exit +check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${TARGET}" +else + exit +fi validate_user() { if jexec -l "${TARGET}" id "${USER}" >/dev/null 2>&1; then diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh index 086490d28..3a88c205e 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -43,21 +43,13 @@ EOF exit 1 } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac - -if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then - usage -fi - # Handle options. FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -f|--force) FORCE=1 shift @@ -71,6 +63,10 @@ while [ "$#" -gt 0 ]; do esac done +if [ "$#" -ne 1 ]; then + usage +fi + TARGET="${1}" bastille_root_check diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index 03e6fd3bd..c77a8ccf4 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -33,10 +33,11 @@ usage() { error_exit "Usage: bastille cp [option(s)] TARGET HOST_PATH JAIL_PATH" + cat << EOF Options: - -q | -- quiet -- Suppress output. + -q | --quiet -- Suppress output. EOF exit 1 @@ -46,9 +47,9 @@ EOF OPTION="-av" while [ "$#" -gt 0 ]; do case "${1}" in - -h|--help|help) - usage - ;; + -h|--help|help) + usage + ;; -q|--quiet) OPTION="-a" shift @@ -78,6 +79,5 @@ for _jail in ${JAILS}; do bastille_jail_path="${bastille_jailsdir}/${_jail}/root" cp "${OPTION}" "${CPSOURCE}" "${bastille_jail_path}${CPDEST}" RETURN="$?" - echo return "${RETURN}" done diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index d6832e47f..e7dfb8fd2 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -34,7 +34,7 @@ usage() { # Build an independent usage for the create command # If no option specified, will create a thin container by default - error_notify "Usage: bastille create [option(s)] name release ip [interface]" + error_notify "Usage: bastille create [option(s)] NAME RELEASE IP_ADDRESS [interface]" cat << EOF Options: @@ -111,6 +111,7 @@ validate_ip() { fi fi } + validate_ips() { IP6_MODE="disable" IP4_DEFINITION="" @@ -239,7 +240,6 @@ post_create_jail() { # Using relative paths here. # MAKE SURE WE'RE IN THE RIGHT PLACE. cd "${bastille_jail_path}" || error_exit "Could not cd to ${bastille_jail_path}" - echo if [ ! -f "${bastille_jail_conf}" ]; then if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then @@ -277,9 +277,9 @@ create_jail() { bastille_jail_fstab="${bastille_jailsdir}/${NAME}/fstab" ## file bastille_jail_conf="${bastille_jailsdir}/${NAME}/jail.conf" ## file bastille_jail_log="${bastille_logsdir}/${NAME}_console.log" ## file - # shellcheck disable=SC2034 + # shellcheck disable=SC2034 bastille_jail_rc_conf="${bastille_jailsdir}/${NAME}/root/etc/rc.conf" ## file - # shellcheck disable=SC2034 + # shellcheck disable=SC2034 bastille_jail_resolv_conf="${bastille_jailsdir}/${NAME}/root/etc/resolv.conf" ## file if [ ! -d "${bastille_jailsdir}/${NAME}" ]; then @@ -362,7 +362,7 @@ create_jail() { if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then LINK_LIST="bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/sbin usr/share usr/src" - info "Creating a thinjail...\n" + info "Creating a thinjail..." for _link in ${LINK_LIST}; do ln -sf /.bastille/${_link} ${_link} done @@ -591,19 +591,12 @@ create_jail() { fi } -# Handle special-case commands first. -case "$1" in -help|-h|--help) - usage - ;; -esac - bastille_root_check -if echo "$3" | grep '@'; then +if echo "${3}" | grep '@'; then # shellcheck disable=SC2034 BASTILLE_JAIL_IP=$(echo "$3" | awk -F@ '{print $2}') - # shellcheck disable=SC2034 + # shellcheck disable=SC2034 BASTILLE_JAIL_INTERFACES=$( echo "$3" | awk -F@ '{print $1}') fi @@ -617,6 +610,9 @@ LINUX_JAIL="" # Handle and parse options while [ $# -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -E|--empty) EMPTY_JAIL="1" shift @@ -687,7 +683,7 @@ while [ $# -gt 0 ]; do shift ;; -*) - error_notify "Unknown Option." + error_notify "Unknown option: \"${1}\"" usage ;; *) diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index e18d1df6e..e51ed51f9 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -33,6 +33,7 @@ usage() { error_notify "Usage: bastille destroy [option(s)] [JAIL|RELEASE]" + cat << EOF Options: @@ -49,15 +50,21 @@ destroy_jail() { bastille_jail_base="${bastille_jailsdir}/${TARGET}" ## dir bastille_jail_log="${bastille_logsdir}/${TARGET}_console.log" ## file - check_target_is_running "${TARGET}" || if [ "${FORCE}" = "1" ]; then + check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq "1" ]; then bastille stop "${TARGET}" else exit fi if [ -d "${bastille_jail_base}" ]; then - ## make sure no filesystem is currently mounted in the jail directory - mount_points="$(mount | cut -d ' ' -f 3 | grep "${bastille_jail_base}"/root/)" + # Force unmount an existing mount points + mount_points="$(mount | cut -d ' ' -f 3 | grep ${bastille_jail_base}/root/)" + for _mount in ${mount_points}; do + echo "Unmounting: \"${_mount}\"" + umount -f "${_mount}" || error_exit "Failed to unmount: \"${_mount}\"" + done + + ## make sure no filesystem is currently mounted in the jail directory if [ -n "${mount_points}" ]; then error_notify "Failed to destroy jail: ${TARGET}" error_exit "Jail has mounted filesystems:\n$mount_points" @@ -102,7 +109,6 @@ destroy_jail() { info "Clearing RDR rules:" pfctl -a "rdr/${TARGET}" -Fn fi - echo fi } @@ -183,7 +189,6 @@ destroy_rel() { rm -rf "${bastille_cachedir:?}/${TARGET:?}" fi fi - echo else error_notify "Cannot destroy base with child containers." fi @@ -194,9 +199,9 @@ destroy_rel() { FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in - -h|--help|help) - usage - ;; + -h|--help|help) + usage + ;; -f|--force|force) FORCE="1" shift diff --git a/usr/local/share/bastille/edit.sh b/usr/local/share/bastille/edit.sh index caacdc13d..992dd9c59 100644 --- a/usr/local/share/bastille/edit.sh +++ b/usr/local/share/bastille/edit.sh @@ -38,9 +38,9 @@ usage() { # Handle options. while [ "$#" -gt 0 ]; do case "${1}" in - -h|--help|help) - usage - ;; + -h|--help|help) + usage + ;; -*) error_notify "Unknown Option: \"${1}\"" usage diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh index 8b7588ae7..87410009e 100644 --- a/usr/local/share/bastille/etcupdate.sh +++ b/usr/local/share/bastille/etcupdate.sh @@ -42,17 +42,6 @@ EOF exit 1 } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac - -if [ $# -lt 2 ] || [ $# -gt 3 ]; then - usage -fi - bootstrap_etc_release() { local _release="${1}" local _release_version="$( echo "${1}" | awk -F "-" '{print $1}' )" @@ -86,9 +75,16 @@ update_jail_etc() { fi } +if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then + usage +fi + # Handle options. while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -d|--dry-run) if [ -z "${2}" ] || [ -z "${3}" ]; then usage diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index 52a3ece1f..5c3b059dc 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -217,9 +217,7 @@ fi if [ -n "${SAFE_EXPORT}" ]; then # Check if container is running, otherwise just ignore - if [ -z "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then - SAFE_EXPORT= - fi + check_target_is_stopped "${TARGET}" || SAFE_EXPORT="" fi # Export directory check diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh index 5582a8899..e7c60fcf4 100644 --- a/usr/local/share/bastille/htop.sh +++ b/usr/local/share/bastille/htop.sh @@ -33,6 +33,7 @@ usage() { error_exit "Usage: bastille htop [option(s)] TARGET" + cat << EOF Options: diff --git a/usr/local/share/bastille/limits.sh b/usr/local/share/bastille/limits.sh index e1ca91ab2..76b7daa85 100644 --- a/usr/local/share/bastille/limits.sh +++ b/usr/local/share/bastille/limits.sh @@ -59,10 +59,15 @@ fi bastille_root_check set_target "${TARGET}" -check_target_is_running "${TARGET}" || exit for _jail in ${JAILS}; do + info "[${_jail}]:" + check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${_jail}" + else + exit + fi _rctl_rule="jail:${_jail}:${OPTION}:deny=${VALUE}/jail" _rctl_rule_log="jail:${_jail}:${OPTION}:log=${VALUE}/jail" @@ -79,5 +84,5 @@ for _jail in ${JAILS}; do echo -e "${OPTION} ${VALUE}" rctl -a "${_rctl_rule}" "${_rctl_rule_log}" - echo -e "${COLOR_RESET}" + done diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 9632c31ee..4b44bb4a5 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -246,9 +246,9 @@ if [ "$#" -gt 0 ]; then list_import exit 0 ;; - -*) - error_exit "Unknown option: \"${1}\"" - ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; *) # Check if we want to query all info for a specific jail instead. if [ -f "${bastille_jailsdir}/${1}/jail.conf" ]; then diff --git a/usr/local/share/bastille/pkg.sh b/usr/local/share/bastille/pkg.sh index ff442fd4c..8824a5d65 100644 --- a/usr/local/share/bastille/pkg.sh +++ b/usr/local/share/bastille/pkg.sh @@ -38,30 +38,21 @@ usage() { Options: -f | --force -- Start the jail if it is stopped. - -h | --host -- Use the hosts pkg command. + -p | --host -- Use the hosts pkg command. EOF exit 1 } - -# Handle special-case commands first. -case "$1" in - help|-h|--help) - usage - ;; -esac - -if [ $# -lt 2 ]; then - usage -fi - # Handle options. FORCE=0 USE_HOST_PKG=0 while [ "$#" -gt 0 ]; do case "${1}" in - -h|--host) + -h|--help|help) + usage + ;; + -p|--host) USE_HOST_PKG=1 shift ;; @@ -78,6 +69,10 @@ while [ "$#" -gt 0 ]; do esac done +if [ $# -lt 2 ]; then + usage +fi + TARGET="${1}" bastille_root_check @@ -92,7 +87,7 @@ for _jail in ${JAILS}; do continue fi info "[${_jail}]:" - bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path) + bastille_jail_path="$( ${bastille_jailsdir}/${_jail}/root )" if [ -f "/usr/sbin/mport" ]; then if ! jexec -l -U root "${_jail}" /usr/sbin/mport "$@"; then errors=1 @@ -110,10 +105,8 @@ for _jail in ${JAILS}; do errors=1 fi fi - echo done if [ $errors -ne 0 ]; then error_exit "Failed to apply on some jails, please check logs" - exit 1 fi diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh index 59cc5c98b..aeff4f988 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -33,10 +33,11 @@ usage() { error_exit "Usage: bastille rcp [option(s)] TARGET JAIL_PATH HOST_PATH" + cat << EOF Options: - -q | -- quiet -- Suppress output. + -q | --quiet -- Suppress output. EOF exit 1 @@ -46,9 +47,9 @@ EOF OPTION="-av" while [ "$#" -gt 0 ]; do case "${1}" in - -h|--help|help) - usage - ;; + -h|--help|help) + usage + ;; -q|--quiet) OPTION="-a" shift @@ -78,6 +79,5 @@ for _jail in ${JAILS}; do bastille_jail_path="${bastille_jailsdir}/${_jail}/root" cp "${OPTION}" "${bastille_jail_path}/${CPSOURCE}" "${CPDEST}" RETURN="$?" - echo return "${RETURN}" done diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index c3487cfce..d5eb7658e 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -33,6 +33,7 @@ usage() { error_notify "Usage: bastille rdr TARGET [option(s)] [clear|reset|list|(tcp|udp)] HOST_PORT JAIL_PORT [log ['(' logopts ')'] ] )]" + cat << EOF Options: @@ -57,7 +58,7 @@ check_jail_validity() { # Check if jail ip6 address (ip6.addr) is valid (non-VNET only) if [ "$( bastille config $TARGET get vnet )" != 'enabled' ]; then if [ "$( bastille config $TARGET get ip6 )" != 'disable' ] && [ "$( bastille config $TARGET get ip6 )" != 'not set' ]; then - JAIL_IP6="$( bastille config ${TARGET} get ip6 )" + JAIL_IP6="$( bastille config ${TARGET} get ip6.addr )" fi fi diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index 6343e1cbc..f6b8ab895 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -33,6 +33,7 @@ usage() { error_exit "Usage: bastille rename [option(s)] TARGET NEW_NAME" + cat << EOF Options: @@ -46,9 +47,9 @@ EOF FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in - -h|--help|help) - usage - ;; + -h|--help|help) + usage + ;; -f|--force) FORCE=1 shift @@ -99,8 +100,8 @@ update_jailconf() { sed -i '' "s|mount.fstab.*=.*;|mount.fstab = ${bastille_jailsdir}/${NEWNAME}/fstab;|" "${JAIL_CONFIG}" sed -i '' "s|${TARGET}.*{|${NEWNAME} {|" "${JAIL_CONFIG}" # update vnet config - sed -i '' "s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|" "${JAIL_CONFIG}" - sed -i '' "/vnet.interface/s|_${TARGET};|_${NEWNAME};|" "${JAIL_CONFIG}" + sed -i '' "s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|" "${JAIL_CONFIG}" + sed -i '' "/vnet.interface/s|_${TARGET};|_${NEWNAME};|" "${JAIL_CONFIG}" sed -i '' "/ifconfig/s|_${TARGET}|_${NEWNAME}|" "${JAIL_CONFIG}" sed -i '' "/ifconfig/s|_${TARGET}_name=|_${NEWNAME}_name=|" "${BASTILLE_JAIL_RC_CONF}" fi @@ -161,6 +162,9 @@ change_name() { if [ "$?" -ne 0 ]; then error_exit "An error has occurred while attempting to rename '${TARGET}'." else + if [ "${FORCE}" -eq 1 ]; then + bastille start "${NEWNAME}" + fi info "Renamed '${TARGET}' to '${NEWNAME}' successfully." fi } diff --git a/usr/local/share/bastille/service.sh b/usr/local/share/bastille/service.sh index c9808a808..df8a18520 100644 --- a/usr/local/share/bastille/service.sh +++ b/usr/local/share/bastille/service.sh @@ -33,6 +33,7 @@ usage() { error_exit "Usage: bastille service [options(s)] TARGET SERVICE_NAME ACTION" + cat << EOF Options: @@ -46,9 +47,9 @@ EOF FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in - -h|--help|help) - usage - ;; + -h|--help|help) + usage + ;; -f|--force) FORCE=1 shift @@ -62,7 +63,7 @@ while [ "$#" -gt 0 ]; do esac done -if [ "$#" -lt 3 ] || [ "$#" -gt 4 ]; then +if [ "$#" -ne 3 ]; then usage fi diff --git a/usr/local/share/bastille/setup.sh b/usr/local/share/bastille/setup.sh index f6153e5b3..3f0e41169 100644 --- a/usr/local/share/bastille/setup.sh +++ b/usr/local/share/bastille/setup.sh @@ -45,7 +45,7 @@ usage() { } # Check for too many args -if [ $# -gt 1 ]; then +if [ "$#" -gt 1 ]; then usage fi diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index 42bf2f9da..8f25e5adf 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -53,7 +53,7 @@ set_target "${TARGET}" for _jail in ${JAILS}; do - # Check if jail is running + # Check if jail is running check_target_is_stopped "${_jail}" || continue if [ "$(bastille config $_jail get vnet)" != 'enabled' ]; then _interface="$(bastille config ${_jail} get interface)" @@ -72,7 +72,7 @@ for _jail in ${JAILS}; do else ## add ip4.addr to firewall table pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip4}" - fi + fi fi # Start jail diff --git a/usr/local/share/bastille/sysrc.sh b/usr/local/share/bastille/sysrc.sh index 96f0fc20e..ff1c9171d 100644 --- a/usr/local/share/bastille/sysrc.sh +++ b/usr/local/share/bastille/sysrc.sh @@ -33,6 +33,7 @@ usage() { error_exit "Usage: bastille sysrc [option(s)] TARGET ARGS" + cat << EOF Options: @@ -46,9 +47,9 @@ EOF FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in - -h|--help|help) - usage - ;; + -h|--help|help) + usage + ;; -f|--force) FORCE=1 shift diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 2184e24d5..cedc796c4 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf bastille_usage() { - error_exit "Usage: bastille template TARGET|--convert project/template" + error_exit "Usage: bastille template TARGET [--convert|project/template|template]" } post_command_hook() { @@ -125,7 +125,6 @@ fi bastille_root_check set_target "${TARGET}" -check_target_is_running "${TARGET}" # Special case conversion of hook-style template files into a Bastillefile. -- cwells if [ "${TARGET}" = '--convert' ]; then @@ -230,17 +229,22 @@ if [ -n "${ARG_FILE}" ] && [ ! -f "${ARG_FILE}" ]; then fi for _jail in ${JAILS}; do + + check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${TARGET}" || continue + fi + info "[${_jail}]:" echo "Applying template: ${TEMPLATE}..." ## jail-specific variables. - bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path) + bastille_jail_path="${bastille_jailsdir}/${_jail}/root" if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then - _jail_ip=$(/usr/sbin/jls -j "${_jail}" ip4.addr 2>/dev/null) - _jail_ip6=$(/usr/sbin/jls -j "${_jail}" ip6.addr 2>/dev/null) - if [ -z "${_jail_ip}" ] || [ "${_jail_ip}" = "-" ]; then - error_notify "Jail IP not found: ${_jail}" - _jail_ip='' # In case it was -. -- cwells + if [ "$( bastille config ${TARGET} get ip4.addr )" != 'disable' ] && [ "$( bastille config ${TARGET} get ip4.addr )" != 'not set' ]; then + _jail_ip="$( bastille config ${TARGET} get ip4.addr )" + fi + if [ "$( bastille config $TARGET get ip6 )" != 'disable' ] && [ "$( bastille config $TARGET get ip6 )" != 'not set' ]; then + _jail_ip6="$( bastille config ${TARGET} get ip6.addr )" fi fi @@ -395,5 +399,5 @@ for _jail in ${JAILS}; do done info "Template applied: ${TEMPLATE}" - echo + done diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh index ec30311b5..5def17e23 100644 --- a/usr/local/share/bastille/top.sh +++ b/usr/local/share/bastille/top.sh @@ -33,6 +33,7 @@ usage() { error_exit "Usage: bastille top [options(s)] TARGET" + cat << EOF Options: diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index cc5b9b81e..8e38798a7 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -37,28 +37,29 @@ usage() { cat << EOF Options: + -s | --start -- Start the jail if it is stopped. -f | --force -- Force update a release. EOF exit 1 } - -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac - if [ $# -gt 2 ] || [ $# -lt 1 ]; then usage fi # Handle options. OPTION="" +FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; + -s|--start) + FORCE=1 + shift + ;; -f|--force) OPTION="-F" shift @@ -94,28 +95,26 @@ arch_check() { jail_check() { # Check if the jail is thick and is running - if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then - error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'." + set_target_single "${TARGET}" + check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${TARGET}" else - if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then - error_exit "${TARGET} is not a thick container." - fi + exit + fi + if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then + error_exit "${TARGET} is not a thick container." fi } jail_update() { # Update a thick container - if [ -d "${bastille_jailsdir}/${TARGET}" ]; then - jail_check - CURRENT_VERSION=$(/usr/sbin/jexec -l "${TARGET}" freebsd-version 2>/dev/null) - if [ -z "${CURRENT_VERSION}" ]; then - error_exit "Can't determine '${TARGET}' version." - else - env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_jailsdir}/${TARGET}/root" \ - fetch install --currently-running "${CURRENT_VERSION}" - fi + jail_check + CURRENT_VERSION=$(/usr/sbin/jexec -l "${TARGET}" freebsd-version 2>/dev/null) + if [ -z "${CURRENT_VERSION}" ]; then + error_exit "Can't determine '${TARGET}' version." else - error_exit "${TARGET} not found. See 'bastille bootstrap'." + env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_jailsdir}/${TARGET}/root" \ + fetch install --currently-running "${CURRENT_VERSION}" fi } diff --git a/usr/local/share/bastille/upgrade.sh b/usr/local/share/bastille/upgrade.sh index 9179bba91..eee6e08ca 100644 --- a/usr/local/share/bastille/upgrade.sh +++ b/usr/local/share/bastille/upgrade.sh @@ -33,23 +33,29 @@ usage() { error_exit "Usage: bastille upgrade [option(s)] [RELEASE NEW_RELEASE (install)] [TARGET NEW_RELEASE (install)]" -} -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac + cat << EOF + Options: + + -s | --start -- Start the jail if it is stopped. + -f | --force -- Force upgrade a release. + +EOF + exit 1 +} -if [ $# -gt 3 ] || [ $# -lt 2 ]; then - usage -fi # Handle options. OPTION="" while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; + -s|--start) + FORCE=1 + shift + ;; -f|--force) OPTION="-F" shift @@ -63,16 +69,16 @@ while [ "$#" -gt 0 ]; do esac done +if [ $# -lt 2 ] || [ $# -gt 3 ]; then + usage +fi + TARGET="${1}" NEWRELEASE="${2}" bastille_root_check -# Check for unsupported actions -if [ "${TARGET}" = "ALL" ]; then - error_exit "Batch upgrade is unsupported." -fi - +# Check for unsupported actions if [ -f "/bin/midnightbsd-version" ]; then echo -e "${COLOR_RED}Not yet supported on MidnightBSD.${COLOR_RESET}" exit 1 @@ -83,13 +89,16 @@ if freebsd-version | grep -qi HBSD; then fi jail_check() { + # Check if the jail is thick and is running - if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then - error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'." + set_target_single "${TARGET}" + check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${TARGET}" else - if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then - error_exit "${TARGET} is not a thick container." - fi + exit + fi + if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then + error_exit "${TARGET} is not a thick container." fi } @@ -114,16 +123,12 @@ release_upgrade() { jail_upgrade() { # Upgrade a thick container - if [ -d "${bastille_jailsdir}/${TARGET}" ]; then - jail_check - release_check - CURRENT_VERSION=$(jexec -l ${TARGET} freebsd-version) - env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_jailsdir}/${TARGET}/root" --currently-running "${CURRENT_VERSION}" -r ${NEWRELEASE} upgrade - echo - echo -e "${COLOR_YELLOW}Please run 'bastille upgrade ${TARGET} install' to finish installing updates.${COLOR_RESET}" - else - error_exit "${TARGET} not found. See 'bastille bootstrap'." - fi + jail_check + release_check + CURRENT_VERSION=$(jexec -l ${TARGET} freebsd-version) + env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_jailsdir}/${TARGET}/root" --currently-running "${CURRENT_VERSION}" -r ${NEWRELEASE} upgrade + echo + echo -e "${COLOR_YELLOW}Please run 'bastille upgrade ${TARGET} install' to finish installing updates.${COLOR_RESET}" } jail_updates_install() { diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh index 7470b1211..179241b7e 100644 --- a/usr/local/share/bastille/verify.sh +++ b/usr/local/share/bastille/verify.sh @@ -31,8 +31,8 @@ . /usr/local/share/bastille/common.sh . /usr/local/etc/bastille/bastille.conf -bastille_usage() { - error_exit "Usage: bastille verify [release|template]" +usage() { + error_exit "Usage: bastille verify [RELEASE|TEMPLATE]" } verify_release() { @@ -145,14 +145,14 @@ verify_template() { } # Handle special-case commands first. -case "$1" in +case "${1}" in help|-h|--help) bastille_usage ;; esac -if [ $# -ne 1 ]; then - bastille_usage +if [ "$#" -ne 1 ]; then + usage fi bastille_root_check diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 374824aa0..6e9be0add 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -38,18 +38,16 @@ usage() { zfs_snapshot() { for _jail in ${JAILS}; do info "[${_jail}]:" - # shellcheck disable=SC2140 + # shellcheck disable=SC2140 zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" - echo done } zfs_destroy_snapshot() { for _jail in ${JAILS}; do info "[${_jail}]:" - # shellcheck disable=SC2140 + # shellcheck disable=SC2140 zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" - echo done } @@ -57,7 +55,6 @@ zfs_set_value() { for _jail in ${JAILS}; do info "[${_jail}]:" zfs "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}" - echo done } From 3fdd00ac11b7c476b06e1a8fed5670517762e5ba Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Tue, 24 Dec 2024 16:11:22 -0700 Subject: [PATCH 100/120] fixes --- usr/local/share/bastille/clone.sh | 9 +-------- usr/local/share/bastille/cmd.sh | 6 +++--- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 43046a68e..8c12f9a2c 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -38,8 +38,6 @@ usage() { Options: -f | --force -- Start the jail if it is stopped. - -u | --unsafe -- Force clone even if the jail is running. - Only works with ZFS for now. EOF exit 1 @@ -47,16 +45,11 @@ EOF # Handle options. FORCE=0 -UNSAFE=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; - -u|--unsafe) - UNSAFE=1 - shift - ;; -f|--force) FORCE=1 shift @@ -205,7 +198,7 @@ clone_jail() { check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then bastille stop "${TARGET}" - elif [ "${UNSAFE}" -ne 1 ] || [ ! checkyesno bastille_zfs_enable ]; then + else exit fi diff --git a/usr/local/share/bastille/cmd.sh b/usr/local/share/bastille/cmd.sh index 245ad7022..025496b2b 100644 --- a/usr/local/share/bastille/cmd.sh +++ b/usr/local/share/bastille/cmd.sh @@ -88,13 +88,13 @@ for _jail in ${JAILS}; do info "[${_jail}]:" if grep -qw "linsysfs" "${bastille_jailsdir}/${_jail}/fstab"; then # Allow executing commands on Linux jails. - jexec -l -u root "${_jail}" "$@" echo "$@" + jexec -l -u root "${_jail}" "$@" else - jexec -l -U root "${_jail}" "$@" echo "$@" + jexec -l -U root "${_jail}" "$@" fi - ERROR_CODE=$? + ERROR_CODE="$?" if [ "${ERROR_CODE}" -ne 0 ]; then warn "[${_jail}]: ${ERROR_CODE}" fi From 96466c2a3683f82d3b0c34192af89a8b3100dd52 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 24 Dec 2024 17:12:23 -0700 Subject: [PATCH 101/120] Remove warn about existing rdr rule --- usr/local/share/bastille/rdr.sh | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index d5eb7658e..30a188ef2 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -101,11 +101,6 @@ persist_rdr_rule() { local jail_port="${7}" if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then echo "$inet $if $src $dst $proto $host_port $jail_port" >> "${bastille_jailsdir}/${TARGET}/rdr.conf" - else - info "[${TARGET}]:" - warn "Rule already exists in rdr.conf" - echo "$inet $if $src $dst $proto $host_port $jail_port" - exit 1 fi } @@ -121,11 +116,6 @@ persist_rdr_log_rule() { log=$@; if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port $log" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then echo "$inet $if $src $dst $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${TARGET}/rdr.conf" - else - info "[${TARGET}]:" - warn "Rule already exists in rdr.conf" - echo "$inet $if $src $dst $proto $host_port $jail_port $log" - exit 1 fi } From 029c656308380c65dfe483fb0134ddb9303d12d3 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 25 Dec 2024 08:35:02 -0700 Subject: [PATCH 102/120] Optional stop on clone with zfs --- usr/local/share/bastille/clone.sh | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 8c12f9a2c..439f78ba2 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -37,7 +37,8 @@ usage() { cat << EOF Options: - -f | --force -- Start the jail if it is stopped. + -f | --force -- Stop the jail if it is running. + Mandatory for UFS, optional for ZFS. EOF exit 1 @@ -196,14 +197,11 @@ clone_jail() { info "Attempting to clone ${TARGET} to ${NEWNAME}..." - check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then - bastille stop "${TARGET}" - else - exit - fi - if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then if checkyesno bastille_zfs_enable; then + check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille stop "${TARGET}" + fi if [ -n "${bastille_zfs_zpool}" ]; then # Replicate the existing container DATE=$(date +%F-%H%M%S) @@ -220,7 +218,12 @@ clone_jail() { fi else # Perform container file copy (archive mode) - cp -a "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}" + check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille stop "${TARGET}" + cp -a "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}" + else + exit + fi fi else error_exit "${NEWNAME} already exists." From d8b0a8d4c4c44c6a7392f85120668fada8a0837a Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 25 Dec 2024 08:42:08 -0700 Subject: [PATCH 103/120] Add restart to clone --- usr/local/share/bastille/clone.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 439f78ba2..168145f03 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -36,9 +36,10 @@ usage() { cat << EOF Options: - - -f | --force -- Stop the jail if it is running. - Mandatory for UFS, optional for ZFS. + + -r | --restart -- Start/Restart jail(s) on completion. + -f | --force -- Stop the jail if it is running. + Mandatory for UFS, optional for ZFS. EOF exit 1 @@ -46,11 +47,16 @@ EOF # Handle options. FORCE=0 +RESTART=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; + -r|--restart) + RESTART=1 + shift + ;; -f|--force) FORCE=1 shift From b4060fe3f8655674af31dace303b115a1e94f95a Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Thu, 26 Dec 2024 18:08:37 -0700 Subject: [PATCH 104/120] more fixes and improvements --- usr/local/share/bastille/clone.sh | 61 +++++++++++++++++++-------- usr/local/share/bastille/cmd.sh | 15 ++++--- usr/local/share/bastille/common.sh | 7 +-- usr/local/share/bastille/console.sh | 8 ++-- usr/local/share/bastille/convert.sh | 7 +-- usr/local/share/bastille/cp.sh | 9 ++-- usr/local/share/bastille/create.sh | 6 +++ usr/local/share/bastille/destroy.sh | 8 ++-- usr/local/share/bastille/etcupdate.sh | 7 ++- usr/local/share/bastille/export.sh | 1 - usr/local/share/bastille/htop.sh | 9 ++-- usr/local/share/bastille/import.sh | 1 - usr/local/share/bastille/limits.sh | 16 +++++-- usr/local/share/bastille/mount.sh | 21 +++++---- usr/local/share/bastille/pkg.sh | 20 +++++---- usr/local/share/bastille/rcp.sh | 9 ++-- usr/local/share/bastille/rdr.sh | 14 +++--- usr/local/share/bastille/rename.sh | 20 ++++++--- usr/local/share/bastille/service.sh | 12 +++--- usr/local/share/bastille/setup.sh | 2 +- usr/local/share/bastille/start.sh | 12 +++--- usr/local/share/bastille/stop.sh | 5 ++- usr/local/share/bastille/sysrc.sh | 12 +++--- usr/local/share/bastille/template.sh | 45 +++++++++++++++----- usr/local/share/bastille/top.sh | 12 +++--- usr/local/share/bastille/umount.sh | 11 ++--- usr/local/share/bastille/update.sh | 8 ++-- usr/local/share/bastille/upgrade.sh | 14 +++--- 28 files changed, 223 insertions(+), 149 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 168145f03..18fe942be 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -32,33 +32,48 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille clone TARGET NEW_NAME IP_ADDRESS" - + error_notify "Usage: bastille clone [option(s)] TARGET NEW_NAME IP_ADDRESS" cat << EOF Options: - - -r | --restart -- Start/Restart jail(s) on completion. - -f | --force -- Stop the jail if it is running. - Mandatory for UFS, optional for ZFS. + + -l | --live -- Clone a running jail. ZFS only. + Jail must be running. + Cannot be used with [-f|--force]. + -f | --force -- Stop the jail if it is running. + Cannot be used with [-l|--live]. + -s | --start -- Start jail(s) when complete. EOF exit 1 } # Handle options. +LIVE=0 FORCE=0 -RESTART=0 +START=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; - -r|--restart) - RESTART=1 - shift + -l|--live) + if ! checkyesno bastille_zfs_enable; then + error_exit "[-l|--live] can only be used with ZFS." + else + LIVE=1 + shift + fi ;; -f|--force) - FORCE=1 + if [ "${LIVE}" -eq 1 ]; then + error_exit "[-f|--force] cannot be used with [-l|--live]." + else + FORCE=1 + shift + fi + ;; + -s|--start) + START=1 shift ;; -*) @@ -161,8 +176,8 @@ update_jailconf_vnet() { 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}" + sed -i '' "s|ether.*:.*:.*:.*:.*:.*a |ether ${macaddr}a |" "${JAIL_CONFIG}" + sed -i '' "s|ether.*:.*:.*:.*:.*:.*b |ether ${macaddr}b |" "${JAIL_CONFIG}" break fi fi @@ -205,8 +220,13 @@ clone_jail() { if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then if checkyesno bastille_zfs_enable; then - check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then - bastille stop "${TARGET}" + if [ "${LIVE}" -eq 1 ]; then + check_target_is_running "${TARGET}" || error_exit "[-l|--live] can only be used with a running jail." + elif [ "${FORCE}" -eq 1 ]; then + check_target_is_stopped "${TARGET}" || bastille stop "${TARGET}" + else + error_notify "Jail is running." + error_exit "Use [-f|--force] to force stop the jail, or [-l|--live] (ZFS only) to clone a running jail." fi if [ -n "${bastille_zfs_zpool}" ]; then # Replicate the existing container @@ -226,10 +246,11 @@ clone_jail() { # Perform container file copy (archive mode) check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then bastille stop "${TARGET}" - cp -a "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}" else - exit + error_notify "Jail is running." + error_exit "Use [-f|--force] to force stop the jail." fi + cp -a "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}" fi else error_exit "${NEWNAME} already exists." @@ -245,6 +266,12 @@ clone_jail() { else info "Cloned '${TARGET}' to '${NEWNAME}' successfully." fi + if [ "${START}" -eq 1 ]; then + if [ "${LIVE}" -eq 0 ]; then + bastille start "${TARGET}" + fi + bastille start "${NEWNAME}" + fi } # Check if IP address is valid. diff --git a/usr/local/share/bastille/cmd.sh b/usr/local/share/bastille/cmd.sh index 025496b2b..ce226043d 100644 --- a/usr/local/share/bastille/cmd.sh +++ b/usr/local/share/bastille/cmd.sh @@ -32,8 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille cmd TARGET command" - + error_notify "Usage: bastille cmd TARGET command" cat << EOF Options: @@ -77,15 +76,17 @@ RETURN=0 set_target "${TARGET}" for _jail in ${JAILS}; do - # If target is stopped or not found, continue... + + info "[${_jail}]:" + check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then bastille start "${_jail}" - else - continue + else + error_notify "Jail is not running." + error_continue "Use [-f|--force] to force start the jail." fi COUNT=$(($COUNT+1)) - info "[${_jail}]:" if grep -qw "linsysfs" "${bastille_jailsdir}/${_jail}/fstab"; then # Allow executing commands on Linux jails. echo "$@" @@ -94,7 +95,7 @@ for _jail in ${JAILS}; do echo "$@" jexec -l -U root "${_jail}" "$@" fi - ERROR_CODE="$?" + ERROR_CODE=$? if [ "${ERROR_CODE}" -ne 0 ]; then warn "[${_jail}]: ${ERROR_CODE}" fi diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 3bddafb81..56857d4d2 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -82,7 +82,6 @@ warn() { check_target_exists() { local _TARGET="${1}" if [ ! -d "${bastille_jailsdir}"/"${_TARGET}" ]; then - error_notify "Jail not found \"${_TARGET}\"" return 1 else return 0 @@ -92,7 +91,6 @@ check_target_exists() { check_target_is_running() { local _TARGET="${1}" if [ ! "$(/usr/sbin/jls name | awk "/^${_TARGET}$/")" ]; then - error_notify "[${_TARGET}]: Not started. See 'bastille start ${_TARGET}'." return 1 else return 0 @@ -102,7 +100,6 @@ check_target_is_running() { check_target_is_stopped() { local _TARGET="${1}" if [ "$(/usr/sbin/jls name | awk "/^${_TARGET}$/")" ]; then - error_notify "${_TARGET} is running. See 'bastille stop ${_TARGET}'." return 1 else return 0 @@ -114,7 +111,7 @@ set_target() { if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then target_all_jails else - check_target_exists "${_TARGET}" || exit + check_target_exists "${_TARGET}" || error_exit "Jail not found \"${_TARGET}\"" JAILS="${_TARGET}" TARGET="${_TARGET}" export JAILS @@ -127,7 +124,7 @@ set_target_single() { if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then error_exit "[all|ALL] not supported with this command." else - check_target_exists "${_TARGET}" || exit + check_target_exists "${_TARGET}" || error_exit "Jail not found \"${_TARGET}\"" JAILS="${_TARGET}" TARGET="${_TARGET}" export JAILS diff --git a/usr/local/share/bastille/console.sh b/usr/local/share/bastille/console.sh index 0bbce64a4..bf7e32fc1 100644 --- a/usr/local/share/bastille/console.sh +++ b/usr/local/share/bastille/console.sh @@ -32,8 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille console TARGET [user]" - + error_notify "Usage: bastille console [option(s)] TARGET [user]" cat << EOF Options: @@ -75,8 +74,9 @@ bastille_root_check set_target_single "${TARGET}" check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then bastille start "${TARGET}" -else - exit +else + error_notify "Jail is not running." + error_continue "Use [-f|--force] to force start the jail." fi validate_user() { diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh index 3a88c205e..f8de61e94 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille convert [option(s)] TARGET" + error_notify "Usage: bastille convert [option(s)] TARGET" cat << EOF Options: @@ -73,8 +73,9 @@ bastille_root_check set_target_single "${TARGET}" check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then bastille stop "${TARGET}" -else - exit +else + error_notify "Jail is running." + error_exit "Use [-f|--force] to force stop the jail." fi convert_symlinks() { diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index c77a8ccf4..aa3e68646 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -32,8 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille cp [option(s)] TARGET HOST_PATH JAIL_PATH" - + error_notify "Usage: bastille cp [option(s)] TARGET HOST_PATH JAIL_PATH" cat << EOF Options: @@ -77,7 +76,7 @@ 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="$?" - return "${RETURN}" + if ! cp "${OPTION}" "${CPSOURCE}" "${bastille_jail_path}${CPDEST}"; then + error_continue "CP failed: ${CPSOURCE} -> ${bastille_jail_path}${CPDEST}" + fi done diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index e7dfb8fd2..19aefb669 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -506,6 +506,12 @@ create_jail() { fi fi + # Exit if jail was not started, which means something is wrong. + if ! check_target_is_running "${NAME}"; then + bastille destroy "${NAME}" + error_exit "[${NAME}]: Failed to create jail..." + fi + if [ -n "${VNET_JAIL}" ]; then if [ -n "${bastille_template_vnet}" ]; then ## rename interface to generic vnet0 diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index e51ed51f9..06cff854a 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -33,7 +33,6 @@ usage() { error_notify "Usage: bastille destroy [option(s)] [JAIL|RELEASE]" - cat << EOF Options: @@ -50,10 +49,11 @@ destroy_jail() { bastille_jail_base="${bastille_jailsdir}/${TARGET}" ## dir bastille_jail_log="${bastille_logsdir}/${TARGET}_console.log" ## file - check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq "1" ]; then + check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then bastille stop "${TARGET}" - else - exit + else + error_notify "Jail is running." + error_exit "Use [-f|--force] to force stop the jail." fi if [ -d "${bastille_jail_base}" ]; then diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh index 87410009e..7445fe5da 100644 --- a/usr/local/share/bastille/etcupdate.sh +++ b/usr/local/share/bastille/etcupdate.sh @@ -31,12 +31,11 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille etcupdate [option(s)] [TARGET|bootstrap RELEASE]" - + error_notify "Usage: bastille etcupdate [option(s)] [TARGET|bootstrap RELEASE]" cat << EOF Options: - -d | --dry-run | -- Only show output of what etcupdate will do. + -d | --dry-run -- Only show output of what etcupdate will do. EOF exit 1 @@ -75,7 +74,7 @@ update_jail_etc() { fi } -if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then +if [ $# -lt 2 ] || [ $# -gt 3 ]; then usage fi diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index 5c3b059dc..acc1b1470 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -37,7 +37,6 @@ usage() { # Valid compress/options for non ZFS configured systems are .tgz and .txz # If no compression option specified, user must redirect standard output error_notify "Usage: bastille export | option(s) | TARGET | PATH" - cat << EOF Options: diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh index e7c60fcf4..10795da15 100644 --- a/usr/local/share/bastille/htop.sh +++ b/usr/local/share/bastille/htop.sh @@ -33,7 +33,6 @@ usage() { error_exit "Usage: bastille htop [option(s)] TARGET" - cat << EOF Options: @@ -71,16 +70,18 @@ TARGET="${1}" bastille_root_check set_target_single "${TARGET}" + +info "[${TARGET}]:" check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then bastille start "${TARGET}" -else - exit +else + error_notify "Jail is not running." + error_continue "Use [-f|--force] to force start the jail." fi bastille_jail_path="${bastille_jailsdir}/${TARGET}/root" if [ ! -x "${bastille_jail_path}/usr/local/bin/htop" ]; then error_notify "htop not found on ${TARGET}." elif [ -x "${bastille_jail_path}/usr/local/bin/htop" ]; then - info "[${TARGET}]:" jexec -l ${TARGET} /usr/local/bin/htop fi diff --git a/usr/local/share/bastille/import.sh b/usr/local/share/bastille/import.sh index 09437eb02..604b210fd 100644 --- a/usr/local/share/bastille/import.sh +++ b/usr/local/share/bastille/import.sh @@ -35,7 +35,6 @@ usage() { # Build an independent usage for the import command # If no file/extension specified, will import from standard input error_notify "Usage: bastille import [option(s)] FILE" - cat << EOF Options: diff --git a/usr/local/share/bastille/limits.sh b/usr/local/share/bastille/limits.sh index 76b7daa85..14627a080 100644 --- a/usr/local/share/bastille/limits.sh +++ b/usr/local/share/bastille/limits.sh @@ -33,8 +33,14 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille limits TARGET OPTION VALUE" + error_notify "Usage: bastille limits [option(s)] TARGET OPTION VALUE" echo -e "Example: bastille limits JAILNAME memoryuse 1G" + cat << EOF + Options: + + -f | --force -- Start the jail if it is stopped. + +EOF exit 1 } @@ -63,10 +69,12 @@ set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" - check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + + check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then bastille start "${_jail}" - else - exit + else + error_notify "Jail is not running." + error_continue "Use [-f|--force] to force start the jail." fi _rctl_rule="jail:${_jail}:${OPTION}:deny=${VALUE}/jail" diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 318937e8f..9f3276c7b 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -50,17 +50,19 @@ TARGET="${1}" shift if [ "$#" -eq 2 ]; then - _fstab="$@ nullfs ro 0 0" + _fstab="$(echo "$@ nullfs ro 0 0" | sed 's#\\ #\\040#g')" else - _fstab="$@" + _fstab="$(echo "$@" | sed 's#\\ #\\040#g')" fi bastille_root_check set_target "${TARGET}" # Assign variables -_hostpath=$(echo "${_fstab}" | awk '{print $1}') -_jailpath=$(echo "${_fstab}" | awk '{print $2}') +_hostpath_fstab=$(echo "${_fstab}" | awk '{print $1}') +_hostpath="$(echo ${_hostpath_fstab} 2>/dev/null | sed 's#\\040# #g')" +_jailpath_fstab=$(echo "${_fstab}" | awk '{print $2}') +_jailpath="$(echo "${_jailpath_fstab}" 2>/dev/null | sed 's#\\040# #g')" _type=$(echo "${_fstab}" | awk '{print $3}') _perms=$(echo "${_fstab}" | awk '{print $4}') _checks=$(echo "${_fstab}" | awk '{print $5" "$6}') @@ -107,13 +109,15 @@ for _jail in ${JAILS}; do info "[${_jail}]:" + _fullpath_fstab="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath_fstab} 2>/dev/null | sed 's#//#/#' )" _fullpath="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath} 2>/dev/null | sed 's#//#/#' )" - _fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}" + _fstab_entry="${_hostpath_fstab} ${_fullpath_fstab} ${_type} ${_perms} ${_checks}" # Check if mount point has already been added - if grep -Eq "[[:blank:]]${_fullpath}" "${bastille_jailsdir}/${_jail}/fstab"; then + _existing_mount="$(echo ${_fullpath_fstab} 2>/dev/null | sed 's#\\#\\\\#')" + if grep -Eq "[[:blank:]]${_existing_mount}" "${bastille_jailsdir}/${_jail}/fstab"; then warn "Mountpoint already present in ${bastille_jailsdir}/${_jail}/fstab" - grep -E "[[:blank:]]${_fullpath}" "${bastille_jailsdir}/${_jail}/fstab" + grep -E "[[:blank:]]${_existing_mount}" "${bastille_jailsdir}/${_jail}/fstab" continue fi @@ -132,8 +136,9 @@ for _jail in ${JAILS}; do continue fi else + _fullpath_fstab="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath_fstab}/${_filename} 2>/dev/null | sed 's#//#/#' )" _fullpath="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath}/${_filename} 2>/dev/null | sed 's#//#/#' )" - _fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}" + _fstab_entry="${_hostpath_fstab} ${_fullpath} ${_type} ${_perms} ${_checks}" mkdir -p "$( dirname ${_fullpath} )" || error_continue "Failed to create mount point." if [ ! -f "${_fullpath}" ]; then touch "${_fullpath}" || error_continue "Failed to create mount point." diff --git a/usr/local/share/bastille/pkg.sh b/usr/local/share/bastille/pkg.sh index 8824a5d65..738c99f2e 100644 --- a/usr/local/share/bastille/pkg.sh +++ b/usr/local/share/bastille/pkg.sh @@ -32,13 +32,12 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille pkg [option(s)] TARGET COMMAND [args]" - + error_notify "Usage: bastille pkg [option(s)] TARGET COMMAND [args]" cat << EOF Options: -f | --force -- Start the jail if it is stopped. - -p | --host -- Use the hosts pkg command. + -H | --host -- Use the hosts pkg command. EOF exit 1 @@ -52,7 +51,7 @@ while [ "$#" -gt 0 ]; do -h|--help|help) usage ;; - -p|--host) + -H|--host) USE_HOST_PKG=1 shift ;; @@ -74,6 +73,7 @@ if [ $# -lt 2 ]; then fi TARGET="${1}" +shift bastille_root_check set_target "${TARGET}" @@ -81,13 +81,17 @@ set_target "${TARGET}" errors=0 for _jail in ${JAILS}; do + + info "[${_jail}]:" + check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then bastille start "${_jail}" - else - continue + else + error_notify "Jail is not running." + error_continue "Use [-f|--force] to force start the jail." fi - info "[${_jail}]:" - bastille_jail_path="$( ${bastille_jailsdir}/${_jail}/root )" + + bastille_jail_path="${bastille_jailsdir}/${_jail}/root" if [ -f "/usr/sbin/mport" ]; then if ! jexec -l -U root "${_jail}" /usr/sbin/mport "$@"; then errors=1 diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh index aeff4f988..81935d045 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -32,8 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille rcp [option(s)] TARGET JAIL_PATH HOST_PATH" - + error_notify "Usage: bastille rcp [option(s)] TARGET JAIL_PATH HOST_PATH" cat << EOF Options: @@ -77,7 +76,7 @@ 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="$?" - return "${RETURN}" + if ! cp "${OPTION}" "${bastille_jail_path}${CPSOURCE}" "${CPDEST}"; then + error_continue "RCP failed: ${CPSOURCE} -> ${bastille_jail_path}${CPDEST}" + fi done diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 30a188ef2..d42a2f1b1 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -33,7 +33,6 @@ usage() { error_notify "Usage: bastille rdr TARGET [option(s)] [clear|reset|list|(tcp|udp)] HOST_PORT JAIL_PORT [log ['(' logopts ')'] ] )]" - cat << EOF Options: @@ -53,6 +52,8 @@ check_jail_validity() { if [ "$( bastille config ${TARGET} get ip4.addr )" != 'disable' ] && [ "$( bastille config ${TARGET} get ip4.addr )" != 'not set' ]; then JAIL_IP="$( bastille config ${TARGET} get ip4.addr )" fi + else + error_exit "VNET jails do not support rdr." fi # Check if jail ip6 address (ip6.addr) is valid (non-VNET only) @@ -202,9 +203,9 @@ OPTION_DST=0 OPTION_INET_TYPE=0 while [ "$#" -gt 0 ]; do case "${1}" in - -h|--help|help) - usage - ;; + -h|--help|help) + usage + ;; -i|--interface) if ifconfig | grep -owq "${2}:"; then OPTION_IF=1 @@ -360,15 +361,12 @@ while [ "$#" -gt 0 ]; do fi ;; *) - if [ "${OPTION}" -eq 1 ];then - usage - fi if [ "${1}" = "dual" ] || [ "${1}" = "ipv4" ] || [ "${1}" = "ipv6" ]; then RDR_INET="${1}" else usage fi - if [ "$#" -eq 7 ] && [ "${5}" = "tcp" ] || [ "${5}" = "udp" ]; then + if [ "$#" -eq 7 ] && { [ "${5}" = "tcp" ] || [ "${5}" = "udp" ]; } then check_jail_validity persist_rdr_rule "$@" load_rdr_rule "$@" diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index f6b8ab895..b59f29253 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -32,12 +32,12 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille rename [option(s)] TARGET NEW_NAME" - + error_notify "Usage: bastille rename [option(s)] TARGET NEW_NAME" cat << EOF Options: - -f | --force -- Stop the jail if it is running. + -f | --force -- Stop the jail if it is running. + -s | --start -- Start jail(s) when complete. EOF exit 1 @@ -45,11 +45,16 @@ EOF # Handle options. FORCE=0 +START=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; + -s|--start) + START=1 + shift + ;; -f|--force) FORCE=1 shift @@ -74,8 +79,9 @@ bastille_root_check set_target_single "${TARGET}" check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then bastille stop "${TARGET}" -else - usage +else + error_notify "Jail is running." + error_exit "Use [-f|--force] to force stop the jail." fi validate_name() { @@ -162,10 +168,10 @@ change_name() { if [ "$?" -ne 0 ]; then error_exit "An error has occurred while attempting to rename '${TARGET}'." else - if [ "${FORCE}" -eq 1 ]; then + info "Renamed '${TARGET}' to '${NEWNAME}' successfully." + if [ "${START}" -eq 1 ]; then bastille start "${NEWNAME}" fi - info "Renamed '${TARGET}' to '${NEWNAME}' successfully." fi } diff --git a/usr/local/share/bastille/service.sh b/usr/local/share/bastille/service.sh index df8a18520..ec89a8867 100644 --- a/usr/local/share/bastille/service.sh +++ b/usr/local/share/bastille/service.sh @@ -32,8 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille service [options(s)] TARGET SERVICE_NAME ACTION" - + error_notify "Usage: bastille service [options(s)] TARGET SERVICE_NAME ACTION" cat << EOF Options: @@ -74,11 +73,12 @@ bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do + info "[${_jail}]:" check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then - bastille start "${_jail}" - else - continue + bastille start "${_jail}" + else + error_notify "Jail is not running." + error_continue "Use [-f|--force] to force start the jail." fi - info "[${_jail}]:" jexec -l "${_jail}" /usr/sbin/service "$@" done diff --git a/usr/local/share/bastille/setup.sh b/usr/local/share/bastille/setup.sh index 3f0e41169..f6153e5b3 100644 --- a/usr/local/share/bastille/setup.sh +++ b/usr/local/share/bastille/setup.sh @@ -45,7 +45,7 @@ usage() { } # Check for too many args -if [ "$#" -gt 1 ]; then +if [ $# -gt 1 ]; then usage fi diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index 8f25e5adf..759d2fa1f 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -52,10 +52,11 @@ bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do - - # Check if jail is running - check_target_is_stopped "${_jail}" || continue - if [ "$(bastille config $_jail get vnet)" != 'enabled' ]; then + + info "[${_jail}]:" + + check_target_is_stopped "${_jail}" || error_continue "Jail is already running." + if [ "$(bastille config ${_jail} get vnet)" != 'enabled' ]; then _interface="$(bastille config ${_jail} get interface)" if ! ifconfig | grep "^${_interface}:" >/dev/null; then error_notify "Error: ${_interface} interface does not exist." @@ -76,7 +77,6 @@ for _jail in ${JAILS}; do fi # Start jail - info "[${_jail}]:" jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -c "${_jail}" # Add rctl limits @@ -89,7 +89,7 @@ for _jail in ${JAILS}; do # Add rdr rules if [ -s "${bastille_jailsdir}/${_jail}/rdr.conf" ]; then while read _rules; do - bastille rdr "${_jail}" ${_rules} + bastille rdr ${_jail} ${_rules} done < "${bastille_jailsdir}/${_jail}/rdr.conf" fi done diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index 12e9a9955..05a34e796 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -53,7 +53,9 @@ set_target "${TARGET}" for _jail in ${JAILS}; do - check_target_is_running "${_jail}" || continue + info "[${_jail}]:" + + check_target_is_running "${_jail}" || error_continue "Jail is already stopped." # Capture ip4.addr address while still running _ip4="$(bastille config ${_jail} get ip4.addr)" @@ -75,7 +77,6 @@ for _jail in ${JAILS}; do fi # Stop jail - info "[${_jail}]:" jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" # Remove (captured above) ip4.addr from firewall table diff --git a/usr/local/share/bastille/sysrc.sh b/usr/local/share/bastille/sysrc.sh index ff1c9171d..fd2032cc0 100644 --- a/usr/local/share/bastille/sysrc.sh +++ b/usr/local/share/bastille/sysrc.sh @@ -32,8 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille sysrc [option(s)] TARGET ARGS" - + error_notify "Usage: bastille sysrc [option(s)] TARGET ARGS" cat << EOF Options: @@ -74,11 +73,12 @@ bastille_root_check set_target "${TARGET}" for _jail in ${JAILS}; do + info "[${_jail}]:" check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then - bastille start "${_jail}" - else - continue + bastille start "${_jail}" + else + error_notify "Jail is not running." + error_continue "Use [-f|--force] to force start the jail." fi - info "[${_jail}]:" jexec -l "${_jail}" /usr/sbin/sysrc "$@" done diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index cedc796c4..c59863dca 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -32,9 +32,17 @@ . /usr/local/etc/bastille/bastille.conf bastille_usage() { - error_exit "Usage: bastille template TARGET [--convert|project/template|template]" + error_notify "Usage: bastille template [option(s)] TARGET [--convert|project/template|template]" + cat << EOF + Options: + + -f | --force -- Start the jail if it is stopped. + +EOF + exit 1 } + post_command_hook() { _jail=$1 _cmd=$2 @@ -105,12 +113,25 @@ render() { fi } -# Handle special-case commands first. -case "$1" in - help|-h|--help) - bastille_usage - ;; -esac +# Handle options. +FORCE=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -f|--force) + FORCE=1 + shift + ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done if [ $# -lt 2 ]; then bastille_usage @@ -230,11 +251,15 @@ fi for _jail in ${JAILS}; do - check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then - bastille start "${TARGET}" || continue + info "[${_jail}]:" + + check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then + bastille start "${_jail}" + else + error_notify "Jail is not running." + error_continue "Use [-f|--force] to force start the jail." fi - info "[${_jail}]:" echo "Applying template: ${TEMPLATE}..." ## jail-specific variables. diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh index 5def17e23..669c11646 100644 --- a/usr/local/share/bastille/top.sh +++ b/usr/local/share/bastille/top.sh @@ -32,8 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille top [options(s)] TARGET" - + error_notify "Usage: bastille top [options(s)] TARGET" cat << EOF Options: @@ -71,11 +70,12 @@ TARGET="${1}" bastille_root_check set_target_single "${TARGET}" + +info "[${TARGET}]:" check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then bastille start "${TARGET}" -else - exit +else + error_notify "Jail is not running." + error_continue "Use [-f|--force] to force start the jail." fi - -info "[${TARGET}]:" jexec -l "${TARGET}" /usr/bin/top diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index 8a0e78fc7..10d8dda4b 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -56,9 +56,10 @@ for _jail in ${JAILS}; do info "[${_jail}]:" - _jailpath="$( echo ${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH} 2>/dev/null | sed 's#//#/#' )" - _mount="$( mount | grep -ow ${_jailpath} )" - _fstab_entry="$( cat ${bastille_jailsdir}/${_jail}/fstab | grep -ow ${_jailpath} )" + _jailpath="$( echo ${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH} 2>/dev/null | sed 's#//#/#' | sed 's#\\##g')" + _mount="$( mount | grep -ow "${_jailpath}" )" + _jailpath_fstab="$(echo "${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH}" | sed 's#//#/#' | sed 's#\\ #\\\\040#g')" + _fstab_entry="$(grep -Eow "${_jailpath_fstab}" ${bastille_jailsdir}/${_jail}/fstab)" # Exit if mount point non-existent if [ -z "${_mount}" ] && [ -z "${_fstab_entry}" ]; then @@ -72,7 +73,7 @@ for _jail in ${JAILS}; do # Remove entry from fstab if [ -n "${_fstab_entry}" ]; then - if ! sed -E -i '' "\, +${_jailpath} +,d" "${bastille_jailsdir}/${_jail}/fstab"; then + if ! sed -E -i '' "\, +${_jailpath_fstab} +,d" "${bastille_jailsdir}/${_jail}/fstab"; then error_continue "Failed to delete fstab entry: ${MOUNT_PATH}" fi fi @@ -82,6 +83,6 @@ for _jail in ${JAILS}; do rm -f "${_jailpath}" || error_continue "Failed to unmount volume: ${MOUNT_PATH}" fi - echo "Unmounted: ${MOUNT_PATH}" + echo "Unmounted: ${_jailpath}" done diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index 8e38798a7..c0573b9fa 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -32,8 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille update [option(s)] [RELEASE|JAIL|TEMPLATE]" - + error_notify "Usage: bastille update [option(s)] [RELEASE|JAIL|TEMPLATE]" cat << EOF Options: @@ -98,8 +97,9 @@ jail_check() { set_target_single "${TARGET}" check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then bastille start "${TARGET}" - else - exit + else + error_notify "Jail is not running." + error_continue "Use [-s|--start] to force start the jail." fi if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then error_exit "${TARGET} is not a thick container." diff --git a/usr/local/share/bastille/upgrade.sh b/usr/local/share/bastille/upgrade.sh index eee6e08ca..5c661ce5f 100644 --- a/usr/local/share/bastille/upgrade.sh +++ b/usr/local/share/bastille/upgrade.sh @@ -32,19 +32,17 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille upgrade [option(s)] [RELEASE NEW_RELEASE (install)] [TARGET NEW_RELEASE (install)]" - + error_notify "Usage: bastille upgrade [option(s)] [RELEASE NEW_RELEASE (install)] [TARGET NEW_RELEASE (install)]" cat << EOF Options: - -s | --start -- Start the jail if it is stopped. - -f | --force -- Force upgrade a release. + -s | --start -- Start the jail if it is stopped. + -f | --force -- Force upgrade a release. EOF exit 1 } - # Handle options. OPTION="" while [ "$#" -gt 0 ]; do @@ -89,13 +87,13 @@ if freebsd-version | grep -qi HBSD; then fi jail_check() { - # Check if the jail is thick and is running set_target_single "${TARGET}" check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then bastille start "${TARGET}" - else - exit + else + error_notify "Jail is not running." + error_continue "Use [-s|--start] to force start the jail." fi if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then error_exit "${TARGET} is not a thick container." From 9c676f655be029121c58d6dbe9e4a05b0e3023b8 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Thu, 26 Dec 2024 18:13:53 -0700 Subject: [PATCH 105/120] fix mount --- usr/local/share/bastille/mount.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 9f3276c7b..86f940b14 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -50,9 +50,9 @@ TARGET="${1}" shift if [ "$#" -eq 2 ]; then - _fstab="$(echo "$@ nullfs ro 0 0" | sed 's#\\ #\\040#g')" + _fstab="$(echo "$* nullfs ro 0 0" | sed 's#\\ #\\040#g')" else - _fstab="$(echo "$@" | sed 's#\\ #\\040#g')" + _fstab="$(echo "$*" | sed 's#\\ #\\040#g')" fi bastille_root_check From f6a6439cff388b31ef77df26017f71d61d8486b9 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Mon, 30 Dec 2024 17:06:51 -0700 Subject: [PATCH 106/120] update for multi interfaces --- usr/local/bin/bastille | 4 +- usr/local/share/bastille/clone.sh | 111 ++++---- usr/local/share/bastille/common.sh | 44 ++- usr/local/share/bastille/create.sh | 2 +- usr/local/share/bastille/htop.sh | 2 +- usr/local/share/bastille/limits.sh | 2 +- usr/local/share/bastille/list.sh | 33 +-- usr/local/share/bastille/mount.sh | 22 +- usr/local/share/bastille/network.sh | 390 +++++++++++++++++++++++++++ usr/local/share/bastille/pkg.sh | 2 +- usr/local/share/bastille/rename.sh | 8 +- usr/local/share/bastille/template.sh | 1 + usr/local/share/bastille/umount.sh | 8 +- usr/local/share/bastille/zfs.sh | 3 + 14 files changed, 523 insertions(+), 109 deletions(-) create mode 100644 usr/local/share/bastille/network.sh diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index 400ef3abb..d1c669ebf 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -86,6 +86,7 @@ Available Commands: limits Apply resources limits to targeted container(s). See rctl(8). list List containers (running). mount Mount a volume inside the targeted container(s). + network Add or remove interfaces from 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. @@ -112,7 +113,7 @@ EOF exit 1 } -if [ $# -lt 1 ]; then +if [ "$#" -lt 1 ]; then usage else CMD="${1}" @@ -145,6 +146,7 @@ case "${CMD}" in limits| \ list| \ mount| \ + network| \ pkg| \ rcp| \ rdr| \ diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 40073b8a1..dc6ae5bc0 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -153,55 +153,72 @@ 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 jails)" - 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}" - 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_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}" - break + # 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 _if_count="$(grep -Eo 'epair[0-9]+|bastille[0-9]+' ${bastille_jailsdir}/*/jail.conf 2>/dev/null | sort -u | wc -l | awk '{print $1}')" + local num_range=$((_if_count + 1)) + for _num in $(seq 0 "${num_range}"); do + if ! grep -Eoq "epair${_num}|bastille${_num}" ${bastille_jailsdir}/*/jail.conf; then + local uniq_epair="bastille${_num}" + 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 ${_if} | 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 interfaces + if echo ${_if} 2>/dev/null | grep -Eoq 'bastille[0-9]+'; then + local _if_vnet="$(grep ${_if} "${bastille_jail_rc_conf}" | grep -Eo "vnet[0-9]+")" + sed -i '' "s|${_if}|${uniq_epair}|g" "${JAIL_CONFIG}" + 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}" + sed -i '' "s|exec.prestart += \"ifconfig.*${uniq_epair}.*description.*|exec.prestart += \"ifconfig e0a_${uniq_epair} description \\\\\"vnet host interface for Bastille jail ${NEWNAME}\\\\\"\";|" "${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 + # for bridged VNET interfaces + elif echo ${_if} 2>/dev/null | grep -Eoq 'epair[0-9]+'; then + local _if_epaira="$(grep "${_if}" ${JAIL_CONFIG} | grep -Eo "e[0-9]+a_${TARGET}")" + local _if_epairb="$(grep "${_if}" ${JAIL_CONFIG} | grep -Eo "e[0-9]+b_${TARGET}")" + local _if_vnet="$(grep ${_if_epairb} "${bastille_jail_rc_conf}" | grep -Eo "vnet[0-9]+")" + sed -i '' "s|${_if}|epair${uniq_epair_bridge}|g" "${JAIL_CONFIG}" + sed -i '' "s|${_if_epaira}|e${uniq_epair_bridge}a_${NEWNAME}|g" "${JAIL_CONFIG}" + sed -i '' "s|${_if_epairb}|e${uniq_epair_bridge}b_${NEWNAME}|g" "${JAIL_CONFIG}" + sed -i '' "s|e${uniq_epair}a_${TARGET} ether.*:.*:.*:.*:.*:.*a\";|e${uniq_epair}a_${NEWNAME} ether ${macaddr}a\";|" "${JAIL_CONFIG}" + sed -i '' "s|e${uniq_epair}b_${TARGET} ether.*:.*:.*:.*:.*:.*b\";|e${uniq_epair}b_${NEWNAME} ether ${macaddr}b\";|" "${JAIL_CONFIG}" + # Update /etc/rc.conf + sed -i '' "s|${_if_epairb}_name|e${uniq_epair_bridge}b_${NEWNAME}_name|" "${bastille_jail_rc_conf}" + if grep "vnet0" "${bastille_jail_rc_conf}" | grep -q "e${uniq_epair_bridge}b_${NEWNAME}_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 fi + break fi - fi + done 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() { # Update fstab to use the new name FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab" if [ -f "${FSTAB_CONFIG}" ]; then - # Update additional fstab paths with new jail path + # Update fstab paths with new jail path sed -i '' "s|${bastille_jailsdir}/${TARGET}/root/|${bastille_jailsdir}/${NEWNAME}/root/|" "${FSTAB_CONFIG}" fi } @@ -214,11 +231,12 @@ clone_jail() { if checkyesno bastille_zfs_enable; then if [ "${LIVE}" -eq 1 ]; then check_target_is_running "${TARGET}" || error_exit "[-l|--live] can only be used with a running jail." - elif [ "${FORCE}" -eq 1 ]; then - check_target_is_stopped "${TARGET}" || bastille stop "${TARGET}" - else - error_notify "Jail is running." - error_exit "Use [-f|--force] to force stop the jail, or [-l|--live] (ZFS only) to clone a running jail." + else check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille stop "${TARGET}" + else + error_notify "Jail is running." + error_exit "Use [-f|--force] to force stop the jail, or [-l|--live] (ZFS only) to clone a running jail." + fi fi if [ -n "${bastille_zfs_zpool}" ]; then # Replicate the existing container @@ -273,5 +291,4 @@ else usage fi -clone_jail - +clone_jail \ No newline at end of file diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 56857d4d2..f3d26250f 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -146,9 +146,14 @@ target_all_jails() { generate_static_mac() { local jail_name="${1}" local external_interface="${2}" - local macaddr_prefix="$(ifconfig ${external_interface} | grep ether | awk '{print $2}' | cut -d':' -f1-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}' | 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/')" + if [ -z "${macaddr_prefix}" ] || [ -z "${macaddr_suffix}" ]; then + error_notify "Failed to generate MAC address." + fi macaddr="${macaddr_prefix}:${macaddr_suffix}" + export macaddr } generate_vnet_jail_netblock() { @@ -159,22 +164,32 @@ generate_vnet_jail_netblock() { ## determine number of containers + 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 _vnet_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 vnet_num_range=$((_vnet_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 [ "${_vnet_if_count}" -gt 0 ]; then + for _num in $(seq 0 "${vnet_num_range}"); do + if ! grep -Eosq "bastillle${_num}" ${bastille_jailsdir}/*/jail.conf; then + local uniq_epair="${_num}" + break + fi + done + else + local uniq_epair="bastille0" + fi fi if [ -n "${use_unique_bridge}" ]; then ## generate bridge config @@ -203,6 +218,7 @@ EOF EOF fi } + checkyesno() { ## copied from /etc/rc.subr -- cedwards (20231125) ## issue #368 (lowercase values should be parsed) diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index 19aefb669..dce4c8b07 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -577,7 +577,7 @@ create_jail() { jexec -l "${NAME}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive rm /var/cache/apt/archives/rsyslog*.deb" jexec -l "${NAME}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive dpkg --force-depends --force-confdef --force-confold -i /var/cache/apt/archives/*.deb" jexec -l "${NAME}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive dpkg --force-depends --force-confdef --force-confold -i /var/cache/apt/archives/*.deb" - jexec -l "${NAME}" /bin/bash -c "chmod 777 /tmp" + jexec -l "${NAME}" /bin/bash -c "chmod 1777 /tmp" jexec -l "${NAME}" /bin/bash -c "apt update" else # Thin jail. diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh index 10795da15..88627e868 100644 --- a/usr/local/share/bastille/htop.sh +++ b/usr/local/share/bastille/htop.sh @@ -84,4 +84,4 @@ if [ ! -x "${bastille_jail_path}/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 -fi +fi \ No newline at end of file diff --git a/usr/local/share/bastille/limits.sh b/usr/local/share/bastille/limits.sh index 14627a080..53334e9d0 100644 --- a/usr/local/share/bastille/limits.sh +++ b/usr/local/share/bastille/limits.sh @@ -51,7 +51,7 @@ case "${1}" in ;; esac -if [ $# -ne 3 ]; then +if [ "$#" -ne 3 ]; then usage fi diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index df43d0bd4..02be47dbb 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -57,7 +57,7 @@ list_all(){ if [ "${MAX_LENGTH_JAIL_NAME}" -lt 3 ]; then MAX_LENGTH_JAIL_NAME=3; fi 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) + 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 -hs "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 @@ -68,11 +68,11 @@ 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) + 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 -hEs "^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=$(find "${bastille_jailsdir}/*/root/bin/freebsd-version" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -hEs "^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) + 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 -hEs "^NAME=|^VERSION_ID=|^VERSION_CODENAME=" "$(sed -n "s/^linprocfs *\(.*\)\/.*$/\1\/etc\/os-release/p")" | 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 @@ -110,7 +110,7 @@ list_all(){ JAIL_RELEASE=$(jexec -l ${JAIL_NAME} freebsd-version -u 2> /dev/null) fi if [ "${IS_LINUX_JAIL}" -eq 1 ]; then - JAIL_RELEASE=$(grep -hE "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }') + JAIL_RELEASE=$(grep -hEs "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }') fi else JAIL_STATE=$(if [ "$(sed -n "/^${JAIL_NAME} {$/,/^}$/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | awk '$0 ~ /^'${JAIL_NAME}' \{|\}/ { printf "%s",$0 }')" = "${JAIL_NAME} {}" ]; then echo "Down"; else echo "n/a"; fi) @@ -125,13 +125,13 @@ list_all(){ if [ "${JAIL_PATH}" ]; then if [ "${IS_FREEBSD_JAIL}" -eq 1 ]; then if [ -f "${JAIL_PATH}/bin/freebsd-version" ]; then - JAIL_RELEASE=$(grep -hE "^USERLAND_VERSION=" "${JAIL_PATH}/bin/freebsd-version" 2> /dev/null | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") + JAIL_RELEASE=$(grep -hEs "^USERLAND_VERSION=" "${JAIL_PATH}/bin/freebsd-version" | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") else - JAIL_RELEASE=$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | 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") + JAIL_RELEASE=$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | grep -hEs "^USERLAND_VERSION=" "$(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++')" | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") fi fi if [ "${IS_LINUX_JAIL}" -eq 1 ]; then - JAIL_RELEASE=$(grep -hE "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }') + JAIL_RELEASE=$(grep -hEs "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }') fi else JAIL_RELEASE="" @@ -146,22 +146,7 @@ list_all(){ JAIL_HOSTNAME=${JAIL_HOSTNAME:-${DEFAULT_VALUE}} JAIL_RELEASE=${JAIL_RELEASE:-${DEFAULT_VALUE}} JAIL_PATH=${JAIL_PATH:-${DEFAULT_VALUE}} - JAIL_IP_COUNT=$(echo "${JAIL_IP}" | wc -l) - if [ ${JAIL_IP_COUNT} -gt 1 ]; then - # vnet0 has more than one IPs assigned. - # Put each IP in its own line below the jails first address. For instance: - # JID State IP Address Published Ports Hostname Release Path - # foo Up 10.10.10.10 - foo 14.0-RELEASE-p5 /usr/local/bastille/jails/foo/root - # 10.10.10.11 - # 10.10.10.12 - FIRST_IP="$(echo "${JAIL_IP}" | head -n 1)" - printf " ${JAIL_NAME}%*s${JAIL_STATE}%*s${FIRST_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JAIL_NAME} - ${#JAIL_NAME} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#FIRST_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" "" - for IP in $(echo "${JAIL_IP}" | tail -n +2); do - printf "%*s %*s${IP}\n" "$((${MAX_LENGTH_JAIL_NAME} + ${SPACER}))" "" "$((5 + ${SPACER}))" "" - done - else - printf " ${JAIL_NAME}%*s${JAIL_STATE}%*s${JAIL_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JAIL_NAME} - ${#JAIL_NAME} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#JAIL_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" "" - fi + printf " ${JAIL_NAME}%*s${JAIL_STATE}%*s${JAIL_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JAIL_NAME} - ${#JAIL_NAME} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#JAIL_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" "" fi done else diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 86f940b14..817268b87 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -60,7 +60,7 @@ set_target "${TARGET}" # Assign variables _hostpath_fstab=$(echo "${_fstab}" | awk '{print $1}') -_hostpath="$(echo ${_hostpath_fstab} 2>/dev/null | sed 's#\\040# #g')" +_hostpath="$(echo "${_hostpath_fstab}" 2>/dev/null | sed 's#\\040# #g')" _jailpath_fstab=$(echo "${_fstab}" | awk '{print $2}') _jailpath="$(echo "${_jailpath_fstab}" 2>/dev/null | sed 's#\\040# #g')" _type=$(echo "${_fstab}" | awk '{print $3}') @@ -109,15 +109,15 @@ for _jail in ${JAILS}; do info "[${_jail}]:" - _fullpath_fstab="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath_fstab} 2>/dev/null | sed 's#//#/#' )" - _fullpath="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath} 2>/dev/null | sed 's#//#/#' )" + _fullpath_fstab="$( echo "${bastille_jailsdir}/${_jail}/root/${_jailpath_fstab}" 2>/dev/null | sed 's#//#/#' )" + _fullpath="$( echo "${bastille_jailsdir}/${_jail}/root/${_jailpath}" 2>/dev/null | sed 's#//#/#' )" _fstab_entry="${_hostpath_fstab} ${_fullpath_fstab} ${_type} ${_perms} ${_checks}" # Check if mount point has already been added - _existing_mount="$(echo ${_fullpath_fstab} 2>/dev/null | sed 's#\\#\\\\#')" - if grep -Eq "[[:blank:]]${_existing_mount}" "${bastille_jailsdir}/${_jail}/fstab"; then + _existing_mount="$(echo ${_fullpath_fstab} 2>/dev/null | sed 's#\\#\\\\#g')" + if grep -Eoq "[[:blank:]]${_existing_mount}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab"; then warn "Mountpoint already present in ${bastille_jailsdir}/${_jail}/fstab" - grep -E "[[:blank:]]${_existing_mount}" "${bastille_jailsdir}/${_jail}/fstab" + grep -Eo "[[:blank:]]${_existing_mount}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" continue fi @@ -127,7 +127,7 @@ for _jail in ${JAILS}; do elif [ -f "${_hostpath}" ] ; then _filename="$( basename ${_hostpath} )" if echo "${_fullpath}" 2>/dev/null | grep -qow "${_filename}"; then - mkdir -p "$( dirname ${_fullpath} )" || error_continue "Failed to create mount point." + mkdir -p "$( dirname "${_fullpath}" )" || error_continue "Failed to create mount point." if [ ! -f "${_fullpath}" ]; then touch "${_fullpath}" || error_continue "Failed to create mount point." else @@ -136,10 +136,10 @@ for _jail in ${JAILS}; do continue fi else - _fullpath_fstab="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath_fstab}/${_filename} 2>/dev/null | sed 's#//#/#' )" - _fullpath="$( echo ${bastille_jailsdir}/${_jail}/root/${_jailpath}/${_filename} 2>/dev/null | sed 's#//#/#' )" - _fstab_entry="${_hostpath_fstab} ${_fullpath} ${_type} ${_perms} ${_checks}" - mkdir -p "$( dirname ${_fullpath} )" || error_continue "Failed to create mount point." + _fullpath_fstab="$( echo "${bastille_jailsdir}/${_jail}/root/${_jailpath_fstab}/${_filename}" 2>/dev/null | sed 's#//#/#' )" + _fullpath="$( echo "${bastille_jailsdir}/${_jail}/root/${_jailpath}/${_filename}" 2>/dev/null | sed 's#//#/#' )" + _fstab_entry="${_hostpath_fstab} ${_fullpath_fstab} ${_type} ${_perms} ${_checks}" + mkdir -p "$( dirname "${_fullpath}" )" || error_continue "Failed to create mount point." if [ ! -f "${_fullpath}" ]; then touch "${_fullpath}" || error_continue "Failed to create mount point." else diff --git a/usr/local/share/bastille/network.sh b/usr/local/share/bastille/network.sh new file mode 100644 index 000000000..56940a66e --- /dev/null +++ b/usr/local/share/bastille/network.sh @@ -0,0 +1,390 @@ +#!/bin/sh +# +# Copyright (c) 2018-2024, 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 network [option(s)] TARGET [remove INTERFACE] [add INTERFACE IP_ADDRESS]" + + cat << EOF + Options: + + -f | --force Stop the jail if it is running. + -s | --start Start jail on completion. + -v | --vnet Adds a VNET interface to an existing jail. + -b | --bridge Adds a bridged VNET interface to an existing jail. + +EOF + exit 1 +} + +# Handle options. +FORCE=0 +START=0 +VNET_JAIL=0 +BRIDGE_VNET_JAIL=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -f|--force) + FORCE=1 + shift + ;; + -r|--restart) + START=1 + shift + ;; + -v|-V|--vnet) + VNET_JAIL=1 + shift + ;; + -b|-B|--bridge) + BRIDGE_VNET_JAIL=1 + shift + ;; + -*) + error_notify "Unknown Option: \"${1}\"" + usage + ;; + *) + break + ;; + esac +done + +if [ "${ACTION}" = "add" ]; then + if [ "${VNET_JAIL}" -eq 1 ] && [ "${BRIDGE_VNET_JAIL}" -eq 1 ]; then + error_notify "Error: [-v|-V|--vnet] and [-b|-B|--bridge] cannot both be set." + usage + elif [ "${VNET_JAIL}" -eq 0 ] && [ "${BRIDGE_VNET_JAIL}" -eq 0 ]; then + error_notify "Error: [-v|-V|--vnet] or [-b|-B|--bridge] must be set." + usage + fi +fi + +if [ "$#" -lt 2 ] || [ "$#" -gt 4 ]; then + usage +fi + +TARGET="${1}" +ACTION="${2}" +INTERFACE="${3}" +IP="${4}" + +bastille_root_check +set_target_single "${TARGET}" +check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + bastille stop "${TARGET}" +else + error_notify "Jail is running." + error_continue "Use [-f|--force] to force stop the jail." +fi + +validate_ip() { + local ip="${1}" + local ip6="$( echo "${ip}" 2>/dev/null | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )" + if [ -n "${ip6}" ]; then + info "Valid: (${ip6})." + else + local IFS + if echo "${ip}" 2>/dev/null | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then + TEST_IP=$(echo "${ip}" | cut -d / -f1) + IFS=. + set ${TEST_IP} + for quad in 1 2 3 4; do + if eval [ \$$quad -gt 255 ]; then + error_exit "Invalid: (${TEST_IP})" + fi + done + info "Valid: (${ip})." + else + error_exit "Invalid: (${ip})." + fi + fi +} + +validate_netif() { + local _interface="${1}" + if ifconfig -l | grep -qwo ${_interface}; then + info "Valid: (${_interface})." + else + error_exit "Invalid: (${_interface})." + fi +} + +validate_netconf() { + if [ -n "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then + error_exit "Invalid network configuration." + fi +} + +check_interface_added() { + local _jailname="${1}" + local _if="${2}" + local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" + if grep -o "${_if}" "${_jail_config}"; then + return 0 + else + return 1 + fi +} + +add_vnet_interface_block() { + local _jailname="${1}" + local _if="${2}" + local _ip="${3}" + local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" + local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" + local _if_count="$(grep -Eo 'bastille[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')" + local _if_vnet_count="$(grep -Eo 'vnet[1-9]+' ${_jail_rc_config} | sort -u | wc -l | awk '{print $1}')" + local _if_vnet="vnet$((_if_vnet_count + 1))" + local num_range=$((_if_count + 1)) + for _num in $(seq 0 "${num_range}"); do + if ! grep -Eq "bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then + local uniq_epair="bastille${_num}" + break + fi + done + generate_static_mac "${_jailname}" "${_if}" + sed -i '' "s|}||" "${_jail_config}" + ## generate config + cat << EOF >> "${_jail_config}" + ## ${uniq_epair} interface + vnet.interface += e0b_${uniq_epair}; + exec.prestart += "jib addm ${uniq_epair} ${_if}"; + exec.prestart += "ifconfig e0a_${uniq_epair} ether ${macaddr}a"; + exec.prestart += "ifconfig e0b_${uniq_epair} ether ${macaddr}b"; + exec.prestart += "ifconfig e0a_${uniq_epair} description \"vnet host interface for Bastille jail ${_jailname}\""; + exec.poststop += "jib destroy ${uniq_epair}"; +} +EOF + + # add config to /etc/rc.conf + sysrc -f "${_jail_rc_config}" ifconfig_e0b_${uniq_epair}_name="${_if_vnet}" + # If 0.0.0.0 set DHCP, else set static IP address + if [ "${_ip}" = "0.0.0.0" ]; then + sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}="SYNCDHCP" + else + sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}=" inet ${_ip} " + fi + + info "[${_jailname}]:" + echo "Added interface: \"${_if}\"" +} + +add_bridge_interface_block() { + local _jailname="${1}" + local _if="${2}" + local _ip="${3}" + local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" + local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" + local _if_count="$(grep -Eo 'epair[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')" + local _if_vnet_count="$(grep -Eo 'vnet[1-9]+' ${_jail_rc_config} | sort -u | wc -l | awk '{print $1}')" + local _if_vnet=vnet$((_if_vnet_count + 1)) + local num_range=$((_if_count + 1)) + for _num in $(seq 0 "${num_range}"); do + if ! grep -Eq "epair${_num}" "${bastille_jailsdir}"/*/jail.conf; then + local uniq_epair="${_num}" + break + fi + done + generate_static_mac "${_jailname}" "${_if}" + sed -i '' "s|}||" "${_jail_config}" + ## generate config + cat << EOF >> "${_jail_config}" + ## epair${uniq_epair} interface + vnet.interface += e${uniq_epair}b_${_jailname}; + exec.prestart += "ifconfig epair${uniq_epair} create"; + exec.prestart += "ifconfig ${_if} addm epair${uniq_epair}a"; + exec.prestart += "ifconfig epair${uniq_epair}a up name e${uniq_epair}a_${_jailname}"; + exec.prestart += "ifconfig epair${uniq_epair}b up name e${uniq_epair}b_${_jailname}"; + exec.prestart += "ifconfig e${uniq_epair}a_${_jailname} ether ${macaddr}a"; + exec.prestart += "ifconfig e${uniq_epair}b_${_jailname} ether ${macaddr}b"; + exec.poststop += "ifconfig ${_if} deletem e${uniq_epair}a_${_jailname}"; + exec.poststop += "ifconfig e${uniq_epair}a_${_jailname} destroy"; +} +EOF + + # Add config to /etc/rc.conf + sysrc -f "${_jail_rc_config}" ifconfig_e${uniq_epair}b_${_jailname}_name="${_if_vnet}" + # If 0.0.0.0 set DHCP, else set static IP address + if [ "${_ip}" = "0.0.0.0" ]; then + sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}="SYNCDHCP" + else + sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}=" inet ${_ip} " + fi + + info "[${_jailname}]:" + echo "Added interface: \"${_if}\"" +} + +remove_vnet_interface_block() { + local _jailname="${1}" + local _if="${2}" + local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" + local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" + local _if_jail="$(grep "${_if}" ${_jail_config} | grep -Eo 'bastille[0-9]+')" + if grep -o "${_if_jail}" ${_jail_rc_config}; then + local _if_vnet="$(grep "${_if_jail}" ${_jail_rc_config} | grep -Eo 'vnet[0-9]+')" + else + error_exit "Interface not found: ${_if_jail}" + fi + + # Do not allow removing default vnet0 interface + if [ "${_if_vnet}" = "vnet0" ]; then + error_exit "Default interface cannot be removed." + fi + + # Avoid removing entire file contents if variables aren't set for some reason + if [ -z "${_if_jail}" ]; then + error_exit "Error: Could not find specifed interfaces. Exiting..." + fi + + # Remove interface from jail.conf + if [ -n "${_if_jail}" ]; then + sed -i '' "s|.*${_if_jail}.*||" "${_jail_config}" + sed -i '' '/^$/d' "${_jail_config}" + else + error_exit "Failed to remove interface from jail.conf" + fi + + # Remove interface from /etc/rc.conf + if [ -n "${_if_vnet}" ] && echo ${_if_vnet} 2>/dev/null | grep -Eo 'vnet[0-9]+'; then + sed -i '' "s|.*${_if_vnet}.*||" "${_jail_rc_config}" + sed -i '' '/^$/d' "${_jail_rc_config}" + else + error_exit "Failed to remove interface from /etc/rc.conf" + fi + + info "[${_jailname}]:" + echo "Removed interface: \"${_if}\"" +} + +remove_bridge_interface_block() { + local _jailname="${1}" + local _if="${2}" + local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" + local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" + local _if_epair="$(grep "${_if}" ${_jail_config} | grep -Eo 'epair[0-9]+')" + local _if_epaira_name="$(grep "${_if_epair}" ${_jail_config} | grep -Eo "e[0-9]+a_${_jailname}")" + local _if_epairb_name="$(grep "${_if_epair}" ${_jail_config} | grep -Eo "e[0-9]+b_${_jailname}")" + if grep -o "${_if_epairb_name}" ${_jail_rc_config}; then + local _if_vnet="$(grep "${_if_epairb_name}" ${_jail_rc_config} | grep -Eo 'vnet[0-9]+')" + else + error_exit "Interface not found: ${_if_epair_name}" + fi + + # Do not allow removing default vnet0 interface + if [ "${_if_vnet}" = "vnet0" ]; then + error_exit "Default interface cannot be removed." + fi + + # Avoid removing entire file contents if variables aren't set for some reason + if [ -z "${_if_epair}" ] || [ -z "${_if_epaira_name}" ] || [ -z "${_if_epairb_name}" ] || [ -z "${_if_vnet}" ]; then + error_exit "Error: Could not find specifed interfaces. Exiting..." + fi + + # Remove interface from jail.conf + if [ -n "${_if_epair}" ] && [ -n "${_if_epaira_name}" ] && [ -n "${_if_epairb_name}" ] && [ -n "${_if_vnet}" ]; then + sed -i '' "s|.*${_if_epair}.*||" "${_jail_config}" + sed -i '' "s|.*${_if_epaira_name}.*||" "${_jail_config}" + sed -i '' "s|.*${_if_epairb_name}.*||" "${_jail_config}" + sed -i '' '/^$/d' "${_jail_config}" + else + error_exit "Failed to remove interface from jail.conf" + fi + + # Remove interface from /etc/rc.conf + if [ -n "${_if_vnet}" ] && echo ${_if_vnet} 2>/dev/null | grep -Eo 'vnet[0-9]+'; then + sed -i '' "s|ifconfig.*${_if_vnet}.*||" "${_jail_rc_config}" + sed -i '' '/^$/d' "${_jail_rc_config}" + else + error_exit "Failed to remove interface from /etc/rc.conf" + fi + + info "[${_jailname}]:" + echo "Removed interface: \"${_if}\"" +} + +case "${ACTION}" in + add) + validate_netconf + validate_netif "${INTERFACE}" + if check_interface_added "${TARGET}" "${INTERFACE}"; then + error_exit "Interface is already added: \"${INTERFACE}\"" + fi + validate_ip "${IP}" + if [ "${VNET_JAIL}" -eq 1 ]; then + if ifconfig | grep "${INTERFACE}" | grep -q bridge; then + error_exit "\"${INTERFACE}\" is a bridge interface." + else + add_vnet_interface_block "${TARGET}" "${INTERFACE}" "${IP}" + if [ "${START}" -eq 1 ]; then + bastille start "${TARGET}" + fi + fi + elif [ "${BRIDGE_VNET_JAIL}" -eq 1 ]; then + if ! ifconfig | grep "${INTERFACE}" | grep -q bridge; then + error_exit "\"${INTERFACE}\" is not a bridge interface." + else + add_bridge_interface_block "${TARGET}" "${INTERFACE}" "${IP}" + if [ "${START}" -eq 1 ]; then + bastille start "${TARGET}" + fi + fi + fi + ;; + remove|delete) + check_interface_added "${TARGET}" "${INTERFACE}" || error_exit "Interface not found in jail.conf: \"${INTERFACE}\"" + validate_netif "${INTERFACE}" + if ! grep -q "${INTERFACE}" ${bastille_jailsdir}/${TARGET}/jail.conf; then + error_exit "Interface not found in jail.conf: \"${INTERFACE}\"" + else + if grep "${INTERFACE}" ${bastille_jailsdir}/${TARGET}/jail.conf 2>/dev/null | grep -qE '[[:blank:]]bastille[0-9]+'; then + remove_vnet_interface_block "${TARGET}" "${INTERFACE}" + if [ "${START}" -eq 1 ]; then + bastille start "${TARGET}" + fi + elif grep "${INTERFACE}" ${bastille_jailsdir}/${TARGET}/jail.conf 2>/dev/null | grep -qE '[[:blank:]]epair[0-9]+'; then + remove_bridge_interface_block "${TARGET}" "${INTERFACE}" + if [ "${START}" -eq 1 ]; then + bastille start "${TARGET}" + fi + fi + fi + ;; + *) + error_exit "Only [add|remove] are supported." + ;; +esac + diff --git a/usr/local/share/bastille/pkg.sh b/usr/local/share/bastille/pkg.sh index 738c99f2e..edf09f220 100644 --- a/usr/local/share/bastille/pkg.sh +++ b/usr/local/share/bastille/pkg.sh @@ -68,7 +68,7 @@ while [ "$#" -gt 0 ]; do esac done -if [ $# -lt 2 ]; then +if [ "$#" -lt 2 ]; then usage fi diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index b59f29253..f1afb0082 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -106,10 +106,10 @@ update_jailconf() { sed -i '' "s|mount.fstab.*=.*;|mount.fstab = ${bastille_jailsdir}/${NEWNAME}/fstab;|" "${JAIL_CONFIG}" sed -i '' "s|${TARGET}.*{|${NEWNAME} {|" "${JAIL_CONFIG}" # update vnet config - sed -i '' "s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|" "${JAIL_CONFIG}" - sed -i '' "/vnet.interface/s|_${TARGET};|_${NEWNAME};|" "${JAIL_CONFIG}" - sed -i '' "/ifconfig/s|_${TARGET}|_${NEWNAME}|" "${JAIL_CONFIG}" - sed -i '' "/ifconfig/s|_${TARGET}_name=|_${NEWNAME}_name=|" "${BASTILLE_JAIL_RC_CONF}" + sed -i '' "s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|g" "${JAIL_CONFIG}" + sed -i '' "/vnet.interface/s|_${TARGET};|_${NEWNAME};|g" "${JAIL_CONFIG}" + sed -i '' "/ifconfig/s|_${TARGET}|_${NEWNAME}|g" "${JAIL_CONFIG}" + sed -i '' "/ifconfig/s|_${TARGET}_name=|_${NEWNAME}_name=|g" "${BASTILLE_JAIL_RC_CONF}" fi fi } diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index c59863dca..9ec0bc686 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -223,6 +223,7 @@ case ${TEMPLATE} in else bastille_template=${TEMPLATE} fi + ;; esac if [ -z "${JAILS}" ]; then diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index 10d8dda4b..ebbb52c5a 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -56,10 +56,10 @@ for _jail in ${JAILS}; do info "[${_jail}]:" - _jailpath="$( echo ${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH} 2>/dev/null | sed 's#//#/#' | sed 's#\\##g')" - _mount="$( mount | grep -ow "${_jailpath}" )" - _jailpath_fstab="$(echo "${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH}" | sed 's#//#/#' | sed 's#\\ #\\\\040#g')" - _fstab_entry="$(grep -Eow "${_jailpath_fstab}" ${bastille_jailsdir}/${_jail}/fstab)" + _jailpath="$( echo "${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH}" 2>/dev/null | sed 's#//#/#' | sed 's#\\##g')" + _mount="$( mount | grep -Eo "[[:blank:]]${_jailpath}[[:blank:]]" )" + _jailpath_fstab="$(echo "${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH}" | sed 's#//#/#g' | sed 's# #\\#g' | sed 's#\\#\\\\040#g')" + _fstab_entry="$(grep -Eo "[[:blank:]]${_jailpath_fstab}[[:blank:]]" ${bastille_jailsdir}/${_jail}/fstab)" # Exit if mount point non-existent if [ -z "${_mount}" ] && [ -z "${_fstab_entry}" ]; then diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 6e9be0add..21a5be67a 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -120,4 +120,7 @@ case "${2}" in df|usage) zfs_disk_usage ;; + *) + usage + ;; esac From b5dcf5a5e412f5ed9b42c899ae1ea6e19395ec70 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Mon, 30 Dec 2024 18:28:50 -0700 Subject: [PATCH 107/120] add autocomplete --- usr/local/share/bastille/common.sh | 65 ++++++++++++++++++------------ 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index f3d26250f..cc4573294 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -106,14 +106,49 @@ check_target_is_stopped() { fi } -set_target() { +checkyesno() { + ## copied from /etc/rc.subr -- cedwards (20231125) + ## issue #368 (lowercase values should be parsed) + ## now used for all bastille_zfs_enable=YES|NO tests + ## example: if checkyesno bastille_zfs_enable; then ... + ## returns 0 for enabled; returns 1 for disabled + eval _value=\$${1} + case $_value in + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + return 0 + ;; + [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) + return 1 + ;; + *) + warn "\$${1} is not set properly - see rc.conf(5)." + return 1 + ;; + esac +} + +jail_autocomplete() { local _TARGET="${1}" + local _AUTOTARGET=$( ls "${bastille_jailsdir}" 2>/dev/null | grep ${_TARGET} 2>/dev/null ) + if [ $( echo "${_AUTOTARGET}" 2>/dev/null | wc -l ) -eq 1 ]; then + return 0 + else + error_continue "Multiple jails found for ${_TARGET}:\n${_AUTOTARGET}" + return 1 + fi +} + +set_target() { + local _TARGET=${1} if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then target_all_jails else - check_target_exists "${_TARGET}" || error_exit "Jail not found \"${_TARGET}\"" - JAILS="${_TARGET}" - TARGET="${_TARGET}" + for _jail in ${_TARGET}; do + jail_autocomplete "${_jail}" + check_target_exists "${_jail}" || error_continue "Jail not found \"${_jail}\"" + JAILS="${JAILS} ${_jail}" + TARGET="${TARGET} ${_jail}" + done export JAILS export TARGET fi @@ -124,6 +159,7 @@ set_target_single() { if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then error_exit "[all|ALL] not supported with this command." else + jail_autocomplete "${_TARGET}" check_target_exists "${_TARGET}" || error_exit "Jail not found \"${_TARGET}\"" JAILS="${_TARGET}" TARGET="${_TARGET}" @@ -218,24 +254,3 @@ EOF EOF fi } - -checkyesno() { - ## copied from /etc/rc.subr -- cedwards (20231125) - ## issue #368 (lowercase values should be parsed) - ## now used for all bastille_zfs_enable=YES|NO tests - ## example: if checkyesno bastille_zfs_enable; then ... - ## returns 0 for enabled; returns 1 for disabled - eval _value=\$${1} - case $_value in - [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) - return 0 - ;; - [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) - return 1 - ;; - *) - warn "\$${1} is not set properly - see rc.conf(5)." - return 1 - ;; - esac -} From 2beeefecb4267a400af7ef386a05ee36c5317066 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Mon, 30 Dec 2024 18:32:39 -0700 Subject: [PATCH 108/120] fix "" --- usr/local/share/bastille/common.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index cc4573294..cd0b8cb93 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -129,8 +129,8 @@ checkyesno() { jail_autocomplete() { local _TARGET="${1}" - local _AUTOTARGET=$( ls "${bastille_jailsdir}" 2>/dev/null | grep ${_TARGET} 2>/dev/null ) - if [ $( echo "${_AUTOTARGET}" 2>/dev/null | wc -l ) -eq 1 ]; then + local _AUTOTARGET="$( ls "${bastille_jailsdir}" 2>/dev/null | grep ${_TARGET} 2>/dev/null )" + if [ "$( echo "${_AUTOTARGET}" 2>/dev/null | wc -l )" -eq 1 ]; then return 0 else error_continue "Multiple jails found for ${_TARGET}:\n${_AUTOTARGET}" From cf29557052d76251943d3f57b61c56033b8888e8 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Mon, 30 Dec 2024 18:33:30 -0700 Subject: [PATCH 109/120] fix "" --- usr/local/share/bastille/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index cd0b8cb93..7efcadd94 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -129,7 +129,7 @@ checkyesno() { jail_autocomplete() { local _TARGET="${1}" - local _AUTOTARGET="$( ls "${bastille_jailsdir}" 2>/dev/null | grep ${_TARGET} 2>/dev/null )" + local _AUTOTARGET="$( ls "${bastille_jailsdir}" 2>/dev/null | grep "${_TARGET}" 2>/dev/null )" if [ "$( echo "${_AUTOTARGET}" 2>/dev/null | wc -l )" -eq 1 ]; then return 0 else From 101d1b518eee02a880f41b8f02f04828c84b4783 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Mon, 30 Dec 2024 18:37:26 -0700 Subject: [PATCH 110/120] disable sc2010 --- usr/local/share/bastille/common.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 7efcadd94..3b07cf6b9 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -129,6 +129,7 @@ checkyesno() { jail_autocomplete() { local _TARGET="${1}" + # shellcheck disable=SC2010 local _AUTOTARGET="$( ls "${bastille_jailsdir}" 2>/dev/null | grep "${_TARGET}" 2>/dev/null )" if [ "$( echo "${_AUTOTARGET}" 2>/dev/null | wc -l )" -eq 1 ]; then return 0 From 54489a8078812a85437201ae85d17812497dc11d Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Fri, 3 Jan 2025 08:03:29 -0700 Subject: [PATCH 111/120] rewrite: update network and template --- usr/local/share/bastille/bootstrap.sh | 2 +- usr/local/share/bastille/clone.sh | 92 ++++---- usr/local/share/bastille/cmd.sh | 2 - usr/local/share/bastille/common.sh | 107 ++++++---- usr/local/share/bastille/config.sh | 2 +- usr/local/share/bastille/cp.sh | 2 +- usr/local/share/bastille/create.sh | 20 +- usr/local/share/bastille/destroy.sh | 8 +- usr/local/share/bastille/etcupdate.sh | 29 +-- usr/local/share/bastille/htop.sh | 2 +- usr/local/share/bastille/limits.sh | 2 +- usr/local/share/bastille/mount.sh | 4 +- usr/local/share/bastille/network.sh | 292 ++++++++++++-------------- usr/local/share/bastille/pkg.sh | 2 +- usr/local/share/bastille/rename.sh | 3 - usr/local/share/bastille/template.sh | 4 +- 16 files changed, 301 insertions(+), 272 deletions(-) diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index d7c937747..18890dcf7 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -610,4 +610,4 @@ case "${OPTION}" in update) bastille update "${RELEASE}" ;; -esac +esac \ No newline at end of file diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index dc6ae5bc0..0e7e0ba98 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -156,61 +156,77 @@ update_jailconf_vnet() { # 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 _if_count="$(grep -Eo 'epair[0-9]+|bastille[0-9]+' ${bastille_jailsdir}/*/jail.conf 2>/dev/null | sort -u | wc -l | awk '{print $1}')" - local num_range=$((_if_count + 1)) - for _num in $(seq 0 "${num_range}"); do - if ! grep -Eoq "epair${_num}|bastille${_num}" ${bastille_jailsdir}/*/jail.conf; then - local uniq_epair="bastille${_num}" - 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 ${_if} | 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 interfaces - if echo ${_if} 2>/dev/null | grep -Eoq 'bastille[0-9]+'; then - local _if_vnet="$(grep ${_if} "${bastille_jail_rc_conf}" | grep -Eo "vnet[0-9]+")" - sed -i '' "s|${_if}|${uniq_epair}|g" "${JAIL_CONFIG}" - 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}" - sed -i '' "s|exec.prestart += \"ifconfig.*${uniq_epair}.*description.*|exec.prestart += \"ifconfig e0a_${uniq_epair} description \\\\\"vnet host interface for Bastille jail ${NEWNAME}\\\\\"\";|" "${JAIL_CONFIG}" + local _epair_if_count="$(grep -Eo 'epair[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')" + local _vnet_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 vnet_num_range=$((_vnet_if_count + 1)) + if echo ${_if} 2>/dev/null | grep -Eoq 'epair[0-9]+'; then + # Update bridged VNET config + for _num in $(seq 0 "${epair_num_range}"); do + if ! grep -Eoq "epair${_num}" ${bastille_jailsdir}/*/jail.conf; then + # Update jail.conf epair name + local uniq_epair_bridge="${_num}" + local _if_epaira="$(grep "${_if}" ${JAIL_CONFIG} | grep -Eo -m 1 "epair[0-9]+a")" + local _if_epairb="$(grep "${_if}" ${JAIL_CONFIG} | grep -Eo -m 1 "epair[0-9]+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}" + # 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 + if grep -Eo "${_if}" ${JAIL_CONFIG} | grep -oq ether; then + local macaddr_prefix="$(cat ${JAIL_CONFIG} | grep ${_if} | 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}" + sed -i '' "s|epair${uniq_epair}a ether.*:.*:.*:.*:.*:.*a\";|epair${uniq_epair}a ether ${macaddr}a\";|" "${JAIL_CONFIG}" + sed -i '' "s|epair${uniq_epair}b ether.*:.*:.*:.*:.*:.*b\";|epair${uniq_epair}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|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 + 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} " + sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}" fi else sysrc -f "${bastille_jail_rc_conf}" ifconfig_${_if_vnet}="SYNCDHCP" fi - # for bridged VNET interfaces - elif echo ${_if} 2>/dev/null | grep -Eoq 'epair[0-9]+'; then - local _if_epaira="$(grep "${_if}" ${JAIL_CONFIG} | grep -Eo "e[0-9]+a_${TARGET}")" - local _if_epairb="$(grep "${_if}" ${JAIL_CONFIG} | grep -Eo "e[0-9]+b_${TARGET}")" - local _if_vnet="$(grep ${_if_epairb} "${bastille_jail_rc_conf}" | grep -Eo "vnet[0-9]+")" - sed -i '' "s|${_if}|epair${uniq_epair_bridge}|g" "${JAIL_CONFIG}" - sed -i '' "s|${_if_epaira}|e${uniq_epair_bridge}a_${NEWNAME}|g" "${JAIL_CONFIG}" - sed -i '' "s|${_if_epairb}|e${uniq_epair_bridge}b_${NEWNAME}|g" "${JAIL_CONFIG}" - sed -i '' "s|e${uniq_epair}a_${TARGET} ether.*:.*:.*:.*:.*:.*a\";|e${uniq_epair}a_${NEWNAME} ether ${macaddr}a\";|" "${JAIL_CONFIG}" - sed -i '' "s|e${uniq_epair}b_${TARGET} ether.*:.*:.*:.*:.*:.*b\";|e${uniq_epair}b_${NEWNAME} ether ${macaddr}b\";|" "${JAIL_CONFIG}" + break + fi + done + elif echo ${_if} 2>/dev/null | grep -Eoq 'bastille[0-9]+'; then + # Update VNET config + for _num in $(seq 0 "${bastille_num_range}"); do + if ! grep -Eoq "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}" + # 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 + if grep -Eo ${_if} ${JAIL_CONFIG} | grep -oq ether; then + local macaddr_prefix="$(cat ${JAIL_CONFIG} | grep ${_if} | 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}" + 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|${_if_epairb}_name|e${uniq_epair_bridge}b_${NEWNAME}_name|" "${bastille_jail_rc_conf}" - if grep "vnet0" "${bastille_jail_rc_conf}" | grep -q "e${uniq_epair_bridge}b_${NEWNAME}_name"; then + sed -i '' "s|ifconfig_${_if}_name|ifconfig_${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}" + 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 - break - fi - done + done + fi done } diff --git a/usr/local/share/bastille/cmd.sh b/usr/local/share/bastille/cmd.sh index ce226043d..70b9d7aa0 100644 --- a/usr/local/share/bastille/cmd.sh +++ b/usr/local/share/bastille/cmd.sh @@ -89,10 +89,8 @@ for _jail in ${JAILS}; do COUNT=$(($COUNT+1)) if grep -qw "linsysfs" "${bastille_jailsdir}/${_jail}/fstab"; then # Allow executing commands on Linux jails. - echo "$@" jexec -l -u root "${_jail}" "$@" else - echo "$@" jexec -l -U root "${_jail}" "$@" fi ERROR_CODE=$? diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 3b07cf6b9..3bdeb5e11 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -106,32 +106,11 @@ check_target_is_stopped() { fi } -checkyesno() { - ## copied from /etc/rc.subr -- cedwards (20231125) - ## issue #368 (lowercase values should be parsed) - ## now used for all bastille_zfs_enable=YES|NO tests - ## example: if checkyesno bastille_zfs_enable; then ... - ## returns 0 for enabled; returns 1 for disabled - eval _value=\$${1} - case $_value in - [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) - return 0 - ;; - [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) - return 1 - ;; - *) - warn "\$${1} is not set properly - see rc.conf(5)." - return 1 - ;; - esac -} - jail_autocomplete() { local _TARGET="${1}" # shellcheck disable=SC2010 - local _AUTOTARGET="$( ls "${bastille_jailsdir}" 2>/dev/null | grep "${_TARGET}" 2>/dev/null )" - if [ "$( echo "${_AUTOTARGET}" 2>/dev/null | wc -l )" -eq 1 ]; then + local _AUTOTARGET=$( grep -Eo "^${_TARGET}" "${bastille_jailsdir}" 2>/dev/null ) + if [ $( echo "^${_AUTOTARGET}" 2>/dev/null | wc -l ) -eq 1 ]; then return 0 else error_continue "Multiple jails found for ${_TARGET}:\n${_AUTOTARGET}" @@ -141,6 +120,7 @@ jail_autocomplete() { set_target() { local _TARGET=${1} + JAILS= if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then target_all_jails else @@ -148,10 +128,14 @@ set_target() { jail_autocomplete "${_jail}" check_target_exists "${_jail}" || error_continue "Jail not found \"${_jail}\"" JAILS="${JAILS} ${_jail}" - TARGET="${TARGET} ${_jail}" done - export JAILS + fi + if [ $( echo "${JAILS}" 2>/dev/null | wc -l ) -eq 1 ]; then + TARGET="${JAILS}" export TARGET + export JAILS + else + export JAILS fi } @@ -197,8 +181,8 @@ 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 static_mac="${4}" + ## determine number of interfaces + 1 ## iterate num and grep all jail configs ## define uniq_epair local _epair_if_count="$(grep -Eos 'epair[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')" @@ -228,23 +212,39 @@ generate_vnet_jail_netblock() { 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 [ "${STATIC_MAC}" -eq 1 ]; 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 [ "${STATIC_MAC}" -eq 1 ]; 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}"; @@ -253,5 +253,36 @@ 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 } + +checkyesno() { + ## copied from /etc/rc.subr -- cedwards (20231125) + ## issue #368 (lowercase values should be parsed) + ## now used for all bastille_zfs_enable=YES|NO tests + ## example: if checkyesno bastille_zfs_enable; then ... + ## returns 0 for enabled; returns 1 for disabled + eval _value=\$${1} + case $_value in + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + return 0 + ;; + [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) + return 1 + ;; + *) + warn "\$${1} is not set properly - see rc.conf(5)." + return 1 + ;; + esac +} diff --git a/usr/local/share/bastille/config.sh b/usr/local/share/bastille/config.sh index a878fca9f..c1d386939 100644 --- a/usr/local/share/bastille/config.sh +++ b/usr/local/share/bastille/config.sh @@ -175,4 +175,4 @@ if [ "${ACTION}" = 'set' ]; then info "A restart is required for the changes to be applied. See 'bastille restart ${TARGET}'." fi -exit 0 +exit 0 \ No newline at end of file diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index aa3e68646..4a4723fd1 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -79,4 +79,4 @@ for _jail in ${JAILS}; do if ! cp "${OPTION}" "${CPSOURCE}" "${bastille_jail_path}${CPDEST}"; then error_continue "CP failed: ${CPSOURCE} -> ${bastille_jail_path}${CPDEST}" fi -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index dce4c8b07..bae8bbe3c 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -39,12 +39,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 the jail. + -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 @@ -213,7 +214,7 @@ EOF } generate_vnet_jail_conf() { - 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} { devfs_ruleset = 13; @@ -612,6 +613,7 @@ THICK_JAIL="" CLONE_JAIL="" VNET_JAIL="" LINUX_JAIL="" +STATIC_MAC=0 # Handle and parse options while [ $# -gt 0 ]; do @@ -619,6 +621,10 @@ while [ $# -gt 0 ]; do -h|--help|help) usage ;; + -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 06cff854a..b6b4865b3 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -57,14 +57,8 @@ destroy_jail() { fi if [ -d "${bastille_jail_base}" ]; then - # Force unmount an existing mount points - mount_points="$(mount | cut -d ' ' -f 3 | grep ${bastille_jail_base}/root/)" - for _mount in ${mount_points}; do - echo "Unmounting: \"${_mount}\"" - umount -f "${_mount}" || error_exit "Failed to unmount: \"${_mount}\"" - done - ## make sure no filesystem is currently mounted in the jail directory + mount_points="$(mount | cut -d ' ' -f 3 | grep ${bastille_jail_base}/root/)" if [ -n "${mount_points}" ]; then error_notify "Failed to destroy jail: ${TARGET}" error_exit "Jail has mounted filesystems:\n$mount_points" diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh index 7445fe5da..50bc5e413 100644 --- a/usr/local/share/bastille/etcupdate.sh +++ b/usr/local/share/bastille/etcupdate.sh @@ -31,11 +31,11 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille etcupdate [option(s)] [TARGET|bootstrap RELEASE]" + error_notify "Usage: bastille etcupdate [option(s)] [TARGET|bootstrap] RELEASE" cat << EOF Options: - -d | --dry-run -- Only show output of what etcupdate will do. + -d | --dry-run Show output, but do not apply. EOF exit 1 @@ -43,22 +43,27 @@ EOF bootstrap_etc_release() { local _release="${1}" - local _release_version="$( echo "${1}" | awk -F "-" '{print $1}' )" - if [ ! -d /usr/local/bastille/source/"${_release}" ]; then - if ! git clone --branch releng/"${_release_version}" --depth 1 https://git.FreeBSD.org/src.git /usr/local/bastille/source/"${_release}"; then - error_exit "Failed to bootstrap etcupdate release \"${_release}\"" + 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}"; then + error_notify "Failed to bootstrap etcupdate \"${_release}\"" fi + sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives="${_current}" fi } bootstrap_etc_tarball() { local _release="${1}" - if [ ! -f /usr/local/bastille/source/"${_release}".tbz2 ]; then - if ! etcupdate build -d /tmp/etcupdate -s /usr/local/bastille/source/"${_release}" "${_release}".tbz2; then + if [ ! -f ${bastille_cachedir}/${_release}.tbz2 ]; then + 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 "\"${_release}\" has already been bootstrapped." + info "Etcupdate release has already been prepared for application: \"${_release}\"" + exit 0 fi } @@ -67,14 +72,14 @@ update_jail_etc() { local _release="${2}" if [ "${DRY_RUN}" -eq 1 ]; then info "[_jail]: --dry-run" - etcupdate -n -D "${bastille_jailsdir}"/"${_jail}"/root -t /usr/local/bastille/source/"${_release}".tbz2 + etcupdate -n -D "${bastille_jailsdir}"/"${_jail}"/root -t ${bastille_cachedir}/${_release}.tbz2 else info "[_jail]:" - etcupdate -D "${bastille_jailsdir}"/"${_jail}"/root -t /usr/local/bastille/source/"${_release}".tbz2 + etcupdate -D "${bastille_jailsdir}"/"${_jail}"/root -t ${bastille_cachedir}/${_release}.tbz2 fi } -if [ $# -lt 2 ] || [ $# -gt 3 ]; then +if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then usage fi diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh index 88627e868..10795da15 100644 --- a/usr/local/share/bastille/htop.sh +++ b/usr/local/share/bastille/htop.sh @@ -84,4 +84,4 @@ if [ ! -x "${bastille_jail_path}/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 -fi \ No newline at end of file +fi diff --git a/usr/local/share/bastille/limits.sh b/usr/local/share/bastille/limits.sh index 53334e9d0..14627a080 100644 --- a/usr/local/share/bastille/limits.sh +++ b/usr/local/share/bastille/limits.sh @@ -51,7 +51,7 @@ case "${1}" in ;; esac -if [ "$#" -ne 3 ]; then +if [ $# -ne 3 ]; then usage fi diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 817268b87..416ba745c 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -115,9 +115,9 @@ for _jail in ${JAILS}; do # Check if mount point has already been added _existing_mount="$(echo ${_fullpath_fstab} 2>/dev/null | sed 's#\\#\\\\#g')" - if grep -Eoq "[[:blank:]]${_existing_mount}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab"; then + if grep -Eq "[[:blank:]]${_existing_mount}.*[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab"; then warn "Mountpoint already present in ${bastille_jailsdir}/${_jail}/fstab" - grep -Eo "[[:blank:]]${_existing_mount}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" + grep -E "[[:blank:]]${_existing_mount}" "${bastille_jailsdir}/${_jail}/fstab" continue fi diff --git a/usr/local/share/bastille/network.sh b/usr/local/share/bastille/network.sh index 56940a66e..362ddb0b0 100644 --- a/usr/local/share/bastille/network.sh +++ b/usr/local/share/bastille/network.sh @@ -32,35 +32,44 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille network [option(s)] TARGET [remove INTERFACE] [add INTERFACE IP_ADDRESS]" - + error_notify "Usage: bastille network [option(s)] TARGET [remove|add] INTERFACE [IP_ADDRESS]" cat << EOF Options: - -f | --force Stop the jail if it is running. - -s | --start Start jail on completion. - -v | --vnet Adds a VNET interface to an existing jail. - -b | --bridge Adds a bridged VNET interface to an existing jail. + -b | --bridge Add a bridged VNET interface to an existing jail. + -f | --force Stop the jail if it is running. + -m | --static-mac Generate a static MAC address for the interface. + -s | --start Start jail on completion. + -v | --vnet Add a VNET interface to an existing jail. EOF exit 1 } # Handle options. +BRIDGE_VNET_JAIL=0 FORCE=0 +STATIC_MAC=0 START=0 VNET_JAIL=0 -BRIDGE_VNET_JAIL=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; + -b|-B|--bridge) + BRIDGE_VNET_JAIL=1 + shift + ;; -f|--force) FORCE=1 shift ;; - -r|--restart) + -m|-M|--static-mac) + STATIC_MAC=1 + shift + ;; + -s|--start) START=1 shift ;; @@ -68,13 +77,18 @@ while [ "$#" -gt 0 ]; do VNET_JAIL=1 shift ;; - -b|-B|--bridge) - BRIDGE_VNET_JAIL=1 - shift - ;; -*) - error_notify "Unknown Option: \"${1}\"" - usage + for _o in $(echo ${1} 2>/dev/null | sed 's/-//g' | fold -w1); do + case ${_o} in + b|B) BRIDGE_VNET_JAIL=1 ;; + f) FORCE=1 ;; + m|M) STATIC_MAC=1 ;; + s) START=1 ;; + v|V) VNET_JAIL=1 ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift ;; *) break @@ -82,6 +96,11 @@ while [ "$#" -gt 0 ]; do esac done +TARGET="${1}" +ACTION="${2}" +INTERFACE="${3}" +IP="${4}" + if [ "${ACTION}" = "add" ]; then if [ "${VNET_JAIL}" -eq 1 ] && [ "${BRIDGE_VNET_JAIL}" -eq 1 ]; then error_notify "Error: [-v|-V|--vnet] and [-b|-B|--bridge] cannot both be set." @@ -96,18 +115,13 @@ if [ "$#" -lt 2 ] || [ "$#" -gt 4 ]; then usage fi -TARGET="${1}" -ACTION="${2}" -INTERFACE="${3}" -IP="${4}" - bastille_root_check set_target_single "${TARGET}" check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then bastille stop "${TARGET}" else error_notify "Jail is running." - error_continue "Use [-f|--force] to force stop the jail." + error_exit "Use [-f|--force] to force stop the jail." fi validate_ip() { @@ -159,103 +173,122 @@ check_interface_added() { fi } -add_vnet_interface_block() { +add_interface() { local _jailname="${1}" local _if="${2}" local _ip="${3}" local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" - local _if_count="$(grep -Eo 'bastille[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')" - local _if_vnet_count="$(grep -Eo 'vnet[1-9]+' ${_jail_rc_config} | sort -u | wc -l | awk '{print $1}')" - local _if_vnet="vnet$((_if_vnet_count + 1))" - local num_range=$((_if_count + 1)) - for _num in $(seq 0 "${num_range}"); do - if ! grep -Eq "bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then - local uniq_epair="bastille${_num}" + 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 _vnet_if_count="$(grep -Eo 'vnet[1-9]+' ${_jail_rc_config} | sort -u | wc -l | awk '{print $1}')" + local _if_vnet="vnet$((_vnet_if_count + 1))" + local epair_num_range=$((_epair_if_count + 1)) + local bastille_num_range=$((_bastille_if_count + 1)) + if [ "${BRIDGE_VNET_JAIL}" -eq 1 ]; then + for _num in $(seq 0 "${epair_num_range}"); do + if ! grep -Eq "epair${_num}" "${bastille_jailsdir}"/*/jail.conf; then + local bridge_epair="epair${_num}" break fi done - generate_static_mac "${_jailname}" "${_if}" - sed -i '' "s|}||" "${_jail_config}" - ## generate config - cat << EOF >> "${_jail_config}" - ## ${uniq_epair} interface - vnet.interface += e0b_${uniq_epair}; - exec.prestart += "jib addm ${uniq_epair} ${_if}"; - exec.prestart += "ifconfig e0a_${uniq_epair} ether ${macaddr}a"; - exec.prestart += "ifconfig e0b_${uniq_epair} ether ${macaddr}b"; - exec.prestart += "ifconfig e0a_${uniq_epair} description \"vnet host interface for Bastille jail ${_jailname}\""; - exec.poststop += "jib destroy ${uniq_epair}"; + # Remove ending brace (it is added again with the netblock) + sed -i '' '/}/d' "${_jail_config}" + if [ "${STATIC_MAC}" -eq 1 ]; then + # Generate NETBLOCK with static MAC + generate_static_mac "${_jailname}" "${_if}" + cat << EOF >> "${_jail_config}" + ## ${bridge_epair} interface + vnet.interface += ${bridge_epair}b; + exec.prestart += "ifconfig ${bridge_epair} create"; + exec.prestart += "ifconfig ${_if} addm ${bridge_epair}a"; + exec.prestart += "ifconfig ${bridge_epair}a ether ${macaddr}a"; + exec.prestart += "ifconfig ${bridge_epair}b ether ${macaddr}b"; + exec.prestart += "ifconfig ${bridge_epair}a description \"vnet host interface for Bastille jail ${_jailname}\""; + exec.poststop += "ifconfig ${_if} deletem ${bridge_epair}a"; + exec.poststop += "ifconfig ${bridge_epair}a destroy"; } EOF - - # add config to /etc/rc.conf - sysrc -f "${_jail_rc_config}" ifconfig_e0b_${uniq_epair}_name="${_if_vnet}" - # If 0.0.0.0 set DHCP, else set static IP address - if [ "${_ip}" = "0.0.0.0" ]; then - sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}="SYNCDHCP" - else - sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}=" inet ${_ip} " - fi - - info "[${_jailname}]:" - echo "Added interface: \"${_if}\"" + else + # Generate NETBLOCK without static MAC + cat << EOF >> "${_jail_config}" + ## ${bridge_epair} interface + vnet.interface += ${bridge_epair}b; + exec.prestart += "ifconfig ${bridge_epair} create"; + exec.prestart += "ifconfig ${_if} addm ${bridge_epair}a"; + exec.prestart += "ifconfig ${bridge_epair}a description \"vnet host interface for Bastille jail ${_jailname}\""; + exec.poststop += "ifconfig ${_if} deletem ${bridge_epair}a"; + exec.poststop += "ifconfig ${bridge_epair}a destroy"; } +EOF + fi + # Add config to /etc/rc.conf + sysrc -f "${_jail_rc_config}" ifconfig_${bridge_epair}b_name="${_if_vnet}" + # If 0.0.0.0 set DHCP, else set static IP address + if [ "${_ip}" = "0.0.0.0" ]; then + sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}="SYNCDHCP" + else + sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}=" inet ${_ip} " + fi -add_bridge_interface_block() { - local _jailname="${1}" - local _if="${2}" - local _ip="${3}" - local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" - local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" - local _if_count="$(grep -Eo 'epair[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')" - local _if_vnet_count="$(grep -Eo 'vnet[1-9]+' ${_jail_rc_config} | sort -u | wc -l | awk '{print $1}')" - local _if_vnet=vnet$((_if_vnet_count + 1)) - local num_range=$((_if_count + 1)) - for _num in $(seq 0 "${num_range}"); do - if ! grep -Eq "epair${_num}" "${bastille_jailsdir}"/*/jail.conf; then - local uniq_epair="${_num}" + info "[${_jailname}]:" + echo "Added interface: \"${_if}\"" + + elif [ "${VNET_JAIL}" -eq 1 ]; then + for _num in $(seq 0 "${bastille_num_range}"); do + if ! grep -Eq "bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then + local bastille_epair="bastille${_num}" break fi done - generate_static_mac "${_jailname}" "${_if}" - sed -i '' "s|}||" "${_jail_config}" - ## generate config - cat << EOF >> "${_jail_config}" - ## epair${uniq_epair} interface - vnet.interface += e${uniq_epair}b_${_jailname}; - exec.prestart += "ifconfig epair${uniq_epair} create"; - exec.prestart += "ifconfig ${_if} addm epair${uniq_epair}a"; - exec.prestart += "ifconfig epair${uniq_epair}a up name e${uniq_epair}a_${_jailname}"; - exec.prestart += "ifconfig epair${uniq_epair}b up name e${uniq_epair}b_${_jailname}"; - exec.prestart += "ifconfig e${uniq_epair}a_${_jailname} ether ${macaddr}a"; - exec.prestart += "ifconfig e${uniq_epair}b_${_jailname} ether ${macaddr}b"; - exec.poststop += "ifconfig ${_if} deletem e${uniq_epair}a_${_jailname}"; - exec.poststop += "ifconfig e${uniq_epair}a_${_jailname} destroy"; + # Remove ending brace (it is added again with the netblock) + sed -i '' '/}/d' "${_jail_config}" + if [ "${STATIC_MAC}" -eq 1 ]; then + # Generate NETBLOCK with static MAC + generate_static_mac "${_jailname}" "${_if}" + cat << EOF >> "${_jail_config}" + ## ${bastille_epair} interface + vnet.interface += e0b_${bastille_epair}; + exec.prestart += "jib addm ${bastille_epair} ${_if}"; + exec.prestart += "ifconfig e0a_${bastille_epair} ether ${macaddr}a"; + exec.prestart += "ifconfig e0b_${bastille_epair} ether ${macaddr}b"; + exec.prestart += "ifconfig e0a_${bastille_epair} description \"vnet host interface for Bastille jail ${_jailname}\""; + exec.poststop += "jib destroy ${bastille_epair}"; } EOF + else + # Generate NETBLOCK without static MAC + cat << EOF >> "${_jail_config}" + ## ${bastille_epair} interface + vnet.interface += e0b_${bastille_epair}; + exec.prestart += "jib addm ${bastille_epair} ${_if}"; + exec.prestart += "ifconfig e0a_${bastille_epair} description \"vnet host interface for Bastille jail ${_jailname}\""; + exec.poststop += "jib destroy ${bastille_epair}"; +} +EOF + fi + # Add config to /etc/rc.conf + sysrc -f "${_jail_rc_config}" ifconfig_e0b_${bastille_epair}_name="${_if_vnet}" + # If 0.0.0.0 set DHCP, else set static IP address + if [ "${_ip}" = "0.0.0.0" ]; then + sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}="SYNCDHCP" + else + sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}=" inet ${_ip} " + fi - # Add config to /etc/rc.conf - sysrc -f "${_jail_rc_config}" ifconfig_e${uniq_epair}b_${_jailname}_name="${_if_vnet}" - # If 0.0.0.0 set DHCP, else set static IP address - if [ "${_ip}" = "0.0.0.0" ]; then - sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}="SYNCDHCP" - else - sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}=" inet ${_ip} " + info "[${_jailname}]:" + echo "Added VNET interface: \"${_if}\"" fi - - info "[${_jailname}]:" - echo "Added interface: \"${_if}\"" } -remove_vnet_interface_block() { +remove_interface() { local _jailname="${1}" local _if="${2}" local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" - local _if_jail="$(grep "${_if}" ${_jail_config} | grep -Eo 'bastille[0-9]+')" + local _if_jail="$(grep ${_if} ${_jail_config} | grep -Eo -m 1 'epair[0-9]+|bastille[0-9]+')" if grep -o "${_if_jail}" ${_jail_rc_config}; then - local _if_vnet="$(grep "${_if_jail}" ${_jail_rc_config} | grep -Eo 'vnet[0-9]+')" + local _if_vnet="$(grep ${_if_jail} ${_jail_rc_config} | grep -Eo 'vnet[0-9]+')" else error_exit "Interface not found: ${_if_jail}" fi @@ -267,67 +300,19 @@ remove_vnet_interface_block() { # Avoid removing entire file contents if variables aren't set for some reason if [ -z "${_if_jail}" ]; then - error_exit "Error: Could not find specifed interfaces. Exiting..." + error_exit "Error: Could not find specifed interface." fi # Remove interface from jail.conf if [ -n "${_if_jail}" ]; then - sed -i '' "s|.*${_if_jail}.*||" "${_jail_config}" - sed -i '' '/^$/d' "${_jail_config}" - else - error_exit "Failed to remove interface from jail.conf" - fi - - # Remove interface from /etc/rc.conf - if [ -n "${_if_vnet}" ] && echo ${_if_vnet} 2>/dev/null | grep -Eo 'vnet[0-9]+'; then - sed -i '' "s|.*${_if_vnet}.*||" "${_jail_rc_config}" - sed -i '' '/^$/d' "${_jail_rc_config}" - else - error_exit "Failed to remove interface from /etc/rc.conf" - fi - - info "[${_jailname}]:" - echo "Removed interface: \"${_if}\"" -} - -remove_bridge_interface_block() { - local _jailname="${1}" - local _if="${2}" - local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" - local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" - local _if_epair="$(grep "${_if}" ${_jail_config} | grep -Eo 'epair[0-9]+')" - local _if_epaira_name="$(grep "${_if_epair}" ${_jail_config} | grep -Eo "e[0-9]+a_${_jailname}")" - local _if_epairb_name="$(grep "${_if_epair}" ${_jail_config} | grep -Eo "e[0-9]+b_${_jailname}")" - if grep -o "${_if_epairb_name}" ${_jail_rc_config}; then - local _if_vnet="$(grep "${_if_epairb_name}" ${_jail_rc_config} | grep -Eo 'vnet[0-9]+')" - else - error_exit "Interface not found: ${_if_epair_name}" - fi - - # Do not allow removing default vnet0 interface - if [ "${_if_vnet}" = "vnet0" ]; then - error_exit "Default interface cannot be removed." - fi - - # Avoid removing entire file contents if variables aren't set for some reason - if [ -z "${_if_epair}" ] || [ -z "${_if_epaira_name}" ] || [ -z "${_if_epairb_name}" ] || [ -z "${_if_vnet}" ]; then - error_exit "Error: Could not find specifed interfaces. Exiting..." - fi - - # Remove interface from jail.conf - if [ -n "${_if_epair}" ] && [ -n "${_if_epaira_name}" ] && [ -n "${_if_epairb_name}" ] && [ -n "${_if_vnet}" ]; then - sed -i '' "s|.*${_if_epair}.*||" "${_jail_config}" - sed -i '' "s|.*${_if_epaira_name}.*||" "${_jail_config}" - sed -i '' "s|.*${_if_epairb_name}.*||" "${_jail_config}" - sed -i '' '/^$/d' "${_jail_config}" + sed -i '' "/.*${_if_jail}.*/d" "${_jail_config}" else error_exit "Failed to remove interface from jail.conf" fi # Remove interface from /etc/rc.conf if [ -n "${_if_vnet}" ] && echo ${_if_vnet} 2>/dev/null | grep -Eo 'vnet[0-9]+'; then - sed -i '' "s|ifconfig.*${_if_vnet}.*||" "${_jail_rc_config}" - sed -i '' '/^$/d' "${_jail_rc_config}" + sed -i '' "/.*${_if_vnet}.*/d" "${_jail_rc_config}" else error_exit "Failed to remove interface from /etc/rc.conf" fi @@ -343,12 +328,16 @@ case "${ACTION}" in if check_interface_added "${TARGET}" "${INTERFACE}"; then error_exit "Interface is already added: \"${INTERFACE}\"" fi - validate_ip "${IP}" + if [ -z "${IP}" ] || [ "${IP}" = "0.0.0.0" ]; then + IP="SYNCDHCP" + else + validate_ip "${IP}" + fi if [ "${VNET_JAIL}" -eq 1 ]; then if ifconfig | grep "${INTERFACE}" | grep -q bridge; then error_exit "\"${INTERFACE}\" is a bridge interface." else - add_vnet_interface_block "${TARGET}" "${INTERFACE}" "${IP}" + add_interface "${TARGET}" "${INTERFACE}" "${IP}" if [ "${START}" -eq 1 ]; then bastille start "${TARGET}" fi @@ -357,7 +346,7 @@ case "${ACTION}" in if ! ifconfig | grep "${INTERFACE}" | grep -q bridge; then error_exit "\"${INTERFACE}\" is not a bridge interface." else - add_bridge_interface_block "${TARGET}" "${INTERFACE}" "${IP}" + add_interface "${TARGET}" "${INTERFACE}" "${IP}" if [ "${START}" -eq 1 ]; then bastille start "${TARGET}" fi @@ -370,16 +359,9 @@ case "${ACTION}" in if ! grep -q "${INTERFACE}" ${bastille_jailsdir}/${TARGET}/jail.conf; then error_exit "Interface not found in jail.conf: \"${INTERFACE}\"" else - if grep "${INTERFACE}" ${bastille_jailsdir}/${TARGET}/jail.conf 2>/dev/null | grep -qE '[[:blank:]]bastille[0-9]+'; then - remove_vnet_interface_block "${TARGET}" "${INTERFACE}" - if [ "${START}" -eq 1 ]; then - bastille start "${TARGET}" - fi - elif grep "${INTERFACE}" ${bastille_jailsdir}/${TARGET}/jail.conf 2>/dev/null | grep -qE '[[:blank:]]epair[0-9]+'; then - remove_bridge_interface_block "${TARGET}" "${INTERFACE}" - if [ "${START}" -eq 1 ]; then - bastille start "${TARGET}" - fi + remove_interface "${TARGET}" "${INTERFACE}" + if [ "${START}" -eq 1 ]; then + bastille start "${TARGET}" fi fi ;; diff --git a/usr/local/share/bastille/pkg.sh b/usr/local/share/bastille/pkg.sh index edf09f220..738c99f2e 100644 --- a/usr/local/share/bastille/pkg.sh +++ b/usr/local/share/bastille/pkg.sh @@ -68,7 +68,7 @@ while [ "$#" -gt 0 ]; do esac done -if [ "$#" -lt 2 ]; then +if [ $# -lt 2 ]; then usage fi diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index f1afb0082..cad78c082 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -107,9 +107,6 @@ update_jailconf() { sed -i '' "s|${TARGET}.*{|${NEWNAME} {|" "${JAIL_CONFIG}" # update vnet config sed -i '' "s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|g" "${JAIL_CONFIG}" - sed -i '' "/vnet.interface/s|_${TARGET};|_${NEWNAME};|g" "${JAIL_CONFIG}" - sed -i '' "/ifconfig/s|_${TARGET}|_${NEWNAME}|g" "${JAIL_CONFIG}" - sed -i '' "/ifconfig/s|_${TARGET}_name=|_${NEWNAME}_name=|g" "${BASTILLE_JAIL_RC_CONF}" fi fi } diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 9ec0bc686..92e96bb6e 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -317,7 +317,7 @@ for _jail in ${JAILS}; do # First word converted to lowercase is the Bastille command. -- cwells _cmd=$(echo "${_line}" | awk '{print tolower($1);}') # Rest of the line with "arg" variables replaced will be the arguments. -- cwells - _args=$(echo "${_line}" | awk '{$1=""; sub(/^ */, ""); print;}' | eval "sed ${ARG_REPLACEMENTS}") + _args=$(echo "${_line}" | awk -F '[ ]' '{$1=""; sub(/^ */, ""); print;}' | eval "sed "${ARG_REPLACEMENTS}"") # Apply overrides for commands/aliases and arguments. -- cwells case $_cmd in @@ -335,7 +335,7 @@ for _jail in ${JAILS}; do # Escape single-quotes in the command being executed. -- cwells _args=$(echo "${_args}" | sed "s/'/'\\\\''/g") # Allow redirection within the jail. -- cwells - _args="sh -c \"${_args}\"" + _args="sh -c '${_args}'" ;; cp|copy) _cmd='cp' From 140ac351212f58d455712757ec2f6d2a12ac1ca7 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Fri, 3 Jan 2025 08:22:44 -0700 Subject: [PATCH 112/120] fix shellcheck --- usr/local/share/bastille/clone.sh | 7 ++++--- usr/local/share/bastille/common.sh | 10 +++++----- usr/local/share/bastille/etcupdate.sh | 2 +- usr/local/share/bastille/rename.sh | 1 - usr/local/share/bastille/template.sh | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 0e7e0ba98..7c4cf2ef0 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -157,9 +157,9 @@ update_jailconf_vnet() { 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 _vnet_if_count="$(grep -Eo 'bastille[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 vnet_num_range=$((_vnet_if_count + 1)) + local bastille_num_range=$((_vnet_if_count + 1)) if echo ${_if} 2>/dev/null | grep -Eoq 'epair[0-9]+'; then # Update bridged VNET config for _num in $(seq 0 "${epair_num_range}"); do @@ -307,4 +307,5 @@ else usage fi -clone_jail \ No newline at end of file +clone_jail + diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 3bdeb5e11..57bce86b1 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -109,8 +109,8 @@ check_target_is_stopped() { jail_autocomplete() { local _TARGET="${1}" # shellcheck disable=SC2010 - local _AUTOTARGET=$( grep -Eo "^${_TARGET}" "${bastille_jailsdir}" 2>/dev/null ) - if [ $( echo "^${_AUTOTARGET}" 2>/dev/null | wc -l ) -eq 1 ]; then + local _AUTOTARGET="$(grep -Eo "^${_TARGET}" "${bastille_jailsdir}" 2>/dev/null)" + if [ "$(echo "^${_AUTOTARGET}" 2>/dev/null | wc -l)" -eq 1 ]; then return 0 else error_continue "Multiple jails found for ${_TARGET}:\n${_AUTOTARGET}" @@ -130,7 +130,7 @@ set_target() { JAILS="${JAILS} ${_jail}" done fi - if [ $( echo "${JAILS}" 2>/dev/null | wc -l ) -eq 1 ]; then + if [ "$(echo "${JAILS}" 2>/dev/null | wc -l)" -eq 1 ]; then TARGET="${JAILS}" export TARGET export JAILS @@ -214,7 +214,7 @@ generate_vnet_jail_netblock() { fi ## If BRIDGE is enabled, generate bridge config, else generate VNET config if [ -n "${use_unique_bridge}" ]; then - if [ "${STATIC_MAC}" -eq 1 ]; then + if [ "${static_mac}" -eq 1 ]; then ## Generate bridged VNET config with static MAC address generate_static_mac "${jail_name}" "${external_interface}" cat <<-EOF @@ -241,7 +241,7 @@ EOF EOF fi else - if [ "${STATIC_MAC}" -eq 1 ]; then + if [ "${static_mac}" -eq 1 ]; then ## Generate VNET config with static MAC address generate_static_mac "${jail_name}" "${external_interface}" cat <<-EOF diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh index 50bc5e413..f0d1100f6 100644 --- a/usr/local/share/bastille/etcupdate.sh +++ b/usr/local/share/bastille/etcupdate.sh @@ -44,7 +44,7 @@ EOF 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 + 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}"; then error_notify "Failed to bootstrap etcupdate \"${_release}\"" diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index cad78c082..1b9709e54 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -97,7 +97,6 @@ validate_name() { update_jailconf() { # Update jail.conf JAIL_CONFIG="${bastille_jailsdir}/${NEWNAME}/jail.conf" - BASTILLE_JAIL_RC_CONF="${bastille_jailsdir}/${NEWNAME}/root/etc/rc.conf" if [ -f "${JAIL_CONFIG}" ]; then if ! grep -qw "path = ${bastille_jailsdir}/${NEWNAME}/root;" "${JAIL_CONFIG}"; then sed -i '' "s|host.hostname.*=.*${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}" diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 92e96bb6e..6485eb514 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -317,7 +317,7 @@ for _jail in ${JAILS}; do # First word converted to lowercase is the Bastille command. -- cwells _cmd=$(echo "${_line}" | awk '{print tolower($1);}') # Rest of the line with "arg" variables replaced will be the arguments. -- cwells - _args=$(echo "${_line}" | awk -F '[ ]' '{$1=""; sub(/^ */, ""); print;}' | eval "sed "${ARG_REPLACEMENTS}"") + _args=$(echo "${_line}" | awk -F '[ ]' '{$1=""; sub(/^ */, ""); print;}' | eval "sed ${ARG_REPLACEMENTS}") # Apply overrides for commands/aliases and arguments. -- cwells case $_cmd in From 366d4e738b71262a7d485c7b53dad1edbc889fe4 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Sat, 4 Jan 2025 10:53:35 -0700 Subject: [PATCH 113/120] add classic jail multiple if --- usr/local/share/bastille/clone.sh | 25 ++- usr/local/share/bastille/cmd.sh | 2 +- usr/local/share/bastille/common.sh | 2 +- usr/local/share/bastille/config.sh | 3 +- usr/local/share/bastille/console.sh | 6 +- usr/local/share/bastille/convert.sh | 2 +- usr/local/share/bastille/cp.sh | 2 +- usr/local/share/bastille/create.sh | 30 +++- usr/local/share/bastille/destroy.sh | 2 +- usr/local/share/bastille/mount.sh | 2 +- usr/local/share/bastille/network.sh | 231 +++++++++++++++++++-------- usr/local/share/bastille/pkg.sh | 2 +- usr/local/share/bastille/setup.sh | 2 +- usr/local/share/bastille/start.sh | 64 ++++++-- usr/local/share/bastille/stop.sh | 37 +++-- usr/local/share/bastille/sysrc.sh | 2 +- usr/local/share/bastille/tags.sh | 3 +- usr/local/share/bastille/template.sh | 4 +- usr/local/share/bastille/top.sh | 2 +- usr/local/share/bastille/umount.sh | 2 +- usr/local/share/bastille/zfs.sh | 2 +- 21 files changed, 302 insertions(+), 125 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 7c4cf2ef0..5ebe5754d 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -108,7 +108,7 @@ validate_ip() { if [ -n "${ip6}" ]; then info "Valid: (${ip6})." IPX_ADDR="ip6.addr" - # shellcheck disable=SC2034 + # shellcheck disable=SC2034 IP6_MODE="new" else local IFS @@ -142,12 +142,30 @@ update_jailconf() { sed -i '' "s|path = .*;|path = ${bastille_jailsdir}/${NEWNAME}/root;|" "${JAIL_CONFIG}" sed -i '' "s|mount.fstab = .*;|mount.fstab = ${bastille_jailsdir}/${NEWNAME}/fstab;|" "${JAIL_CONFIG}" sed -i '' "s|${TARGET} {|${NEWNAME} {|" "${JAIL_CONFIG}" - sed -i '' "s|${IPX_ADDR} = .*;|${IPX_ADDR} = ${IP};|" "${JAIL_CONFIG}" fi fi if grep -qw "vnet;" "${JAIL_CONFIG}"; then update_jailconf_vnet + else + _ip4="$(bastille config ${TARGET} get ip4.addr | sed 's/,/ /g')" + _ip6="$(bastille config ${TARGET} get ip6.addr | sed 's/,/ /g')" + # IP4 + if [ "${_ip4}" != "not set" ]; then + for _ip in ${_ip4}; do + _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" + sed -i '' "/${IPX_ADDR} = .*/ s/${_ip}/${IP}/" "${JAIL_CONFIG}" + sed -i '' "/${IPX_ADDR} += .*/ s/${_ip}/127.0.0.1/" "${JAIL_CONFIG}" + done + fi + # IP6 + if [ "${_ip6}" != "not set" ]; then + for _ip in ${_ip6}; do + _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" + sed -i '' "/${IPX_ADDR} = .*/ s/${_ip}/${IP}/" "${JAIL_CONFIG}" + sed -i '' "/${IPX_ADDR} += .*/ s/${_ip}/127.0.0.1/" "${JAIL_CONFIG}" + done + fi fi } @@ -307,5 +325,4 @@ else usage fi -clone_jail - +clone_jail \ No newline at end of file diff --git a/usr/local/share/bastille/cmd.sh b/usr/local/share/bastille/cmd.sh index 70b9d7aa0..116bf28ad 100644 --- a/usr/local/share/bastille/cmd.sh +++ b/usr/local/share/bastille/cmd.sh @@ -109,4 +109,4 @@ if [ "${COUNT}" -gt 1 ] && [ "${RETURN}" -gt 0 ]; then RETURN=1 fi -return "${RETURN}" +return "${RETURN}" \ No newline at end of file diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 57bce86b1..54b41dfa3 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -285,4 +285,4 @@ checkyesno() { return 1 ;; esac -} +} \ No newline at end of file diff --git a/usr/local/share/bastille/config.sh b/usr/local/share/bastille/config.sh index c1d386939..1c48e8639 100644 --- a/usr/local/share/bastille/config.sh +++ b/usr/local/share/bastille/config.sh @@ -97,6 +97,7 @@ for _jail in ${JAILS}; do # check if there is a value for this property if (NF == 2) { # remove any quotes surrounding the string + #sub(",[^|]*\\|", ",", $2); sub(/^"/, "", $2); sub(/"$/, "", $2); print $2; @@ -175,4 +176,4 @@ if [ "${ACTION}" = 'set' ]; then info "A restart is required for the changes to be applied. See 'bastille restart ${TARGET}'." fi -exit 0 \ No newline at end of file +exit 0 diff --git a/usr/local/share/bastille/console.sh b/usr/local/share/bastille/console.sh index bf7e32fc1..761b11d9a 100644 --- a/usr/local/share/bastille/console.sh +++ b/usr/local/share/bastille/console.sh @@ -74,9 +74,9 @@ bastille_root_check set_target_single "${TARGET}" check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then bastille start "${TARGET}" -else +else error_notify "Jail is not running." - error_continue "Use [-f|--force] to force start the jail." + error_exit "Use [-f|--force] to force start the jail." fi validate_user() { @@ -112,4 +112,4 @@ if [ -n "${USER}" ]; then else LOGIN="$(jexec -l "${TARGET}" which login)" ${_setfib} jexec -l "${TARGET}" $LOGIN -f root -fi +fi \ No newline at end of file diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh index f8de61e94..04df66b80 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -184,4 +184,4 @@ while :; do [Yy]) start_convert;; [Nn]) exit 0;; esac -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index 4a4723fd1..aa3e68646 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -79,4 +79,4 @@ for _jail in ${JAILS}; do if ! cp "${OPTION}" "${CPSOURCE}" "${bastille_jail_path}${CPDEST}"; then error_continue "CP failed: ${CPSOURCE} -> ${bastille_jail_path}${CPDEST}" fi -done \ No newline at end of file +done diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index bae8bbe3c..2c58a5295 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -71,14 +71,14 @@ validate_name() { validate_ip() { ipx_addr="ip4.addr" - ip="$1" + ip="${1}" ip6=$(echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)') if [ -n "${ip6}" ]; then info "Valid: (${ip6})." ipx_addr="ip6.addr" IP6_MODE="new" else - if [ "${ip}" = "DHCP" ]; then + if [ "${ip}" = "DHCP" ] || [ "${ip}" = "inherit" ]; then info "Valid: (${ip})." else local IFS @@ -102,13 +102,28 @@ validate_ip() { fi fi fi - if echo "${ip}" | grep -qvE '(SLAAC|DHCP|0[.]0[.]0[.]0)'; then + if [ ! -f "${bastille_jail_conf}" ]; then + if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then + local bastille_jail_conf_interface=${bastille_network_shared} + fi + if [ -n "${bastille_network_loopback}" ] && [ -z "${bastille_network_shared}" ]; then + local bastille_jail_conf_interface=${bastille_network_loopback} + fi + if [ -n "${INTERFACE}" ]; then + local bastille_jail_conf_interface=${INTERFACE} + fi + fi + if [ "${ip}" = "inherit" ]; then + IP4_DEFINITION="ip4 = ${ip};" + IP6_DEFINITION="ip6 = ${ip};" + IP6_MODE="new" + elif echo "${ip}" | grep -qvE '(SLAAC|DHCP|0[.]0[.]0[.]0)'; then if [ "${ipx_addr}" = "ip4.addr" ]; then IP4_ADDR="${ip}" - IP4_DEFINITION="${ipx_addr} = ${ip};" + IP4_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${ip};" else IP6_ADDR="${ip}" - IP6_DEFINITION="${ipx_addr} = ${ip};" + IP6_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${ip};" fi fi } @@ -182,7 +197,6 @@ ${NAME} { securelevel = 2; osrelease = ${RELEASE}; - interface = ${bastille_jail_conf_interface}; ${IP4_DEFINITION} ${IP6_DEFINITION} ip6 = ${IP6_MODE}; @@ -206,8 +220,8 @@ ${NAME} { allow.mount; allow.mount.devfs; - interface = ${bastille_jail_conf_interface}; - ${ipx_addr} = ${IP}; + ${IP4_DEFINITION} + ${IP6_DEFINITION} ip6 = ${IP6_MODE}; } EOF diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index b6b4865b3..101e102f1 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -270,4 +270,4 @@ case "${TARGET}" in set_target_single "${TARGET}" destroy_jail "${TARGET}" ;; -esac +esac \ No newline at end of file diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 416ba745c..f16b1edc3 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -154,4 +154,4 @@ for _jail in ${JAILS}; do echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab" || error_continue "Failed to create fstab entry: ${_fstab_entry}" mount -F "${bastille_jailsdir}/${_jail}/fstab" -a || error_continue "Failed to mount volume: ${_fullpath}" echo "Added: ${_fstab_entry}" -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/network.sh b/usr/local/share/bastille/network.sh index 362ddb0b0..0f9574124 100644 --- a/usr/local/share/bastille/network.sh +++ b/usr/local/share/bastille/network.sh @@ -32,15 +32,16 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille network [option(s)] TARGET [remove|add] INTERFACE [IP_ADDRESS]" + error_notify "Usage: bastille network [option(s)] TARGET [remove|add|change] INTERFACE [IP_ADDRESS]" cat << EOF Options: - -b | --bridge Add a bridged VNET interface to an existing jail. + -b | --bridge Add a bridged VNET interface to an existing VNET jail. + -c | --classic Add an interface to a classic (non-VNET) jail. -f | --force Stop the jail if it is running. - -m | --static-mac Generate a static MAC address for the interface. + -m | --static-mac Generate a static MAC address for the VNET interface. -s | --start Start jail on completion. - -v | --vnet Add a VNET interface to an existing jail. + -v | --vnet Add a VNET interface to an existing VNET jail. EOF exit 1 @@ -48,6 +49,7 @@ EOF # Handle options. BRIDGE_VNET_JAIL=0 +CLASSIC_JAIL=0 FORCE=0 STATIC_MAC=0 START=0 @@ -61,7 +63,11 @@ while [ "$#" -gt 0 ]; do BRIDGE_VNET_JAIL=1 shift ;; - -f|--force) + -c|--classic) + CLASSIC_JAIL=1 + shift + ;; + -f|--force) FORCE=1 shift ;; @@ -81,6 +87,7 @@ while [ "$#" -gt 0 ]; do for _o in $(echo ${1} 2>/dev/null | sed 's/-//g' | fold -w1); do case ${_o} in b|B) BRIDGE_VNET_JAIL=1 ;; + c) CLASSIC_JAIL=1 ;; f) FORCE=1 ;; m|M) STATIC_MAC=1 ;; s) START=1 ;; @@ -95,6 +102,7 @@ while [ "$#" -gt 0 ]; do ;; esac done +set -x TARGET="${1}" ACTION="${2}" @@ -102,11 +110,13 @@ INTERFACE="${3}" IP="${4}" if [ "${ACTION}" = "add" ]; then - if [ "${VNET_JAIL}" -eq 1 ] && [ "${BRIDGE_VNET_JAIL}" -eq 1 ]; then - error_notify "Error: [-v|-V|--vnet] and [-b|-B|--bridge] cannot both be set." + if { [ "${VNET_JAIL}" -eq 1 ] && [ "${BRIDGE_VNET_JAIL}" -eq 1 ]; } || \ + { [ "${VNET_JAIL}" -eq 1 ] && [ "${CLASSIC_JAIL}" -eq 1 ]; } || \ + { [ "${CLASSIC_JAIL}" -eq 1 ] && [ "${BRIDGE_VNET_JAIL}" -eq 1 ]; } then + error_notify "Error: Only one of [-b|-B|--bridge], [-c|--classic] or [-v|-V|--vnet] should be set." usage - elif [ "${VNET_JAIL}" -eq 0 ] && [ "${BRIDGE_VNET_JAIL}" -eq 0 ]; then - error_notify "Error: [-v|-V|--vnet] or [-b|-B|--bridge] must be set." + elif [ "${VNET_JAIL}" -eq 0 ] && [ "${BRIDGE_VNET_JAIL}" -eq 0 ] && [ "${CLASSIC_JAIL}" -eq 0 ]; then + error_notify "Error: [-c|--classic], [-b|-B|--bridge] or [-v|-V|--vnet] must be set." usage fi fi @@ -125,14 +135,20 @@ else fi validate_ip() { - local ip="${1}" - local ip6="$( echo "${ip}" 2>/dev/null | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )" - if [ -n "${ip6}" ]; then - info "Valid: (${ip6})." + IP6_ENABLE=0 + local _ip="${1}" + local _jail_config="${bastille_jailsdir}/${TARGET}/jail.conf" + if grep -Eqo ${_ip} ${_jail_config}; then + error_exit "Error: IP already present in jail.conf" + fi + local _ip6="$( echo "${_ip}" 2>/dev/null | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )" + if [ -n "${_ip6}" ]; then + info "Valid: (${_ip6})." + IP6_ENABLE=1 else local IFS - if echo "${ip}" 2>/dev/null | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then - TEST_IP=$(echo "${ip}" | cut -d / -f1) + if echo "${_ip}" 2>/dev/null | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then + TEST_IP=$(echo "${_ip}" | cut -d / -f1) IFS=. set ${TEST_IP} for quad in 1 2 3 4; do @@ -140,9 +156,9 @@ validate_ip() { error_exit "Invalid: (${TEST_IP})" fi done - info "Valid: (${ip})." + info "Valid: (${_ip})." else - error_exit "Invalid: (${ip})." + error_exit "Invalid: (${_ip})." fi fi } @@ -156,23 +172,55 @@ validate_netif() { fi } -validate_netconf() { - if [ -n "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then - error_exit "Invalid network configuration." - fi -} - check_interface_added() { local _jailname="${1}" local _if="${2}" local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" - if grep -o "${_if}" "${_jail_config}"; then + if grep -qo "${_if}" "${_jail_config}"; then return 0 else return 1 fi } +change_ip() { + local _jailname="${1}" + local _if="${2}" + local _ip="${3}" + local _type="${4}" + local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" + local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" + local _epair="$(grep -E ${_if} ${_jail_config} | grep -Eo -m 1 'epair[0-9]+|bastille[0-9]+')" + local _jail_vnet="$(grep -E ${_epair} ${_jail_rc_config} | grep -Eo -m 1 'vnet[0-9]+')" + sysrc -f "${_jail_rc_config}" ifconfig_${_jail_vnet}=" inet ${IP} " +} + +test_change_ip() { + local _jailname="${1}" + local _if="${2}" + local _ip="${3}" + local _type="${4}" + local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" + if [ "${_type}" = "vnet" ]; then + local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" + local _epair="$(grep -E ${_if} ${_jail_config} | grep -Eo -m 1 'epair[0-9]+|bastille[0-9]+')" + local _jail_vnet="$(grep -E ${_epair} ${_jail_rc_config} | grep -Eo -m 1 'vnet[0-9]+')" + sysrc -f "${_jail_rc_config}" ifconfig_${_jail_vnet}=" inet ${IP} " + elif [ "${_type}" = "classic" ]; then + if [ "${IP6_ENABLE}" -eq 1 ]; then + local _ip6="$(bastille config ${_jailname} get ip6.addr | sed 's/,/ /g' | grep -F ${_if})" + if [ "${_ip6}" != "not set" ]; then + sed -i '' "s/${_if}|.*/${_if}|${_ip};/" "${_jail_config}" + fi + else + local _ip4="$(bastille config ${_jailname} get ip4.addr | sed 's/,/ /g' | grep -F ${_if})" + if [ "${_ip4}" != "not set" ]; then + sed -i '' "s/${_if}|.*/${_if}|${_ip};/" "${_jail_config}" + fi + fi + fi +} + add_interface() { local _jailname="${1}" local _if="${2}" @@ -278,62 +326,93 @@ EOF info "[${_jailname}]:" echo "Added VNET interface: \"${_if}\"" + + elif [ "${CLASSIC_JAIL}" -eq 1 ]; then + if [ "${IP6_ENABLE}" -eq 1 ]; then + if [ "$(bastille config ${TARGET} get ip6)" = "disable" ]; then + error_exit "Error: IPv6 is not enabled for this jail." + else + sed -i '' "s/ip6.addr = .*/&\n ip6.addr += ${_if}|${_ip};/" ${_jail_config} + fi + else + if [ "$(bastille config ${TARGET} get ip4)" = "disable" ]; then + error_exit "Error: IPv4 is not enabled for this jail." + else + sed -i '' "s/ip4.addr = .*/&\n ip4.addr += ${_if}|${_ip};/" ${_jail_config} + fi + fi fi + + info "[${_jailname}]:" + echo "Added interface: \"${_if}\"" } remove_interface() { local _jailname="${1}" local _if="${2}" local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" - local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" - local _if_jail="$(grep ${_if} ${_jail_config} | grep -Eo -m 1 'epair[0-9]+|bastille[0-9]+')" - if grep -o "${_if_jail}" ${_jail_rc_config}; then - local _if_vnet="$(grep ${_if_jail} ${_jail_rc_config} | grep -Eo 'vnet[0-9]+')" - else - error_exit "Interface not found: ${_if_jail}" - fi - - # Do not allow removing default vnet0 interface - if [ "${_if_vnet}" = "vnet0" ]; then - error_exit "Default interface cannot be removed." - fi + # Skip next block in case of classic jail + if [ "$(bastille config ${TARGET} get vnet)" != "not set" ]; then + local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" + local _if_jail="$(grep ${_if} ${_jail_config} | grep -Eo -m 1 'epair[0-9]+|bastille[0-9]+')" - # Avoid removing entire file contents if variables aren't set for some reason - if [ -z "${_if_jail}" ]; then - error_exit "Error: Could not find specifed interface." - fi + if grep -o "${_if_jail}" ${_jail_rc_config}; then + local _if_vnet="$(grep ${_if_jail} ${_jail_rc_config} | grep -Eo 'vnet[0-9]+')" + else + error_exit "Interface not found: ${_if_jail}" + fi + + # Do not allow removing default vnet0 interface + if [ "${_if_vnet}" = "vnet0" ]; then + error_exit "Default interface cannot be removed." + fi - # Remove interface from jail.conf - if [ -n "${_if_jail}" ]; then - sed -i '' "/.*${_if_jail}.*/d" "${_jail_config}" - else - error_exit "Failed to remove interface from jail.conf" - fi + # Avoid removing entire file contents if variables aren't set for some reason + if [ -z "${_if_jail}" ]; then + error_exit "Error: Could not find specifed interface." + fi + + # Remove interface from /etc/rc.conf + if [ -n "${_if_vnet}" ] && echo ${_if_vnet} 2>/dev/null | grep -Eo 'vnet[0-9]+'; then + sed -i '' "/.*${_if_vnet}.*/d" "${_jail_rc_config}" + else + error_exit "Failed to remove interface from /etc/rc.conf" + fi - # Remove interface from /etc/rc.conf - if [ -n "${_if_vnet}" ] && echo ${_if_vnet} 2>/dev/null | grep -Eo 'vnet[0-9]+'; then - sed -i '' "/.*${_if_vnet}.*/d" "${_jail_rc_config}" + # Remove VNET interface from jail.conf (VNET) + if [ -n "${_if_jail}" ]; then + sed -i '' "/.*${_if_jail}.*/d" "${_jail_config}" + else + error_exit "Failed to remove interface from jail.conf" + fi else - error_exit "Failed to remove interface from /etc/rc.conf" + # Remove interface from jail.conf (non-VNET) + if [ -n "${_if}" ]; then + if grep ${_if} ${_jail_config} 2>/dev/null | grep -qo " = "; then + error_exit "Default interface cannot be removed." + else + sed -i '' "/.*${_if}.*/d" "${_jail_config}" + fi + else + error_exit "Failed to remove interface from jail.conf" + fi fi - + info "[${_jailname}]:" echo "Removed interface: \"${_if}\"" } case "${ACTION}" in add) - validate_netconf validate_netif "${INTERFACE}" - if check_interface_added "${TARGET}" "${INTERFACE}"; then - error_exit "Interface is already added: \"${INTERFACE}\"" - fi if [ -z "${IP}" ] || [ "${IP}" = "0.0.0.0" ]; then IP="SYNCDHCP" + IP6_ENABLE=0 else validate_ip "${IP}" fi if [ "${VNET_JAIL}" -eq 1 ]; then + ! check_interface_added "${TARGET}" "${INTERFACE}" || error_exit "Interface is already added: \"${INTERFACE}\"" if ifconfig | grep "${INTERFACE}" | grep -q bridge; then error_exit "\"${INTERFACE}\" is a bridge interface." else @@ -343,6 +422,7 @@ case "${ACTION}" in fi fi elif [ "${BRIDGE_VNET_JAIL}" -eq 1 ]; then + ! check_interface_added "${TARGET}" "${INTERFACE}" || error_exit "Interface is already added: \"${INTERFACE}\"" if ! ifconfig | grep "${INTERFACE}" | grep -q bridge; then error_exit "\"${INTERFACE}\" is not a bridge interface." else @@ -351,22 +431,47 @@ case "${ACTION}" in bastille start "${TARGET}" fi fi + elif [ "${CLASSIC_JAIL}" -eq 1 ]; then + if [ "$(bastille config ${TARGET} get vnet)" != "not set" ]; then + error_exit "Error: ${TARGET} is a VNET jail." + elif [ "$(bastille config ${TARGET} get ip4)" = "inherit" ] || [ "$(bastille config ${TARGET} get ip6)" = "inherit" ]; then + error_exit "Error: Jail IP mode is set to inherit." + elif [ "${IP}" = "SYNCDHCP" ]; then + error_exit "Error: Valid IP is required for non-VNET jails." + else + add_interface "${TARGET}" "${INTERFACE}" "${IP}" + if [ "${START}" -eq 1 ]; then + bastille start "${TARGET}" + fi + fi fi ;; remove|delete) check_interface_added "${TARGET}" "${INTERFACE}" || error_exit "Interface not found in jail.conf: \"${INTERFACE}\"" validate_netif "${INTERFACE}" - if ! grep -q "${INTERFACE}" ${bastille_jailsdir}/${TARGET}/jail.conf; then - error_exit "Interface not found in jail.conf: \"${INTERFACE}\"" - else - remove_interface "${TARGET}" "${INTERFACE}" + remove_interface "${TARGET}" "${INTERFACE}" + if [ "${START}" -eq 1 ]; then + bastille start "${TARGET}" + fi + ;; + change) + validate_netif "${INTERFACE}" + check_interface_added "${TARGET}" "${INTERFACE}" || error_exit "Interface not found in jail.conf: \"${INTERFACE}\"" + if grep -qo "vnet;" "${bastille_jailsdir}/${TARGET}/jail.conf"; then + if [ -z "${IP}" ] || [ "${IP}" = "0.0.0.0" ]; then + IP="SYNCDHCP" + fi + validate_ip "${IP}" + change_ip "${TARGET}" "${INTERFACE}" "${IP}" if [ "${START}" -eq 1 ]; then bastille start "${TARGET}" fi - fi + else + error_notify "Error: Changing IP is not supported for non-VNET jails." + error_exit "Please use [add] to add an additional IP to a classic, non-VNET jail." + fi ;; *) - error_exit "Only [add|remove] are supported." + error_exit "Only [add|remove|change] are supported." ;; -esac - +esac \ No newline at end of file diff --git a/usr/local/share/bastille/pkg.sh b/usr/local/share/bastille/pkg.sh index 738c99f2e..72d5224d7 100644 --- a/usr/local/share/bastille/pkg.sh +++ b/usr/local/share/bastille/pkg.sh @@ -113,4 +113,4 @@ done if [ $errors -ne 0 ]; then error_exit "Failed to apply on some jails, please check logs" -fi +fi \ No newline at end of file diff --git a/usr/local/share/bastille/setup.sh b/usr/local/share/bastille/setup.sh index b069ea325..3b165f1ba 100644 --- a/usr/local/share/bastille/setup.sh +++ b/usr/local/share/bastille/setup.sh @@ -38,7 +38,7 @@ usage() { } # Check for too many args -if [ $# -gt 1 ]; then +if [ "$#" -gt 1 ]; then usage fi diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index 759d2fa1f..e51b1e6c5 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -53,27 +53,61 @@ set_target "${TARGET}" for _jail in ${JAILS}; do - info "[${_jail}]:" - + info "[${_jail}]:" check_target_is_stopped "${_jail}" || error_continue "Jail is already running." + + # Validate interfaces if [ "$(bastille config ${_jail} get vnet)" != 'enabled' ]; then - _interface="$(bastille config ${_jail} get interface)" - if ! ifconfig | grep "^${_interface}:" >/dev/null; then - error_notify "Error: ${_interface} interface does not exist." - continue + _ip4_interfaces="$(bastille config ${_jail} get ip4.addr | sed 's/,/ /g')" + _ip6_interfaces="$(bastille config ${_jail} get ip6.addr | sed 's/,/ /g')" + # IP4 + if [ "${_ip4_interfaces}" != "not set" ]; then + for _interface in ${_ip4_interfaces}; do + _interface="$(echo ${_interface} 2>/dev/null | awk -F"|" '{print $1}')" + if ! ifconfig | grep "^${_interface}:" >/dev/null; then + error_notify "Error: ${_interface} interface does not exist." + continue + fi + done + fi + # IP6 + if [ "${_ip6_interfaces}" != "not set" ]; then + for _interface in ${_ip6_interfaces}; do + _interface="$(echo ${_interface} 2>/dev/null | awk -F"|" '{print $1}')" + if ! ifconfig | grep "^${_interface}:" >/dev/null; then + error_notify "Error: ${_interface} interface does not exist." + continue + fi + done fi fi - # warn if matching configured (but not online) ip4.addr, ignore if there's no ip4.addr entry - _ip4="$(bastille config "${_jail}" get ip4.addr)" + # Validate and/or add IP to firewall table (in use or not in use) + _ip4="$(bastille config "${_jail}" get ip4.addr | sed 's/,/ /g')" + _ip6="$(bastille config "${_jail}" get ip6.addr | sed 's/,/ /g')" + # IP4 if [ "${_ip4}" != "not set" ]; then - if ifconfig | grep -wF "${_ip4}" >/dev/null; then - error_notify "Error: IP address (${_ip4}) already in use." - continue - else - ## add ip4.addr to firewall table - pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip4}" - fi + for _ip in ${_ip4}; do + _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" + if ifconfig | grep -wF "${_ip}" >/dev/null; then + error_notify "Error: IP address (${_ip}) already in use." + continue + else + pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip}" + fi + done + fi + # IP6 + if [ "${_ip6}" != "not set" ]; then + for _ip in ${_ip6}; do + _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" + if ifconfig | grep -wF "${_ip}" >/dev/null; then + error_notify "Error: IP address (${_ip}) already in use." + continue + else + pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip}" + fi + done fi # Start jail diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index 05a34e796..d6b04f1ab 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -54,17 +54,17 @@ set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" - check_target_is_running "${_jail}" || error_continue "Jail is already stopped." - # Capture ip4.addr address while still running - _ip4="$(bastille config ${_jail} get ip4.addr)" - # Check if pfctl is present - # Do not invoke pfctl if no ip4.addr found - if [ "${_ip4}" != "not set" ]; then - if which -s pfctl; then - if [ "$(bastille rdr ${_jail} list)" ]; then - bastille rdr "${_jail}" clear + # Remove RDR rules + if [ "$(bastille config ${_jail} get vnet)" != "enabled" ]; then + _ip4="$(bastille config ${_jail} get ip4.addr | sed 's/,/ /g')" + _ip6="$(bastille config ${_jail} get ip6.addr | sed 's/,/ /g')" + if [ "${_ip4}" != "not set" ] || [ "${_ip6}" != "not set" ]; then + if which -s pfctl; then + if [ "$(bastille rdr ${_jail} list)" ]; then + bastille rdr "${_jail}" clear + fi fi fi fi @@ -79,10 +79,17 @@ for _jail in ${JAILS}; do # Stop jail jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" - # Remove (captured above) ip4.addr from firewall table - if [ -n "${bastille_network_loopback}" ] && [ "${_ip4}" != "not set" ]; then - if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then - pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip4}" - fi + # Remove (captured above) ipX.addr from firewall table + if [ "${_ip4}" != "not set" ]; then + for _ip in ${_ip4}; do + _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" + pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" + done + fi + if [ "${_ip6}" != "not set" ]; then + for _ip in ${_ip6}; do + _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" + pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" + done fi -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/sysrc.sh b/usr/local/share/bastille/sysrc.sh index fd2032cc0..e0f4df92e 100644 --- a/usr/local/share/bastille/sysrc.sh +++ b/usr/local/share/bastille/sysrc.sh @@ -81,4 +81,4 @@ for _jail in ${JAILS}; do error_continue "Use [-f|--force] to force start the jail." fi jexec -l "${_jail}" /usr/sbin/sysrc "$@" -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/tags.sh b/usr/local/share/bastille/tags.sh index 1b2835884..89327206f 100644 --- a/usr/local/share/bastille/tags.sh +++ b/usr/local/share/bastille/tags.sh @@ -102,5 +102,4 @@ for _jail in ${JAILS}; do usage ;; esac -done - +done \ No newline at end of file diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 66af892dd..ad668e96b 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -335,7 +335,7 @@ for _jail in ${JAILS}; do # Escape single-quotes in the command being executed. -- cwells _args=$(echo "${_args}" | sed "s/'/'\\\\''/g") # Allow redirection within the jail. -- cwells - _args="sh -c \"${_args}\"" + _args="sh -c '${_args}'" ;; cp|copy) _cmd='cp' @@ -426,4 +426,4 @@ for _jail in ${JAILS}; do info "Template applied: ${TEMPLATE}" -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh index 669c11646..e31a6e6f4 100644 --- a/usr/local/share/bastille/top.sh +++ b/usr/local/share/bastille/top.sh @@ -78,4 +78,4 @@ else error_notify "Jail is not running." error_continue "Use [-f|--force] to force start the jail." fi -jexec -l "${TARGET}" /usr/bin/top +jexec -l "${TARGET}" /usr/bin/top \ No newline at end of file diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index ebbb52c5a..fdfb1a53a 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -85,4 +85,4 @@ for _jail in ${JAILS}; do echo "Unmounted: ${_jailpath}" -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 21a5be67a..e7a48ba88 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -123,4 +123,4 @@ case "${2}" in *) usage ;; -esac +esac \ No newline at end of file From 6e3d2079e3e7b01efbbd3f8d311b55f324eacc98 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Sat, 4 Jan 2025 16:33:36 -0700 Subject: [PATCH 114/120] update --- usr/local/share/bastille/clone.sh | 2 +- usr/local/share/bastille/common.sh | 6 +- usr/local/share/bastille/create.sh | 70 +++++++++++------ usr/local/share/bastille/network.sh | 118 +++++++++++----------------- 4 files changed, 97 insertions(+), 99 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 5ebe5754d..898a2e4b4 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -231,7 +231,7 @@ update_jailconf_vnet() { 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_${_if}_name|ifconfig_${uniq_epair}_name|" "${bastille_jail_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" diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 54b41dfa3..e67375a5e 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -204,7 +204,7 @@ generate_vnet_jail_netblock() { if [ "${_vnet_if_count}" -gt 0 ]; then for _num in $(seq 0 "${vnet_num_range}"); do if ! grep -Eosq "bastillle${_num}" ${bastille_jailsdir}/*/jail.conf; then - local uniq_epair="${_num}" + local uniq_epair="bastille${_num}" break fi done @@ -214,7 +214,7 @@ generate_vnet_jail_netblock() { fi ## If BRIDGE is enabled, generate bridge config, else generate VNET config if [ -n "${use_unique_bridge}" ]; then - if [ "${static_mac}" -eq 1 ]; then + if [ -n "${static_mac}" ]; then ## Generate bridged VNET config with static MAC address generate_static_mac "${jail_name}" "${external_interface}" cat <<-EOF @@ -241,7 +241,7 @@ EOF EOF fi else - if [ "${static_mac}" -eq 1 ]; then + if [ -n "${static_mac}" ]; then ## Generate VNET config with static MAC address generate_static_mac "${jail_name}" "${external_interface}" cat <<-EOF diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index 2c58a5295..92afc4d85 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -39,7 +39,7 @@ usage() { cat << EOF Options: - -M | --static-mac Generate a static MAC address for the jail. + -M | --static-mac Generate a static MAC address for the 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. @@ -70,20 +70,18 @@ validate_name() { } validate_ip() { - ipx_addr="ip4.addr" - ip="${1}" - ip6=$(echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)') - if [ -n "${ip6}" ]; then - info "Valid: (${ip6})." + _ip="${1}" + _ip6=$(echo "${_ip}" 2>/dev/null | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)') + if [ -n "${_ip6}" ]; then + info "Valid: (${_ip6})." ipx_addr="ip6.addr" - IP6_MODE="new" else - if [ "${ip}" = "DHCP" ] || [ "${ip}" = "inherit" ]; then - info "Valid: (${ip})." + if [ "${_ip}" = "DHCP" ] || [ "${_ip}" = "inherit" ] || [ "${_ip}" = "ip_hostname" ]; then + info "Valid: (${_ip})." else local IFS - if echo "${ip}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then - TEST_IP=$(echo "${ip}" | cut -d / -f1) + if echo "${_ip}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then + TEST_IP=$(echo "${_ip}" | cut -d / -f1) IFS=. set ${TEST_IP} for quad in 1 2 3 4; do @@ -95,13 +93,15 @@ validate_ip() { if ifconfig | grep -qwF "${TEST_IP}"; then warn "Warning: IP address already in use (${TEST_IP})." else - info "Valid: (${ip})." + ipx_addr="ip4.addr" + info "Valid: (${_ip})." fi else - error_exit "Invalid: (${ip})." + error_exit "Invalid: (${_ip})." fi fi fi + # Set interface value if [ ! -f "${bastille_jail_conf}" ]; then if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then local bastille_jail_conf_interface=${bastille_network_shared} @@ -113,17 +113,38 @@ validate_ip() { local bastille_jail_conf_interface=${INTERFACE} fi fi - if [ "${ip}" = "inherit" ]; then - IP4_DEFINITION="ip4 = ${ip};" - IP6_DEFINITION="ip6 = ${ip};" - IP6_MODE="new" - elif echo "${ip}" | grep -qvE '(SLAAC|DHCP|0[.]0[.]0[.]0)'; then - if [ "${ipx_addr}" = "ip4.addr" ]; then - IP4_ADDR="${ip}" - IP4_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${ip};" + # Determine IP/Interface mode + if [ "${_ip}" = "inherit" ]; then + if [ -n "${_ip6}" ]; then + IP4_DEFINITION="" + IP6_DEFINITION="ip6 = ${_ip};" + IP6_MODE="new" + else + IP4_DEFINITION="ip4 = ${_ip};" + IP6_DEFINITION="" + IP6_MODE="disable" + fi + elif [ "${_ip}" = "ip_hostname" ]; then + if [ -n "${_ip6}" ]; then + IP_HOSTNAME="${_ip}" + IP4_DEFINITION="" + IP6_DEFINITION="${IP_HOSTNAME};" + IP6_MODE="new" else - IP6_ADDR="${ip}" - IP6_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${ip};" + IP_HOSTNAME="${_ip}" + IP4_DEFINITION="${IP_HOSTNAME};" + IP6_DEFINITION="" + IP6_MODE="disable" + fi + elif echo "${_ip}" | grep -qvE '(SLAAC|DHCP|0[.]0[.]0[.]0)'; then + if [ "${ipx_addr}" = "ip4.addr" ]; then + IP4_ADDR="${_ip}" + IP4_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${_ip};" + IP6_MODE="disable" + elif [ "${ipx_addr}" = "ip6.addr" ]; then + IP6_ADDR="${_ip}" + IP6_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${_ip};" + IP6_MODE="new" fi fi } @@ -134,6 +155,7 @@ validate_ips() { IP6_DEFINITION="" IP4_ADDR="" IP6_ADDR="" + IP_HOSTNAME="" for ip in ${IP}; do validate_ip "${ip}" done @@ -627,7 +649,7 @@ THICK_JAIL="" CLONE_JAIL="" VNET_JAIL="" LINUX_JAIL="" -STATIC_MAC=0 +STATIC_MAC="" # Handle and parse options while [ $# -gt 0 ]; do diff --git a/usr/local/share/bastille/network.sh b/usr/local/share/bastille/network.sh index 0f9574124..3e6d793fc 100644 --- a/usr/local/share/bastille/network.sh +++ b/usr/local/share/bastille/network.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2024, Christer Edwards +# Copyright (c) 2018-2024, Victor Tschetter # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -84,8 +84,8 @@ while [ "$#" -gt 0 ]; do shift ;; -*) - for _o in $(echo ${1} 2>/dev/null | sed 's/-//g' | fold -w1); do - case ${_o} in + for _opt in $(echo ${1} 2>/dev/null | sed 's/-//g' | fold -w1); do + case ${_opt} in b|B) BRIDGE_VNET_JAIL=1 ;; c) CLASSIC_JAIL=1 ;; f) FORCE=1 ;; @@ -116,7 +116,7 @@ if [ "${ACTION}" = "add" ]; then error_notify "Error: Only one of [-b|-B|--bridge], [-c|--classic] or [-v|-V|--vnet] should be set." usage elif [ "${VNET_JAIL}" -eq 0 ] && [ "${BRIDGE_VNET_JAIL}" -eq 0 ] && [ "${CLASSIC_JAIL}" -eq 0 ]; then - error_notify "Error: [-c|--classic], [-b|-B|--bridge] or [-v|-V|--vnet] must be set." + error_notify "Error: [-b|-B|--bridge], [-c|--classic] or [-v|-V|--vnet] must be set." usage fi fi @@ -135,30 +135,34 @@ else fi validate_ip() { - IP6_ENABLE=0 + IP6="" local _ip="${1}" local _jail_config="${bastille_jailsdir}/${TARGET}/jail.conf" - if grep -Eqo ${_ip} ${_jail_config}; then - error_exit "Error: IP already present in jail.conf" - fi - local _ip6="$( echo "${_ip}" 2>/dev/null | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )" - if [ -n "${_ip6}" ]; then - info "Valid: (${_ip6})." - IP6_ENABLE=1 + if [ -z "${IP}" ] || [ "${IP}" = "0.0.0.0" ]; then + IP="SYNCDHCP" else - local IFS - if echo "${_ip}" 2>/dev/null | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then - TEST_IP=$(echo "${_ip}" | cut -d / -f1) - IFS=. - set ${TEST_IP} - for quad in 1 2 3 4; do - if eval [ \$$quad -gt 255 ]; then - error_exit "Invalid: (${TEST_IP})" - fi - done - info "Valid: (${_ip})." + if grep -Eqo ${_ip} ${_jail_config}; then + error_exit "Error: IP already present in jail.conf" + fi + local _ip6="$( echo "${_ip}" 2>/dev/null | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )" + if [ -n "${_ip6}" ]; then + info "Valid: (${_ip6})." + IP6="${_ip6}" else - error_exit "Invalid: (${_ip})." + local IFS + if echo "${_ip}" 2>/dev/null | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then + TEST_IP=$(echo "${_ip}" | cut -d / -f1) + IFS=. + set ${TEST_IP} + for quad in 1 2 3 4; do + if eval [ \$$quad -gt 255 ]; then + error_exit "Invalid: (${TEST_IP})" + fi + done + info "Valid: (${_ip})." + else + error_exit "Invalid: (${_ip})." + fi fi fi } @@ -187,38 +191,11 @@ change_ip() { local _jailname="${1}" local _if="${2}" local _ip="${3}" - local _type="${4}" local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" local _epair="$(grep -E ${_if} ${_jail_config} | grep -Eo -m 1 'epair[0-9]+|bastille[0-9]+')" local _jail_vnet="$(grep -E ${_epair} ${_jail_rc_config} | grep -Eo -m 1 'vnet[0-9]+')" - sysrc -f "${_jail_rc_config}" ifconfig_${_jail_vnet}=" inet ${IP} " -} - -test_change_ip() { - local _jailname="${1}" - local _if="${2}" - local _ip="${3}" - local _type="${4}" - local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" - if [ "${_type}" = "vnet" ]; then - local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" - local _epair="$(grep -E ${_if} ${_jail_config} | grep -Eo -m 1 'epair[0-9]+|bastille[0-9]+')" - local _jail_vnet="$(grep -E ${_epair} ${_jail_rc_config} | grep -Eo -m 1 'vnet[0-9]+')" - sysrc -f "${_jail_rc_config}" ifconfig_${_jail_vnet}=" inet ${IP} " - elif [ "${_type}" = "classic" ]; then - if [ "${IP6_ENABLE}" -eq 1 ]; then - local _ip6="$(bastille config ${_jailname} get ip6.addr | sed 's/,/ /g' | grep -F ${_if})" - if [ "${_ip6}" != "not set" ]; then - sed -i '' "s/${_if}|.*/${_if}|${_ip};/" "${_jail_config}" - fi - else - local _ip4="$(bastille config ${_jailname} get ip4.addr | sed 's/,/ /g' | grep -F ${_if})" - if [ "${_ip4}" != "not set" ]; then - sed -i '' "s/${_if}|.*/${_if}|${_ip};/" "${_jail_config}" - fi - fi - fi + sysrc -f "${_jail_rc_config}" ifconfig_${_jail_vnet}=" inet ${_ip} " } add_interface() { @@ -226,13 +203,15 @@ add_interface() { local _if="${2}" local _ip="${3}" local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" - local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" - 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 _vnet_if_count="$(grep -Eo 'vnet[1-9]+' ${_jail_rc_config} | sort -u | wc -l | awk '{print $1}')" - local _if_vnet="vnet$((_vnet_if_count + 1))" - local epair_num_range=$((_epair_if_count + 1)) - local bastille_num_range=$((_bastille_if_count + 1)) + if [ "${VNET_JAIL}" -eq 1 ] || [ "${BRIDGE_VNET_JAIL}" -eq 1 ]; then + local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" + 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 _vnet_if_count="$(grep -Eo 'vnet[1-9]+' ${_jail_rc_config} | sort -u | wc -l | awk '{print $1}')" + local _if_vnet="vnet$((_vnet_if_count + 1))" + local epair_num_range=$((_epair_if_count + 1)) + local bastille_num_range=$((_bastille_if_count + 1)) + fi if [ "${BRIDGE_VNET_JAIL}" -eq 1 ]; then for _num in $(seq 0 "${epair_num_range}"); do if ! grep -Eq "epair${_num}" "${bastille_jailsdir}"/*/jail.conf; then @@ -328,17 +307,18 @@ EOF echo "Added VNET interface: \"${_if}\"" elif [ "${CLASSIC_JAIL}" -eq 1 ]; then - if [ "${IP6_ENABLE}" -eq 1 ]; then + if [ -n "${IP6_ENABLE}" ]; then if [ "$(bastille config ${TARGET} get ip6)" = "disable" ]; then - error_exit "Error: IPv6 is not enabled for this jail." + error_notify "Error: IPv6 is not enabled for this jail." + error_exit "Enable it by setting \"ip6 = new;\" in jail.conf." else - sed -i '' "s/ip6.addr = .*/&\n ip6.addr += ${_if}|${_ip};/" ${_jail_config} + sed -i '' "s/ip6.addr = .*/&\n ip6.addr += ${_if}|${_ip};/" "${_jail_config}" fi else if [ "$(bastille config ${TARGET} get ip4)" = "disable" ]; then error_exit "Error: IPv4 is not enabled for this jail." else - sed -i '' "s/ip4.addr = .*/&\n ip4.addr += ${_if}|${_ip};/" ${_jail_config} + sed -i '' "s/ip4.addr = .*/&\n ip4.addr += ${_if}|${_ip};/" "${_jail_config}" fi fi fi @@ -405,12 +385,7 @@ remove_interface() { case "${ACTION}" in add) validate_netif "${INTERFACE}" - if [ -z "${IP}" ] || [ "${IP}" = "0.0.0.0" ]; then - IP="SYNCDHCP" - IP6_ENABLE=0 - else - validate_ip "${IP}" - fi + validate_ip "${IP}" if [ "${VNET_JAIL}" -eq 1 ]; then ! check_interface_added "${TARGET}" "${INTERFACE}" || error_exit "Interface is already added: \"${INTERFACE}\"" if ifconfig | grep "${INTERFACE}" | grep -q bridge; then @@ -434,8 +409,9 @@ case "${ACTION}" in elif [ "${CLASSIC_JAIL}" -eq 1 ]; then if [ "$(bastille config ${TARGET} get vnet)" != "not set" ]; then error_exit "Error: ${TARGET} is a VNET jail." - elif [ "$(bastille config ${TARGET} get ip4)" = "inherit" ] || [ "$(bastille config ${TARGET} get ip6)" = "inherit" ]; then - error_exit "Error: Jail IP mode is set to inherit." + elif [ "$(bastille config ${TARGET} get ip4)" = "inherit" ] || [ "$(bastille config ${TARGET} get ip6)" = "inherit" ] || \ + [ "$(bastille config ${TARGET} get ip4)" = "ip_hostname" ] || [ "$(bastille config ${TARGET} get ip6)" = "ip_hostname" ]; then + error_exit "Error: Jail IP mode must not [inherit|ip_hostname]." elif [ "${IP}" = "SYNCDHCP" ]; then error_exit "Error: Valid IP is required for non-VNET jails." else From 82f94a6bebb00ad1b75d6a2cb8303c29ad68b5ac Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 4 Jan 2025 17:03:52 -0700 Subject: [PATCH 115/120] Shellcheck 2034 disable --- usr/local/share/bastille/network.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/usr/local/share/bastille/network.sh b/usr/local/share/bastille/network.sh index 3e6d793fc..b894c2cd3 100644 --- a/usr/local/share/bastille/network.sh +++ b/usr/local/share/bastille/network.sh @@ -147,6 +147,7 @@ validate_ip() { local _ip6="$( echo "${_ip}" 2>/dev/null | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )" if [ -n "${_ip6}" ]; then info "Valid: (${_ip6})." + # shellcheck disable=SC2034 IP6="${_ip6}" else local IFS From 35ff2ec29e917a169ce4ba43864ce1f9d3ce9573 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Fri, 10 Jan 2025 13:42:53 -0700 Subject: [PATCH 116/120] new: add debug + code cleanup --- usr/local/bin/bastille | 1 + usr/local/share/bastille/bootstrap.sh | 61 +++++++++++- usr/local/share/bastille/clone.sh | 78 +++++++-------- usr/local/share/bastille/cmd.sh | 30 ++++-- usr/local/share/bastille/common.sh | 106 +++++++++++++++----- usr/local/share/bastille/config.sh | 8 +- usr/local/share/bastille/console.sh | 28 ++++-- usr/local/share/bastille/convert.sh | 28 ++++-- usr/local/share/bastille/cp.sh | 18 +++- usr/local/share/bastille/create.sh | 121 ++++++++--------------- usr/local/share/bastille/destroy.sh | 40 +++++--- usr/local/share/bastille/edit.sh | 15 ++- usr/local/share/bastille/etcupdate.sh | 134 +++++++++++++++++++------- usr/local/share/bastille/export.sh | 39 ++++---- usr/local/share/bastille/htop.sh | 30 ++++-- usr/local/share/bastille/import.sh | 83 ++++++++-------- usr/local/share/bastille/limits.sh | 47 ++++++--- usr/local/share/bastille/list.sh | 85 ++++++++++------ usr/local/share/bastille/mount.sh | 37 +++++-- usr/local/share/bastille/network.sh | 40 ++++---- usr/local/share/bastille/pkg.sh | 31 ++++-- usr/local/share/bastille/rcp.sh | 18 +++- usr/local/share/bastille/rdr.sh | 97 ++++++++++--------- usr/local/share/bastille/rename.sh | 47 +++++---- usr/local/share/bastille/service.sh | 32 ++++-- usr/local/share/bastille/setup.sh | 23 +++-- usr/local/share/bastille/start.sh | 62 ++++++++---- usr/local/share/bastille/stop.sh | 52 ++++++++-- usr/local/share/bastille/sysrc.sh | 28 ++++-- usr/local/share/bastille/tags.sh | 38 +++++--- usr/local/share/bastille/template.sh | 53 ++++++---- usr/local/share/bastille/top.sh | 26 +++-- usr/local/share/bastille/umount.sh | 33 +++++-- usr/local/share/bastille/update.sh | 33 +++++-- usr/local/share/bastille/upgrade.sh | 33 +++++-- usr/local/share/bastille/verify.sh | 44 ++++++--- usr/local/share/bastille/zfs.sh | 15 ++- 37 files changed, 1103 insertions(+), 591 deletions(-) diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index 1d1bec4bd..e24d06ad4 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -79,6 +79,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 container /etc directory to specified release. export Exports a specified container. help Help about any command. htop Interactive process viewer (requires htop). diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index 18890dcf7..3b02f8b7e 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -32,9 +32,48 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille bootstrap [RELEASE|TEMPLATE] [update|arch]" + error_notify "Usage: bastille bootstrap [option(s)] [RELEASE|TEMPLATE] [update|arch]" + cat << EOF + Options: + + -r | --repo Bootstrap multiple templates inside one repository. + -x | --debug Enable debug mode. + +EOF + exit 1 } +# Handle options. +MULTI_REPO=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -r|--repo) + MULTI_REPO=1 + shift + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + r) MULTI_REPO=1 ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift + ;; + *) + break + ;; + esac +done + validate_release_url() { ## check upstream url, else warn user if [ -n "${NAME_VERIFY}" ]; then @@ -389,8 +428,12 @@ bootstrap_template() { _url=${BASTILLE_TEMPLATE_URL} _user=${BASTILLE_TEMPLATE_USER} _repo=${BASTILLE_TEMPLATE_REPO%.*} # Remove the trailing ".git" - _template=${bastille_templatesdir}/${_user}/${_repo} - + if [ "${MULTI_REPO}" -eq 1 ]; then + _template=${bastille_templatesdir}/${_repo} + else + _template=${bastille_templatesdir}/${_user}/${_repo} + fi +set -x ## support for non-git if ! which -s git; then error_notify "Git not found." @@ -404,8 +447,15 @@ bootstrap_template() { error_notify "Template update unsuccessful." fi fi - - bastille verify "${_user}/${_repo}" + if [ "${MULTI_REPO}" -eq 1 ]; then + for _template_dir in $(ls ${_template}); do + if [ -f ${_template}/${_template_dir}/Bastillefile ]; then + bastille verify "${_repo}/${_template_dir}" + fi + done + else + bastille verify "${_user}/${_repo}" + fi } # Handle special-case commands first. @@ -549,6 +599,7 @@ case "${1}" in BASTILLE_TEMPLATE_URL=${1} BASTILLE_TEMPLATE_USER=$(echo "${1}" | awk -F / '{ print $4 }') BASTILLE_TEMPLATE_REPO=$(echo "${1}" | awk -F / '{ print $5 }') + BASTILLE_TEMPLATE_DIR=$(echo "${1}" | awk -F / '{ print $6 }') bootstrap_template ;; git@*:*/*) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 898a2e4b4..8bd791225 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -36,26 +36,27 @@ usage() { cat << EOF Options: - -l | --live -- Clone a running jail. ZFS only. - Jail must be running. - Cannot be used with [-f|--force]. - -f | --force -- Stop the jail if it is running. - Cannot be used with [-l|--live]. - -s | --start -- Start jail(s) when complete. + -f | --force Stop the jail if it is running. Cannot be used with [-l|--live]. + -l | --live Clone a running jail. ZFS only. Jail must be running. Cannot be used with [-f|--force]. + -s | --start Start jail(s) when complete. + -x | --debug Enable debug mode. EOF exit 1 } # Handle options. +AUTO=0 LIVE=0 -FORCE=0 -START=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; + -a|--auto) + AUTO=1 + shift + ;; -l|--live) if ! checkyesno bastille_zfs_enable; then error_exit "[-l|--live] can only be used with ZFS." @@ -64,20 +65,20 @@ while [ "$#" -gt 0 ]; do shift fi ;; - -f|--force) - if [ "${LIVE}" -eq 1 ]; then - error_exit "[-f|--force] cannot be used with [-l|--live]." - else - FORCE=1 - shift - fi - ;; - -s|--start) - START=1 + -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 ;; + l) LIVE=1 ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift ;; *) break @@ -85,6 +86,10 @@ while [ "$#" -gt 0 ]; do esac done +if [ "${AUTO}" -eq 1 ] && [ "${LIVE}" -eq 1 ]; then + error_exit "[-a|--auto] cannot be used with [-l|--live]" +fi + if [ $# -ne 3 ]; then usage fi @@ -153,7 +158,7 @@ update_jailconf() { # IP4 if [ "${_ip4}" != "not set" ]; then for _ip in ${_ip4}; do - _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" + _ip="$(echo ${_ip} | awk -F"|" '{print $2}')" sed -i '' "/${IPX_ADDR} = .*/ s/${_ip}/${IP}/" "${JAIL_CONFIG}" sed -i '' "/${IPX_ADDR} += .*/ s/${_ip}/127.0.0.1/" "${JAIL_CONFIG}" done @@ -161,7 +166,7 @@ update_jailconf() { # IP6 if [ "${_ip6}" != "not set" ]; then for _ip in ${_ip6}; do - _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" + _ip="$(echo ${_ip} | awk -F"|" '{print $2}')" sed -i '' "/${IPX_ADDR} = .*/ s/${_ip}/${IP}/" "${JAIL_CONFIG}" sed -i '' "/${IPX_ADDR} += .*/ s/${_ip}/127.0.0.1/" "${JAIL_CONFIG}" done @@ -178,19 +183,19 @@ update_jailconf_vnet() { 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=$((_vnet_if_count + 1)) - if echo ${_if} 2>/dev/null | grep -Eoq 'epair[0-9]+'; then + if echo ${_if} | grep -Eoq 'epair[0-9]+'; then # Update bridged VNET config for _num in $(seq 0 "${epair_num_range}"); do - if ! grep -Eoq "epair${_num}" ${bastille_jailsdir}/*/jail.conf; then + if ! grep -oq "epair${_num}" ${bastille_jailsdir}/*/jail.conf; then # Update jail.conf epair name local uniq_epair_bridge="${_num}" - local _if_epaira="$(grep "${_if}" ${JAIL_CONFIG} | grep -Eo -m 1 "epair[0-9]+a")" - local _if_epairb="$(grep "${_if}" ${JAIL_CONFIG} | grep -Eo -m 1 "epair[0-9]+b")" - local _if_vnet="$(grep ${_if_epairb} "${bastille_jail_rc_conf}" | grep -Eo -m 1 "vnet[0-9]+")" + local _if_epaira="$(grep "${_if}" ${JAIL_CONFIG} | grep -Eo -m 1 "epair[1-9]+a")" + local _if_epairb="$(grep "${_if}" ${JAIL_CONFIG} | grep -Eo -m 1 "epair[1-9]+b")" + local _if_vnet="$(grep ${_if_epairb} "${bastille_jail_rc_conf}" | grep -Eo -m 1 "vnet[1-9]+")" sed -i '' "s|${_if}|epair${uniq_epair_bridge}|g" "${JAIL_CONFIG}" # 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 - if grep -Eo "${_if}" ${JAIL_CONFIG} | grep -oq ether; then + if grep -oq ${_if} ${JAIL_CONFIG} | grep -oq ether; then local macaddr_prefix="$(cat ${JAIL_CONFIG} | grep ${_if} | 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}" @@ -212,17 +217,17 @@ update_jailconf_vnet() { break fi done - elif echo ${_if} 2>/dev/null | grep -Eoq 'bastille[0-9]+'; then + elif echo ${_if} | grep -Eoq 'bastille[0-9]+'; then # Update VNET config for _num in $(seq 0 "${bastille_num_range}"); do - if ! grep -Eoq "bastille${_num}" ${bastille_jailsdir}/*/jail.conf; then + 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}" # 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 - if grep -Eo ${_if} ${JAIL_CONFIG} | grep -oq ether; then + if grep -oq ${_if} ${JAIL_CONFIG} | grep -oq ether; then local macaddr_prefix="$(cat ${JAIL_CONFIG} | grep ${_if} | 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}" @@ -248,15 +253,6 @@ update_jailconf_vnet() { done } -update_fstab() { - # Update fstab to use the new name - FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab" - if [ -f "${FSTAB_CONFIG}" ]; then - # Update fstab paths with new jail path - sed -i '' "s|${bastille_jailsdir}/${TARGET}/root/|${bastille_jailsdir}/${NEWNAME}/root/|" "${FSTAB_CONFIG}" - fi -} - clone_jail() { info "Attempting to clone ${TARGET} to ${NEWNAME}..." @@ -302,7 +298,7 @@ clone_jail() { # Generate jail configuration files update_jailconf - update_fstab + update_fstab "${TARGET}" "${NEWNAME}" # Display the exist status if [ "$?" -ne 0 ]; then diff --git a/usr/local/share/bastille/cmd.sh b/usr/local/share/bastille/cmd.sh index 116bf28ad..7ecaa4009 100644 --- a/usr/local/share/bastille/cmd.sh +++ b/usr/local/share/bastille/cmd.sh @@ -32,29 +32,41 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille cmd TARGET command" + error_notify "Usage: bastille cmd [option(s)] TARGET command" 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 ;; - -*) - error_exit "Unknown option: \"${1}\"" + -x|--debug) + enable_debug + shift + ;; + -*) + 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 @@ -79,11 +91,11 @@ for _jail in ${JAILS}; do info "[${_jail}]:" - check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then + check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then bastille start "${_jail}" 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 COUNT=$(($COUNT+1)) diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index e67375a5e..187ca1d8d 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -47,6 +47,12 @@ enable_color() { . /usr/local/share/bastille/colors.pre.sh } +enable_debug() { + # Enable debug mode. + warn "***DEBUG MODE START***" + set -x +} + # If "NO_COLOR" environment variable is present, or we aren't speaking to a # tty, disable output colors. if [ -z "${NO_COLOR}" ] && [ -t 1 ]; then @@ -81,7 +87,8 @@ warn() { check_target_exists() { local _TARGET="${1}" - if [ ! -d "${bastille_jailsdir}"/"${_TARGET}" ]; then + local _jaillist="$(bastille list jails)" + if ! echo "${_jaillist}" | grep -Eq "^${_TARGET}$"; then return 1 else return 0 @@ -90,7 +97,7 @@ check_target_exists() { check_target_is_running() { local _TARGET="${1}" - if [ ! "$(/usr/sbin/jls name | awk "/^${_TARGET}$/")" ]; then + if ! jls name | grep -Eq "^${_TARGET}$"; then return 1 else return 0 @@ -99,43 +106,67 @@ check_target_is_running() { check_target_is_stopped() { local _TARGET="${1}" - if [ "$(/usr/sbin/jls name | awk "/^${_TARGET}$/")" ]; then + if jls name | grep -Eq "^${_TARGET}$"; then return 1 else return 0 fi } +get_jail_name() { + local _JID="${1}" + local _jailname="$(jls -j ${_JID} name 2>/dev/null)" + if [ -z "${_jailname}" ]; then + return 1 + else + echo "${_jailname}" + fi +} + jail_autocomplete() { local _TARGET="${1}" - # shellcheck disable=SC2010 - local _AUTOTARGET="$(grep -Eo "^${_TARGET}" "${bastille_jailsdir}" 2>/dev/null)" - if [ "$(echo "^${_AUTOTARGET}" 2>/dev/null | wc -l)" -eq 1 ]; then - return 0 + local _jaillist="$(bastille list jails)" + local _AUTOTARGET="$(echo "${_jaillist}" | grep -E "^${_TARGET}")" + if [ -n "${_AUTOTARGET}" ]; then + if [ "$(echo "${_AUTOTARGET}" | wc -l)" -eq 1 ]; then + echo "${_AUTOTARGET}" + else + error_continue "Multiple jails found for ${_TARGET}:\n${_AUTOTARGET}" + return 1 + fi else - error_continue "Multiple jails found for ${_TARGET}:\n${_AUTOTARGET}" - return 1 + return 2 fi } set_target() { local _TARGET=${1} - JAILS= + JAILS="" + TARGET="" if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then target_all_jails else for _jail in ${_TARGET}; do - jail_autocomplete "${_jail}" - check_target_exists "${_jail}" || error_continue "Jail not found \"${_jail}\"" + if [ ! -d "${bastille_jailsdir}/${_TARGET}" ] && echo "${_jail}" | grep -Eq '^[0-9]+$'; then + if get_jail_name "${_jail}" > /dev/null; then + _jail="$(get_jail_name ${_jail})" + else + error_continue "Error: JID \"${_jail}\" not found. Is jail running?" + fi + elif ! check_target_exists "${_jail}"; then + if jail_autocomplete "${_jail}" > /dev/null; then + _jail="$(jail_autocomplete ${_jail})" + elif [ $? -eq 2 ]; then + error_continue "Jail not found \"${_jail}\"" + else + exit 1 + fi + fi + TARGET="${TARGET} ${_jail}" JAILS="${JAILS} ${_jail}" done - fi - if [ "$(echo "${JAILS}" 2>/dev/null | wc -l)" -eq 1 ]; then - TARGET="${JAILS}" export TARGET export JAILS - else - export JAILS fi } @@ -143,14 +174,28 @@ set_target_single() { local _TARGET="${1}" if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then error_exit "[all|ALL] not supported with this command." - else - jail_autocomplete "${_TARGET}" - 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 [ ! -d "${bastille_jailsdir}/${_TARGET}" ] && 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() { @@ -164,6 +209,15 @@ target_all_jails() { export JAILS } +update_fstab() { + local _oldname="${1}" + local _newname="${2}" + local _fstab="${bastille_jailsdir}/${_newname}/fstab" + if [ -f "${_fstab}" ]; then + sed -i '' "s|${bastille_jailsdir}/${_oldname}/root/|${bastille_jailsdir}/${_newname}/root/|" "${_fstab}" + fi +} + generate_static_mac() { local jail_name="${1}" local external_interface="${2}" @@ -186,7 +240,7 @@ generate_vnet_jail_netblock() { ## iterate num and grep all jail configs ## define uniq_epair local _epair_if_count="$(grep -Eos 'epair[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')" - local _vnet_if_count="$(grep -Eos 'bastille[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')" + local _vnet_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 vnet_num_range=$((_vnet_if_count + 1)) if [ -n "${use_unique_bridge}" ]; then @@ -203,7 +257,7 @@ generate_vnet_jail_netblock() { else if [ "${_vnet_if_count}" -gt 0 ]; then for _num in $(seq 0 "${vnet_num_range}"); do - if ! grep -Eosq "bastillle${_num}" ${bastille_jailsdir}/*/jail.conf; then + if ! grep -Eosq "_bastille${_num}" ${bastille_jailsdir}/*/jail.conf; then local uniq_epair="bastille${_num}" break fi diff --git a/usr/local/share/bastille/config.sh b/usr/local/share/bastille/config.sh index 1c48e8639..6c72ac53b 100644 --- a/usr/local/share/bastille/config.sh +++ b/usr/local/share/bastille/config.sh @@ -42,7 +42,7 @@ help|-h|--help) ;; esac -if [ $# -lt 3 ] || [ $# -gt 4 ]; then +if [ "$#" -lt 3 ] || [ "$#" -gt 4 ]; then usage fi @@ -56,7 +56,7 @@ set_target "${TARGET}" case "${ACTION}" in get) - if [ $# -ne 1 ]; then + if [ "$#" -ne 1 ]; then error_notify 'Too many parameters for a "get" operation.' usage fi @@ -143,7 +143,7 @@ for _jail in ${JAILS}; do awk -F= -v line="${LINE}" -v property="${PROPERTY}" ' BEGIN { # build RE as string as we can not expand vars in RE literals - prop_re = "^[[:space:]]*" property "[[:space:]]*$"; + prop_re = "^[[:space:]]*" property "[[:space:]]*;?$"; } $1 ~ prop_re && !found { # we already have an entry in the config for this property so @@ -176,4 +176,4 @@ if [ "${ACTION}" = 'set' ]; then info "A restart is required for the changes to be applied. See 'bastille restart ${TARGET}'." fi -exit 0 +exit 0 \ No newline at end of file diff --git a/usr/local/share/bastille/console.sh b/usr/local/share/bastille/console.sh index 761b11d9a..ca40a1386 100644 --- a/usr/local/share/bastille/console.sh +++ b/usr/local/share/bastille/console.sh @@ -36,26 +36,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_notify "Unknown Option: \"${1}\"" - usage + 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,11 +83,11 @@ USER="${2}" bastille_root_check set_target_single "${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_exit "Use [-f|--force] to force start the jail." + error_exit "Use [-a|--auto] to auto-start the jail." fi validate_user() { @@ -110,6 +121,7 @@ LOGIN="$(jexec -l "${TARGET}" which login)" if [ -n "${USER}" ]; then validate_user else + check_fib LOGIN="$(jexec -l "${TARGET}" which login)" ${_setfib} jexec -l "${TARGET}" $LOGIN -f root fi \ No newline at end of file diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh index 04df66b80..6a720b8ce 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -37,25 +37,37 @@ usage() { cat << EOF Options: - -f | --force -- Stop the jail if it is running. + -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 ;; - -*) - error_exit "Unknown option: \"${1}\"" + -x|--debug) + enable_debug + shift + ;; + -*) + 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 @@ -71,11 +83,11 @@ TARGET="${1}" bastille_root_check set_target_single "${TARGET}" -check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then +check_target_is_stopped "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then bastille stop "${TARGET}" else error_notify "Jail is running." - error_exit "Use [-f|--force] to force stop the jail." + error_exit "Use [-a|--auto] to auto-stop the jail." fi convert_symlinks() { diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index aa3e68646..999718abc 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -36,7 +36,8 @@ usage() { cat << EOF Options: - -q | --quiet -- Suppress output. + -q | --quiet Suppress output. + -x | --debug Enable debug mode. EOF exit 1 @@ -53,8 +54,19 @@ while [ "$#" -gt 0 ]; do OPTION="-a" 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 + q) OPTION="-a" ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift ;; *) break @@ -79,4 +91,4 @@ for _jail in ${JAILS}; do if ! cp "${OPTION}" "${CPSOURCE}" "${bastille_jail_path}${CPDEST}"; then error_continue "CP failed: ${CPSOURCE} -> ${bastille_jail_path}${CPDEST}" fi -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index 92afc4d85..c9d85832f 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -39,7 +39,8 @@ usage() { cat << EOF Options: - -M | --static-mac Generate a static MAC address for the jail (VNET only). + -D | --dual Creates the jails with bot IPv4 and IPv6 networking ('inherit' and 'ip_hostname' only). + -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. @@ -51,14 +52,6 @@ EOF exit 1 } -running_jail() { - if [ -n "$(/usr/sbin/jls name | awk "/^${NAME}$/")" ]; then - error_exit "A running jail matches name." - elif [ -d "${bastille_jailsdir}/${NAME}" ]; then - error_exit "Jail: ${NAME} already created." - fi -} - validate_name() { local NAME_VERIFY=${NAME} local NAME_SANITY="$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')" @@ -71,12 +64,12 @@ validate_name() { validate_ip() { _ip="${1}" - _ip6=$(echo "${_ip}" 2>/dev/null | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)') + _ip6=$(echo "${_ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)') if [ -n "${_ip6}" ]; then info "Valid: (${_ip6})." ipx_addr="ip6.addr" else - if [ "${_ip}" = "DHCP" ] || [ "${_ip}" = "inherit" ] || [ "${_ip}" = "ip_hostname" ]; then + if [ "${_ip}" = "inherit" ] || [ "${_ip}" = "ip_hostname" ]; then info "Valid: (${_ip})." else local IFS @@ -86,8 +79,7 @@ validate_ip() { set ${TEST_IP} for quad in 1 2 3 4; do if eval [ \$$quad -gt 255 ]; then - echo "Invalid: (${TEST_IP})" - exit 1 + error_continue "Invalid: (${TEST_IP})" fi done if ifconfig | grep -qwF "${TEST_IP}"; then @@ -97,7 +89,7 @@ validate_ip() { info "Valid: (${_ip})." fi else - error_exit "Invalid: (${_ip})." + error_continue "Invalid: (${_ip})." fi fi fi @@ -115,8 +107,8 @@ validate_ip() { fi # Determine IP/Interface mode if [ "${_ip}" = "inherit" ]; then - if [ -n "${_ip6}" ]; then - IP4_DEFINITION="" + if [ -n "${DUAL_STACK}" ]; then + IP4_DEFINITION="ip4 = ${_ip};" IP6_DEFINITION="ip6 = ${_ip};" IP6_MODE="new" else @@ -125,9 +117,9 @@ validate_ip() { IP6_MODE="disable" fi elif [ "${_ip}" = "ip_hostname" ]; then - if [ -n "${_ip6}" ]; then + if [ -n "${DUAL_STACK}" ]; then IP_HOSTNAME="${_ip}" - IP4_DEFINITION="" + IP4_DEFINITION="${IP_HOSTNAME};" IP6_DEFINITION="${IP_HOSTNAME};" IP6_MODE="new" else @@ -138,13 +130,12 @@ validate_ip() { fi elif echo "${_ip}" | grep -qvE '(SLAAC|DHCP|0[.]0[.]0[.]0)'; then if [ "${ipx_addr}" = "ip4.addr" ]; then - IP4_ADDR="${_ip}" - IP4_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${_ip};" - IP6_MODE="disable" + IP4_ADDR="${_ip}" + IP4_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${_ip};" elif [ "${ipx_addr}" = "ip6.addr" ]; then - IP6_ADDR="${_ip}" - IP6_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${_ip};" - IP6_MODE="new" + IP6_ADDR="${_ip}" + IP6_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${_ip};" + IP6_MODE="new" fi fi } @@ -643,20 +634,23 @@ if echo "${3}" | grep '@'; then BASTILLE_JAIL_INTERFACES=$( echo "$3" | awk -F@ '{print $1}') fi -## reset this options +# Handle options. EMPTY_JAIL="" THICK_JAIL="" CLONE_JAIL="" VNET_JAIL="" LINUX_JAIL="" STATIC_MAC="" - -# Handle and parse options +DUAL_STACK="" while [ $# -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; + -D|--dual) + DUAL_STACK="1" + shift + ;; -M|--static-mac) STATIC_MAC="1" shift @@ -686,61 +680,30 @@ while [ $# -gt 0 ]; do CLONE_JAIL="1" shift ;; - -CV|-VC|--clone-vnet) - CLONE_JAIL="1" - VNET_JAIL="1" - shift - ;; - -CB|-BC|--clone-bridge) - CLONE_JAIL="1" - VNET_JAIL="1" - VNET_JAIL_BRIDGE="1" - shift - ;; - -TV|-VT|--thick-vnet) - THICK_JAIL="1" - VNET_JAIL="1" - shift - ;; - -TB|-BT|--thick-bridge) - THICK_JAIL="1" - VNET_JAIL="1" - VNET_JAIL_BRIDGE="1" - shift - ;; - -EB|-BE|--empty-bridge) - EMPTY_JAIL="1" - VNET_JAIL="1" - VNET_JAIL_BRIDGE="1" - shift - ;; - -EV|-VE|--empty-vnet) - EMPTY_JAIL="1" - VNET_JAIL="1" - shift - ;; - -LV|-VL|--linux-vnet) - LINUX_JAIL="1" - VNET_JAIL="1" - shift - ;; - -LB|-BL|--linux-bridge) - LINUX_JAIL="1" - VNET_JAIL="1" - VNET_JAIL_BRIDGE="1" + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + B) VNET_JAIL=1 VNET_JAIL_BRIDGE=1 ;; + C) CLONE_JAIL=1 ;; + D) DUAL_STACK=1 ;; + E) EMPTY_JAIL=1 ;; + L) LINUX_JAIL=1 ;; + M) STATIC_MAC=1 ;; + T) THICK_JAIL=1 ;; + V) VNET_JAIL=1 ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done shift ;; - -*) - error_notify "Unknown option: \"${1}\"" - usage - ;; *) break ;; esac done -## validate for combined options +# Validate options if [ -n "${EMPTY_JAIL}" ]; then if [ -n "${CLONE_JAIL}" ] || [ -n "${THICK_JAIL}" ] || [ -n "${VNET_JAIL}" ] || [ -n "${LINUX_JAIL}" ]; then error_exit "Error: Empty jail option can't be used with other options." @@ -919,11 +882,6 @@ else info "Creating empty jail: ${NAME}." fi -## check if a running jail matches name or already exist -if [ -n "${NAME}" ]; then - running_jail -fi - # May not exist on deployments created before Bastille 0.7.20200714, so creating it. -- cwells if [ ! -e "${bastille_templatesdir}/default" ]; then ln -s "${bastille_sharedir}/templates/default" "${bastille_templatesdir}/default" @@ -953,4 +911,7 @@ if [ -z ${bastille_template_vnet+x} ]; then bastille_template_vnet='default/vnet' fi -create_jail "${NAME}" "${RELEASE}" "${IP}" "${INTERFACE}" +if check_target_exists "${NAME}"; then + error_exit "Error: Existing jail found: ${NAME}" +fi +create_jail "${NAME}" "${RELEASE}" "${IP}" "${INTERFACE}" \ No newline at end of file diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index 101e102f1..83d3a59ed 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -36,24 +36,26 @@ usage() { cat << EOF Options: - -f | --force -- Stop the jail if it is running. + -a | --auto Auto mode. Start/stop jail(s) if required. + -f | --force Jails - Force unmount any mounted datasets (ZFS only). + Releases - Destroy cache as well as release. + -x | --debug Enable debug mode. EOF exit 1 } - destroy_jail() { local TARGET="${1}" local OPTIONS bastille_jail_base="${bastille_jailsdir}/${TARGET}" ## dir bastille_jail_log="${bastille_logsdir}/${TARGET}_console.log" ## file - check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then + check_target_is_stopped "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then bastille stop "${TARGET}" else error_notify "Jail is running." - error_exit "Use [-f|--force] to force stop the jail." + error_exit "Use [-a|--auto] to auto-stop the jail." fi if [ -d "${bastille_jail_base}" ]; then @@ -190,19 +192,35 @@ destroy_rel() { } # Handle options. +AUTO=0 FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in - -h|--help|help) - usage + -h|--help|help) + usage + ;; + -a|--auto) + AUTO=1 + shift + ;; + -f|--force) + FORCE=1 + shift ;; - -f|--force|force) - FORCE="1" + -x|--debug) + enable_debug shift ;; - -*) - error_exit "Unknown Option: \"${1}\"" - usage + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + a) AUTO=1 ;; + f) FORCE=1 ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift ;; *) break diff --git a/usr/local/share/bastille/edit.sh b/usr/local/share/bastille/edit.sh index 992dd9c59..0512a3fff 100644 --- a/usr/local/share/bastille/edit.sh +++ b/usr/local/share/bastille/edit.sh @@ -32,7 +32,14 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille edit [option(s)] TARGET [filename]" + error_notify "Usage: bastille edit [option(s)] TARGET [filename]" + cat << EOF + Options: + + -x | --debug Enable debug mode. + +EOF + exit 1 } # Handle options. @@ -41,6 +48,10 @@ while [ "$#" -gt 0 ]; do -h|--help|help) usage ;; + -x|--debug) + enable_debug + shift + ;; -*) error_notify "Unknown Option: \"${1}\"" usage @@ -69,4 +80,4 @@ if [ -z "${EDITOR}" ]; then EDITOR=nano fi -"${EDITOR}" "${bastille_jailsdir}/${TARGET}/${TARGET_FILENAME}" +"${EDITOR}" "${bastille_jailsdir}/${TARGET}/${TARGET_FILENAME}" \ No newline at end of file diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh index f0d1100f6..b98ff6e3a 100644 --- a/usr/local/share/bastille/etcupdate.sh +++ b/usr/local/share/bastille/etcupdate.sh @@ -31,11 +31,13 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille etcupdate [option(s)] [TARGET|bootstrap] RELEASE" + 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 @@ -46,60 +48,108 @@ bootstrap_etc_release() { 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}"; then - error_notify "Failed to bootstrap etcupdate \"${_release}\"" + 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 - sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives="${_current}" 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}\"" + 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}\"" - exit 0 + info "Etcupdate release has already been prepared for application: ${_release}" fi } +diff_review() { + local _jail="${1}" + info "[${_jail}]: etcupdate --diff mode" + etcupdate diff -D "${bastille_jailsdir}/${_jail}/root" +} + +resolve_conflicts() { + local _jail="${1}" + 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]: --dry-run" - etcupdate -n -D "${bastille_jailsdir}"/"${_jail}"/root -t ${bastille_cachedir}/${_release}.tbz2 + info "[${_jail}]: etcupdate update --dry-run" + etcupdate -n -D "${bastille_jailsdir}/${_jail}/root" -t ${bastille_cachedir}/${_release}.tbz2 else - info "[_jail]:" - etcupdate -D "${bastille_jailsdir}"/"${_jail}"/root -t ${bastille_cachedir}/${_release}.tbz2 + info "[${_jail}]: etcupdate update" + etcupdate -D "${bastille_jailsdir}/${_jail}/root" -t ${bastille_cachedir}/${_release}.tbz2 fi } -if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then - usage -fi - # Handle options. +DRY_RUN=0 +FORCE=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; -d|--dry-run) - if [ -z "${2}" ] || [ -z "${3}" ]; then - usage - else - DRY_RUN=1 - shift - fi + DRY_RUN=1 + shift + ;; + -f|--force) + FORCE=1 + shift ;; - -*) - error_exit "Unknown option: \"${1}\"" + -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 @@ -111,17 +161,31 @@ while [ "$#" -gt 0 ]; do fi ;; *) - if [ -z "${2}" ]; then - usage - else - TARGET="${1}" - RELEASE="${2}" - fi - if [ -z "${DRY_RUN}" ]; then - DRY_RUN=0 - fi - update_jail_etc "${TARGET}" "${RELEASE}" - shift "$#" + 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 +done \ No newline at end of file diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index acc1b1470..0041773ea 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -36,17 +36,18 @@ usage() { # Valid compress/options for ZFS systems are raw, .gz, .tgz, .txz and .xz # Valid compress/options for non ZFS configured systems are .tgz and .txz # If no compression option specified, user must redirect standard output - error_notify "Usage: bastille export | option(s) | TARGET | PATH" + error_notify "Usage: bastille export [option(s)] TARGET PATH" cat << EOF Options: - --gz -- Export a ZFS jail using GZIP(.gz) compressed image. - -r | --raw -- Export a ZFS jail to an uncompressed RAW image. - -s | --safe -- Safely stop and start a ZFS jail before the exporting process. - --tgz -- Export a jail using simple .tgz compressed archive instead. - --txz -- Export a jail using simple .txz compressed archive instead. - -v | --verbose -- Be more verbose during the ZFS send operation. - --xz -- Export a ZFS jail using XZ(.xz) compressed image. + --gz Export a ZFS jail using GZIP(.gz) compressed image. + -r | --raw Export a ZFS jail to an uncompressed RAW image. + -s | --safe Safely stop and start a ZFS jail before the exporting process. + --tgz Export a jail using simple .tgz compressed archive instead. + --txz Export a jail using simple .txz compressed archive instead. + -v | --verbose Be more verbose during the ZFS send operation. + --xz Export a ZFS jail using XZ(.xz) compressed image. + -x | --debug Enable debug mode. Note: If no export option specified, the container should be redirected to standard output. @@ -54,13 +55,6 @@ EOF exit 1 } -# Handle special-case commands first -case "$1" in - help|-h|--help) - usage - ;; -esac - if [ $# -gt 5 ] || [ $# -lt 1 ]; then usage fi @@ -85,7 +79,7 @@ if [ -n "${bastille_export_options}" ]; then DEFAULT_EXPORT_OPTS="${bastille_export_options}" info "Default export option(s): '${DEFAULT_EXPORT_OPTS}'" - + # Handle default options. for opt in ${DEFAULT_EXPORT_OPTS}; do case "${opt}" in --gz) @@ -121,9 +115,12 @@ if [ -n "${bastille_export_options}" ]; then esac done else - # Handle and parse option args + # Handle options. while [ $# -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; --gz) GZIP_EXPORT="1" TARGET="${2}" @@ -166,8 +163,12 @@ else TARGET="${2}" shift ;; + -x|--debug) + enable_debug + shift + ;; -*) - error_notify "Unknown Option." + error_notify "Unknown Option: \"${1}\"" usage ;; *) @@ -385,4 +386,4 @@ if [ -n "${TARGET}" ]; then fi fi jail_export -fi +fi \ No newline at end of file diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh index 10795da15..5b7fdc815 100644 --- a/usr/local/share/bastille/htop.sh +++ b/usr/local/share/bastille/htop.sh @@ -32,29 +32,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,11 +84,11 @@ 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" @@ -84,4 +96,4 @@ if [ ! -x "${bastille_jail_path}/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 -fi +fi \ No newline at end of file diff --git a/usr/local/share/bastille/import.sh b/usr/local/share/bastille/import.sh index 604b210fd..2271fa8c6 100644 --- a/usr/local/share/bastille/import.sh +++ b/usr/local/share/bastille/import.sh @@ -38,8 +38,9 @@ usage() { cat << EOF Options: - -f | --force -- Force an archive import regardless if the checksum file does not match or missing. - -v | --verbose -- Be more verbose during the ZFS receive operation. + -f | --force Force an archive import regardless if the checksum file does not match or missing. + -v | --verbose Be more verbose during the ZFS receive operation. + -x | --debug Enable debug mode. Tip: If no option specified, container should be imported from standard input. @@ -47,50 +48,52 @@ EOF exit 1 } -# Handle special-case commands first -case "${1}" in - help|-h|--help) - usage - ;; -esac - -if [ $# -gt 3 ] || [ $# -lt 1 ]; then - usage -fi - -TARGET="${1}" -OPT_FORCE= +# Handle options. +FORCE=0 +ZRECV="-u" USER_IMPORT= -OPT_ZRECV="-u" - -bastille_root_check - -# Handle and parse option args -while [ $# -gt 0 ]; do +while [ "$#" -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; -f|--force) - OPT_FORCE="1" - TARGET="${2}" + FORCE="1" shift ;; -v|--verbose) - OPT_ZRECV="-u -v" - TARGET="${2}" + ZRECV="-u -v" shift ;; - -*) - error_notify "Unknown Option." - usage + -x|--debug) + enable_debug + shift ;; - *) - if [ $# -gt 1 ] || [ $# -lt 1 ]; then - usage - fi + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + f) FORCE=1 ;; + v) ZRECV="-u -v" + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done shift ;; + *) + break + ;; esac done +if [ $# -gt 3 ] || [ $# -lt 1 ]; then + usage +fi + +TARGET="${1}" + +bastille_root_check + # Fallback to default if missing config parameters if [ -z "${bastille_decompress_xz_options}" ]; then bastille_decompress_xz_options="-c -d -v" @@ -114,7 +117,7 @@ validate_archive() { fi else # Check if user opt to force import - if [ -n "${OPT_FORCE}" ]; then + if [ -n "${FORCE}" ]; then warn "Warning: Skipping archive validation!" else error_exit "Checksum file not found. See 'bastille import [option(s)] FILE'." @@ -417,7 +420,7 @@ jail_import() { info "Importing '${TARGET_TRIM}' from compressed ${FILE_EXT} image." info "Receiving ZFS data stream..." xz ${bastille_decompress_xz_options} "${bastille_backupsdir}/${TARGET}" | \ - zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" + zfs receive ${ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" # Update ZFS mountpoint property if required update_zfsmount @@ -427,7 +430,7 @@ jail_import() { info "Importing '${TARGET_TRIM}' from compressed ${FILE_EXT} image." info "Receiving ZFS data stream..." gzip ${bastille_decompress_gz_options} "${bastille_backupsdir}/${TARGET}" | \ - zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" + zfs receive ${ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" # Update ZFS mountpoint property if required update_zfsmount @@ -470,9 +473,9 @@ jail_import() { rm -f "${FILE_TRIM}" "${FILE_TRIM}_root" fi info "Receiving ZFS data stream..." - zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" < "${FILE_TRIM}" + zfs receive ${ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" < "${FILE_TRIM}" zfs set ${ZFS_OPTIONS} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" - zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" < "${FILE_TRIM}_root" + zfs receive ${ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" < "${FILE_TRIM}_root" # Update ZFS mountpoint property if required update_zfsmount @@ -527,14 +530,14 @@ jail_import() { # Import from uncompressed image file info "Importing '${TARGET_TRIM}' from uncompressed image archive." info "Receiving ZFS data stream..." - zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" < "${bastille_backupsdir}/${TARGET}" + zfs receive ${ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" < "${bastille_backupsdir}/${TARGET}" # Update ZFS mountpoint property if required update_zfsmount else # Based on the file name, looks like we are importing from previous redirected bastille image # Quietly import from previous redirected bastille image - if ! zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}"; then + if ! zfs receive ${ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}"; then exit 1 else # Update ZFS mountpoint property if required @@ -636,4 +639,4 @@ fi if [ -n "${TARGET}" ]; then jail_import -fi +fi \ No newline at end of file diff --git a/usr/local/share/bastille/limits.sh b/usr/local/share/bastille/limits.sh index 14627a080..2f9fe38a3 100644 --- a/usr/local/share/bastille/limits.sh +++ b/usr/local/share/bastille/limits.sh @@ -38,18 +38,43 @@ 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 special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac +# Handle options. +AUTO=0 +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -a|--auto) + AUTO=1 + shift + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + 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 + ;; + esac +done if [ $# -ne 3 ]; then usage @@ -58,7 +83,7 @@ fi TARGET="${1}" OPTION="${2}" VALUE="${3}" -RACCT_ENABLE=$(sysctl -n kern.racct.enable) +RACCT_ENABLE="$(sysctl -n kern.racct.enable)" if [ "${RACCT_ENABLE}" != '1' ]; then error_exit "Racct not enabled. Append 'kern.racct.enable=1' to /boot/loader.conf and reboot" fi @@ -70,11 +95,11 @@ for _jail in ${JAILS}; do info "[${_jail}]:" - check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then + check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then bastille start "${_jail}" 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 _rctl_rule="jail:${_jail}:${OPTION}:deny=${VALUE}/jail" @@ -93,4 +118,4 @@ for _jail in ${JAILS}; do echo -e "${OPTION} ${VALUE}" rctl -a "${_rctl_rule}" "${_rctl_rule_log}" -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 02be47dbb..a326b54eb 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -32,7 +32,14 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille list [-j|-a] [release [-p]|template|(jail|container)|log|limit|(import|export|backup)]" + error_notify "Usage: bastille list [option(s)] [-j|-a] [release [-p]|template|(jail|container)|log|limit|(import|export|backup)]" + cat << EOF + Options: + + -x | --debug Enable debug mode. + +EOF + exit 1 } bastille_root_check @@ -41,11 +48,6 @@ if [ "$#" -eq 0 ]; then /usr/sbin/jls fi -if [ "${1}" = "-j" ]; then - /usr/sbin/jls -N --libxo json - exit 0 -fi - TARGET= list_all(){ @@ -55,29 +57,30 @@ list_all(){ MAX_LENGTH_JAIL_NAME=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h -m 1 -e "^.* {$" | awk '{ print length($1) }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_NAME=${MAX_LENGTH_JAIL_NAME:-3} if [ "${MAX_LENGTH_JAIL_NAME}" -lt 3 ]; then MAX_LENGTH_JAIL_NAME=3; fi - 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_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 -hs "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=$(find ${bastille_jailsdir}/*/jail.conf -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -l "vnet;" | grep -hs "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 - MAX_LENGTH_JAIL_HOSTNAME=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h -m 1 -e "^[ ]*host.hostname[ ]*=[ ]*\(.*\);" | awk '{ print length(substr($3, 1, length($3)-1)) }' | sort -nr | head -n 1) + MAX_LENGTH_JAIL_HOSTNAME=$(find ${bastille_jailsdir}/*/jail.conf -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h -m 1 -e "^[ ]*host.hostname[ ]*=[ ]*\(.*\);" | awk '{ print length(substr($3, 1, length($3)-1)) }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_HOSTNAME=${MAX_LENGTH_JAIL_HOSTNAME:-8} if [ "${MAX_LENGTH_JAIL_HOSTNAME}" -lt 8 ]; then MAX_LENGTH_JAIL_HOSTNAME=8; fi - MAX_LENGTH_JAIL_PORTS=$(find ""${bastille_jailsdir}/*/rdr.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 -n1 awk '{ lines++; chars += length($0)} END { chars += lines - 1; print chars }' | sort -nr | head -n 1) + MAX_LENGTH_JAIL_PORTS=$(find ${bastille_jailsdir}/*/rdr.conf -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 -n1 awk '{ lines++; chars += length($0)} END { chars += lines - 1; print chars }' | sort -nr | head -n 1) 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 -hEs "^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=$(find ${bastille_jailsdir}/*/fstab -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/releases/.*/root/.bastille.*nullfs" | grep -hEs "^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 -hEs "^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 -hEs "^NAME=|^VERSION_ID=|^VERSION_CODENAME=" "$(sed -n "s/^linprocfs *\(.*\)\/.*$/\1\/etc\/os-release/p")" | 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=$(find ${bastille_jailsdir}/*/fstab -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/jails/.*/root/proc.*linprocfs" | grep -hEs "^NAME=|^VERSION_ID=|^VERSION_CODENAME=" "$(sed -n "s/^linprocfs *\(.*\)\/.*$/\1\/etc\/os-release/p")" | 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 if [ "${MAX_LENGTH_JAIL_RELEASE}" -lt 7 ]; then MAX_LENGTH_JAIL_RELEASE=7; fi - printf " JID%*sState%*sIP Address%*sPublished Ports%*sHostname%*sRelease%*sPath\n" "$((${MAX_LENGTH_JAIL_NAME} + ${SPACER} - 3))" "" "$((${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} + ${SPACER} - 10))" "" "$((${MAX_LENGTH_JAIL_PORTS} + ${SPACER} - 15))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} + ${SPACER} - 8))" "" "$((${MAX_LENGTH_JAIL_RELEASE} + ${SPACER} - 7))" "" + printf " JID%*sState%*sIP Address%*sPublished Ports%*sHostname%*sRelease%*sPath\n" "$((${MAX_LENGTH_JID} + ${SPACER} - 3))" "" "$((${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} + ${SPACER} - 10))" "" "$((${MAX_LENGTH_JAIL_PORTS} + ${SPACER} - 15))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} + ${SPACER} - 8))" "" "$((${MAX_LENGTH_JAIL_RELEASE} + ${SPACER} - 7))" "" if [ -n "${TARGET}" ]; then # Query all info for a specific jail. JAIL_LIST="${TARGET}" @@ -88,6 +91,7 @@ list_all(){ for _JAIL in ${JAIL_LIST}; do if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then JAIL_NAME=$(grep -h -m 1 -e "^.* {$" "${bastille_jailsdir}/${_JAIL}/jail.conf" 2> /dev/null | awk '{ print $1 }') + JID="$(jls -j ${_JAIL} jid 2>/dev/null)" IS_FREEBSD_JAIL=0 if [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/bin/freebsd-version" ] || [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/.bastille/bin/freebsd-version" ] || [ "$(grep -c "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_FREEBSD_JAIL=1; fi IS_FREEBSD_JAIL=${IS_FREEBSD_JAIL:-0} @@ -115,12 +119,12 @@ list_all(){ else JAIL_STATE=$(if [ "$(sed -n "/^${JAIL_NAME} {$/,/^}$/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | awk '$0 ~ /^'${JAIL_NAME}' \{|\}/ { printf "%s",$0 }')" = "${JAIL_NAME} {}" ]; then echo "Down"; else echo "n/a"; fi) if [ "$(awk '$1 == "vnet;" { print $1 }' "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)" ]; then - JAIL_IP=$(sed -n 's/^ifconfig_vnet0="\(.*\)"$/\1/p' "${bastille_jailsdir}/${JAIL_NAME}/root/etc/rc.conf" 2> /dev/null | sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print $2; else print $1 }') + JAIL_IP=$(sed -n 's/^ifconfig_vnet0="\(.*\)"$/\1/p' "${bastille_jailsdir}/${JAIL_NAME}/root/etc/rc.conf" 2> /dev/null | sed "s/\// /g" | awk -F"|" '{print $2}' | awk '{ if ($1 ~ /^[inet|inet6]/) print $2; else print $1 }') else - JAIL_IP=$(sed -n "s/^[ ]*ip[4,6].addr[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | sed "s/\// /g" | awk '{ print $1 }') + JAIL_IP=$(sed -n "s/^[ ]*ip[4,6].addr[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | sed "s/\// /g" | awk -F"|" '{print $2}' | awk '{ print $1 }') fi JAIL_HOSTNAME=$(sed -n "s/^[ ]*host.hostname[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null) - if [ -f "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" ]; then JAIL_PORTS=$(awk '$1 ~ /^[tcp|udp]/ { printf "%s/%s:%s,",$1,$2,$3 }' "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" 2> /dev/null | sed "s/,$//"); else JAIL_PORTS=""; fi + if [ -f "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" ]; then JAIL_PORTS=$(awk '$0 ~ /(tcp|udp)/ { printf "%s/%s:%s,",$5,$6,$7 }' "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" 2> /dev/null | sed "s/,$//"); else JAIL_PORTS=""; fi JAIL_PATH=$(sed -n "s/^[ ]*path[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null) if [ "${JAIL_PATH}" ]; then if [ "${IS_FREEBSD_JAIL}" -eq 1 ]; then @@ -140,13 +144,14 @@ list_all(){ if [ "${#JAIL_PORTS}" -gt "${MAX_LENGTH_JAIL_PORTS}" ]; then JAIL_PORTS="$(echo ${JAIL_PORTS} | cut -c-$((${MAX_LENGTH_JAIL_PORTS} - 3)))..."; fi JAIL_NAME=${JAIL_NAME:-${DEFAULT_VALUE}} + JID=${JID:-${DEFAULT_VALUE}} JAIL_STATE=${JAIL_STATE:-${DEFAULT_VALUE}} JAIL_IP=${JAIL_IP:-${DEFAULT_VALUE}} JAIL_PORTS=${JAIL_PORTS:-${DEFAULT_VALUE}} JAIL_HOSTNAME=${JAIL_HOSTNAME:-${DEFAULT_VALUE}} JAIL_RELEASE=${JAIL_RELEASE:-${DEFAULT_VALUE}} JAIL_PATH=${JAIL_PATH:-${DEFAULT_VALUE}} - printf " ${JAIL_NAME}%*s${JAIL_STATE}%*s${JAIL_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JAIL_NAME} - ${#JAIL_NAME} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#JAIL_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" "" + printf " ${JID}%*s${JAIL_STATE}%*s${JAIL_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JID} - ${#JID} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#JAIL_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" "" fi done else @@ -205,25 +210,46 @@ list_import(){ list_ports() { if [ -d "${bastille_jailsdir}" ]; then - JAIL_LIST="$(ls "${bastille_jailsdir}" | sed "s/\n//g")" - for _JAIL in ${JAIL_LIST}; do - if [ -f "${bastille_jailsdir}/${_JAIL}/rdr.conf" ]; then - _PORTS="$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf)" - info "[$_JAIL]:" - echo "${_PORTS}" + JAIL_LIST="$(bastille list jails)" + for _jail in ${JAIL_LIST}; do + if [ -f "${bastille_jailsdir}/${_jail}/rdr.conf" ]; then + _ports="$(cat ${bastille_jailsdir}/${_jail}/rdr.conf)" + info "[$_jail]:" + echo "${_ports}" fi done fi } -if [ "$#" -gt 0 ]; then +# Handle options. +while [ "$#" -gt 0 ]; do case "${1}" in - -h|--help|help) - usage - ;; - all|-a|--all) + -h|--help|help) + usage + ;; + -a|--all|all) list_all + exit 0 + ;; + -j|--json) + /usr/sbin/jls -N --libxo json + exit 0 + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break ;; + esac +done + +if [ "$#" -gt 0 ]; then + case "${1}" in port|ports) list_ports ;; @@ -246,9 +272,6 @@ if [ "$#" -gt 0 ]; then list_import exit 0 ;; - -*) - error_exit "Unknown option: \"${1}\"" - ;; *) # Check if we want to query all info for a specific jail instead. if [ -f "${bastille_jailsdir}/${1}/jail.conf" ]; then diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index f16b1edc3..3f11afedc 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -32,17 +32,36 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille mount TARGET HOST_PATH JAIL_PATH [filesystem_type options dump pass_number]" -} + error_notify "Usage: bastille mount TARGET HOST_PATH JAIL_PATH [filesystem_type options dump pass_number]" + cat << EOF + Options: + + -x | --debug Enable debug mode. -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac +EOF + exit 1 +} -if [ "$#" -lt 3 ] || [ "$#" -gt 6 ]; then +# Handle options. +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done + +if [ "$#" -lt 3 ] || [ "$#" -gt 7 ]; then usage fi diff --git a/usr/local/share/bastille/network.sh b/usr/local/share/bastille/network.sh index b894c2cd3..d2abe53c2 100644 --- a/usr/local/share/bastille/network.sh +++ b/usr/local/share/bastille/network.sh @@ -36,29 +36,33 @@ usage() { cat << EOF Options: + -a | --auto Auto mode. Start/stop jail(s) if required. -b | --bridge Add a bridged VNET interface to an existing VNET jail. -c | --classic Add an interface to a classic (non-VNET) jail. - -f | --force Stop the jail if it is running. -m | --static-mac Generate a static MAC address for the VNET interface. -s | --start Start jail on completion. -v | --vnet Add a VNET interface to an existing VNET jail. + -x | --debug Enable debug mode. EOF exit 1 } # Handle options. +AUTO=0 BRIDGE_VNET_JAIL=0 CLASSIC_JAIL=0 -FORCE=0 STATIC_MAC=0 -START=0 VNET_JAIL=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; + -a|--auto) + AUTO=1 + shift + ;; -b|-B|--bridge) BRIDGE_VNET_JAIL=1 shift @@ -66,32 +70,28 @@ while [ "$#" -gt 0 ]; do -c|--classic) CLASSIC_JAIL=1 shift - ;; - -f|--force) - FORCE=1 - shift ;; -m|-M|--static-mac) STATIC_MAC=1 shift ;; - -s|--start) - START=1 - shift - ;; -v|-V|--vnet) VNET_JAIL=1 shift ;; + -x|--debug) + enable_debug + shift + ;; -*) for _opt in $(echo ${1} 2>/dev/null | sed 's/-//g' | fold -w1); do case ${_opt} in + a) FORCE=1 ;; b|B) BRIDGE_VNET_JAIL=1 ;; - c) CLASSIC_JAIL=1 ;; - f) FORCE=1 ;; + c|C) CLASSIC_JAIL=1 ;; m|M) STATIC_MAC=1 ;; - s) START=1 ;; v|V) VNET_JAIL=1 ;; + x) enable_debug ;; *) error_exit "Unknown Option: \"${1}\"" ;; esac done @@ -102,7 +102,6 @@ while [ "$#" -gt 0 ]; do ;; esac done -set -x TARGET="${1}" ACTION="${2}" @@ -127,11 +126,11 @@ fi bastille_root_check set_target_single "${TARGET}" -check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then +check_target_is_stopped "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then bastille stop "${TARGET}" else error_notify "Jail is running." - error_exit "Use [-f|--force] to force stop the jail." + error_exit "Use [-a|--auto] to auto-stop the jail." fi validate_ip() { @@ -147,7 +146,6 @@ validate_ip() { local _ip6="$( echo "${_ip}" 2>/dev/null | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )" if [ -n "${_ip6}" ]; then info "Valid: (${_ip6})." - # shellcheck disable=SC2034 IP6="${_ip6}" else local IFS @@ -417,7 +415,7 @@ case "${ACTION}" in error_exit "Error: Valid IP is required for non-VNET jails." else add_interface "${TARGET}" "${INTERFACE}" "${IP}" - if [ "${START}" -eq 1 ]; then + if [ "${AUTO}" -eq 1 ]; then bastille start "${TARGET}" fi fi @@ -427,7 +425,7 @@ case "${ACTION}" in check_interface_added "${TARGET}" "${INTERFACE}" || error_exit "Interface not found in jail.conf: \"${INTERFACE}\"" validate_netif "${INTERFACE}" remove_interface "${TARGET}" "${INTERFACE}" - if [ "${START}" -eq 1 ]; then + if [ "${AUTO}" -eq 1 ]; then bastille start "${TARGET}" fi ;; @@ -440,7 +438,7 @@ case "${ACTION}" in fi validate_ip "${IP}" change_ip "${TARGET}" "${INTERFACE}" "${IP}" - if [ "${START}" -eq 1 ]; then + if [ "${AUTO}" -eq 1 ]; then bastille start "${TARGET}" fi else diff --git a/usr/local/share/bastille/pkg.sh b/usr/local/share/bastille/pkg.sh index 72d5224d7..b04e724de 100644 --- a/usr/local/share/bastille/pkg.sh +++ b/usr/local/share/bastille/pkg.sh @@ -36,31 +36,44 @@ usage() { cat << EOF Options: - -f | --force -- Start the jail if it is stopped. - -H | --host -- Use the hosts pkg command. + -a | --auto Auto mode. Start/stop jail(s) if required. + -H | --host Use the hosts pkg command. + -x | --debug Enable debug mode. EOF exit 1 } # Handle options. -FORCE=0 +AUTO=0 USE_HOST_PKG=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; + -a|--auto) + AUTO=1 + shift + ;; -H|--host) USE_HOST_PKG=1 shift ;; - -f|--force) - FORCE=1 + -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 ;; + H) USE_HOST_PKG=1 ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift ;; *) break @@ -84,11 +97,11 @@ for _jail in ${JAILS}; do info "[${_jail}]:" - check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then + check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then bastille start "${_jail}" 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}/${_jail}/root" diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh index 81935d045..84fadba53 100644 --- a/usr/local/share/bastille/rcp.sh +++ b/usr/local/share/bastille/rcp.sh @@ -36,7 +36,8 @@ usage() { cat << EOF Options: - -q | --quiet -- Suppress output. + -q | --quiet Suppress output. + -x | --debug Enable debug mode. EOF exit 1 @@ -53,8 +54,19 @@ while [ "$#" -gt 0 ]; do OPTION="-a" 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 + q) OPTION="-a" ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift ;; *) break @@ -79,4 +91,4 @@ for _jail in ${JAILS}; do if ! cp "${OPTION}" "${bastille_jail_path}${CPSOURCE}" "${CPDEST}"; then error_continue "RCP failed: ${CPSOURCE} -> ${bastille_jail_path}${CPDEST}" fi -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index d42a2f1b1..bdf899604 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -32,14 +32,15 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille rdr TARGET [option(s)] [clear|reset|list|(tcp|udp)] HOST_PORT JAIL_PORT [log ['(' logopts ')'] ] )]" + error_notify "Usage: bastille rdr [option(s)] TARGET [clear|reset|list|(tcp|udp)] HOST_PORT JAIL_PORT [log ['(' logopts ')'] ] )]" cat << EOF Options: - -i | --interface [interface] -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. - -s | --source [source ip] -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. - -d | --destination [destination ip] -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. - -t | --type [ipv4|ipv6] -- Specify IP type. Must be used if -s or -d are used. Defaults to both. + -d | --destination [destination ip] Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + -i | --interface [interface] Set the interface to create the rdr rule on. Useful if you have multiple interfaces. + -s | --source [source ip] Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. + -t | --type [ipv4|ipv6] Specify IP type. Must be used if -s or -d are used. Defaults to both. + -x | --debug Enable debug mode. EOF exit 1 @@ -47,22 +48,22 @@ EOF check_jail_validity() { - # Check if jail ip4 address (ip4.addr) is valid (non-VNET only) + # Validate jail network type and set IP4/6 if [ "$( bastille config ${TARGET} get vnet )" != 'enabled' ]; then - if [ "$( bastille config ${TARGET} get ip4.addr )" != 'disable' ] && [ "$( bastille config ${TARGET} get ip4.addr )" != 'not set' ]; then - JAIL_IP="$( bastille config ${TARGET} get ip4.addr )" + _ip4_interfaces="$(bastille config ${TARGET} get ip4.addr | sed 's/,/ /g')" + _ip6_interfaces="$(bastille config ${TARGET} get ip6.addr | sed 's/,/ /g')" + # Check if jail ip4.addr is valid (non-VNET only) + if [ "${_ip4_interfaces}" != "not set" ] && [ "${_ip4_interfaces}" != "disable" ]; then + JAIL_IP="$(echo ${_ip4_interfaces} | awk '{print $1}' | awk -F"|" '{print $2}')" + fi + # Check if jail ip6.addr is valid (non-VNET only) + if [ "${_ip6_interfaces}" != "not set" ] && [ "${_ip6_interfaces}" != "disable" ]; then + JAIL_IP6="$(echo ${_ip6_interfaces} | awk '{print $1}' | awk -F"|" '{print $2}')" fi else error_exit "VNET jails do not support rdr." fi - # Check if jail ip6 address (ip6.addr) is valid (non-VNET only) - if [ "$( bastille config $TARGET get vnet )" != 'enabled' ]; then - if [ "$( bastille config $TARGET get ip6 )" != 'disable' ] && [ "$( bastille config $TARGET get ip6 )" != 'not set' ]; then - JAIL_IP6="$( bastille config ${TARGET} get ip6.addr )" - fi - fi - # Check if rdr-anchor is defined in pf.conf if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then error_exit "rdr-anchor not found in pf.conf" @@ -92,6 +93,19 @@ check_rdr_ip_validity() { fi } +validate_rdr_rule() { + local if="${1}" + local src="${2}" + local dst="${3}" + local proto="${4}" + local host_port="${5}" + local jail_port="${6}" + if grep -qs "$if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then + error_notify "Error: Ports already in use on this interface." + error_exit "See 'bastille list ports' or 'bastille rdr TARGET clear'." + fi +} + persist_rdr_rule() { local inet="${1}" local if="${2}" @@ -206,6 +220,15 @@ while [ "$#" -gt 0 ]; do -h|--help|help) usage ;; + -d|--destination) + if ifconfig | grep -owq "inet ${2}"; then + OPTION_DST=1 + RDR_DST="${2}" + shift 2 + else + error_exit "${2} is not an IP on this system." + fi + ;; -i|--interface) if ifconfig | grep -owq "${2}:"; then OPTION_IF=1 @@ -221,15 +244,6 @@ while [ "$#" -gt 0 ]; do RDR_SRC="${2}" shift 2 ;; - -d|--destination) - if ifconfig | grep -owq "inet ${2}"; then - OPTION_DST=1 - RDR_DST="${2}" - shift 2 - else - error_exit "${2} is not an IP on this system." - fi - ;; -t|--type) if [ "${2}" != "ipv4" ] && [ "${2}" != "ipv6" ]; then error_exit "[-t|--type] must be [ipv4|ipv6]" @@ -239,6 +253,10 @@ while [ "$#" -gt 0 ]; do shift 2 fi ;; + -x|--debug) + enable_debug + shift + ;; -*) error_exit "Unknown option: \"${1}\"" ;; @@ -261,17 +279,12 @@ bastille_root_check set_target_single "${TARGET}" while [ "$#" -gt 0 ]; do - case "$1" in + case "${1}" in list) if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage - elif [ "${TARGET}" = 'ALL' ]; then - for _jail in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do - echo "${_jail} redirects:" - pfctl -a "rdr/${_jail}" -Psn 2>/dev/null - done else check_jail_validity pfctl -a "rdr/${TARGET}" -Psn 2>/dev/null @@ -283,13 +296,9 @@ while [ "$#" -gt 0 ]; do error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage - elif [ "${TARGET}" = 'ALL' ]; then - for _jail in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do - echo "${_jail} redirects:" - pfctl -a "rdr/${_jail}" -Fn - done else check_jail_validity + echo "${TARGET} redirects:" pfctl -a "rdr/${TARGET}" -Fn fi shift @@ -299,18 +308,11 @@ while [ "$#" -gt 0 ]; do error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage - elif [ "${TARGET}" = 'ALL' ]; then - for _jail in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do - echo "${_jail} redirects:" - pfctl -a "rdr/${_jail}" -Fn - if rm -f "${bastille_jailsdir}"/"${_jail}"/rdr.conf; then - info "[${_jail}]: rdr.conf removed" - fi - done else check_jail_validity + echo "${TARGET} redirects:" pfctl -a "rdr/${TARGET}" -Fn - if rm -f "${bastille_jailsdir}"/"${_jail}"/rdr.conf; then + if rm -f "${bastille_jailsdir}/${_jail}/rdr.conf"; then info "[${TARGET}]: rdr.conf removed" fi fi @@ -323,6 +325,7 @@ while [ "$#" -gt 0 ]; do error_exit "[-t|--type] must be set when using [-s|--source] or [-d|--destination]" elif [ "$#" -eq 3 ]; then check_jail_validity + validate_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 persist_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 load_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 shift "$#" @@ -339,6 +342,7 @@ while [ "$#" -gt 0 ]; do done if [ "${2}" = "(" ] && [ "${last}" = ")" ] ; then check_jail_validity + validate_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 persist_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" load_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift $# @@ -347,6 +351,7 @@ while [ "$#" -gt 0 ]; do fi elif [ $# -eq 1 ]; then check_jail_validity + validate_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 persist_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" load_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift 1 @@ -368,11 +373,13 @@ while [ "$#" -gt 0 ]; do fi if [ "$#" -eq 7 ] && { [ "${5}" = "tcp" ] || [ "${5}" = "udp" ]; } then check_jail_validity + validate_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 persist_rdr_rule "$@" load_rdr_rule "$@" shift "$#" elif [ "$#" -ge 8 ] && [ "${8}" = "log" ]; then check_jail_validity + validate_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 persist_rdr_log_rule "$@" load_rdr_log_rule "$@" shift "$#" @@ -381,4 +388,4 @@ while [ "$#" -gt 0 ]; do fi ;; esac -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index 1b9709e54..d65d34746 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -36,16 +36,15 @@ usage() { cat << EOF Options: - -f | --force -- Stop the jail if it is running. - -s | --start -- Start jail(s) when complete. + -a | --auto Auto mode. Start/stop jail(s) if required. + -x | --debug Enable debug mode. EOF exit 1 } # Handle options. -FORCE=0 -START=0 +AUTO=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) @@ -55,12 +54,19 @@ while [ "$#" -gt 0 ]; do START=1 shift ;; - -f|--force) - FORCE=1 + -a|--auto) + AUTO=1 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 @@ -77,11 +83,11 @@ NEWNAME="${2}" bastille_root_check set_target_single "${TARGET}" -check_target_is_stopped "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then +check_target_is_stopped "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then bastille stop "${TARGET}" else error_notify "Jail is running." - error_exit "Use [-f|--force] to force stop the jail." + error_exit "Use [-a|--auto] to auto-stop the jail." fi validate_name() { @@ -110,15 +116,6 @@ update_jailconf() { fi } -update_fstab() { - # Update fstab to use the new name - FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab" - if [ -f "${FSTAB_CONFIG}" ] && [ -s "${FSTAB_CONFIG}" ]; then - # Update fstab paths with new jail path - sed -i '' "s|${bastille_jailsdir}/${TARGET}/root/|${bastille_jailsdir}/${NEWNAME}/root/|g" "${FSTAB_CONFIG}" - fi -} - change_name() { # Attempt container name change info "Attempting to rename '${TARGET}' to ${NEWNAME}..." @@ -156,29 +153,29 @@ change_name() { fi fi - # Update jail configuration files accordingly + # Update jail conf files update_jailconf - update_fstab + update_fstab "${TARGET}" "${NEWNAME}" # Check exit status and notify if [ "$?" -ne 0 ]; then error_exit "An error has occurred while attempting to rename '${TARGET}'." else info "Renamed '${TARGET}' to '${NEWNAME}' successfully." - if [ "${START}" -eq 1 ]; then + if [ "${AUTO}" -eq 1 ]; then bastille start "${NEWNAME}" fi fi } -## Validate new name. +# Validate NEW_NAME if [ -n "${NEWNAME}" ]; then validate_name fi -## check if a jail already exists with the new name +# Check if a jail already exists with NEW_NAME if [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then error_exit "Jail: ${NEWNAME} already exists." fi -change_name +change_name \ No newline at end of file diff --git a/usr/local/share/bastille/service.sh b/usr/local/share/bastille/service.sh index ec89a8867..db0660b67 100644 --- a/usr/local/share/bastille/service.sh +++ b/usr/local/share/bastille/service.sh @@ -36,25 +36,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) + -h|--help|help) usage ;; - -f|--force) - FORCE=1 + -a|--auto) + AUTO=1 shift ;; - -*) - error_exit "Unknown option: \"${1}\"" + -x|--debug) + enable_debug + shift + ;; + -*) + 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 @@ -74,11 +86,11 @@ set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" - check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then + check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then bastille start "${_jail}" 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 "${_jail}" /usr/sbin/service "$@" -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/setup.sh b/usr/local/share/bastille/setup.sh index 3b165f1ba..50eb59e4d 100644 --- a/usr/local/share/bastille/setup.sh +++ b/usr/local/share/bastille/setup.sh @@ -44,6 +44,9 @@ fi # Configure bastille loopback network interface configure_network() { + if ifconfig -l | grep -qo ${bastille_network_loopback}; then + error_notify "Error: Network has already been configured." + fi info "Configuring ${bastille_network_loopback} loopback interface" sysrc cloned_interfaces+=lo1 sysrc ifconfig_lo1_name="${bastille_network_loopback}" @@ -54,6 +57,9 @@ configure_network() { configure_vnet() { info "Configuring bridge interface" + if ifconfig -l | grep -qo bridge1; then + error_notify "Error: VNET has already been configured." + fi sysrc cloned_interfaces+=bridge1 sysrc ifconfig_bridge1_name=bastille1 @@ -80,8 +86,8 @@ configure_pf() { 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)" + 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 @@ -105,7 +111,7 @@ EOF 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." + error_notify "${bastille_pf_conf} already exists. Exiting." fi } @@ -113,6 +119,8 @@ fi configure_zfs() { if [ ! "$(kldstat -m zfs)" ]; then info "ZFS module not loaded; skipping..." + elif [ -n "$(sysrc -f ${bastille_config} bastille_zfs_zpool)" ] && [ -n "$(sysrc -f ${bastille_config} bastille_zfs_enable)" ]; then + error_notify "Error: ZFS has already been configured." else ## attempt to determine bastille_zroot from `zpool list` bastille_zroot=$(zpool list | grep -v NAME | awk '{print $1}') @@ -127,7 +135,7 @@ configure_zfs() { } # Run all base functions (w/o vnet) if no args -if [ $# -eq 0 ]; then +if [ "$#" -eq 0 ]; then sysrc bastille_enable=YES configure_network configure_pf @@ -135,18 +143,13 @@ if [ $# -eq 0 ]; then fi # Handle special-case commands first. -case "$1" in +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 ;; diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index e51b1e6c5..13161f580 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -32,15 +32,47 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille start TARGET" + error_notify "Usage: bastille start TARGET" + cat << EOF + Options: + + -v | --verbose Print every action on jail start. + -x | --debug Enable debug mode. + +EOF + exit 1 } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac +# Handle options. +OPTION="" +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -v|--verbose) + OPTION="-v" + shift + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + v) OPTION="-v" ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift + ;; + *) + break + ;; + esac +done if [ "$#" -ne 1 ]; then usage @@ -65,8 +97,7 @@ for _jail in ${JAILS}; do for _interface in ${_ip4_interfaces}; do _interface="$(echo ${_interface} 2>/dev/null | awk -F"|" '{print $1}')" if ! ifconfig | grep "^${_interface}:" >/dev/null; then - error_notify "Error: ${_interface} interface does not exist." - continue + error_continue "Error: ${_interface} interface does not exist." fi done fi @@ -75,8 +106,7 @@ for _jail in ${JAILS}; do for _interface in ${_ip6_interfaces}; do _interface="$(echo ${_interface} 2>/dev/null | awk -F"|" '{print $1}')" if ! ifconfig | grep "^${_interface}:" >/dev/null; then - error_notify "Error: ${_interface} interface does not exist." - continue + error_continue "Error: ${_interface} interface does not exist." fi done fi @@ -90,8 +120,7 @@ for _jail in ${JAILS}; do for _ip in ${_ip4}; do _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" if ifconfig | grep -wF "${_ip}" >/dev/null; then - error_notify "Error: IP address (${_ip}) already in use." - continue + error_continue "Error: IP address (${_ip}) already in use." else pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip}" fi @@ -102,8 +131,7 @@ for _jail in ${JAILS}; do for _ip in ${_ip6}; do _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" if ifconfig | grep -wF "${_ip}" >/dev/null; then - error_notify "Error: IP address (${_ip}) already in use." - continue + error_continue "Error: IP address (${_ip}) already in use." else pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip}" fi @@ -111,7 +139,7 @@ for _jail in ${JAILS}; do fi # Start jail - jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -c "${_jail}" + jail ${OPTION} -f "${bastille_jailsdir}/${_jail}/jail.conf" -c "${_jail}" # Add rctl limits if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then @@ -126,4 +154,4 @@ for _jail in ${JAILS}; do bastille rdr ${_jail} ${_rules} done < "${bastille_jailsdir}/${_jail}/rdr.conf" fi -done +done \ No newline at end of file diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index d6b04f1ab..c4f0fac5d 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -32,15 +32,47 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille stop TARGET" + error_notify "Usage: bastille stop [option(s)] TARGET" + cat << EOF + Options: + + -v | --verbose Print every action on jail stop. + -x | --debug Enable debug mode. + +EOF + exit 1 } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac +# Handle options. +OPTION="" +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -v|--verbose) + OPTION="-v" + shift + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + v) OPTION="-v" ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift + ;; + *) + break + ;; + esac +done if [ "$#" -ne 1 ]; then usage @@ -77,18 +109,18 @@ for _jail in ${JAILS}; do fi # Stop jail - jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" + jail ${OPTION} -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" # Remove (captured above) ipX.addr from firewall table if [ "${_ip4}" != "not set" ]; then for _ip in ${_ip4}; do - _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" + _ip="$(echo ${_ip} | awk -F"|" '{print $2}')" pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" done fi if [ "${_ip6}" != "not set" ]; then for _ip in ${_ip6}; do - _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" + _ip="$(echo ${_ip} | awk -F"|" '{print $2}')" pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" done fi diff --git a/usr/local/share/bastille/sysrc.sh b/usr/local/share/bastille/sysrc.sh index e0f4df92e..975f3d51f 100644 --- a/usr/local/share/bastille/sysrc.sh +++ b/usr/local/share/bastille/sysrc.sh @@ -36,25 +36,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 ;; - -*) - error_exit "Unknown option: \"${1}\"" + -x|--debug) + enable_debug + shift + ;; + -*) + 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 @@ -74,11 +86,11 @@ set_target "${TARGET}" for _jail in ${JAILS}; do info "[${_jail}]:" - check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then + check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then bastille start "${_jail}" 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 "${_jail}" /usr/sbin/sysrc "$@" done \ No newline at end of file diff --git a/usr/local/share/bastille/tags.sh b/usr/local/share/bastille/tags.sh index 89327206f..d616f5de0 100644 --- a/usr/local/share/bastille/tags.sh +++ b/usr/local/share/bastille/tags.sh @@ -33,22 +33,34 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille tags TARGET add tag1[,tag2,...]" - error_notify " bastille tags TARGET delete tag1[,tag2,...]" - error_notify " bastille tags TARGET list [tag]" - echo -e "Example: bastille tags JAILNAME add database,mysql" - echo -e " bastille tags JAILNAME delete mysql" - echo -e " bastille tags ALL list" - echo -e " bastille tags ALL list mysql" + error_notify "Usage: bastille tags TARGET [add|delete|list] [tag1,tag2] + cat << EOF + Options: + + -x | --debug Enable debug mode. + +EOF exit 1 } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac +# Handle options. +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + error_exit "Unknown Option: \"${1}\"" ;; + ;; + *) + break + ;; + esac +done if [ $# -lt 2 ] || [ $# -gt 3 ]; then usage diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index ad668e96b..c61ac4974 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -32,11 +32,12 @@ . /usr/local/etc/bastille/bastille.conf bastille_usage() { - error_notify "Usage: bastille template [option(s)] TARGET [--convert|project/template|template]" + error_notify "Usage: bastille template [option(s)] TARGET [--convert|project/template]" 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 @@ -114,18 +115,29 @@ render() { } # 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 ;; - -*) - error_exit "Unknown option: \"${1}\"" + -x|--debug) + enable_debug + shift + ;; + -*) + 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 @@ -218,12 +230,7 @@ case ${TEMPLATE} in fi ;; *) - if [ ! -f ${TEMPLATE}/Bastillefile ]; then - error_exit "${TEMPLATE} not found." - else - bastille_template=${TEMPLATE} - fi - ;; + error_exit "Template name/URL not recognized." esac if [ -z "${JAILS}" ]; then @@ -254,23 +261,27 @@ for _jail in ${JAILS}; do info "[${_jail}]:" - check_target_is_running "${_jail}" || if [ "${FORCE}" -eq 1 ]; then + check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then bastille start "${_jail}" 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 echo "Applying template: ${TEMPLATE}..." - ## jail-specific variables. + # Get default IPv4 and IPv6 addresses bastille_jail_path="${bastille_jailsdir}/${_jail}/root" - if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then - if [ "$( bastille config ${TARGET} get ip4.addr )" != 'disable' ] && [ "$( bastille config ${TARGET} get ip4.addr )" != 'not set' ]; then - _jail_ip="$( bastille config ${TARGET} get ip4.addr )" + if [ "$(bastille config ${_jail} get vnet)" != 'enabled' ]; then + _ip4_interfaces="$(bastille config ${_jail} get ip4.addr | sed 's/,/ /g')" + _ip6_interfaces="$(bastille config ${_jail} get ip6.addr | sed 's/,/ /g')" + # IP4 + if [ "${_ip4_interfaces}" != "not set" ]; then + _jail_ip="$(echo ${_ip4_interface} 2>/dev/null | awk -F"|" '{print $2}')" fi - if [ "$( bastille config $TARGET get ip6 )" != 'disable' ] && [ "$( bastille config $TARGET get ip6 )" != 'not set' ]; then - _jail_ip6="$( bastille config ${TARGET} get ip6.addr )" + # IP6 + if [ "${_ip6_interfaces}" != "not set" ]; then + _jail_ip="$(echo ${_ip6_interface} 2>/dev/null | awk -F"|" '{print $2}')" fi fi diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh index e31a6e6f4..d5a375de5 100644 --- a/usr/local/share/bastille/top.sh +++ b/usr/local/share/bastille/top.sh @@ -36,25 +36,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 +84,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 \ No newline at end of file diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index fdfb1a53a..999677ce9 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -32,15 +32,34 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille umount TARGET JAIL_PATH" + error_notify "Usage: bastille umount [option(s)] TARGET JAIL_PATH" + cat << EOF + Options: + + -x | --debug Enable debug mode. + +EOF + exit 1 } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - usage - ;; -esac +# Handle options. +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done if [ "$#" -ne 2 ]; then usage diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index c0573b9fa..adf4999eb 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -36,8 +36,9 @@ usage() { cat << EOF Options: - -s | --start -- Start the jail if it is stopped. - -f | --force -- Force update a release. + -a | --auto Auto mode. Start/stop jail(s) if required. + -f | --force Force upgrade a release. + -x | --debug Enable debug mode. EOF exit 1 @@ -49,22 +50,34 @@ fi # Handle options. OPTION="" -FORCE=0 +AUTO=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) usage ;; - -s|--start) - FORCE=1 + -a|--auto) + AUTO=1 shift ;; -f|--force) OPTION="-F" shift ;; - -*) - error_exit "Unknown option: \"${1}\"" + -x|--debug) + enable_debug + shift + ;; + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + a) AUTO=1 ;; + f) OPTION="-F" ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift ;; *) break @@ -95,11 +108,11 @@ arch_check() { jail_check() { # Check if the jail is thick and is running set_target_single "${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 [-s|--start] to force start the jail." + error_continue "Use [-a|--auto] to auto-start the jail." fi if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then error_exit "${TARGET} is not a thick container." @@ -182,4 +195,4 @@ elif echo "${TARGET}" | grep -q "[0-9]\{2\}.[0-9]-RELEASE"; then release_update else jail_update -fi +fi \ No newline at end of file diff --git a/usr/local/share/bastille/upgrade.sh b/usr/local/share/bastille/upgrade.sh index 5c661ce5f..51b2f3c2d 100644 --- a/usr/local/share/bastille/upgrade.sh +++ b/usr/local/share/bastille/upgrade.sh @@ -32,12 +32,13 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille upgrade [option(s)] [RELEASE NEW_RELEASE (install)] [TARGET NEW_RELEASE (install)]" + error_notify "Usage: bastille upgrade [option(s)] [RELEASE NEW_RELEASE install] [TARGET NEW_RELEASE install]" cat << EOF Options: - -s | --start -- Start the jail if it is stopped. - -f | --force -- Force upgrade a release. + -a | --auto Auto mode. Start/stop jail(s) if required. + -f | --force Force upgrade a release. + -x | --debug Enable debug mode. EOF exit 1 @@ -50,16 +51,28 @@ while [ "$#" -gt 0 ]; do -h|--help|help) usage ;; - -s|--start) - FORCE=1 + -a|--auto) + AUTO=1 shift ;; -f|--force) OPTION="-F" shift ;; - -*) - error_exit "Unknown option: \"${1}\"" + -x|--debug) + enable_debug + shift + ;; + -*) + for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do + case ${_opt} in + a) AUTO=1 ;; + f) OPTION="-F" ;; + x) enable_debug ;; + *) error_exit "Unknown Option: \"${1}\"" ;; + esac + done + shift ;; *) break @@ -89,11 +102,11 @@ fi jail_check() { # Check if the jail is thick and is running set_target_single "${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 [-s|--start] to force start the jail." + error_continue "Use [-a|--auto] to auto-start the jail." fi if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then error_exit "${TARGET} is not a thick container." @@ -159,4 +172,4 @@ elif [ "${NEWRELEASE}" = "install" ]; then jail_updates_install else jail_upgrade -fi +fi \ No newline at end of file diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh index 179241b7e..17b95c8b8 100644 --- a/usr/local/share/bastille/verify.sh +++ b/usr/local/share/bastille/verify.sh @@ -32,9 +32,17 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille verify [RELEASE|TEMPLATE]" + error_notify "Usage: bastille verify [RELEASE|TEMPLATE]" + cat << EOF + Options: + + -x | --debug Enable debug mode. + +EOF + exit 1 } + verify_release() { if [ -f "/bin/midnightbsd-version" ]; then echo -e "${COLOR_RED}Not yet supported on MidnightBSD.${COLOR_RESET}" @@ -133,23 +141,37 @@ verify_template() { ## remove bad templates if [ "${_hook_validate}" -lt 1 ]; then error_notify "No valid template hooks found." - error_notify "Template discarded." - rm -rf "${bastille_template}" + error_notify "Template discarded: ${BASTILLE_TEMPLATE}" + echo + rm -rf "${_template_path}" exit 1 fi ## if validated; ready to use if [ "${_hook_validate}" -gt 0 ]; then - info "Template ready to use." + info "Template ready to use: ${BASTILLE_TEMPLATE}" + echo fi } -# Handle special-case commands first. -case "${1}" in - help|-h|--help) - bastille_usage - ;; -esac +# Handle options. +while [ "$#" -gt 0 ]; do + case "${1}" in + -h|--help|help) + usage + ;; + -x|--debug) + enable_debug + shift + ;; + -*) + error_exit "Unknown Option: \"${1}\"" + ;; + *) + break + ;; + esac +done if [ "$#" -ne 1 ]; then usage @@ -174,6 +196,6 @@ case "${1}" in verify_template ;; *) - bastille_usage + usage ;; esac diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index e7a48ba88..3ef1cb5eb 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -32,9 +32,17 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille zfs TARGET [set|get|snap] [key=value|date]" + error_notify "Usage: bastille zfs TARGET [set|get|snap|destroy_snap|df|usage] [key=value|date]" + cat << EOF + Options: + + -x | --debug Enable debug mode. + +EOF + exit 1 } + zfs_snapshot() { for _jail in ${JAILS}; do info "[${_jail}]:" @@ -86,9 +94,10 @@ if [ "$#" -lt 2 ]; then fi TARGET="${1}" +ACTION="${2}" bastille_root_check -set_target_single "${TARGET}" +set_target "${TARGET}" # Check if ZFS is enabled if ! checkyesno bastille_zfs_enable; then @@ -100,7 +109,7 @@ if [ -z "${bastille_zfs_zpool}" ]; then error_exit "ZFS zpool not defined." fi -case "${2}" in +case "${ACTION}" in set) ATTRIBUTE="${3}" zfs_set_value From 9381e191a63339bade9c4d738e4928fa74ae9c59 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Fri, 10 Jan 2025 13:59:16 -0700 Subject: [PATCH 117/120] new: fix shellcheck --- usr/local/share/bastille/bootstrap.sh | 2 +- usr/local/share/bastille/import.sh | 2 +- usr/local/share/bastille/network.sh | 3 ++- usr/local/share/bastille/rename.sh | 4 ++-- usr/local/share/bastille/tags.sh | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index 3b02f8b7e..f84ccd504 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -448,6 +448,7 @@ set -x fi fi if [ "${MULTI_REPO}" -eq 1 ]; then + # shellcheck disable=SC2045 for _template_dir in $(ls ${_template}); do if [ -f ${_template}/${_template_dir}/Bastillefile ]; then bastille verify "${_repo}/${_template_dir}" @@ -599,7 +600,6 @@ case "${1}" in BASTILLE_TEMPLATE_URL=${1} BASTILLE_TEMPLATE_USER=$(echo "${1}" | awk -F / '{ print $4 }') BASTILLE_TEMPLATE_REPO=$(echo "${1}" | awk -F / '{ print $5 }') - BASTILLE_TEMPLATE_DIR=$(echo "${1}" | awk -F / '{ print $6 }') bootstrap_template ;; git@*:*/*) diff --git a/usr/local/share/bastille/import.sh b/usr/local/share/bastille/import.sh index 2271fa8c6..03798cb4d 100644 --- a/usr/local/share/bastille/import.sh +++ b/usr/local/share/bastille/import.sh @@ -73,7 +73,7 @@ while [ "$#" -gt 0 ]; do for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do case ${_opt} in f) FORCE=1 ;; - v) ZRECV="-u -v" + v) ZRECV="-u -v" ;; x) enable_debug ;; *) error_exit "Unknown Option: \"${1}\"" ;; esac diff --git a/usr/local/share/bastille/network.sh b/usr/local/share/bastille/network.sh index d2abe53c2..f7519d2cb 100644 --- a/usr/local/share/bastille/network.sh +++ b/usr/local/share/bastille/network.sh @@ -86,7 +86,7 @@ while [ "$#" -gt 0 ]; do -*) for _opt in $(echo ${1} 2>/dev/null | sed 's/-//g' | fold -w1); do case ${_opt} in - a) FORCE=1 ;; + a) AUTO=1 ;; b|B) BRIDGE_VNET_JAIL=1 ;; c|C) CLASSIC_JAIL=1 ;; m|M) STATIC_MAC=1 ;; @@ -146,6 +146,7 @@ validate_ip() { local _ip6="$( echo "${_ip}" 2>/dev/null | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )" if [ -n "${_ip6}" ]; then info "Valid: (${_ip6})." + # shellcheck disable=SC2034 IP6="${_ip6}" else local IFS diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index d65d34746..a7c3225a0 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -50,8 +50,8 @@ while [ "$#" -gt 0 ]; do -h|--help|help) usage ;; - -s|--start) - START=1 + -a|--auto) + AUTO=1 shift ;; -a|--auto) diff --git a/usr/local/share/bastille/tags.sh b/usr/local/share/bastille/tags.sh index d616f5de0..34cbf28b1 100644 --- a/usr/local/share/bastille/tags.sh +++ b/usr/local/share/bastille/tags.sh @@ -33,7 +33,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille tags TARGET [add|delete|list] [tag1,tag2] + error_notify "Usage: bastille tags TARGET [add|delete|list] [tag1,tag2]" cat << EOF Options: From ffae7696020bbc32f387df3af0b47cef6ef93301 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Fri, 10 Jan 2025 14:02:51 -0700 Subject: [PATCH 118/120] new: fix more shellchek --- usr/local/share/bastille/rename.sh | 6 +----- usr/local/share/bastille/tags.sh | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index a7c3225a0..48b847fff 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -54,16 +54,12 @@ while [ "$#" -gt 0 ]; do AUTO=1 shift ;; - -a|--auto) - AUTO=1 - shift - ;; -*) 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}\"" ;; + *) error_exit "Unknown Option: \"${1}\"" esac done shift diff --git a/usr/local/share/bastille/tags.sh b/usr/local/share/bastille/tags.sh index 34cbf28b1..f217c4194 100644 --- a/usr/local/share/bastille/tags.sh +++ b/usr/local/share/bastille/tags.sh @@ -54,7 +54,7 @@ while [ "$#" -gt 0 ]; do shift ;; -*) - error_exit "Unknown Option: \"${1}\"" ;; + error_exit "Unknown Option: \"${1}\"" ;; *) break From 0fc58fabffb5b41155cab8714064fc8b360983f9 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 10 Jan 2025 15:24:01 -0700 Subject: [PATCH 119/120] mount: allow options --- usr/local/share/bastille/mount.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 3f11afedc..1f936051b 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -108,8 +108,8 @@ elif [ ! -e "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then usage fi -# Mount permissions need to be "ro" or "rw" -if [ "${_perms}" != "ro" ] && [ "${_perms}" != "rw" ]; then +# Mount permissions/options need to start with "ro" or "rw" +if ! echo "${_perms}" | grep -Eq 'r[w|o],.*$'; then error_notify "Detected invalid mount permissions in FSTAB." warn "Format: /host/path /jail/path nullfs ro 0 0" warn "Read: ${_fstab}" From 83b32018d94b27bab9ee4481fb0fd4bc485492d0 Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Mon, 13 Jan 2025 13:12:26 -0700 Subject: [PATCH 120/120] start/stop: update to allow new style interface --- usr/local/share/bastille/start.sh | 68 +++++++++++++++---------------- usr/local/share/bastille/stop.sh | 16 ++++++-- 2 files changed, 45 insertions(+), 39 deletions(-) diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index d5146acda..318acd7b9 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -34,11 +34,11 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille start TARGET" + error_notify "Usage: bastille start [option(s)] TARGET" cat << EOF Options: - -v | --verbose Print every action on jail start. + -v | --verbose Print every action on jail start. -x | --debug Enable debug mode. EOF @@ -90,56 +90,54 @@ for _jail in ${JAILS}; do info "[${_jail}]:" check_target_is_stopped "${_jail}" || error_continue "Jail is already running." - # Validate interfaces + # Validate interfaces and add IPs to firewall table if [ "$(bastille config ${_jail} get vnet)" != 'enabled' ]; then _ip4_interfaces="$(bastille config ${_jail} get ip4.addr | sed 's/,/ /g')" _ip6_interfaces="$(bastille config ${_jail} get ip6.addr | sed 's/,/ /g')" # IP4 if [ "${_ip4_interfaces}" != "not set" ]; then for _interface in ${_ip4_interfaces}; do - _interface="$(echo ${_interface} 2>/dev/null | awk -F"|" '{print $1}')" - if ! ifconfig | grep "^${_interface}:" >/dev/null; then - error_continue "Error: ${_interface} interface does not exist." + if echo "${_interface}" | grep -q "|"; then + _if="$(echo ${_interface} 2>/dev/null | awk -F"|" '{print $1}')" + _ip="$(echo ${_interface} 2>/dev/null | awk -F"|" '{print $2}' | sed -E 's#/[0-9]+$##g')" + else + _if="$(bastille config ${_jail} get interface)" + _ip="$(echo ${_interface} | sed -E 's#/[0-9]+$##g')" + fi + if ifconfig | grep "^${_if}:" >/dev/null; then + if ifconfig | grep -qwF "${_ip}"; then + error_continue "Error: IP address (${_ip}) already in use." + else + pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip}" + fi + else + error_continue "Error: ${_if} interface does not exist." fi done fi # IP6 if [ "${_ip6_interfaces}" != "not set" ]; then for _interface in ${_ip6_interfaces}; do - _interface="$(echo ${_interface} 2>/dev/null | awk -F"|" '{print $1}')" - if ! ifconfig | grep "^${_interface}:" >/dev/null; then - error_continue "Error: ${_interface} interface does not exist." + if echo "${_interface}" | grep -q "|"; then + _if="$(echo ${_interface} 2>/dev/null | awk -F"|" '{print $1}')" + _ip="$(echo ${_interface} 2>/dev/null | awk -F"|" '{print $2}' | sed -E 's#/[0-9]+$##g')" + else + _if="$(bastille config ${_jail} get interface)" + _ip="$(echo ${_interface} | sed -E 's#/[0-9]+$##g')" + fi + if ifconfig | grep "^${_if}:" >/dev/null; then + if ifconfig | grep -qwF "${_ip}"; then + error_continue "Error: IP address (${_ip}) already in use." + else + pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip}" + fi + else + error_continue "Error: ${_if} interface does not exist." fi done fi fi - # Validate and/or add IP to firewall table (in use or not in use) - _ip4="$(bastille config "${_jail}" get ip4.addr | sed 's/,/ /g')" - _ip6="$(bastille config "${_jail}" get ip6.addr | sed 's/,/ /g')" - # IP4 - if [ "${_ip4}" != "not set" ]; then - for _ip in ${_ip4}; do - _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" - if ifconfig | grep -wF "${_ip}" >/dev/null; then - error_continue "Error: IP address (${_ip}) already in use." - else - pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip}" - fi - done - fi - # IP6 - if [ "${_ip6}" != "not set" ]; then - for _ip in ${_ip6}; do - _ip="$(echo ${_ip} 2>/dev/null | awk -F"|" '{print $2}')" - if ifconfig | grep -wF "${_ip}" >/dev/null; then - error_continue "Error: IP address (${_ip}) already in use." - else - pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip}" - fi - done - fi - # Start jail jail ${OPTION} -f "${bastille_jailsdir}/${_jail}/jail.conf" -c "${_jail}" diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index f67207faa..718c87144 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -38,7 +38,7 @@ usage() { cat << EOF Options: - -v | --verbose Print every action on jail stop. + -v | --verbose Print every action on jail stop. -x | --debug Enable debug mode. EOF @@ -113,16 +113,24 @@ for _jail in ${JAILS}; do # Stop jail jail ${OPTION} -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" - # Remove (captured above) ipX.addr from firewall table + # Remove (captured above) IPs from firewall table if [ "${_ip4}" != "not set" ]; then for _ip in ${_ip4}; do - _ip="$(echo ${_ip} | awk -F"|" '{print $2}')" + if echo "${_ip}" | grep -q "|"; then + _ip="$(echo ${_ip} | awk -F"|" '{print $2}' | sed -E 's#/[0-9]+$##g')" + else + _ip="$(echo ${_ip} | sed -E 's#/[0-9]+$##g')" + fi pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" done fi if [ "${_ip6}" != "not set" ]; then for _ip in ${_ip6}; do - _ip="$(echo ${_ip} | awk -F"|" '{print $2}')" + if echo "${_ip}" | grep -q "|"; then + _ip="$(echo ${_ip} | awk -F"|" '{print $2}' | sed -E 's#/[0-9]+$##g')" + else + _ip="$(echo ${_ip} | sed -E 's#/[0-9]+$##g')" + fi pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" done fi