#!/bin/sh # bastille-init # Bastille Extension for XigmaNAS x64 12.x and later. # Bastille Extension Forum: https://www.xigmanas.com/forums/viewtopic.php?f=71&t=14848 # Bastille Extension GitHub: https://github.com/JRGTH/xigmanas-bastille-extension # Bastille Homepage: http://bastillebsd.org/ # Bastille GitHub: https://github.com/BastilleBSD/bastille # # Debug script #set -x # Copyright (c) 2019-2024, José Rivera (joserprg@gmail.com). # All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. 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. # 3. Neither the name of the developer nor the names of contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``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 DEVELOPER 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. # Set environment. PATH=${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin # Determine full working directory. CWDIR=$(dirname $(realpath $0)) # Global variables. CWDIR_TRIM="" BASTILLE_ZFS_ZPOOL_MOUNTPOINT="" BASTILLE_ZFS_ZPOOL_MOUNTPOINT_TRIM="" REQUIRED_UPDATE="" PLATFORM=$(uname -m) PRODUCT=$(uname -i) PRDVERSION=$(uname -r | cut -d '-' -f1 | tr -d '.') HOSTVERSION=$(freebsd-version | cut -d '-' -f1) PRDPLATFORM=$(cat /etc/platform) PRDPRODUCT=$(cat /etc/prd.name) SCRIPTNAME=$(basename $0) CONFIG="/cf/conf/config.xml" PRDNAME="Bastille" APPNAME="bastille" EXTLOGFILE="${CWDIR}/log/bastille_ext.log" FULLAPPNAME="${APPNAME}-dist" WWWPATH="/usr/local/www" PKGCACHE="/var/cache/pkg" USRLOCAL="/usr/local" VARLOG="/var/log" EXTCONF="/conf/${APPNAME}_config" EXTCONFLINK="/var/etc/${APPNAME}_conf" BASTILLERCD="/usr/local/etc/rc.d/${APPNAME}" BASTILLEPATH="${USRLOCAL}/bin" BASTILLECONF="${USRLOCAL}/etc/${APPNAME}/${APPNAME}.conf" BASTILLECONFFILE="/conf/bastille_config" BASTILLECONFLINK="/var/etc/bastille_conf" BASTILLECONF_EXT="${CWDIR}/conf/bastille.conf.ext" INCLUDE_PATH="${CWDIR}/conf/system" FREEBSD_UPDATE="${INCLUDE_PATH}/freebsd-update/${HOSTVERSION}" SYSTEM_INCLUDE="${INCLUDE_PATH}/include/${HOSTVERSION}" INSTALLPATH="${CWDIR}/${FULLAPPNAME}" BRANCH="master" BASTILLE_URL="https://github.com/BastilleBSD/${APPNAME}/archive/${BRANCH}.zip" # Official Bastille Repository) BASTILLE_ALT="https://github.com/JRGTH/${APPNAME}/archive/${BRANCH}.zip" # Alternate Bastille Repository, early updates) BASTILLE_VERSION="https://raw.githubusercontent.com/BastilleBSD/${APPNAME}/${BRANCH}/usr/local/bin/${APPNAME}" GITURL="https://github.com/JRGTH/xigmanas-${APPNAME}-extension/archive/${BRANCH}.zip" VERFILE="https://raw.githubusercontent.com/JRGTH/xigmanas-${APPNAME}-extension/${BRANCH}/version" URL_FREEBSD="http://ftp.freebsd.org/pub/FreeBSD/releases/" URL_HARDENEDBSD="https://installers.hardenedbsd.org/pub/" URL_MIDNIGHTBSD="https://www.midnightbsd.org/ftp/MidnightBSD/releases/" OPT="${1}" # Bastille required if [ -f "${BASTILLECONF}" ]; then . /${BASTILLECONF} if [ "${bastille_zfs_enable}" = "YES" -o "${bastille_zfs_enable}" = "yes" ]; then if [ -n "${bastille_zfs_prefix}" ] && [ -n "${bastille_zfs_zpool}" ]; then # Always enforce ZFS activation below "/mnt/" from the extension. if echo "${CWDIR}" | grep -q '/mnt/'; then CWDIR_TRIM=$(echo "${CWDIR}" | sed "s|/mnt/||;s|/${bastille_zfs_prefix}||") fi BASTILLE_ZFS_ZPOOL_MOUNTPOINT=$(zfs get -H -o value mountpoint "${bastille_zfs_zpool}") BASTILLE_ZFS_ZPOOL_MOUNTPOINT_TRIM="" if echo "${BASTILLE_ZFS_ZPOOL_MOUNTPOINT}" | grep -q '/mnt/'; then BASTILLE_ZFS_ZPOOL_MOUNTPOINT_TRIM=$(echo "${BASTILLE_ZFS_ZPOOL_MOUNTPOINT}" | sed "s|/mnt/||;s|/${bastille_zfs_prefix}||") fi fi fi fi error_notify() { # Log/notify message on error and exit. MSG="$*" logger -t "${SCRIPTNAME}" "${MSG}" echo -e "$*" >&2; exit 1 } runtime_config() { # Run-time configuration and checks. if [ -f "${INSTALLPATH}/${BASTILLECONF}" ]; then if ! sysrc -f ${BASTILLECONF} -qn bastille_prefix | grep -q "${CWDIR}"; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_prefix="${CWDIR}" >/dev/null 2>&1 fi fi # Check for required directories and files. if [ ! -d "${CWDIR}/backups" ]; then mkdir -p ${CWDIR}/backups fi if [ ! -d "${CWDIR}/conf" ]; then mkdir -p ${CWDIR}/conf fi if [ ! -d "${CWDIR}/log" ]; then mkdir -p ${CWDIR}/log fi if [ ! -d "${CWDIR}/locale-bastille" ]; then mkdir -p ${CWDIR}/locale-bastille fi if [ ! -d "${CWDIR}/freebsd-update" ]; then mkdir ${CWDIR}/freebsd-update fi if [ ! -f "${CWDIR}${BASTILLECONFFILE}" ]; then touch ${CWDIR}${BASTILLECONFFILE} fi if [ ! -d "${CWDIR}/system" ]; then mkdir -p ${CWDIR}/system fi # Check for permissions. if [ -f "${FREEBSD_UPDATE}/freebsd-update" ]; then FREEBSD_UPDATE_PERMS=$(stat -f "%Op" ${FREEBSD_UPDATE}/freebsd-update) if [ "${FREEBSD_UPDATE_PERMS}" != 100555 ]; then chmod 0555 ${FREEBSD_UPDATE}/freebsd-update fi fi # Workaround to check for host /tmp sane permissions. # This is because after working with Linux jails, this may be changed to 0777 but XigmaNAS wants 1777. if grep -qw '\"chmod\ 777\ /tmp\"' ${INSTALLPATH}/usr/local/share/bastille/create.sh; then sed -i '' 's|\"chmod\ 777\ /tmp\"|\"chmod\ 1777\ /tmp\"|g' ${INSTALLPATH}/usr/local/share/bastille/create.sh else if [ -d "/tmp" ]; then TMP_PERMS=$(stat -f "%Op" "/tmp") if [ "${TMP_PERMS}" != "41777" ]; then chmod 1777 /tmp fi fi fi # Check and append new config parameters. update_config } bastille_initial_download() { # Check if bastille already exist. if [ -n "${REQUIRED_UPDATE}" ] || [ ! -f "${CWDIR}/${FULLAPPNAME}${BASTILLEPATH}/${APPNAME}" ]; then # Fetch latest bastille package. echo "Fetching ${APPNAME} files..." fetch -ao ${CWDIR}/${BRANCH}.zip --no-verify-peer --timeout=30 ${BASTILLE_URL} || \ error_notify "Error: A problem has occurred while fetching ${APPNAME}." bastille_pkg_extract fi } bastille_pkg_extract() { # Extract bastille files from package. if [ -n "${REQUIRED_UPDATE}" ] || [ -f "${CWDIR}/${BRANCH}.zip" ]; then if [ -n "${REQUIRED_UPDATE}" ] || [ ! -f "${CWDIR}/${FULLAPPNAME}${BASTILLEPATH}/${APPNAME}" ]; then echo "Extracting ${APPNAME}..." tar -xf ${CWDIR}/${BRANCH}.zip --exclude='.git*' --exclude='docs' --exclude='bastille.conf' --strip-components 1 -C ${CWDIR}/${FULLAPPNAME} || \ error_notify "Error: A problem has occurred while extractig ${APPNAME} files." chmod 555 ${CWDIR}/${FULLAPPNAME}${BASTILLEPATH}/${APPNAME} chmod 555 ${CWDIR}/${FULLAPPNAME}${BASTILLERCD} rm -f ${CWDIR}/${BRANCH}.zip echo "Done!" fi fi } bastille_upgrade() { # Perform an online bastille upgrade. DATE=$(date +"%a %b %d %T %Y") echo "Looking for new ${APPNAME} package!" mkdir -p ${CWDIR}/update fetch -ao ${CWDIR}/update --no-verify-peer --timeout=30 ${BASTILLE_VERSION} || \ error_notify "Error: A problem has occurred while fetching version file." # Compare version files and fetch latest package if available. if [ -f "${CWDIR}/update/${APPNAME}" ]; then UPDATEVER=$(cat ${CWDIR}/update/${APPNAME} | grep BASTILLE_VERSION= | egrep -o "([0-9]{1,}\.)+[0-9]{1,}" | tr -d '.') CURRENTVER=$(cat ${BASTILLEPATH}/${APPNAME} | grep BASTILLE_VERSION= | egrep -o "([0-9]{1,}\.)+[0-9]{1,}" | tr -d '.') if [ "${UPDATEVER}" -gt "${CURRENTVER}" ]; then echo "New ${APPNAME} package found, performing upgrade..." fetch -ao ${CWDIR}/update --no-verify-peer --timeout=30 ${BASTILLE_URL} || \ error_notify "Error: A problem has occurred while fetching ${APPNAME} package." tar -xf ${CWDIR}/update/${BRANCH}.zip --exclude='.git*' --exclude='docs' --exclude='bastille.conf' --strip-components 1 -C ${CWDIR}/update rm -f ${CWDIR}/update/${BRANCH}.zip rm -f ${CWDIR}/update/${APPNAME} chmod 555 ${CWDIR}/update/${BASTILLEPATH}/${APPNAME} chmod 555 ${CWDIR}/${FULLAPPNAME}${BASTILLERCD} cp -Rf ${CWDIR}/update/* ${CWDIR}/${FULLAPPNAME}/ rm -R ${CWDIR}/update # Logging the update event. UPDATEVERSION=$(cat ${BASTILLEPATH}/${APPNAME} | grep BASTILLE_VERSION= | cut -d"=" -f2 | tr -d '."') echo "${DATE}: ${APPNAME} upgraded to ${UPDATEVERSION}" >> ${EXTLOGFILE} echo "${APPNAME} upgraded to version ${UPDATEVERSION}" echo "${APPNAME} package upgrade completed!" else echo "${APPNAME} is on the latest version!" rm -R ${CWDIR}/update fi # Workaround to update legacy config. if [ "${UPDATEVER}" -gt "0620200202" ]; then update_config fi fi } bastille_core_update() { # Check if bastille already exist. if [ -f "${CWDIR}/${FULLAPPNAME}${BASTILLEPATH}/${APPNAME}" ]; then # Fetch latest bastille package. echo "Fetching ${APPNAME} files..." fetch -ao ${CWDIR}/${BRANCH}.zip --no-verify-peer --timeout=30 ${BASTILLE_URL} || \ error_notify "Error: A problem has occurred while fetching ${APPNAME}." bastille_pkg_extract fi if [ -f "${CWDIR}/${BRANCH}.zip" ] && [ -f "${CWDIR}/${FULLAPPNAME}${BASTILLEPATH}/${APPNAME}" ]; then echo "Extracting ${APPNAME}..." tar -xf ${CWDIR}/${BRANCH}.zip --exclude='.git*' --exclude='docs' --exclude='bastille.conf' --strip-components 1 -C ${CWDIR}/${FULLAPPNAME} || \ error_notify "Error: A problem has occurred while extractig ${APPNAME} files." chmod 555 ${CWDIR}/${FULLAPPNAME}${BASTILLEPATH}/${APPNAME} chmod 555 ${CWDIR}/${FULLAPPNAME}${BASTILLERCD} rm -f ${CWDIR}/${BRANCH}.zip echo "Done!" fi echo "${PRDNAME} core package update completed!" exit 0 } ext_initial_download() { # Always ensure the version file is present, otherwise update the extension files on startup. if [ ! -f "${CWDIR}/version" ]; then echo "Fetching and extracting extension files..." mkdir -p ${CWDIR}/update fetch -ao ${CWDIR}/update --no-verify-peer --timeout=30 ${GITURL} || \ error_notify "Error: A problem has occurred while fetching extension package." tar -xf ${CWDIR}/update/${BRANCH}.zip --exclude='.git*' --strip-components 1 -C ${CWDIR}/update chmod +x ${CWDIR}/update/${SCRIPTNAME} rm -f ${CWDIR}/update/${BRANCH}.zip cp -Rf ${CWDIR}/update/* ${CWDIR}/ rm -R ${CWDIR}/update echo "Done!" fi } extension_upgrade() { # Perform an online extension upgrade. DATE=$(date +"%a %b %d %T %Y") echo "Looking for new Extension package!" mkdir -p ${CWDIR}/update fetch -ao ${CWDIR}/update --no-verify-peer --timeout=30 ${VERFILE} || \ error_notify "Error: A problem has occurred while fetching version file." # Compare version files and fetch latest package if available. if [ -f "${CWDIR}/update/version" ]; then UPDATEVER=$(cat ${CWDIR}/update/version | tr -d .) CURRENTVER=$(cat ${CWDIR}/version | tr -d .) if [ "${UPDATEVER}" -gt "${CURRENTVER}" ]; then echo "New Extension package found, performing upgrade..." fetch -ao ${CWDIR}/update --no-verify-peer --timeout=30 ${GITURL} || \ error_notify "Error: A problem has occurred while fetching extension package." tar -xf ${CWDIR}/update/${BRANCH}.zip --exclude='.git*' --strip-components 1 -C ${CWDIR}/update chmod +x ${CWDIR}/update/${SCRIPTNAME} rm -f ${CWDIR}/update/${BRANCH}.zip cp -Rf ${CWDIR}/update/* ${CWDIR}/ rm -R ${CWDIR}/update # Logging the update event. UPDATEVERSION=$(cat ${CWDIR}/version) echo "${DATE}: Extension upgraded to ${UPDATEVERSION}" >> ${EXTLOGFILE} echo "Extension upgraded to version ${UPDATEVERSION}" echo "Extension package upgrade completed!" else echo "Extension is on the latest version!" rm -R ${CWDIR}/update fi fi } create_addon_env() { # Set bastille dir required permissions. chmod 0750 ${CWDIR} # Create required directories. if [ ! -d "${CWDIR}/backups" ]; then mkdir -p ${CWDIR}/backups fi if [ ! -d "${CWDIR}/log" ]; then mkdir -p ${CWDIR}/log fi if [ ! -d "${CWDIR}/${FULLAPPNAME}" ]; then mkdir -p ${CWDIR}/${FULLAPPNAME} fi if [ ! -d "${CWDIR}/${FULLAPPNAME}${BASTILLEPATH}" ]; then mkdir -p ${CWDIR}/${FULLAPPNAME}${BASTILLEPATH} fi if [ ! -d "${CWDIR}/freebsd-update" ]; then mkdir ${CWDIR}/freebsd-update fi # Link bastille-init to /usr/local/sbin. if [ ! -f "${USRLOCAL}/sbin/${SCRIPTNAME}" ]; then ln -fs ${CWDIR}/${SCRIPTNAME} ${USRLOCAL}/sbin/${SCRIPTNAME} fi } platform_check() { # Check for working platform. if [ "${PRDPLATFORM}" = "x64-embedded" ]; then create_addon_env ext_initial_download bastille_initial_download sys_symlinkdir include_files elif [ "${PRDPLATFORM}" = "x64-full" ]; then create_addon_env ext_initial_download bastille_initial_download sys_symlinkdir include_files fi } bin_symlinks() { # Main bastille symlinks. if [ -d "${INSTALLPATH}/${BASTILLEPATH}" ]; then cd ${INSTALLPATH}/${BASTILLEPATH} for file in * do ln -fhs ${INSTALLPATH}/${BASTILLEPATH}/${file} ${USRLOCAL}/bin/${file} done fi } sys_symlinkdir() { # Check and create/relink required symlinks/dirs for bastille. # This environment will be checked each time the script is started for consistency. # Link required binaries. bin_symlinks # Required directories for bastille. if [ ! -d "${USRLOCAL}/share/licenses" ]; then mkdir -p ${USRLOCAL}/share/licenses fi # Required symlinks for bastille. if [ -d "${INSTALLPATH}${USRLOCAL}/share/licenses" ]; then cd ${INSTALLPATH}${USRLOCAL}/share/licenses for file in * do ln -fhs ${INSTALLPATH}${USRLOCAL}/share/licenses/${file} ${USRLOCAL}/share/licenses/${file} done fi # Link bastille config file directory. if [ -d "${INSTALLPATH}${USRLOCAL}/etc/${APPNAME}" ]; then ln -fhs ${INSTALLPATH}${USRLOCAL}/etc/${APPNAME} ${USRLOCAL}/etc/${APPNAME} fi # Link bastille config file. #if [ -f "${INSTALLPATH}${USRLOCAL}/etc/${APPNAME}/${APPNAME}.conf.sample" ]; then # cd ${INSTALLPATH}${USRLOCAL}/etc/${APPNAME} # if [ ! -f "${APPNAME}.conf" ]; then # cp ${APPNAME}.conf.sample ${APPNAME}.conf # fi #else if [ -f "${BASTILLECONF_EXT}" ]; then if [ ! -f "${INSTALLPATH}${USRLOCAL}/etc/${APPNAME}/${APPNAME}.conf" ]; then cp ${BASTILLECONF_EXT} ${INSTALLPATH}${USRLOCAL}/etc/${APPNAME}/${APPNAME}.conf fi fi #fi # Copy bastille shared. if [ -d "${INSTALLPATH}${USRLOCAL}/share/${APPNAME}" ]; then ln -fhs ${INSTALLPATH}${USRLOCAL}/share/${APPNAME} ${USRLOCAL}/share/${APPNAME} fi # Copy bastille rc. if [ -f "${INSTALLPATH}${USRLOCAL}/etc/rc.d/${APPNAME}" ]; then cp ${INSTALLPATH}${USRLOCAL}/etc/rc.d/${APPNAME} ${USRLOCAL}/etc/rc.d/${APPNAME} fi } include_files() { if [ "$(freebsd-version | cut -d '.' -f1)" -ge 12 ]; then sysrc -f ${CWDIR}${EXTCONF} VNET_ENABLE="YES" >/dev/null 2>&1 # Include missing system files. if [ ! -f "/usr/bin/ar" ]; then if [ -f "${SYSTEM_INCLUDE}/ar" ]; then install -m 0555 ${SYSTEM_INCLUDE}/ar /usr/bin/ar fi fi if [ ! -f "/usr/local/bin/jib" ]; then if [ -f "${SYSTEM_INCLUDE}/jib" ]; then install -m 0544 ${SYSTEM_INCLUDE}/jib /usr/local/bin/jib fi fi if [ ! -f "/usr/sbin/setfib" ]; then if [ -f "${SYSTEM_INCLUDE}/setfib" ]; then install -m 0555 ${SYSTEM_INCLUDE}/setfib /usr/sbin/setfib fi fi if [ ! -f "/usr/bin/sum" ]; then if [ -f "${SYSTEM_INCLUDE}/sum" ]; then install -m 0555 ${SYSTEM_INCLUDE}/sum /usr/bin/sum fi fi if [ ! -f "/usr/bin/diff3" ]; then if [ -f "${SYSTEM_INCLUDE}/diff3" ]; then install -m 0555 ${SYSTEM_INCLUDE}/diff3 /usr/bin/diff3 fi fi if [ ! -f "/usr/bin/makewhatis" ]; then if [ -f "${SYSTEM_INCLUDE}/makewhatis" ]; then install -m 0555 ${SYSTEM_INCLUDE}/makewhatis /usr/bin/makewhatis fi fi else sysrc -f ${CWDIR}${EXTCONF} VNET_ENABLE="NO" >/dev/null 2>&1 fi if [ "$(freebsd-version | cut -d '.' -f1)" -ge 12 ]; then # Include missing pf(packet filter) files. PF_FILES="/pfctl /pfilctl /pflogd /pf.os" for _file in ${PF_FILES}; do if [ ! -f "/sbin/${_file}" ]; then if [ "${_file}" = "/pf.os" ]; then if [ ! -f "/etc/${_file}" ]; then if [ -f "${SYSTEM_INCLUDE}/${_file}" ]; then install -m 0644 ${SYSTEM_INCLUDE}/${_file} /etc/${_file} fi fi else if [ -f "${SYSTEM_INCLUDE}/${_file}" ]; then install -m 0555 ${SYSTEM_INCLUDE}/${_file} /sbin/${_file} fi fi fi done fi } required_updates() { # Check for critical and/or required updates and bug fixes and apply them. # This is because not always the bastille version is increased on updates and/or bug fixes. if [ -f "${INSTALLPATH}${USRLOCAL}/share/${APPNAME}/rename.sh" ]; then if ! grep -qw '{ZFS_DATASET_ORIGIN}.*{ZFS_DATASET_TARGET}' ${INSTALLPATH}${USRLOCAL}/share/${APPNAME}/rename.sh; then echo "Required update found, performing update..." echo "${DATE}: ${APPNAME} required update has been applied" >> ${EXTLOGFILE} REQUIRED_UPDATE="1" bastille_initial_download fi fi # Check for a critical bug that prevents VNET jail creation. if grep -q '\\"vnet host interface for Bastille jail ${NAME}"' ${INSTALLPATH}${USRLOCAL}/share/${APPNAME}/create.sh; then sed -i '' 's|\\"vnet host interface for Bastille jail ${NAME}"|\\"vnet host interface for Bastille jail ${NAME}\\"|g' ${INSTALLPATH}${USRLOCAL}/share/${APPNAME}/create.sh fi } postinit_cmd() { # Check and generate temporary php script for postinit command. if ! grep -qw ${CWDIR}/${SCRIPTNAME} ${CONFIG}; then touch ${CWDIR}/postinit || error_notify "Error: A problem has occurred while creating the postinit file." chmod +x ${CWDIR}/postinit if [ "${PRDVERSION}" -ge "110" ]; then # Generate php script for start/stop commands. cat << EOF > ${CWDIR}/postinit EOF fi # Execute temporary php script. if [ "${OBI_INSTALL}" != "ON" ]; then echo "Creating postinit command..." php-cgi -f ${CWDIR}/postinit && rm ${CWDIR}/postinit || \ error_notify "Error: A problem has occurred while executing postinit file." echo "Done!" fi # Set extension to enable by default. sysrc -f ${CWDIR}${EXTCONF} GUI_ENABLE=YES INSTALL_DIR=${CWDIR} >/dev/null 2>&1 fi } gui_start() { # Initialize the extension gui. if [ -d "${CWDIR}/gui" ]; then # Always ensure the config directory/file exist. if [ ! -f "${CWDIR}${EXTCONF}" ]; then # Try to restore default configuration. runtime_config # Set default config. sysrc -f ${CWDIR}${EXTCONF} GUI_ENABLE=YES INSTALL_DIR=${CWDIR} >/dev/null 2>&1 fi GUI_STATUS=$(sysrc -f ${CWDIR}${EXTCONF} -qn GUI_ENABLE) if [ "${GUI_STATUS}" = "YES" ]; then # Store the installation path and link conf. if ! sysrc -f ${CWDIR}${EXTCONF} -n INSTALL_DIR | grep -q "${CWDIR}"; then sysrc -f ${CWDIR}${EXTCONF} INSTALL_DIR=${CWDIR} >/dev/null 2>&1 fi mkdir -p ${BASTILLECONFLINK} ln -fhs ${CWDIR}/conf ${BASTILLECONFLINK}/conf # Link the gui files. if [ ! -d "${WWWPATH}/ext" ]; then mkdir -p ${WWWPATH}/ext fi ln -fhs ${CWDIR}/gui/ext/bastille ${WWWPATH}/ext/ || error_notify "Error: A problem has occurred while copying extension gui files." ln -fhs ${CWDIR}/gui/images ${WWWPATH}/ext/bastille/ || error_notify "Error: A problem has occurred while copying extension gui files." ln -fhs ${CWDIR}/gui/bastille_manager_*.php ${WWWPATH}/ || error_notify "Error: A problem has occurred while linking extension gui files." fi fi } gui_enable() { # Relink conf and gui files. if [ -d "${CWDIR}/gui" ]; then mkdir -p ${BASTILLECONFLINK} ln -fhs ${CWDIR}/conf ${BASTILLECONFLINK}/conf sysrc -f ${CWDIR}${EXTCONF} GUI_ENABLE=YES >/dev/null 2>&1 if [ ! -d "${WWWPATH}/ext" ]; then mkdir -p ${WWWPATH}/ext fi ln -fhs ${CWDIR}/gui/ext/bastille ${WWWPATH}/ext/ || error_notify "Error: A problem has occurred while copying extension gui files." ln -fhs ${CWDIR}/gui/images ${WWWPATH}/ext/bastille/ || error_notify "Error: A problem has occurred while copying extension gui files." ln -fhs ${CWDIR}/gui/bastille_manager_*.php ${WWWPATH}/ || error_notify "Error: A problem has occurred while copying extension gui files." exit 0 else error_notify "Error: Extension gui files not found." fi } gui_disable() { # Disable gui if -t option specified. if [ -d "${CWDIR}/gui" ]; then rm -f ${WWWPATH}bastille_manager_*.php rm -rf ${WWWPATH}/ext/bastille rm -rf ${WWWPATH}/ext/bastille/images rm -rf ${LOCALSHAREPATH}/locale-bastille rm -rf ${BASTILLECONFLINK} sysrc -f ${CWDIR}${EXTCONF} GUI_ENABLE=NO >/dev/null 2>&1 || error_notify "Error: A problem while removing extension gui files." exit 0 else error_notify "Error: Extension gui files not found." fi # Remove empty ext folder to prevent empty "Extensions" tab. if [ -d "${WWWPATH}/ext" ]; then if [ ! "$(ls -A ${WWWPATH}/ext)" ]; then rm -r ${WWWPATH}/ext fi fi } jail_update() { # Workaround since XigmaNAS does not ship with freebsd-update command. if [ "${PRDPRODUCT}" = "XigmaNAS" -o "${PRDPRODUCT}" = "NAS4Free" ]; then if [ ! -d "${FREEBSD_UPDATE}" ]; then echo "Not supported on ${PRDPRODUCT} platform." exit 1 fi else echo "Unsupported platform!"; exit 1 fi if [ ! -z "$(freebsd-version | grep -i HBSD)" ]; then echo "Not supported on HardenedBSD." exit 1 fi if [ -d "${bastille_jailsdir}/${TARGET}" ]; then if ! cat "${bastille_jailsdir}/${TARGET}/fstab" 2>/dev/null | grep -w "${TARGET}" | grep -qw "/.*/.bastille"; then if [ -f "${bastille_jailsdir}/${TARGET}/root/COPYRIGHT" ]; then if [ "$(jls name | grep -w "${TARGET}")" ]; then # Update a thick container. CURRENT_VERSION=$(jexec -l ${TARGET} freebsd-version) if [ -z "${CURRENT_VERSION}" ]; then echo "Can't determine '${TARGET}' version." exit 1 else env PAGER="/bin/cat" ${FREEBSD_UPDATE}/freebsd-update --not-running-from-cron -f ${FREEBSD_UPDATE}/freebsd-update.conf \ -d ${CWDIR}/freebsd-update -b "${bastille_jailsdir}/${TARGET}/root" fetch --currently-running "${CURRENT_VERSION}" ${FREEBSD_UPDATE}/freebsd-update --not-running-from-cron -f ${FREEBSD_UPDATE}/freebsd-update.conf \ -d ${CWDIR}/freebsd-update -b "${bastille_jailsdir}/${TARGET}/root" install --currently-running "${CURRENT_VERSION}" fi else echo "Container not running." echo "See 'bastille start ${TARGET}'." exit 1 fi else echo "${TARGET} state is unknown." exit 1 fi else echo "${TARGET} is not a thick container." exit 1 fi else if [ -d "${bastille_releasesdir}/${TARGET}" ]; then # Update container base(affects base child containers). env PAGER="/bin/cat" ${FREEBSD_UPDATE}/freebsd-update --not-running-from-cron -f ${FREEBSD_UPDATE}/freebsd-update.conf \ -d ${CWDIR}/freebsd-update -b "${bastille_releasesdir}/${TARGET}" fetch --currently-running "${TARGET}" ${FREEBSD_UPDATE}/freebsd-update --not-running-from-cron -f ${FREEBSD_UPDATE}/freebsd-update.conf \ -d ${CWDIR}/freebsd-update -b "${bastille_releasesdir}/${TARGET}" install --currently-running "${TARGET}" else echo "${TARGET} not found. See bootstrap." exit 1 fi fi exit 0 } release_upgrade() { if [ -d "${bastille_releasesdir}/${TARGET}" ]; then if [ -f "${bastille_releasesdir}/${TARGET}/COPYRIGHT" ]; then if [ "${TARGET}" = "${RELEASE}" ]; then echo "Specified releases name match." exit 0 fi # Upgrade a release base. echo "=> Run the command below several times when asked to finish installing updates." echo "bastille-init install ${TARGET}" echo env PAGER="/bin/cat" ${FREEBSD_UPDATE}/freebsd-update --not-running-from-cron -f ${FREEBSD_UPDATE}/freebsd-update.conf \ -d ${CWDIR}/freebsd-update -b "${bastille_releasesdir}/${TARGET}" --currently-running "${TARGET}" -r ${RELEASE} upgrade echo echo "=> Please run: 'bastille-init install ${TARGET}' to finish installing updates." else echo "Unknown ${RELEASE}. See bootstrap."; exit 1 fi else echo "${TARGET} not found. See bootstrap."; exit 1 fi exit 0 } release_install() { if [ -d "${bastille_releasesdir}/${TARGET}" ]; then if [ -f "${bastille_releasesdir}/${TARGET}/COPYRIGHT" ]; then # Finish installing upgrade on a thick container. env PAGER="/bin/cat" ${FREEBSD_UPDATE}/freebsd-update --not-running-from-cron -f ${FREEBSD_UPDATE}/freebsd-update.conf \ -d ${CWDIR}/freebsd-update -b "${bastille_releasesdir}/${TARGET}" install else echo "${TARGET} state is unknown." exit 1 fi else echo "${TARGET} not found. See bootstrap."; exit 1 fi exit 0 } release_change() { if [ ! -z "$(freebsd-version | grep -i HBSD)" ]; then echo "Not supported on HardenedBSD." exit 1 fi # Verify for user input and handle some errors. if [ -d "${bastille_jailsdir}/${TARGET}" ]; then if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then if [ -f "${bastille_releasesdir}/${RELEASE}/COPYRIGHT" ]; then # Check if the container is running. if [ "$(jls name | grep -w "${TARGET}")" ]; then echo "${TARGET} running." echo "See 'bastille stop ${TARGET}'." exit 1 elif [ "${RELEASE}" = "${NEWRELEASE}" ]; then echo "Specified releases name match." exit 0 fi if [ -d "${bastille_releasesdir}/${NEWRELEASE}" ]; then if [ -f "${bastille_releasesdir}/${NEWRELEASE}/COPYRIGHT" ]; then if [ -f "${bastille_jailsdir}/${TARGET}/fstab" ]; then # Check if is a thin container. if cat "${bastille_jailsdir}/${TARGET}/fstab" | grep "${RELEASE}" | grep -qw "/.*/.bastille"; then # If the previous conditions meets, proceed with the container base upgrade. sed -i '' "s/${RELEASE}/${NEWRELEASE}/g" ${bastille_jailsdir}/${TARGET}/fstab echo "${TARGET} release changed to ${NEWRELEASE}." elif cat "${bastille_jailsdir}/${TARGET}/fstab" | grep "${NEWRELEASE}" | grep -qw "/.*/.bastille"; then echo "${TARGET} already using ${NEWRELEASE}." exit 0 else if cat "${bastille_jailsdir}/${TARGET}/fstab" | grep -qw "/.*/.bastille"; then echo "${TARGET} container does not use ${RELEASE}."; exit 1 else echo "${TARGET} is not a thin container."; exit 1 fi fi else echo "${TARGET} fstab not found."; exit 1 fi else echo "Unknown ${NEWRELEASE}. See bootstrap."; exit 1 fi else echo "${NEWRELEASE} not found, bootstrap starting...." bastille bootstrap ${NEWRELEASE} if [ ! $? -ne 0 ]; then release_change fi fi else echo "Unknown ${RELEASE}. See bootstrap."; exit 1 fi else echo "${RELEASE} not found. See bootstrap."; exit 1 fi else echo "${TARGET} not found. See create."; exit 1 fi exit 0 } thickjail_upgrade() { # Workaround since XigmaNAS does not ship with freebsd-update command. if [ "${PRDPRODUCT}" = "XigmaNAS" -o "${PRDPRODUCT}" = "NAS4Free" ]; then if [ ! -d "${FREEBSD_UPDATE}" ]; then echo "Not supported on ${PRDPRODUCT} platform." exit 1 fi else echo "Unsupported platform!"; exit 1 fi if [ ! -z "$(freebsd-version | grep -i HBSD)" ]; then echo "Not supported on HardenedBSD." exit 1 fi # Verify for user input and handle some errors. if [ -d "${bastille_jailsdir}/${TARGET}" ]; then if ! cat "${bastille_jailsdir}/${TARGET}/fstab" 2>/dev/null | grep -w "${TARGET}" | grep -qw "/.*/.bastille"; then if [ -f "${bastille_jailsdir}/${TARGET}/root/COPYRIGHT" ]; then if [ "$(jls name | grep -w "${TARGET}")" ]; then # Upgrade a thick container. echo "=> Run the command below several times when asked to finish installing updates." echo "bastille-init install ${TARGET}" echo CURRENT_VERSION=$(jexec -l ${TARGET} freebsd-version) env PAGER="/bin/cat" ${FREEBSD_UPDATE}/freebsd-update --not-running-from-cron -f ${FREEBSD_UPDATE}/freebsd-update.conf \ -d ${CWDIR}/freebsd-update -b "${bastille_jailsdir}/${TARGET}/root" --currently-running "${CURRENT_VERSION}" -r ${RELEASE} upgrade echo echo "=> Please run: 'bastille-init install ${TARGET}' to finish installing updates." else echo "Container not running." echo "See 'bastille start ${TARGET}'." exit 1 fi else echo "${TARGET} state is unknown." exit 1 fi else echo "${TARGET} is not a thick container." exit 1 fi elif [ -d "${bastille_releasesdir}/${RELEASE}" ]; then # Try to upgrade a release instead. release_upgrade fi exit 0 } thickjail_install() { # Workaround since XigmaNAS does not ship with freebsd-update command. if [ "${PRDPRODUCT}" = "XigmaNAS" -o "${PRDPRODUCT}" = "NAS4Free" ]; then if [ ! -d "${FREEBSD_UPDATE}" ]; then echo "Not supported on ${PRDPRODUCT} platform." exit 1 fi else echo "Unsupported platform!"; exit 1 fi if [ ! -z "$(freebsd-version | grep -i HBSD)" ]; then echo "Not supported on HardenedBSD." exit 1 fi if [ -d "${bastille_jailsdir}/${TARGET}" ]; then if ! cat "${bastille_jailsdir}/${TARGET}/fstab" 2>/dev/null | grep -w "${TARGET}" | grep -qw "/.*/.bastille"; then if [ -f "${bastille_jailsdir}/${TARGET}/root/COPYRIGHT" ]; then if [ "$(jls name | grep -w "${TARGET}")" ]; then # Finish installing upgrade on a thick container. env PAGER="/bin/cat" ${FREEBSD_UPDATE}/freebsd-update --not-running-from-cron -f ${FREEBSD_UPDATE}/freebsd-update.conf \ -d ${CWDIR}/freebsd-update -b "${bastille_jailsdir}/${TARGET}/root" install else echo "Container not running." echo "See 'bastille start ${TARGET}'." exit 1 fi else echo "${TARGET} state is unknown." exit 1 fi else echo "${TARGET} is not a thick container." exit 1 fi elif [ -d "${bastille_releasesdir}/${RELEASE}" ]; then # Try to upgrade a release instead. release_install fi exit 0 } zfs_activate() { # Check if ZFS is already configured. # Always enforce ZFS activation below "/mnt/" from the extension. if echo "${BASTILLE_ZFS_ZPOOL_MOUNTPOINT_TRIM}" | grep -qw "${CWDIR_TRIM}$"; then BASTILLE_DIR=$(echo "${CWDIR}" | grep -o '[^/]*$') if [ "${bastille_zfs_prefix}" != "${BASTILLE_DIR}" ]; then error_notify "Invalid ZFS configuration." fi if zfs list "${bastille_zfs_zpool}/${BASTILLE_DIR}" > /dev/null 2>&1; then echo "Bastille ZFS is already configured." sysrc -f ${CWDIR}${EXTCONF} ZFS_ACTIVATED="YES" >/dev/null 2>&1 exit 0 else BASTILLE_DIRS="cache jails logs releases templates" for dir in ${BASTILLE_DIRS}; do if [ -d "${CWDIR}/${dir}" ]; then # Stop if any of the listed dirs already exist. error_notify "Bastille has been bootstrapped already, aborting." fi done fi echo "Enabling ZFS on ${PRDNAME} Extension..." # Confirm before conversion. while : do read -p "Do you really wish to enable ZFS for ${PRDNAME} Extension? [y/N]:" yn case ${yn} in [Yy]) break;; [Nn]) exit 0;; esac done echo "Proceeding..." if [ "${bastille_zfs_enable}" = "YES" ]; then if [ ! -z "${bastille_zfs_zpool}" ]; then if zfs list "${bastille_zfs_zpool}" > /dev/null 2>&1; then if ! zfs list "${bastille_zfs_zpool}/${BASTILLE_DIR}" > /dev/null 2>&1; then echo "Renaming existing '${BASTILLE_DIR}' directory" mv ${CWDIR} ${CWDIR}.old echo "Creating a new ZFS dataset for '${BASTILLE_DIR}'" zfs create ${bastille_zfs_options} ${bastille_zfs_zpool}/${bastille_zfs_prefix} if [ $? -ne 0 ]; then MSG="Failed to enable ZFS, reverting changes." echo "${MSG}" mv ${CWDIR}.old ${CWDIR} logger -t "${SCRIPTNAME}" "${MSG}" error_notify "${MSG}" else echo "Synchronizing '${BASTILLE_DIR}' data on new dataset" rsync -a ${CWDIR}.old/ ${CWDIR}/ fi else echo "Bastille ZFS is already configured." fi else error_notify "ERROR: ${bastille_zfs_zpool} is not a ZFS pool/dataset." fi else error_notify "Bastille ZPOOL is not set." fi echo "ZFS Enabled for ${PRDNAME} Extension successfully." else error_notify "Bastille ZFS option is not set." fi else error_notify "Invalid ZFS configuration." fi sysrc -f ${CWDIR}${EXTCONF} ZFS_ACTIVATED="YES" >/dev/null 2>&1 exit 0 } pkg_upgrade() { # Re-fetch bastille package and extract. if [ -f "${CWDIR}/${FULLAPPNAME}${BASTILLEPATH}/${APPNAME}" ]; then bastille_upgrade else bastille_initial_download fi # Check for extension updates. extension_upgrade } reset_install() { # Reset the extension environment. echo "Removing extension files..." if [ -f "${CWDIR}/conf/bastille_config" ]; then rm -rf ${CWDIR}/conf/bastille_config fi if [ -d "${CWDIR}/${FULLAPPNAME}" ]; then rm -rf ${CWDIR}/${FULLAPPNAME} fi if [ -d "${CWDIR}/download" ]; then rm -rf ${CWDIR}/download fi if [ -f "${CWDIR}/version" ]; then rm -f ${CWDIR}/version fi # Set default config. sysrc -f ${CWDIR}${EXTCONF} GUI_ENABLE=YES INSTALL_DIR=${CWDIR} >/dev/null 2>&1 echo "" echo "*************************************************************************************************************" echo "* The configuration was reset, please go to [Extensions > Bastille > Configuration] to configure bastille. *" echo "* Alternatively you can edit the '/usr/local/etc/bastille/bastille.conf' file manually. *" echo "*************************************************************************************************************" echo "" echo "Notice: If Linux Jail support was enabled, please execute the below command to re-enable it:" echo "==> sysrc -f ${CWDIR}${EXTCONF} LINUX_COMPAT_SUPPORT=\"YES\"" echo "" } remove_addon() { # Confirm for addon removal. while : do read -p "Do you wish to proceed with the ${FULLAPPNAME} removal? [y/N]:" yn case ${yn} in [Yy]) break;; [Nn]) exit 0;; esac done echo "Proceeding..." # Check for working platform and remove symlinks. if [ "${PRDPLATFORM}" = "x64-embedded" ] || [ "${PRDPLATFORM}" = "x64-full" ]; then if [ -d "${USRLOCAL}/share/licenses/${APPNAME}-*" ]; then rm -rf ${USRLOCAL}/share/licenses/${APPNAME}-* fi if [ -d $"{USRLOCAL}/share/locale-bastille" ]; then rm -rf ${USRLOCAL}/share/locale-bastille fi if [ -f "${USRLOCAL}/etc/rc.d/${APPNAME}" ]; then rm -f ${USRLOCAL}/etc/rc.d/${APPNAME} fi if [ -f "${USRLOCAL}/etc/${APPNAME}.conf" ]; then rm -f ${USRLOCAL}/etc/${APPNAME}.conf fi if [ -f "${BASTILLEPATH}/${APPNAME}" ]; then rm -f ${BASTILLEPATH}/${APPNAME} fi if [ -f "${USRLOCAL}/sbin/${APPNAME}-init" ]; then rm -rf ${USRLOCAL}/sbin/${APPNAME}-init fi if [ -d "${VARLOG}/${APPNAME}" ]; then rm -rf ${VARLOG}/${APPNAME} fi fi # Remove extension and GUI components. if [ -f "${WWWPATH}/bastille_manager_gui.php" ]; then rm -f ${WWWPATH}/bastille_manager_*.php fi if [ -d "${WWWPATH}/ext/bastille" ]; then rm -rf ${WWWPATH}/ext/bastille fi if [ -f "${USRLOCAL}/bin/${APPNAME}" ]; then rm -rf ${USRLOCAL}/bin/${APPNAME} fi if [ -d "${VARLOG}/${APPNAME}" ]; then rm -rf ${VARLOG}/${APPNAME} fi # Remove empty ext folder to prevent empty "Extensions" tab. if [ -d "${WWWPATH}/ext" ]; then if [ ! "$(ls -A ${WWWPATH}/ext)" ]; then rm -R ${WWWPATH}/ext fi fi # Remove addon related files and folders only- # to protect any user-created custom files- # as well as for the containers dirs/files. FILES="conf download freebsd-update gui locale-bastille log bastille-dist LICENSE README.md postinit CHANGELOG version bastille-init" for FILE in ${FILES}; do if [ -f "${CWDIR}/${FILE}" ] || [ -d "${CWDIR}/${FILE}" ]; then rm -rf ${CWDIR}/${FILE} fi done BIN_FILES="/usr/local/bin/ar /usr/local/bin/jib /usr/sbin/setfib /usr/bin/sum /usr/bin/diff3 /usr/bin/makewhatis" for FILE in ${BIN_FILES}; do if [ -f "${FILE}" ]; then rm -rf ${FILE} fi done # Don't remove this files on 13.x versions since they are part of the base. if [ "$(freebsd-version | cut -d '.' -f1)" -le 12 ]; then PF_FILES="/sbin/pfctl /sbin/pfilctl /sbin/pflogd /etc/pf.os" for FILE in ${PF_FILES}; do if [ -f "${FILE}" ]; then rm -rf ${FILE} fi done fi echo "Done!" echo "Please manually remove the Bastille Extension Command Script from the WebGUI." exit 0 } get_versions() { # Get product versions. if [ -f "${CWDIR}/version" ]; then APPVERSION=$(cat ${CWDIR}/version) else APPVERSION="version file not found!" fi # Display product versions. BASTILLEVER=$(${USRLOCAL}/bin/bastille --version) echo "Bastille version: ${BASTILLEVER}" echo "Extension version: ${APPVERSION}" exit 0 } ext_start() { if sysrc -f ${CWDIR}${EXTCONF} -qn LINUX_COMPAT_SUPPORT | grep -q "YES"; then ${CWDIR}/unionfs.sh load_kmods ${CWDIR}/unionfs.sh unionfs_on fi # Start bastille jails. if [ -d "${CWDIR}/jails" ]; then JAIL_LIST=$(bastille list jail) for jail in ${JAIL_LIST}; do if grep -qw "${jail}_AUTO_START=\"YES\"" ${CWDIR}${EXTCONF}; then if ! jls | sed "1 d" | awk '{print $3}' | grep -qw ${jail}; then bastille start ${jail} fi fi done fi if [ $? -eq 0 ]; then MSG="script has been started successfully!" logger -t ${SCRIPTNAME} ${MSG} exit 0 else MSG="script started with faults!" logger -t ${SCRIPTNAME} ${MSG} exit 1 fi } rc_params() { # Bastille required parameters. # Set bastille prefix. if ! sysrc -f ${BASTILLECONF} -qn bastille_prefix | grep -q "${CWDIR}"; then sysrc -f ${BASTILLECONF} bastille_prefix="${CWDIR}" >/dev/null 2>&1 fi # Set required variables. if ! sysrc -f ${BASTILLECONF} -qc bastille_compress_gz_options; then sysrc -f ${BASTILLECONF} bastille_compress_gz_options="-1 -v" >/dev/null 2>&1 fi if ! sysrc -f ${BASTILLECONF} -qc bastille_decompress_gz_options; then sysrc -f ${BASTILLECONF} bastille_decompress_gz_options="-k -d -c -v" >/dev/null 2>&1 fi if ! sysrc -f ${BASTILLECONF} -qc bastille_pf_conf; then sysrc -f ${BASTILLECONF} bastille_pf_conf="${CWDIR}/pf.conf" >/dev/null 2>&1 fi # Set bastille.conf location. if ! sysrc -f ${CWDIR}${EXTCONF} -n BASTILLE_CONFIG 2>/dev/null | grep -q "${CWDIR}/${FULLAPPNAME}${BASTILLECONF}"; then sysrc -f ${CWDIR}${EXTCONF} BASTILLE_CONFIG="${CWDIR}/${FULLAPPNAME}${BASTILLECONF}" >/dev/null 2>&1 fi # Default first network interface. ACTIVE_NETIF=$(ifconfig | grep "UP,BROADCAST" | awk -F":" '{print $1}' | sed 1q) if ! sysrc -f ${BASTILLECONF} -qn bastille_network_shared | grep -q "${ACTIVE_NETIF}" >/dev/null 2>&1; then #echo "" >> ${BASTILLECONF} && echo "## default network interface" >> ${BASTILLECONF} sysrc -f ${BASTILLECONF} bastille_network_shared="${ACTIVE_NETIF}" >/dev/null 2>&1 else EXT_NETIF=$(sysrc -f ${BASTILLECONF} -qn bastille_network_shared) if [ -z "${EXT_NETIF}" ]; then #echo "" >> ${BASTILLECONF} && echo "## default network interface" >> ${BASTILLECONF} sysrc -f ${BASTILLECONF} bastille_network_shared="${ACTIVE_NETIF}" >/dev/null 2>&1 fi fi # Do't start containers by default. if ! sysrc -qn bastille_enable >/dev/null 2>&1; then sysrc bastille_enable="NO" >/dev/null 2>&1 fi # Check if sane ZFS is enabled in this setup. if [ "${bastille_zfs_enable}" = "YES" ]; then if [ -n "${bastille_zfs_zpool}" ]; then if zfs list "${bastille_zfs_zpool}" > /dev/null 2>&1; then BASTILLE_DIR=$(echo ${CWDIR} | grep -o '[^/]*$') if zfs list "${bastille_zfs_zpool}/${BASTILLE_DIR}" > /dev/null 2>&1; then sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="YES" >/dev/null 2>&1 else if echo "${BASTILLE_ZFS_ZPOOL_MOUNTPOINT_TRIM}" | grep -qw "${CWDIR_TRIM}$"; then sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="AVA" >/dev/null 2>&1 else sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="ERR" >/dev/null 2>&1 fi fi else sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="ERR" >/dev/null 2>&1 fi else sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="ERR" >/dev/null 2>&1 fi else sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="NO" >/dev/null 2>&1 fi } update_config() { # Update config based on minimum version. # Network parameters. if grep -qw 'bastille_jail_loopback=' ${INSTALLPATH}/${BASTILLECONF}; then sed -i '' 's/bastille_jail_loopback=/bastille_network_loopback=/' ${INSTALLPATH}/${BASTILLECONF} fi if grep -qw 'bastille_jail_external=' ${INSTALLPATH}/${BASTILLECONF}; then sed -i '' 's/bastille_jail_external=/bastille_network_shared=/' ${INSTALLPATH}/${BASTILLECONF} fi if grep -qw 'bastille_jail_gateway=' ${INSTALLPATH}/${BASTILLECONF}; then sed -i '' 's/bastille_jail_gateway=/bastille_network_gateway=/' ${INSTALLPATH}/${BASTILLECONF} fi if ! grep -qw 'bastille_url_freebsd=' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_url_freebsd="${URL_FREEBSD}" fi if ! grep -qw 'bastille_url_hardenedbsd=' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_url_hardenedbsd="${URL_HARDENEDBSD}" fi if ! grep -qw 'bastille_url_midnightbsd=' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_url_midnightbsd="${URL_MIDNIGHTBSD}" fi if ! grep -qw 'bastille_network_pf_ext_if=' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_network_pf_ext_if="ext_if" fi if ! grep -qw 'bastille_network_pf_table=' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_network_pf_table="jails" fi if ! grep -qw 'bastille_network_gateway6=' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_network_gateway6="" fi # Template parameters. if ! grep -qw 'bastille_template_base=' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_template_base="default/base" fi if ! grep -qw 'bastille_template_empty=' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_template_empty="" fi if ! grep -qw 'bastille_template_thick=' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_template_thick="default/thick" fi if ! grep -qw 'bastille_template_thin=' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_template_thin="default/thin" fi if ! grep -qw 'bastille_template_vnet=' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_template_vnet="default/vnet" fi # Remove deprecated parameters based on minimum version. if grep -qw 'bastille_jail_interface' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} -x bastille_jail_interface fi if grep -qw 'bastille_jail_addr' ${INSTALLPATH}/${BASTILLECONF}; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} -x bastille_jail_addr fi # Update the bootstrap urls accordingly. if ! sysrc -f ${INSTALLPATH}/${BASTILLECONF} -n bastille_url_hardenedbsd | grep -qw "${URL_HARDENEDBSD}"; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_url_hardenedbsd="${URL_HARDENEDBSD}" fi } bastille_start() { # Start all bastille containers. echo "${PRDNAME} Extension: Starting all containers..." bastille start ALL if [ $? -eq 0 ]; then exit 0 else exit 1 fi } bastille_stop() { # Stop all bastille containers. echo "${PRDNAME} Extension: Stopping all containers..." bastille stop ALL if [ $? -eq 0 ]; then exit 0 else exit 1 fi } bastille_restart() { # Restart all bastille containers. echo "${PRDNAME} Extension: Restarting all containers..." bastille restart ALL if [ $? -eq 0 ]; then exit 0 else exit 1 fi } bastille_init() { # Check for system compatibility. if [ ! "${PLATFORM}" = "amd64" ]; then echo "Unsupported platform!"; exit 1 fi # Check for product compatibility. if [ ! "${PRDVERSION}" -ge "112" ]; then echo "Unsupported version!"; exit 1 fi echo "Initializing ${APPNAME}..." # Function calls. platform_check required_updates postinit_cmd gui_start rc_params ext_start } linux_compat() { if ping -c1 -t5 freebsd.org > /dev/null; then # Manually enable Linux compatibility(Experimental). if ! sysrc -f ${CWDIR}${EXTCONF} -qn LINUX_COMPAT_SUPPORT | grep -q "YES"; then ${CWDIR}/unionfs.sh fetch_pkg && ${CWDIR}/unionfs.sh load_kmods && ${CWDIR}/unionfs.sh unionfs_on && sysrc -f ${CWDIR}${EXTCONF} LINUX_COMPAT_SUPPORT="YES" >/dev/null 2>&1 else echo "Already enabled." fi exit 0 else echo "Internet connection required to enable this feature." exit 1 fi } linux_compat_disable() { if sysrc -f ${CWDIR}${EXTCONF} -qn LINUX_COMPAT_SUPPORT | grep -q "YES"; then echo "Disabling Linux jail compatibility support..." sysrc -f ${CWDIR}${EXTCONF} -x LINUX_COMPAT_SUPPORT echo "Done!, server reboot is recommended." fi exit 0 } # Run-time configuration. runtime_config TARGET="${2}" RELEASE="${3}" NEWRELEASE="${4}" # Handle additional commands. case "${OPT}" in install|--install) if [ $# -gt 2 ] || [ $# -lt 2 ]; then echo "Usage: ${SCRIPTNAME} [install|--install] [container]" exit 1 fi thickjail_install ;; upgrade|--upgrade) # Check container type to upgrade if [ -z "${NEWRELEASE}" ]; then if [ $# -gt 3 ] || [ $# -lt 3 ]; then echo "Usage: ${SCRIPTNAME} [upgrade|--upgrade] [container|release] [release]" exit 1 fi thickjail_upgrade else if [ $# -gt 4 ] || [ $# -lt 4 ]; then echo "Usage: ${SCRIPTNAME} [upgrade|--upgrade] [container] [release] [newrelease]" exit 1 fi release_change fi ;; update|--update) if [ $# -gt 2 ] || [ $# -lt 2 ]; then echo "Usage: ${SCRIPTNAME} [update|--update] [container] | [release]" exit 1 fi jail_update ;; clean|--clean) for file in ${CWDIR}/freebsd-update/*; do rm -rf ${file} done exit 0 ;; linux_compat) linux_compat ;; linux_compat_disable) linux_compat_disable ;; bastillebsd_update) bastille_core_update ;; esac while getopts ":ospruxUvgtZh" option; do case ${option} in [h]) echo "Usage: ${SCRIPTNAME} -[option] | [container] | [path]"; echo "Options:" echo " -s Start All ${PRDNAME} Containers." echo " -p Stop All ${PRDNAME} Containers." echo " -r Restart All ${PRDNAME} Containers." echo " -u Upgrade ${PRDNAME}/Extension packages." echo " -v Display product versions." echo " -g Enables the addon GUI." echo " -t Disable the addon GUI." echo " -Z Activate ZFS for ${PRDNAME} Extension." echo " -x Reset ${PRDNAME}/Extension config." echo " -U Uninstall ${PRDNAME} (Extension files only)." #echo " -L Enable Linux compatibility(Experimental)." echo " -h Display this help message." echo echo "Advanced Usage: ${SCRIPTNAME} [option] [container] [release] | [newrelease]" echo "Options:" echo " update|--update Update a container/release to base -pX release." echo " upgrade|--upgrade Upgrade a container/release to X.Y-RELEASE." echo " install|--install Finish installing pending updates on container/release." echo " clean|--clean Cleanup the FreeBSD update/upgrade cached files/folders." echo "" echo "" echo "Experimental:" echo "To enable experimental Linux jail support please execute: \"${SCRIPTNAME} linux_compat\"" echo "To disable experimental Linux jail support please execute: \"${SCRIPTNAME} linux_compat_disable\"" echo "" echo "" echo "Support:" echo "To update BastilleBSD core files only to the latest patches and fixes, please execute: \"${SCRIPTNAME} bastillebsd_update\"" echo ""; exit 0;; [o]) OBI_INSTALL="ON";; # To prevent nested PHP-CGI call for installation with OBI. [s]) bastille_start;; [p]) bastille_stop;; [r]) bastille_restart;; [u]) pkg_upgrade;; [x]) reset_install;; [U]) remove_addon;; [v]) get_versions;; [g]) gui_enable; exit 0 ;; # For enable the addon gui. [t]) gui_disable; exit 0 ;; # For disable the addon gui. [Z]) zfs_activate;; #[L]) linux_compat;; [?]) echo "Invalid option, -h for usage."; exit 1;; esac done bastille_init