diff --git a/.gitignore b/.gitignore index accb26a4..2f6aa1bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ docs/_build +freebsd_commands/* diff --git a/poc/linux_vnet.sh b/poc/linux_vnet.sh new file mode 100644 index 00000000..1dd065c5 --- /dev/null +++ b/poc/linux_vnet.sh @@ -0,0 +1,2 @@ +sudo bastille destroy linux_vnet1 +sudo bastille create -L -V linux_vnet1 trusty 10.0.0.1 bastille0 diff --git a/poc/network.sh b/poc/network.sh new file mode 100644 index 00000000..fafed993 --- /dev/null +++ b/poc/network.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# device init +ifconfig epair0 create up +ifconfig epair1 create up +ifconfig bridge0 create up + +# name setting +ifconfig epair0a name veth0 +ifconfig epair0b name veth0-bridge +ifconfig epair1a name veth1-bridge +ifconfig epair1b name veth1 + +ifconfig bridge0 addm veth0-bridge addm veth1-bridge + +# address setting +ifconfig veth0 inet 10.0.1.1/24 +#ifconfig veth0-bridge 10.0.1.2/24 +#ifconfig veth1-bridge 10.0.1.3/24 + diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index 0542bed8..bed58272 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -73,7 +73,7 @@ bastille_perms_check() { bastille_perms_check ## version -BASTILLE_VERSION="0.9.20220714" +BASTILLE_VERSION= usage() { cat << EOF diff --git a/usr/local/bin/bastille.orig b/usr/local/bin/bastille.orig new file mode 100755 index 00000000..bed58272 --- /dev/null +++ b/usr/local/bin/bastille.orig @@ -0,0 +1,221 @@ +#!/bin/sh +# +# Copyright (c) 2018-2022, 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. + +PATH=${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin + +. /usr/local/share/bastille/common.sh + +## root check first. +bastille_root_check() { + if [ "$(id -u)" -ne 0 ]; then + ## permission denied + error_notify "Bastille: Permission Denied" + error_exit "root / sudo / doas required" + fi +} + +bastille_root_check + +## check for config existance +bastille_conf_check() { + if [ ! -r "/usr/local/etc/bastille/bastille.conf" ]; then + error_exit "Missing Configuration" + 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() { + if [ -d "${bastille_prefix}" ]; then + BASTILLE_PREFIX_PERMS=$(stat -f "%Op" "${bastille_prefix}") + if [ "${BASTILLE_PREFIX_PERMS}" != 40750 ]; then + error_notify "Insecure permissions on ${bastille_prefix}" + error_exit "Try: chmod 0750 ${bastille_prefix}" + fi + fi +} + +bastille_perms_check + +## version +BASTILLE_VERSION= + +usage() { + cat << EOF +Bastille is an open-source system for automating deployment and management of +containerized applications on FreeBSD. + +Usage: + bastille command TARGET [args] + +Available Commands: + bootstrap Bootstrap a FreeBSD release for container base. + cmd Execute arbitrary command on targeted container(s). + clone Clone an existing container. + config Get or set a config value for the targeted container(s). + console Console into a running container. + convert Convert a Thin container into a Thick container. + cp cp(1) files from host to targeted container(s). + 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). + export Exports a specified container. + help Help about any command. + htop Interactive process viewer (requires htop). + import Import a specified container. + limits Apply resources limits to targeted container(s). See rctl(8). + list List containers (running and stopped). + mount Mount a volume inside the targeted container(s). + pkg Manipulate binary packages within targeted container(s). See pkg(8). + rdr Redirect host port to container port. + rename Rename a container. + restart Restart a running container. + service Manage services within targeted container(s). + start Start a stopped container. + stop Stop a running container. + sysrc Safely edit rc files within targeted container(s). + template Apply file templates to targeted container(s). + top Display and update information about the top(1) cpu processes. + umount Unmount a volume from within the targeted container(s). + update Update container base -pX release. + upgrade Upgrade container release to X.Y-RELEASE. + verify Compare release against a "known good" index. + zfs Manage (get|set) ZFS attributes on targeted container(s). + +Use "bastille -v|--version" for version information. +Use "bastille command -h|--help" for more information about a command. + +EOF + exit 1 +} + +[ $# -lt 1 ] && usage + +CMD=$1 +shift + +# 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|start|update|upgrade|verify) + # Nothing "extra" to do for these commands. -- cwells + ;; +clone|config|cmd|console|convert|cp|edit|htop|limits|mount|pkg|rename|service|stop|sysrc|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 + + if [ "${TARGET}" = 'ALL' ]; then + _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 + elif [ "${CMD}" = "pkg" ] && [ "${TARGET}" = '-H' ] || [ "${TARGET}" = '--host' ]; then + TARGET="${1}" + USE_HOST_PKG=1 + JAILS="${TARGET}" + shift + + # Require the target to be running + if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then + error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'." + fi + 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) + # Require the target to be running. -- cwells + if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then + error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'." + fi + ;; + 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 + ;; +esac + +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 +else + error_exit "${SCRIPTPATH} not found." +fi diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index b106e28b..277f2789 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -544,6 +544,13 @@ http?://*/*/*) bootstrap_template ;; #adding Ubuntu Bionic as valid "RELEASE" for POC @hackacad +ubuntu_trusty|trusty|ubuntu-trusty) + PLATFORM_OS="Ubuntu/Linux" + LINUX_FLAVOR="trusty" + DIR_BOOTSTRAP="Ubuntu_1404" + ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} + debootstrap_release + ;; ubuntu_bionic|bionic|ubuntu-bionic) PLATFORM_OS="Ubuntu/Linux" LINUX_FLAVOR="bionic" diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index adc1ac21..cf777620 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -66,7 +66,9 @@ generate_vnet_jail_netblock() { local jail_name="$1" local use_unique_bridge="$2" local external_interface="$3" - ## determine number of containers + 1 + local linux_jail="$4" + + ## determine number of containers + 1 ## iterate num and grep all jail configs ## define uniq_epair local jail_list=$(bastille list jails) @@ -83,12 +85,24 @@ generate_vnet_jail_netblock() { fi done else - local uniq_epair="bastille0" + local uniq_epair="bridge0" local uniq_epair_bridge="0" fi if [ -n "${use_unique_bridge}" ]; then ## generate bridge config - cat <<-EOF + if [ -n "${linux_option}" ];then +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 +cat <<-EOF vnet; vnet.interface = "e${uniq_epair_bridge}b_${jail_name}"; exec.prestart += "ifconfig epair${uniq_epair_bridge} create"; @@ -98,6 +112,7 @@ generate_vnet_jail_netblock() { 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 + fi else ## generate config cat <<-EOF diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index bc2cf700..456fe83c 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -179,6 +179,8 @@ ${NAME} { path = ${bastille_jail_path}; securelevel = 2; + + allow.raw_sockets; interface = ${bastille_jail_conf_interface}; ${IP4_DEFINITION} ${IP6_DEFINITION} @@ -196,12 +198,13 @@ ${NAME} { devfs_ruleset = 4; enforce_statfs = 1; - exec.start = '/bin/true'; - exec.stop = '/bin/true'; + exec.start = ''; + exec.stop = ''; persist; allow.mount; allow.mount.devfs; + allow.raw_sockets; interface = ${bastille_jail_conf_interface}; ${ipx_addr} = ${IP}; @@ -210,6 +213,29 @@ ${NAME} { EOF } +generate_vnet_linux_jail_conf() { + NETBLOCK=$(generate_vnet_jail_netblock "$NAME" "${VNET_JAIL_BRIDGE}" "${bastille_jail_conf_interface}" "Linux") + cat << EOF > "${bastille_jail_conf}" +${NAME} { + host.hostname = ${NAME}; + mount.fstab = ${bastille_jail_fstab}; + path = ${bastille_jail_path}; + devfs_ruleset = 4; + enforce_statfs = 1; + + exec.start = ''; + exec.stop = ''; + persist; + + allow.mount; + allow.mount.devfs; + allow.raw_sockets; + +${NETBLOCK} +} +EOF +} + generate_vnet_jail_conf() { NETBLOCK=$(generate_vnet_jail_netblock "$NAME" "${VNET_JAIL_BRIDGE}" "${bastille_jail_conf_interface}") cat << EOF > "${bastille_jail_conf}" @@ -218,7 +244,9 @@ ${NAME} { enforce_statfs = 2; exec.clean; exec.consolelog = ${bastille_jail_log}; - exec.start = '/bin/sh /etc/rc'; + exec.start = '/bin/true' + exec.stop = '/bin/true' + exec.start = '/bin/sh /etc/rc'; exec.stop = '/bin/sh /etc/rc.shutdown'; host.hostname = ${NAME}; mount.devfs; @@ -261,7 +289,11 @@ post_create_jail() { # Generate the jail configuration file. if [ -n "${VNET_JAIL}" ]; then - generate_vnet_jail_conf + if [ -z "${LINUX_JAIL}"]; then + generate_vnet_jail_conf + else + echo "linux + vnet jail!" + fi else generate_jail_conf fi @@ -477,7 +509,11 @@ create_jail() { fi elif [ -n "${LINUX_JAIL}" ]; then ## Generate configuration for Linux jail - generate_linux_jail_conf + if [ -n "${VNET_JAIL}"]; then + generate_vnet_linux_jail_conf + else + generate_linux_jail_conf + fi elif [ -n "${EMPTY_JAIL}" ]; then ## Generate minimal configuration for empty jail generate_minimal_conf @@ -496,7 +532,7 @@ create_jail() { fi fi - if [ -n "${VNET_JAIL}" ]; then + if [ -n "${VNET_JAIL}" && -z "${LINUX_JAIL}" ]; then if [ -n "${bastille_template_vnet}" ]; then ## rename interface to generic vnet0 uniq_epair=$(grep vnet.interface "${bastille_jailsdir}/${NAME}/jail.conf" | awk '{print $3}' | sed 's/;//') @@ -558,12 +594,15 @@ create_jail() { ## Using templating function to fetch necessary packges @hackacad elif [ -n "${LINUX_JAIL}" ]; then info "Fetching packages..." - 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 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 "apt update" - else + #jexec -l "${NAME}" /bin/bash -c "apt update" + if [ -n "${VNET_JAIL}" ]; then + info "vnet setting to linux jail." + fi + else # Thin jail. if [ -n "${bastille_template_thin}" ]; then bastille template "${NAME}" ${bastille_template_thin} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" @@ -645,7 +684,7 @@ if [ -n "${EMPTY_JAIL}" ]; then fi elif [ -n "${LINUX_JAIL}" ]; then if [ -n "${EMPTY_JAIL}" ] || [ -n "${VNET_JAIL}" ] || [ -n "${THICK_JAIL}" ] || [ -n "${CLONE_JAIL}" ]; then - error_exit "Error: Linux jail option can't be used with other options." + echo "Warning: Linux jail option can't be used with other options." fi elif [ -n "${CLONE_JAIL}" ] && [ -n "${THICK_JAIL}" ]; then error_exit "Error: Clonejail and Thickjail can't be used together." @@ -670,10 +709,14 @@ fi if [ -n "${NAME}" ]; then validate_name fi - if [ -n "${LINUX_JAIL}" ]; then case "${RELEASE}" in - bionic|ubuntu_bionic|ubuntu|ubuntu-bionic) + trusty|ubuntu_trusty|ubuntu-trusty) + ## check for FreeBSD releases name + NAME_VERIFY=ubuntu_trusty + ;; + + bionic|ubuntu_bionic|ubuntu|ubuntu-bionic) ## check for FreeBSD releases name NAME_VERIFY=ubuntu_bionic ;; @@ -743,7 +786,12 @@ if [ -z "${EMPTY_JAIL}" ]; then NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build-latest)' | sed 's/CURRENT/current/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') validate_release ;; - ubuntu_bionic|bionic|ubuntu-bionic) + ubuntu_trusty|trusty|ubuntu-trusty) + UBUNTU="1" + NAME_VERIFY=Ubuntu_1404 + validate_release + ;; + ubuntu_bionic|bionic|ubuntu-bionic) UBUNTU="1" NAME_VERIFY=Ubuntu_1804 validate_release @@ -792,7 +840,7 @@ if [ -z "${EMPTY_JAIL}" ]; then if [ -n "${INTERFACE}" ]; then validate_netif validate_netconf - elif [ -n "${VNET_JAIL}" ]; then + elif [ -n "${VNET_JAIL}" $$ -z "${LINUX_JAIL}"]; then if [ -z "${INTERFACE}" ]; then if [ -z "${bastille_network_shared}" ]; then # User must specify interface on vnet jails. @@ -801,6 +849,8 @@ if [ -z "${EMPTY_JAIL}" ]; then validate_netconf fi fi + elif [-n "${LINUX_JAIL}"]; then + echo "linux vnet jail!" else validate_netconf fi