diff --git a/docs/chapters/subcommands/create.rst b/docs/chapters/subcommands/create.rst index adab8667..d577c7e0 100644 --- a/docs/chapters/subcommands/create.rst +++ b/docs/chapters/subcommands/create.rst @@ -48,3 +48,27 @@ Also, uname does not work from within a jail. Much like MOTD, it gives you the information about the host system instead of the jail. If you need to check the version of freebsd running on the jail use the freebsd-version command to get accurate information. + +Bastille can create many different types of jails, along with many different options. See +the below help output. + +.. code-block:: shell + + ishmael ~ # bastille create help + + Usage: bastille create [option(s)] NAME RELEASE IP_ADDRESS [interface]" + + Options: + + -B | --bridge Enables VNET, VNET containers are attached to a specified, already existing external bridge. + -C | --clone Creates a clone container, they are duplicates of the base release, consume low space and preserves changing data. + -D | --dual Creates the jails with both IPv4 and IPv6 networking ('inherit' and 'ip_hostname' 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. + -M | --static-mac Generate a static MAC address for jail (VNET only). + --no-validate Do not validate the release when creating the jail. + -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. + -x | --debug Enable debug mode. + -Z | --zfs-opts [zfs,options] Comma separated list of ZFS options to create the jail with. This overrides the defaults. + diff --git a/docs/chapters/template.rst b/docs/chapters/template.rst index a2a317cf..e7e2f95e 100644 --- a/docs/chapters/template.rst +++ b/docs/chapters/template.rst @@ -33,6 +33,8 @@ Template Automation Hooks +-------------+---------------------+-----------------------------------------+ | CP/OVERLAY | path(s) | etc root usr (one per line) | +-------------+---------------------+-----------------------------------------+ +| HOSTCMD | command | pkg info | ++-------------+---------------------+-----------------------------------------+ | INCLUDE | template path/URL | http?://TEMPLATE_URL or project/path | +-------------+---------------------+-----------------------------------------+ | LIMITS | resource value | memoryuse 1G | @@ -74,6 +76,8 @@ CONFIG - set the specified property and value CP/OVERLAY - copy specified files from template directory to specified path inside jail +HOSTCMD - run the specified command on the host instead of the jail + INCLUDE - specify a template to include. Make sure the template is bootstrapped, or you are using the template url LIMITS - set the specified resource value for the jail diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index 93691788..7dd48a7b 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -203,6 +203,7 @@ case "${CMD}" in etcupdate| \ export| \ htop| \ + jcp | \ import| \ limits| \ list| \ diff --git a/usr/local/etc/bastille/bastille.conf.sample b/usr/local/etc/bastille/bastille.conf.sample index 4e6395c9..cfdca5b0 100644 --- a/usr/local/etc/bastille/bastille.conf.sample +++ b/usr/local/etc/bastille/bastille.conf.sample @@ -66,3 +66,4 @@ bastille_template_thick="default/thick" ## default bastille_template_clone="default/clone" ## default: "default/clone" bastille_template_thin="default/thin" ## default: "default/thin" bastille_template_vnet="default/vnet" ## default: "default/vnet" +bastille_template_vlan="default/vlan" ## default: "default/vlan" diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index d4336da8..5cfcfac0 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -36,8 +36,8 @@ usage() { error_notify "Usage: bastille bootstrap [option(s)] [RELEASE|TEMPLATE] [update|arch]" cat << EOF Options: - - -x | --debug Enable debug mode. + + -x | --debug Enable debug mode. EOF exit 1 diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index cbea793b..645002de 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -35,19 +35,22 @@ 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_ADDRESS [interface]" - + error_notify "Usage: bastille create [option(s)] NAME RELEASE IP_ADDRESS [INTERFACE]" cat << EOF Options: - - -D | --dual Creates the jails with both 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. - -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. + + -B | --bridge Enables VNET, VNET containers are attached to a specified, already existing external bridge. + -C | --clone Creates a clone container, they are duplicates of the base release, consume low space and preserves changing data. + -D | --dual Creates the jails with both IPv4 and IPv6 networking ('inherit' and 'ip_hostname' 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. + -M | --static-mac Generate a static MAC address for jail (VNET only). + --no-validate Do not validate the release when creating the jail. + -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. + -v | --vlan VLANID Creates the jail with specified VLAN ID (VNET only). + -x | --debug Enable debug mode. + -Z | --zfs-opts "-o option" Custom set of ZFS options to create the jail with. This overrides the defaults. EOF exit 1 @@ -553,10 +556,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..." + # Exit if jail was not started, except for empty jails + if [ -z "${EMPTY_JAIL}" ]; then + if ! check_target_is_running "${NAME}"; then + bastille destroy "${NAME}" + error_exit "[${NAME}]: Failed to create jail..." + fi fi if [ -n "${VNET_JAIL}" ]; then @@ -605,6 +610,11 @@ create_jail() { # Join together IPv4 and IPv6 parts of ifconfig _ifconfig="${_ifconfig_inet} ${_ifconfig_inet6}" bastille template "${NAME}" ${bastille_template_vnet} --arg EPAIR="${uniq_epair}" --arg GATEWAY="${_gateway}" --arg GATEWAY6="${_gateway6}" --arg IFCONFIG="${_ifconfig}" + + # Add VLAN ID if it was given + if [ -n "${VLAN_ID}" ]; then + bastille template "${NAME}" ${bastille_template_vlan} --arg VLANID="${VLAN_ID}" --arg IFCONFIG="${_ifconfig}" + fi fi fi if [ -n "${THICK_JAIL}" ]; then @@ -659,6 +669,7 @@ EMPTY_JAIL="" THICK_JAIL="" CLONE_JAIL="" VNET_JAIL="" +VLAN_ID="" LINUX_JAIL="" STATIC_MAC="" DUAL_STACK="" @@ -668,30 +679,6 @@ while [ $# -gt 0 ]; do -h|--help|help) usage ;; - -D|--dual) - DUAL_STACK="1" - shift - ;; - -M|--static-mac) - STATIC_MAC="1" - shift - ;; - -E|--empty) - EMPTY_JAIL="1" - shift - ;; - -L|--linux) - LINUX_JAIL="1" - shift - ;; - -T|--thick) - THICK_JAIL="1" - shift - ;; - -V|--vnet) - VNET_JAIL="1" - shift - ;; -B|--bridge) VNET_JAIL="1" VNET_JAIL_BRIDGE="1" @@ -701,10 +688,50 @@ while [ $# -gt 0 ]; do CLONE_JAIL="1" shift ;; + -D|--dual) + DUAL_STACK="1" + shift + ;; + -E|--empty) + EMPTY_JAIL="1" + shift + ;; + -L|--linux) + LINUX_JAIL="1" + shift + ;; + -M|--static-mac) + STATIC_MAC="1" + shift + ;; --no-validate|no-validate) VALIDATE_RELEASE="" shift ;; + -T|--thick) + THICK_JAIL="1" + shift + ;; + -V|--vnet) + VNET_JAIL="1" + shift + ;; + -v|--vlan) + if echo "${2}" | grep -Eq '^[0-9]+$'; then + VLAN_ID="${2}" + else + error_exit "Not a valid VLAN ID: ${2}" + fi + shift 2 + ;; + -x|--debug) + enable_debug + shift + ;; + -Z|--zfs-opts) + bastille_zfs_options="${2}" + shift 2 + ;; -*) for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do case ${_opt} in @@ -739,6 +766,8 @@ elif [ -n "${LINUX_JAIL}" ]; then fi elif [ -n "${CLONE_JAIL}" ] && [ -n "${THICK_JAIL}" ]; then error_exit "Error: Clonejail and Thickjail can't be used together." +elif [ -z "${VNET_JAIL}" ] && [ -z "${VNET_JAIL_BRIDGE}" ] && [ -n "${VLAN_ID}" ]; then + error_exit "Error: VLANs can only be used with VNET and bridged VNET jails." fi NAME="$1" diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index d1274798..de4d3e37 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -37,18 +37,17 @@ 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. Note: If no export option specified, the container should be redirected to standard output. @@ -56,32 +55,6 @@ EOF exit 1 } -# Handle help option -case "${1}" in - help|-h|--help) - usage - ;; -esac - -if [ $# -gt 5 ] || [ $# -lt 1 ]; then - usage -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}" - zfs_enable_check() { # Temporarily disable ZFS so we can create a standard backup archive if checkyesno bastille_zfs_enable; then @@ -91,9 +64,21 @@ zfs_enable_check() { } opt_count() { - COMP_OPTION=$(expr ${COMP_OPTION} + 1) + COMP_OPTION=$((COMP_OPTION + 1)) } +# Reset export options +GZIP_EXPORT= +XZ_EXPORT= +SAFE_EXPORT= +USER_EXPORT= +RAW_EXPORT= +DIR_EXPORT= +TXZ_EXPORT= +TGZ_EXPORT= +OPT_ZSEND="-R" +COMP_OPTION="0" + if [ -n "${bastille_export_options}" ]; then # Overrides the case options by the user defined option(s) automatically. # Add bastille_export_options="--optionA --optionB" to bastille.conf, or simply `export bastille_export_options="--optionA --optionB"` environment variable. @@ -123,17 +108,17 @@ if [ -n "${bastille_export_options}" ]; then opt_count zfs_enable_check shift;; - --safe) + -s|--safe) SAFE_EXPORT="1" shift;; - --raw) + -r|--raw) RAW_EXPORT="1" opt_count shift ;; - --verbose) + -v|--verbose) OPT_ZSEND="-Rv" shift;; - --*|-*) error_notify "Unknown Option." + -*) error_notify "Unknown Option: \"${1}\"" usage;; esac done @@ -141,66 +126,73 @@ else # Handle options while [ $# -gt 0 ]; do case "${1}" in + -h|--help|help) + usage + ;; --gz) GZIP_EXPORT="1" - TARGET="${2}" opt_count shift ;; --xz) XZ_EXPORT="1" - TARGET="${2}" opt_count shift ;; --tgz) TGZ_EXPORT="1" - TARGET="${2}" opt_count zfs_enable_check shift ;; --txz) TXZ_EXPORT="1" - TARGET="${2}" opt_count zfs_enable_check shift ;; -s|--safe) SAFE_EXPORT="1" - TARGET="${2}" shift ;; -r|--raw) RAW_EXPORT="1" - TARGET="${2}" opt_count shift ;; -v|--verbose) OPT_ZSEND="-Rv" - TARGET="${2}" shift ;; - --*|-*) - error_notify "Unknown Option." + -x) + enable_debug + shift + ;; + -*) + error_notify "Unknown Option: \"${1}\"" usage ;; *) - if echo "${1}" | grep -q "\/"; then - DIR_EXPORT="${1}" - else - if [ $# -gt 2 ] || [ $# -lt 1 ]; then - usage - fi - fi - shift + break ;; esac done fi +if [ $# -gt 2 ] || [ $# -lt 1 ]; then + usage +fi + +TARGET="${1}" + +# Check for directory export +if echo "${2}" | grep -q "\/"; then + DIR_EXPORT="${2}" +fi + +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." @@ -216,7 +208,7 @@ if ! checkyesno bastille_zfs_enable; then [ -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." + error_exit "Options --xz, --gz, --raw, --safe, and --verbose are valid for ZFS configured systems only." fi fi diff --git a/usr/local/share/bastille/import.sh b/usr/local/share/bastille/import.sh index 15e4677a..c184bb31 100644 --- a/usr/local/share/bastille/import.sh +++ b/usr/local/share/bastille/import.sh @@ -35,14 +35,15 @@ 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" + error_notify "Usage: bastille import [option(s)] FILE [RELEASE]" 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. - -x | --debug Enable debug mode. + -f | --force Force an archive import regardless if the checksum file does not match or missing. + -M | --static-mac Generate static MAC for jail when importing foreign jails like iocage. + -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. @@ -53,16 +54,21 @@ EOF # Handle options. OPT_FORCE=0 OPT_ZRECV="-u" +OPT_STATIC_MAC="" USER_IMPORT= while [ "$#" -gt 0 ]; do case "${1}" in - -h|--help|help) + -h|--help|help) usage ;; -f|--force) OPT_FORCE="1" shift ;; + -M|--static-mac) + OPT_STATIC_MAC="1" + shift + ;; -v|--verbose) OPT_ZRECV="-u -v" shift @@ -75,6 +81,7 @@ while [ "$#" -gt 0 ]; do for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do case ${_opt} in f) OPT_FORCE=1 ;; + M) OPT_STATIC_MAC=1 ;; v) OPT_ZRECV="-u -v" ;; x) enable_debug ;; *) error_exit "Unknown Option: \"${1}\"" ;; @@ -88,11 +95,12 @@ while [ "$#" -gt 0 ]; do esac done -if [ $# -gt 3 ] || [ $# -lt 1 ]; then +if [ $# -gt 2 ] || [ $# -lt 1 ]; then usage fi TARGET="${1}" +RELEASE="${2}" bastille_root_check @@ -175,6 +183,9 @@ update_fstab_import() { # If both variables are set, compare and update as needed if ! grep -qw "${bastille_releasesdir}/${FSTAB_RELEASE}.*${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille" "${FSTAB_CONFIG}"; then info "Updating fstab..." + if [ -n "${RELEASE}" ]; then + FSTAB_NEWCONF="${RELEASE}" + fi sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" "${FSTAB_CONFIG}" fi fi @@ -190,16 +201,20 @@ generate_config() { # Gather some bits from foreign/iocage config files JSON_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/config.json" if [ -n "${JSON_CONFIG}" ]; then - IPV4_CONFIG=$(grep -wo '\"ip4_addr\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/ip4_addr://') - IPV6_CONFIG=$(grep -wo '\"ip6_addr\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/ip6_addr://') + IP4_CONFIG=$(grep -wo '\"ip4_addr\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/ip4_addr://') + IP6_CONFIG=$(grep -wo '\"ip6_addr\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/ip6_addr://') DEVFS_RULESET=$(grep -wo '\"devfs_ruleset\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/devfs_ruleset://') DEVFS_RULESET=${DEVFS_RULESET:-4} IS_THIN_JAIL=$(grep -wo '\"basejail\": .*' "${JSON_CONFIG}" | tr -d '" ,' | sed 's/basejail://') - CONFIG_RELEASE=$(grep -wo '\"release\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/release://' | sed 's/\-[pP].*//') + if [ -z "${RELEASE}" ]; then + CONFIG_RELEASE=$(grep -wo '\"release\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/release://' | sed 's/\-[pP].*//') + else + CONFIG_RELEASE="${RELEASE}" + fi IS_VNET_JAIL=$(grep -wo '\"vnet\": .*' "${JSON_CONFIG}" | tr -d '" ,' | sed 's/vnet://') VNET_DEFAULT_INTERFACE=$(grep -wo '\"vnet_default_interface\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/vnet_default_interface://') ALLOW_EMPTY_DIRS_TO_BE_SYMLINKED=1 - if [ "${VNET_DEFAULT_INTERFACE}" = "auto" ]; then + if [ "${VNET_DEFAULT_INTERFACE}" = "auto" ] || [ "${VNET_DEFAULT_INTERFACE}" = "none" ]; then # Grab the default ipv4 route from netstat and pull out the interface VNET_DEFAULT_INTERFACE=$(netstat -nr4 | grep default | cut -w -f 4) fi @@ -209,7 +224,11 @@ generate_config() { PROP_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/prop.ezjail-${FILE_TRIM}-*" if [ -n "${PROP_CONFIG}" ]; then IPVX_CONFIG=$(grep -wo "jail_${TARGET_TRIM}_ip=.*" ${PROP_CONFIG} | tr -d '" ' | sed "s/jail_${TARGET_TRIM}_ip=//") - CONFIG_RELEASE=$(echo ${PROP_CONFIG} | grep -o '[0-9]\{2\}\.[0-9]_RELEASE' | sed 's/_/-/g') + if [ -z "${RELEASE}" ]; then + CONFIG_RELEASE=$(echo ${PROP_CONFIG} | grep -o '[0-9]\{2\}\.[0-9]_RELEASE' | sed 's/_/-/g') + else + CONFIG_RELEASE="${RELEASE}" + fi fi # Always assume it's thin for ezjail IS_THIN_JAIL=1 @@ -217,58 +236,130 @@ generate_config() { # See if we need to generate a vnet network section if [ "${IS_VNET_JAIL:-0}" = "1" ]; then - NETBLOCK=$(generate_vnet_jail_netblock "${TARGET_TRIM}" "" "${VNET_DEFAULT_INTERFACE}") + NETBLOCK=$(generate_vnet_jail_netblock "${TARGET_TRIM}" "" "${VNET_DEFAULT_INTERFACE}" "${OPT_STATIC_MAC}") vnet_requirements else # If there are multiple IP/NIC let the user configure network - if [ -n "${IPV4_CONFIG}" ]; then - if ! echo "${IPV4_CONFIG}" | grep -q '.*,.*'; then - NETIF_CONFIG=$(echo "${IPV4_CONFIG}" | grep '.*|' | sed 's/|.*//g') - if [ -z "${NETIF_CONFIG}" ]; then + IP4_DEFINITION="" + IP6_DEFINITION="" + IP6_MODE="disable" + # IP4 set, but not IP6 + if [ -n "${IP4_CONFIG}" ] && [ -z "${IP6_CONFIG}" ]; then + if ! echo "${IP4_CONFIG}" | grep -q '.*,.*'; then + IP4_IF=$(echo "${IP4_CONFIG}" | grep '.*|' | sed 's/|.*//g') + if [ -z "${IP4_IF}" ]; then config_netif - fi - IPX_ADDR="ip4.addr" - IP_CONFIG="${IPV4_CONFIG}" - IP6_MODE="disable" - fi - elif [ -n "${IPV6_CONFIG}" ]; then - if ! echo "${IPV6_CONFIG}" | grep -q '.*,.*'; then - NETIF_CONFIG=$(echo "${IPV6_CONFIG}" | grep '.*|' | sed 's/|.*//g') - if [ -z "${NETIF_CONFIG}" ]; then + IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IP4_CONFIG};" + IP6_MODE="disable" + else + IP4_DEFINITION="ip4.addr = ${IP4_CONFIG};" + IP6_MODE="disable" + fi + else + IP4_IF=$(echo "${IP4_CONFIG}" | grep '.*|' | sed 's/|.*//g') + if [ -z "${IP4_IF}" ]; then config_netif - fi - IPX_ADDR="ip6.addr" - IP_CONFIG="${IPV6_CONFIG}" - IP6_MODE="new" + IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IP4_CONFIG};" + IP6_MODE="disable" + else + IP4_DEFINITION="ip4.addr = ${IP4_CONFIG};" + IP6_MODE="disable" + fi fi + # IP6 set, but not IP4 + elif [ -z "${IP4_CONFIG}" ] && [ -z "${IP6_CONFIG}" ]; then + if ! echo "${IP6_CONFIG}" | grep -q '.*,.*'; then + IP6_IF=$(echo "${IP6_CONFIG}" | grep '.*|' | sed 's/|.*//g') + if [ -z "${IP6_IF}" ]; then + config_netif + IP6_DEFINITION="ip6.addr = ${NETIF_CONFIG}|${IP6_CONFIG};" + IP6_MODE="new" + else + IP6_DEFINITION="ip6.addr = ${IP6_CONFIG};" + IP6_MODE="new" + fi + else + IP6_IF=$(echo "${IP6_CONFIG}" | grep '.*|' | sed 's/|.*//g') + if [ -z "${IP6_IF}" ]; then + config_netif + IP6_DEFINITION="ip6.addr = ${NETIF_CONFIG}|${IP6_CONFIG};" + IP6_MODE="new" + else + IP6_DEFINITION="ip6.addr = ${IP6_CONFIG};" + IP6_MODE="new" + fi + fi + # IP4 and IP6 both set + elif [ -n "${IP4_CONFIG}" ] && [ -n "${IP6_CONFIG}" ]; then + if ! echo "${IP4_CONFIG}" | grep -q '.*,.*'; then + IP4_IF=$(echo "${IP4_CONFIG}" | grep '.*|' | sed 's/|.*//g') + if [ -z "${IP4_IF}" ]; then + config_netif + IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IP4_CONFIG};" + else + IP4_DEFINITION="ip4.addr = ${IP4_CONFIG};" + fi + else + IP4_IF=$(echo "${IP4_CONFIG}" | grep '.*|' | sed 's/|.*//g') + if [ -z "${IP4_IF}" ]; then + config_netif + IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IP4_CONFIG};" + else + IP4_DEFINITION="ip4.addr = ${IP4_CONFIG};" + fi + fi + if ! echo "${IP6_CONFIG}" | grep -q '.*,.*'; then + IP6_IF=$(echo "${IP6_CONFIG}" | grep '.*|' | sed 's/|.*//g') + if [ -z "${IP6_IF}" ]; then + config_netif + IP6_DEFINITION="ip6.addr = ${NETIF_CONFIG}|${IP6_CONFIG};" + IP6_MODE="new" + else + IP6_DEFINITION="ip6.addr = ${IP6_CONFIG};" + IP6_MODE="new" + fi + else + IP6_IF=$(echo "${IP6_CONFIG}" | grep '.*|' | sed 's/|.*//g') + if [ -z "${IP6_IF}" ]; then + config_netif + IP6_DEFINITION="ip6.addr = ${NETIF_CONFIG}|${IP6_CONFIG};" + IP6_MODE="new" + else + IP6_DEFINITION="ip6.addr = ${IP6_CONFIG};" + IP6_MODE="new" + fi + fi + # ezjail import elif [ -n "${IPVX_CONFIG}" ]; then if ! echo "${IPVX_CONFIG}" | grep -q '.*,.*'; then NETIF_CONFIG=$(echo "${IPVX_CONFIG}" | grep '.*|' | sed 's/|.*//g') if [ -z "${NETIF_CONFIG}" ]; then config_netif - fi - IPX_ADDR="ip4.addr" - IP_CONFIG="${IPVX_CONFIG}" - IP6_MODE="disable" + IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IPVX_CONFIG};" + IP6_MODE="disable" + else + IP4_DEFINITION="ip4.addr = ${IPVX_CONFIG};" + IP6_MODE="disable" + fi if echo "${IPVX_CONFIG}" | sed 's/.*|//' | grep -Eq '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))'; then - IPX_ADDR="ip6.addr" + IP4_DEFINITION="" + IP6_DEFINITION="ip6.addr = ${IPVX_CONFIG};" IP6_MODE="new" fi fi fi # Let the user configure network manually - if [ -z "${NETIF_CONFIG}" ]; then - NETIF_CONFIG="lo1" - IPX_ADDR="ip4.addr" - IP_CONFIG="-" + if [ -z "${IP4_DEFINITION}" ] && [ -z "${IP6_DEFINITION}" ]; then + IP4_DEFINITION="ip4.addr = lo1|-;" + IP6_DEFINITION="" IP6_MODE="disable" warn "Warning: See 'bastille edit ${TARGET_TRIM} jail.conf' for manual network configuration." fi NETBLOCK=$(cat <<-EOF - interface = ${NETIF_CONFIG}; - ${IPX_ADDR} = ${IP_CONFIG}; + ${IP4_DEFINITION} + ${IP6_DEFINITION} ip6 = ${IP6_MODE}; EOF ) @@ -306,6 +397,7 @@ ${TARGET_TRIM} { mount.fstab = ${bastille_jailsdir}/${TARGET_TRIM}/fstab; path = ${bastille_jailsdir}/${TARGET_TRIM}/root; securelevel = 2; + osrelease = ${CONFIG_RELEASE}; ${NETBLOCK} } @@ -317,7 +409,11 @@ update_config() { # The config on select archives does not provide a clear way to determine # the base release, so lets try to get it from the base/COPYRIGHT file, # otherwise warn user and fallback to host system release - CONFIG_RELEASE=$(grep -wo 'releng/[0-9]\{2\}.[0-9]/COPYRIGHT' "${bastille_jailsdir}/${TARGET_TRIM}/root/COPYRIGHT" | sed 's|releng/||;s|/COPYRIGHT|-RELEASE|') + if [ -z "${RELEASE}" ]; then + CONFIG_RELEASE=$(grep -wo 'releng/[0-9]\{2\}.[0-9]/COPYRIGHT' "${bastille_jailsdir}/${TARGET_TRIM}/root/COPYRIGHT" | sed 's|releng/||;s|/COPYRIGHT|-RELEASE|') + else + CONFIG_RELEASE="${RELEASE}" + fi if [ -z "${CONFIG_RELEASE}" ]; then # Fallback to host version CONFIG_RELEASE=$(freebsd-version | sed 's/\-[pP].*//') diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index 8e8a1f2a..d8c7e73a 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -90,7 +90,7 @@ for _jail in ${JAILS}; do check_target_is_running "${_jail}" || error_continue "Jail is already stopped." # Remove RDR rules - if [ "$(bastille config ${_jail} get vnet)" != "enabled" ]; then + if [ "$(bastille config ${_jail} get vnet)" != "enabled" ] && [ -f "${bastille_pf_conf}" ]; 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 @@ -113,17 +113,17 @@ for _jail in ${JAILS}; do jail ${OPTION} -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" # Remove (captured above) IPs from firewall table - if [ "${_ip4}" != "not set" ]; then + if [ "${_ip4}" != "not set" ] && [ -f "${bastille_pf_conf}" ]; then for _ip in ${_ip4}; do 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}" + pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" done fi - if [ "${_ip6}" != "not set" ]; then + if [ "${_ip6}" != "not set" ] && [ -f "${bastille_pf_conf}" ]; then for _ip in ${_ip6}; do if echo "${_ip}" | grep -q "|"; then _ip="$(echo ${_ip} | awk -F"|" '{print $2}' | sed -E 's#/[0-9]+$##g')" diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index f8cad31e..9803215f 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -153,7 +153,7 @@ 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' + HOOKS='LIMITS INCLUDE PRE FSTAB PF PKG OVERLAY CONFIG SYSRC SERVICE CMD RENDER HOSTCMD' fi bastille_root_check @@ -368,6 +368,11 @@ for _jail in ${JAILS}; do ;; fstab|mount) _cmd='mount' ;; + # Execute this command on the host + hostcmd) + eval "${_args}" + continue + ;; include) _cmd='template' ;; overlay) diff --git a/usr/local/share/bastille/templates/default/vlan/Bastillefile b/usr/local/share/bastille/templates/default/vlan/Bastillefile new file mode 100644 index 00000000..6d594446 --- /dev/null +++ b/usr/local/share/bastille/templates/default/vlan/Bastillefile @@ -0,0 +1,6 @@ +ARG VLANID +ARG IFCONFIG="SYNCDHCP" + +SYSRC ifconfig_vnet0="up" +SYSRC vlans_vnet0="${VLANID}" +SYSRC ifconfig_vnet0_${VLANID}="${IFCONFIG}"