diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index d2e64fe..0a34994 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -258,22 +258,75 @@ bootstrap_release() { for _archive in ${bastille_bootstrap_archives}; do ## check if the dist files already exists then extract + FETCH_VALIDATION="0" if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then echo -e "${COLOR_GREEN}Extracting FreeBSD ${RELEASE} ${_archive}.txz.${COLOR_RESET}" /usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz" + if [ $? -ne 0 ]; then + echo -e "${COLOR_RED}Failed to extract ${_archive}.txz.${COLOR_RESET}" + exit 1 + fi else - for _archive in ${bastille_bootstrap_archives}; do + ## get the manifest for dist files checksum validation + if [ ! -f "${bastille_cachedir}/${RELEASE}/MANIFEST" ]; then + fetch ${UPSTREAM_URL}/MANIFEST -o ${bastille_cachedir}/${RELEASE}/MANIFEST || FETCH_VALIDATION="1" + fi + + if [ "${FETCH_VALIDATION}" -ne "0" ]; then + ## perform cleanup only for stale/empty directories on failure + if [ "${bastille_zfs_enable}" = "YES" ]; then + if [ ! -z "${bastille_zfs_zpool}" ]; then + if [ ! "$(ls -A ${bastille_cachedir}/${RELEASE})" ]; then + zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE} + fi + if [ ! "$(ls -A ${bastille_releasesdir}/${RELEASE})" ]; then + zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE} + fi + fi + fi + if [ -d "${bastille_cachedir}/${RELEASE}" ]; then + if [ ! "$(ls -A ${bastille_cachedir}/${RELEASE})" ]; then + rm -rf ${bastille_cachedir}/${RELEASE} + fi + fi + if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then + if [ ! "$(ls -A ${bastille_releasesdir}/${RELEASE})" ]; then + rm -rf ${bastille_releasesdir}/${RELEASE} + fi + fi + echo -e "${COLOR_RED}Bootstrap failed.${COLOR_RESET}" + exit 1 + fi + ## fetch for missing dist files if [ ! -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then fetch ${UPSTREAM_URL}/${_archive}.txz -o ${bastille_cachedir}/${RELEASE}/${_archive}.txz + if [ $? -ne 0 ]; then + ## alert only if unable to fetch additional dist files + echo -e "${COLOR_RED}Failed to fetch ${_archive}.txz.${COLOR_RESET}" + fi + fi + + ## compare checksums on the fetched dist files + if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then + SHA256_DIST=$(grep -w "${_archive}.txz" ${bastille_cachedir}/${RELEASE}/MANIFEST | awk '{print $2}') + SHA256_FILE=$(sha256 -q ${bastille_cachedir}/${RELEASE}/${_archive}.txz) + if [ "${SHA256_FILE}" != "${SHA256_DIST}" ]; then + echo -e "${COLOR_RED}Failed validation for ${_archive}.txz, please retry bootstrap!${COLOR_RESET}" + rm ${bastille_cachedir}/${RELEASE}/${_archive}.txz + exit 1 + fi fi ## extract the fetched dist files if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then echo -e "${COLOR_GREEN}Extracting FreeBSD ${RELEASE} ${_archive}.txz.${COLOR_RESET}" /usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz" + if [ $? -ne 0 ]; then + echo -e "${COLOR_RED}Failed to extract ${_archive}.txz.${COLOR_RESET}" + exit 1 + fi fi - done fi done echo @@ -359,56 +412,33 @@ bootstrap_template() { HW_MACHINE=$(sysctl hw.machine | awk '{ print $2 }') HW_MACHINE_ARCH=$(sysctl hw.machine_arch | awk '{ print $2 }') +RELEASE="${1}" -# Filter sane release names +## Filter sane release names case "${1}" in -11.2-RELEASE) - RELEASE="${1}" - UPSTREAM_URL="http://ftp.freebsd.org/pub/FreeBSD/releases/${HW_MACHINE}/${HW_MACHINE_ARCH}/11.2-RELEASE" +*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2) +## check for FreeBSD releases name +NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])$' | tr '[:lower:]' '[:upper:]') +if [ -n "${NAME_VERIFY}" ]; then + RELEASE="${NAME_VERIFY}" + UPSTREAM_URL="http://ftp.freebsd.org/pub/FreeBSD/releases/${HW_MACHINE}/${HW_MACHINE_ARCH}/${RELEASE}" bootstrap_directories bootstrap_release +else + usage +fi ;; -11.3-RELEASE) - RELEASE="${1}" - UPSTREAM_URL="http://ftp.freebsd.org/pub/FreeBSD/releases/${HW_MACHINE}/${HW_MACHINE_ARCH}/11.3-RELEASE" - bootstrap_directories - bootstrap_release - ;; -12.0-RELEASE) - RELEASE="${1}" - UPSTREAM_URL="http://ftp.freebsd.org/pub/FreeBSD/releases/${HW_MACHINE}/${HW_MACHINE_ARCH}/12.0-RELEASE" - bootstrap_directories - bootstrap_release - ;; -12.1-RC1) - RELEASE="${1}" - UPSTREAM_URL="http://ftp.freebsd.org/pub/FreeBSD/releases/${HW_MACHINE}/${HW_MACHINE_ARCH}/12.1-RC1" - bootstrap_directories - bootstrap_release - ;; -12.1-RC2) - RELEASE="${1}" - UPSTREAM_URL="http://ftp.freebsd.org/pub/FreeBSD/releases/${HW_MACHINE}/${HW_MACHINE_ARCH}/12.1-RC2" - bootstrap_directories - bootstrap_release - ;; -12.1-RELEASE) - RELEASE="${1}" - UPSTREAM_URL="http://ftp.freebsd.org/pub/FreeBSD/releases/${HW_MACHINE}/${HW_MACHINE_ARCH}/12.1-RELEASE" - bootstrap_directories - bootstrap_release - ;; -11-stable-LAST) - RELEASE="${1}" - UPSTREAM_URL="https://installer.hardenedbsd.org/pub/HardenedBSD/releases/${HW_MACHINE}/${HW_MACHINE_ARCH}/hardenedbsd-11-stable-LAST" - bootstrap_directories - bootstrap_release - ;; -12-stable-LAST) - RELEASE="${1}" - UPSTREAM_URL="https://installer.hardenedbsd.org/pub/HardenedBSD/releases/${HW_MACHINE}/${HW_MACHINE_ARCH}/hardenedbsd-12-stable-LAST" +*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) +## check for HardenedBSD releases name +NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})(-stable-LAST|-STABLE-last|-stable-last|-STABLE-LAST)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g') +if [ -n "${NAME_VERIFY}" ]; then + RELEASE="${NAME_VERIFY}" + UPSTREAM_URL="https://installer.hardenedbsd.org/pub/HardenedBSD/releases/${HW_MACHINE}/${HW_MACHINE_ARCH}/hardenedbsd-${RELEASE}" bootstrap_directories bootstrap_release +else + usage +fi ;; http?://github.com/*/*|http?://gitlab.com/*/*) BASTILLE_TEMPLATE_URL=${1} diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index 5f39a83..3c31175 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -83,7 +83,9 @@ create_jail() { if [ ! -d "${bastille_jailsdir}/${NAME}" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then if [ ! -z "${bastille_zfs_zpool}" ]; then - zfs create ${bastille_zfs_options} -o mountpoint=${bastille_jailsdir}/${NAME} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME} + ## create required zfs datasets + zfs create ${bastille_zfs_options} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME} + zfs create ${bastille_zfs_options} -o mountpoint=${bastille_jailsdir}/${NAME}/root ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root fi else mkdir -p "${bastille_jailsdir}/${NAME}" @@ -202,20 +204,23 @@ INTERFACE="$4" ## verify release case "${RELEASE}" in -11.3-RELEASE|11.3-release) - RELEASE="11.3-RELEASE" +*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2) +## check for FreeBSD releases name +NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])$' | tr '[:lower:]' '[:upper:]') +if [ -n "${NAME_VERIFY}" ]; then + RELEASE="${NAME_VERIFY}" +else + usage +fi ;; -11.2-RELEASE|11.2-release) - RELEASE="11.2-RELEASE" - ;; -12.0-RELEASE|12.0-release) - RELEASE="12.0-RELEASE" - ;; -11-stable-LAST|11-STABLE-last|11-stable-last|11-STABLE-LAST) - RELEASE="11-stable-LAST" - ;; -12-stable-LAST|12-STABLE-last|12-stable-last|12-STABLE-LAST) - RELEASE="12-stable-LAST" +*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) +## check for HardenedBSD releases name +NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})(-stable-LAST|-STABLE-last|-stable-last|-STABLE-LAST)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g') +if [ -n "${NAME_VERIFY}" ]; then + RELEASE="${NAME_VERIFY}" +else + usage +fi ;; *) echo -e "${COLOR_RED}Unknown Release.${COLOR_RESET}" diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index 5542f48..174ca36 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -55,6 +55,8 @@ destroy_jail() { echo -e "${COLOR_GREEN}Deleting Jail: ${NAME}.${COLOR_RESET}" if [ "${bastille_zfs_enable}" = "YES" ]; then if [ ! -z "${bastille_zfs_zpool}" ]; then + ## remove zfs datasets individually + zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME} fi fi @@ -80,27 +82,41 @@ destroy_jail() { destroy_rel() { bastille_rel_base="${bastille_releasesdir}/${NAME}" ## dir + ## check if this release have containers child + BASE_HASCHILD="0" + if [ -d "${bastille_jailsdir}" ]; then + JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") + for _jail in ${JAIL_LIST}; do + if grep -qwo "${NAME}" ${bastille_jailsdir}/${_jail}/fstab 2>/dev/null; then + echo -e "${COLOR_RED}Notice: (${_jail}) depends on ${NAME} base.${COLOR_RESET}" + BASE_HASCHILD="1" + fi + done + fi + if [ ! -d "${bastille_rel_base}" ]; then echo -e "${COLOR_RED}Release base not found.${COLOR_RESET}" exit 1 - fi - - if [ -d "${bastille_rel_base}" ]; then - echo -e "${COLOR_GREEN}Deleting base: ${NAME}.${COLOR_RESET}" - if [ "${bastille_zfs_enable}" = "YES" ]; then - if [ ! -z "${bastille_zfs_zpool}" ]; then - zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${NAME} + else + if [ "${BASE_HASCHILD}" -eq "0" ]; then + echo -e "${COLOR_GREEN}Deleting base: ${NAME}.${COLOR_RESET}" + if [ "${bastille_zfs_enable}" = "YES" ]; then + if [ ! -z "${bastille_zfs_zpool}" ]; then + zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${NAME} + fi fi - fi - if [ -d "${bastille_rel_base}" ]; then - ## removing all flags - chflags -R noschg ${bastille_rel_base} + if [ -d "${bastille_rel_base}" ]; then + ## removing all flags + chflags -R noschg ${bastille_rel_base} - ## remove jail base - rm -rf ${bastille_rel_base} + ## remove jail base + rm -rf ${bastille_rel_base} + fi + echo + else + echo -e "${COLOR_RED}Cannot destroy base with containers child.${COLOR_RESET}" fi - echo fi } @@ -118,8 +134,29 @@ fi NAME="$1" ## check what should we clean -if echo "${NAME}" | grep -qwE '^([0-9]{1,2})\.[0-9]-RELEASE$'; then +case "${NAME}" in +*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2) +## check for FreeBSD releases name +NAME_VERIFY=$(echo "${NAME}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])$' | tr '[:lower:]' '[:upper:]') +if [ -n "${NAME_VERIFY}" ]; then + NAME="${NAME_VERIFY}" destroy_rel else - destroy_jail + usage fi + ;; +*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) +## check for HardenedBSD releases name +NAME_VERIFY=$(echo "${NAME}" | grep -iwE '^([1-9]{2,2})(-stable-LAST|-STABLE-last|-stable-last|-STABLE-LAST)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g') +if [ -n "${NAME_VERIFY}" ]; then + NAME="${NAME_VERIFY}" + destroy_rel +else + usage +fi + ;; +*) + ## just destroy a jail + destroy_jail + ;; +esac diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index ea55ae4..ab37349 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -47,23 +47,28 @@ if [ $# -gt 0 ]; then usage ;; release|releases) - REL_LIST=$(ls "${bastille_releasesdir}" | sed "s/\n//g") - for _REL in ${REL_LIST}; do - if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" ]; then - echo "${bastille_releasesdir}/${_REL}" - fi - done + 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" ]; then + #echo "${bastille_releasesdir}/${_REL}" + echo "${_REL}" + fi + done + fi ;; template|templates) find "${bastille_templatesdir}" -type d -maxdepth 2 ;; jail|jails) - JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") - for _JAIL in ${JAIL_LIST}; do - if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then - echo "${_JAIL}" - fi - done + 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}/jail.conf" ]; then + echo "${_JAIL}" + fi + done + fi ;; log|logs) find "${bastille_logsdir}" -type f -maxdepth 1