diff --git a/Makefile b/Makefile index dc3e1141..529cbbc2 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ install: @echo "BASTILLE_VERSION: ${BASTILLE_BRANCH}-${BASTILLE_VERSION}" @sed -i '' "s/BASTILLE_VERSION=.*/BASTILLE_VERSION=${BASTILLE_BRANCH}-${BASTILLE_VERSION}/" usr/local/bin/bastille @cp -Rv usr / - @gzip -n /usr/local/share/man/man8/bastille.8 + @gzip -f -n /usr/local/share/man/man8/bastille.8 @echo @echo "This method is for testing & development." @echo "Please report any issues to https://github.com/BastilleBSD/bastille/issues" diff --git a/docs/chapters/subcommands/create.rst b/docs/chapters/subcommands/create.rst index bfbd52c9..7d79302c 100644 --- a/docs/chapters/subcommands/create.rst +++ b/docs/chapters/subcommands/create.rst @@ -57,19 +57,20 @@ options. See the below help output. Options: - -B | --bridge Enable VNET, and attach to a specified, already existing external bridge. - -C | --clone Create a clone jail. - -D | --dual Create jail with both IPv4 and IPv6 networking ('inherit' and 'ip_hostname' only). - -E | --empty Create an empty container, intended for custom jail builds (thin/thick/linux or unsupported). - -g | --gateway IP Specify a default router/gateway for the jail. - -L | --linux Create a Linux jail (experimental). - -M | --static-mac Generate a static MAC address for jail (VNET only). - -n | --nameserver IP,IP Specify nameserver(s) for the jail. Comma separated. - --no-validate Do not validate the release when creating the jail. - --no-boot Create jail with boot=off. - -p | --priority VALUE Set priority value for jail. - -T | --thick Creates a thick container, they consume more space as they are self contained and independent. - -V | --vnet Enable VNET, and attach to an existing, physical interface. - -v | --vlan VLANID Creates the jail with specified VLAN ID (VNET only). - -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. + -B | --bridge Enable VNET, and attach to a specified, already existing external bridge. + -C | --clone Create a clone jail. + -D | --dual Create jail with both IPv4 and IPv6 networking ('inherit' and 'ip_hostname' only). + -E | --empty Create an empty container, intended for custom jail builds (thin/thick/linux or unsupported). + -g | --gateway IP Specify a default router/gateway for the jail. + -L | --linux Create a Linux jail (experimental). + -M | --static-mac Generate a static MAC address for jail (VNET only). + -n | --nameserver IP,IP Specify nameserver(s) for the jail. Comma separated. + --no-validate Do not validate the release when creating the jail. + --no-boot Create jail with boot=off. + -P | --passthrough Enable VNET, and pass the specified interface into the jail. + -p | --priority VALUE Set priority value for jail. + -T | --thick Creates a thick container, they consume more space as they are self contained and independent. + -V | --vnet Enable VNET, and attach to an existing, physical interface. + -v | --vlan VLANID Creates the jail with specified VLAN ID (VNET only). + -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/subcommands/network.rst b/docs/chapters/subcommands/network.rst index a31f1892..316a7822 100644 --- a/docs/chapters/subcommands/network.rst +++ b/docs/chapters/subcommands/network.rst @@ -40,11 +40,11 @@ network TARGET remove INTERFACE`` while both jails are stopped. Options: - -a | --auto Start/stop jail(s) if required. - -B | --bridge Add a bridge VNET interface. - -M | --static-mac Generate a static MAC address for the interface (VNET only). - -n | --no-ip Create interface without an IP (VNET only). - -P | --passthrough Add a raw interface. - -V | --vnet Add a VNET interface. - -v | --vlan VLANID Assign VLAN ID to interface (VNET only). - -x | --debug Enable debug mode. \ No newline at end of file + -a | --auto Start/stop jail(s) if required. + -B | --bridge Add a bridge VNET interface. + -M | --static-mac Generate a static MAC address for the interface (VNET only). + -n | --no-ip Create interface without an IP (VNET only). + -P | --passthrough Add a raw interface. + -V | --vnet Add a VNET interface. + -v | --vlan VLANID Assign VLAN ID to interface (VNET only). + -x | --debug Enable debug mode. \ No newline at end of file diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index b73771ff..69340e3f 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -349,50 +349,55 @@ generate_static_mac() { generate_vnet_jail_netblock() { local jail_name="${1}" - local use_unique_bridge="${2}" + # interface_type can be "standard" "bridge" or "passthrough" + local interface_type="${2}" local external_interface="${3}" local static_mac="${4}" + # Set epair/interface values for host/jail if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then - if [ -n "${use_unique_bridge}" ]; then + if [ "${interface_type}" = "bridge" ]; then if [ "$(echo -n "e0a_${jail_name}" | awk '{print length}')" -lt 16 ]; then local host_epair=e0a_${jail_name} local jail_epair=e0b_${jail_name} else - name_prefix="$(echo ${jail_name} | cut -c1-7)" - name_suffix="$(echo ${jail_name} | rev | cut -c1-2 | rev)" - local host_epair="e0a_${name_prefix}xx${name_suffix}" + name_prefix="$(echo ${jail_name} | cut -c1-7)" + name_suffix="$(echo ${jail_name} | rev | cut -c1-2 | rev)" + local host_epair="e0a_${name_prefix}xx${name_suffix}" local jail_epair="e0b_${name_prefix}xx${name_suffix}" fi - else + elif [ "${interface_type}" = "standard" ]; then if [ "$(echo -n "e0a_${jail_name}" | awk '{print length}')" -lt 16 ]; then local host_epair=e0a_${jail_name} local jail_epair=e0b_${jail_name} - local jib_epair=${jail_name} + local jib_epair=${jail_name} else - name_prefix="$(echo ${jail_name} | cut -c1-7)" - name_suffix="$(echo ${jail_name} | rev | cut -c1-2 | rev)" - local host_epair="e0a_${name_prefix}xx${name_suffix}" + name_prefix="$(echo ${jail_name} | cut -c1-7)" + name_suffix="$(echo ${jail_name} | rev | cut -c1-2 | rev)" + local host_epair="e0a_${name_prefix}xx${name_suffix}" local jail_epair="e0b_${name_prefix}xx${name_suffix}" local jib_epair="${name_prefix}xx${name_suffix}" - fi + fi + elif [ "${interface_type}" = "passthrough" ]; then + host_epair="${external_interface}" + jail_epair="${external_interface}" fi elif [ "${bastille_network_vnet_type}" = "netgraph" ]; then if [ "$(echo -n "ng0_${jail_name}" | awk '{print length}')" -lt 16 ]; then local ng_if=ng0_${jail_name} - local jng_if=${jail_name} + local jng_if=${jail_name} else - name_prefix="$(echo ${jail_name} | cut -c1-7)" - name_suffix="$(echo ${jail_name} | rev | cut -c1-2 | rev)" - local ng_if="ng0_${name_prefix}xx${name_suffix}" + name_prefix="$(echo ${jail_name} | cut -c1-7)" + name_suffix="$(echo ${jail_name} | rev | cut -c1-2 | rev)" + local ng_if="ng0_${name_prefix}xx${name_suffix}" local jng_if="${name_prefix}xx${name_suffix}" fi fi - ## If BRIDGE is enabled, generate bridge config, else generate VNET config - if [ -n "${use_unique_bridge}" ]; then - if [ -n "${static_mac}" ]; then - ## Generate bridged VNET config with static MAC address + # VNET_JAIL_BRIDGE + if [ "${interface_type}" = "bridge" ]; then + if [ "${static_mac}" -eq 1 ]; then + # Generate BRIDGE config with static MAC address generate_static_mac "${jail_name}" "${external_interface}" cat <<-EOF vnet; @@ -405,7 +410,7 @@ generate_vnet_jail_netblock() { exec.poststop += "ifconfig ${host_epair} destroy"; EOF else - ## Generate bridged VNET config without static MAC address + # Generate BRIDGE config without static MAC address cat <<-EOF vnet; vnet.interface = ${jail_epair}; @@ -415,10 +420,12 @@ EOF exec.poststop += "ifconfig ${host_epair} destroy"; EOF fi - else + + # VNET_JAIL_STANDARD + elif [ "${interface_type}" = "standard" ]; then if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then - if [ -n "${static_mac}" ]; then - ## Generate VNET config with static MAC address + if [ "${static_mac}" -eq 1 ]; then + # Generate VNET config with static MAC address generate_static_mac "${jail_name}" "${external_interface}" cat <<-EOF vnet; @@ -430,7 +437,7 @@ EOF exec.poststop += "ifconfig ${host_epair} destroy"; EOF else - ## Generate VNET config without static MAC address + # Generate VNET config without static MAC address cat <<-EOF vnet; vnet.interface = ${jail_epair}; @@ -440,8 +447,8 @@ EOF EOF fi elif [ "${bastille_network_vnet_type}" = "netgraph" ]; then - if [ -n "${static_mac}" ]; then - ## Generate VNET config with static MAC address + if [ "${static_mac}" -eq 1 ]; then + # Generate VNET config with static MAC address generate_static_mac "${jail_name}" "${external_interface}" cat <<-EOF vnet; @@ -451,7 +458,7 @@ EOF exec.poststop += "jng shutdown ${jng_if}"; EOF else - ## Generate VNET config without static MAC address + # Generate VNET config without static MAC address cat <<-EOF vnet; vnet.interface = ${ng_if}; @@ -460,6 +467,14 @@ EOF EOF fi fi + + # VNET_JAIL_PASSTHROUGH + elif [ "${interface_type}" = "passthrough" ]; then + cat <<-EOF + vnet; + vnet.interface = ${external_interface}; + exec.prestop += "ifconfig ${external_interface} -vnet ${jail_name}"; +EOF fi } diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index eec94947..88a87eb8 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -34,28 +34,29 @@ usage() { # Build an independent usage for the create command - # If no option specified, will create a thin container by default + # If no option specified, will create a thin jail by default error_notify "Usage: bastille create [option(s)] NAME RELEASE IP [INTERFACE]" cat << EOF Options: - -B | --bridge Enable VNET, and attach to a specified, already existing external bridge. - -C | --clone Create a clone jail. - -D | --dual Create jail with both IPv4 and IPv6 networking ('inherit' and 'ip_hostname' only). - -E | --empty Create an empty container, intended for custom jail builds (thin/thick/linux or unsupported). - -g | --gateway IP Specify a default router/gateway for the jail. - -L | --linux Create a Linux jail (experimental). - -M | --static-mac Generate a static MAC address for jail (VNET only). - -n | --nameserver IP,IP Specify nameserver(s) for the jail. Comma separated. - --no-validate Do not validate the release when creating the jail. - --no-boot Create jail with boot=off. - -p | --priority VALUE Set priority value for jail. - -T | --thick Creates a thick container, they consume more space as they are self contained and independent. - -V | --vnet Enable VNET, and attach to an existing, physical interface. - -v | --vlan VLANID Creates the jail with specified VLAN ID (VNET only). - -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. + -B | --bridge Enable VNET, and attach to a specified, already existing bridge. + -C | --clone Create a clone jail. + -D | --dual Create jail with both IPv4 and IPv6 networking ('inherit' and 'ip_hostname' only). + -E | --empty Create an empty jail, intended for custom jail builds (thin/thick/linux or unsupported). + -g | --gateway IP Specify a default router/gateway for the jail. + -L | --linux Create a Linux jail (experimental). + -M | --static-mac Generate a static MAC address for jail (VNET only). + -n | --nameserver IP,IP Specify nameserver(s) for the jail. Comma separated. + --no-validate Do not validate the release when creating the jail. + --no-boot Create jail with boot=off. + -P | --passthrough Enable VNET, and pass the specified interface into the jail. + -p | --priority VALUE Set priority value for the jail. + -T | --thick Create a thick jail. This is an entirely self contained and independant jail. + -V | --vnet Enable VNET, and attach to an existing, physical interface. + -v | --vlan VLANID Creates the jail with specified VLAN ID (VNET only). + -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. EOF exit 1 @@ -69,7 +70,7 @@ validate_name() { # Make sure NAME has only allowed characters if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then error_exit "[ERROR]: Jail names may not begin with (-|_) characters!" - elif [ -n "${VNET_JAIL}" ] && echo "${NAME_VERIFY}" | grep -qE '(-|_)'; then + elif [ "${VNET_JAIL}" -eq 1 ] && echo "${NAME_VERIFY}" | grep -qE '(-|_)'; then error_exit "[ERROR]: VNET jail names may not contain (-|_) characters." elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then error_exit "[ERROR]: Jail names may not contain special characters!" @@ -89,13 +90,13 @@ validate_ip() { local ipx_addr="ip6.addr" else if [ "${_ip}" = "inherit" ] || [ "${_ip}" = "ip_hostname" ]; then - if [ -n "${VNET_JAIL}" ]; then + if [ "${VNET_JAIL}" -eq 1 ]; then error_exit "[ERROR]: Unsupported IP option for VNET jail: (${_ip})." else info "\nValid: (${_ip})." fi elif [ "${_ip}" = "DHCP" ] || [ "${_ip}" = "SYNCDHCP" ] || [ "${_ip}" = "0.0.0.0" ]; then - if [ -z "${VNET_JAIL}" ]; then + if [ "${VNET_JAIL}" -eq 0 ]; then error_exit "[ERROR]: Unsupported IP option for non-VNET jail: (${_ip})." else info "\nValid: (${_ip})." @@ -139,7 +140,7 @@ validate_ip() { # Determine IP/Interface mode if [ "${_ip}" = "inherit" ]; then - if [ -n "${DUAL_STACK}" ]; then + if [ "${DUAL_STACK}" -eq 1 ]; then IP4_DEFINITION="ip4 = ${_ip};" IP6_DEFINITION="ip6 = ${_ip};" IP6_MODE="new" @@ -149,7 +150,7 @@ validate_ip() { IP6_MODE="disable" fi elif [ "${_ip}" = "ip_hostname" ]; then - if [ -n "${DUAL_STACK}" ]; then + if [ "${DUAL_STACK}" -eq 1 ]; then IP_HOSTNAME="${_ip}" IP4_DEFINITION="${IP_HOSTNAME};" IP6_DEFINITION="${IP_HOSTNAME};" @@ -161,7 +162,7 @@ validate_ip() { IP6_MODE="disable" fi elif [ "${_ip}" = "DHCP" ] || [ "${_ip}" = "SLAAC" ] || [ "${_ip}" = "0.0.0.0" ]; then - if [ -n "${VNET_JAIL}" ]; then + if [ "${VNET_JAIL}" -eq 1 ]; then if [ "${ipx_addr}" = "ip4.addr" ]; then IP4_ADDR="${_ip}" elif [ "${ipx_addr}" = "ip6.addr" ]; then @@ -202,7 +203,7 @@ validate_netif() { if ! echo "${LIST_INTERFACES} VNET" | grep -qwo "${INTERFACE}"; then error_exit "[ERROR]: Invalid: (${INTERFACE})." - elif [ -n "${VNET_JAIL}" ] && [ -z "${VNET_JAIL_BRIDGE}" ]; then + elif [ "${VNET_JAIL_STANDARD}" -eq 1 ]; then for _bridge in $(ifconfig -g bridge | grep -vw "${INTERFACE}bridge"); do if ifconfig ${_bridge} | grep "member" | grep -owq "${INTERFACE}"; then error_exit "[ERROR]: Interface (${INTERFACE}) is already a member of bridge: ${_bridge}" @@ -211,8 +212,9 @@ validate_netif() { else info "\nValid: (${INTERFACE})." fi - # Don't allow dots in INTERFACE if -V - if [ -n "${VNET_JAIL}" ] && [ -z "${VNET_JAIL_BRIDGE}" ]; then + + # Don't allow dots in INTERFACE for -V|--vnet jails + if [ "${VNET_JAIL_STANDARD}" -eq 1 ]; then if echo "${INTERFACE}" | grep -q "\."; then error_exit "[ERROR]: [-V|--vnet] does not support dots (.) in interface names." fi @@ -223,7 +225,7 @@ validate_release() { ## ensure the user set the Linux(experimental) option explicitly if [ -n "${UBUNTU}" ]; then - if [ -z "${LINUX_JAIL}" ]; then + if [ "${LINUX_JAIL}" -eq 0 ]; then usage fi fi @@ -309,7 +311,7 @@ generate_vnet_jail_conf() { devfs_ruleset_value=13 fi - NETBLOCK=$(generate_vnet_jail_netblock "${NAME}" "${VNET_JAIL_BRIDGE}" "${bastille_jail_conf_interface}" "${STATIC_MAC}") + NETBLOCK=$(generate_vnet_jail_netblock "${NAME}" "${VNET_INTERFACE_TYPE}" "${bastille_jail_conf_interface}" "${STATIC_MAC}") cat << EOF > "${bastille_jail_conf}" ${NAME} { @@ -334,7 +336,6 @@ EOF post_create_jail() { # Common config checks and settings. - # Using relative paths here. # MAKE SURE WE'RE IN THE RIGHT PLACE. cd "${bastille_jail_path}" || error_exit "Could not access directory: ${bastille_jail_path}" @@ -352,7 +353,7 @@ post_create_jail() { fi if [ ! -f "${bastille_jail_fstab}" ]; then - if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then + if [ "${THICK_JAIL}" -eq 0 ] && [ "${CLONE_JAIL}" -eq 0 ]; then echo -e "${bastille_releasesdir}/${RELEASE} ${bastille_jail_base} nullfs ro 0 0" > "${bastille_jail_fstab}" else touch "${bastille_jail_fstab}" @@ -360,7 +361,7 @@ post_create_jail() { fi # Generate the jail configuration file. - if [ -n "${VNET_JAIL}" ]; then + if [ "${VNET_JAIL}" -eq 1 ]; then generate_vnet_jail_conf else generate_jail_conf @@ -385,21 +386,21 @@ create_jail() { if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then ## create required zfs datasets, mountpoint inherited from system - if [ -z "${CLONE_JAIL}" ]; then + if [ "${CLONE_JAIL}" -eq 0 ]; then if ! zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}"; then - error_exit "[ERROR]: Failed to create jail dataset: ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}" - fi + error_exit "[ERROR]: Failed to create jail dataset: ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}" + fi fi - if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then + if [ "${THICK_JAIL}" -eq 0 ] && [ "${CLONE_JAIL}" -eq 0 ]; then if ! zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"; then - error_exit "[ERROR]: Failed to create jail root dataset: ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" - fi + error_exit "[ERROR]: Failed to create jail root dataset: ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" + fi fi fi else if ! mkdir -p "${bastille_jailsdir}/${NAME}/root"; then - error_exit "[ERROR]: Failed to create jail directory: ${bastille_jailsdir}/${NAME}/root" - fi + error_exit "[ERROR]: Failed to create jail directory: ${bastille_jailsdir}/${NAME}/root" + fi fi # Check if the jail directory has been mounted under UFS (not supported) elif [ ! -d "${bastille_jailsdir}/${NAME}/root" ] && ! checkyesno bastille_zfs_enable; then @@ -410,7 +411,7 @@ create_jail() { ## PoC for Linux jails @hackacad - if [ -n "${LINUX_JAIL}" ]; then + if [ "${LINUX_JAIL}" -eq 1 ]; then info "\nCreating a linuxjail. This may take a while...\n" if [ ! -d "${bastille_jail_base}" ]; then mkdir -p "${bastille_jail_base}" @@ -454,8 +455,8 @@ create_jail() { fi fi - if [ -z "${EMPTY_JAIL}" ] && [ -z "${LINUX_JAIL}" ]; then - if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then + if [ "${EMPTY_JAIL}" -eq 0 ] && [ "${LINUX_JAIL}" -eq 0 ]; then + if [ "${THICK_JAIL}" -eq 0 ] && [ "${CLONE_JAIL}" -eq 0 ]; then if [ ! -d "${bastille_jail_base}" ]; then mkdir -p "${bastille_jail_base}" fi @@ -471,7 +472,7 @@ create_jail() { # Check and apply required settings. post_create_jail - if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then + if [ "${THICK_JAIL}" -eq 0 ] && [ "${CLONE_JAIL}" -eq 0 ]; then LINK_LIST="bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/sbin usr/share usr/src" info "\nCreating a thinjail..." for _link in ${LINK_LIST}; do @@ -487,7 +488,7 @@ create_jail() { fi fi - if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then + if [ "${THICK_JAIL}" -eq 0 ] && [ "${CLONE_JAIL}" -eq 0 ]; then ## rw ## copy only required files for thin jails FILE_LIST=".cshrc .profile COPYRIGHT dev etc media mnt net proc root tmp var usr/obj usr/tests" @@ -503,7 +504,7 @@ create_jail() { else if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then - if [ -n "${CLONE_JAIL}" ]; then + if [ "${CLONE_JAIL}" -eq 1 ]; then info "\nCreating a clonejail...\n" ## clone the release base to the new basejail SNAP_NAME="bastille-clone-$(date +%Y-%m-%d-%H%M%S)" @@ -515,7 +516,7 @@ create_jail() { # Check and apply required settings. post_create_jail - elif [ -n "${THICK_JAIL}" ]; then + elif [ "${THICK_JAIL}" -eq 1 ]; then info "\nCreating a thickjail. This may take a while..." @@ -565,7 +566,7 @@ create_jail() { fi fi - if [ -z "${LINUX_JAIL}" ]; then + if [ "${LINUX_JAIL}" -eq 0 ]; then ## create home directory if missing if [ ! -d "${bastille_jail_path}/usr/home" ]; then mkdir -p "${bastille_jail_path}/usr/home" @@ -593,9 +594,9 @@ create_jail() { sed -i '' 's|[0-9],[0-9]\{2\}.*[0-9]-[0-9].*root.*kerntz -a|#& # Disabled by bastille|' "etc/crontab" fi - ## VNET specific - if [ -n "${VNET_JAIL}" ]; then - ## VNET requires jib or jng script + # VNET specific + if [ "${VNET_JAIL}" -eq 1 ]; then + # VNET requires jib or jng script if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then if [ ! "$(command -v jib)" ]; then if [ -f /usr/share/examples/jails/jib ] && [ ! -f /usr/local/bin/jib ]; then @@ -610,10 +611,10 @@ create_jail() { fi fi fi - elif [ -n "${LINUX_JAIL}" ]; then + elif [ "${LINUX_JAIL}" -eq 1 ]; then ## Generate configuration for Linux jail generate_linux_jail_conf - elif [ -n "${EMPTY_JAIL}" ]; then + elif [ "${EMPTY_JAIL}" -eq 1 ]; then ## Generate minimal configuration for empty jail generate_minimal_conf fi @@ -621,15 +622,15 @@ create_jail() { # Set strict permissions on the jail by default chmod 0700 "${bastille_jailsdir}/${NAME}" - # Apply boot, depends and priority settings before starting jail + # Apply boot, depend and priority settings before starting jail sysrc -f "${bastille_jailsdir}/${NAME}/settings.conf" boot=${BOOT} >/dev/null sysrc -f "${bastille_jailsdir}/${NAME}/settings.conf" depend="" >/dev/null sysrc -f "${bastille_jailsdir}/${NAME}/settings.conf" priority="${PRIORITY}" >/dev/null # Jail must be started before applying the default template. -- cwells - if [ -z "${EMPTY_JAIL}" ]; then + if [ "${EMPTY_JAIL}" -eq 0 ]; then bastille start "${NAME}" - elif [ -n "${EMPTY_JAIL}" ]; then + elif [ "${EMPTY_JAIL}" -eq 1 ]; then # Don't start empty jails unless a template defined. if [ -n "${bastille_template_empty}" ]; then bastille start "${NAME}" @@ -637,29 +638,29 @@ create_jail() { fi # Exit if jail was not started, except for empty jails - if [ -z "${EMPTY_JAIL}" ]; then + if [ "${EMPTY_JAIL}" -eq 0 ]; then if ! check_target_is_running "${NAME}"; then bastille destroy -afy "${NAME}" error_exit "[ERROR]: Failed to create jail: ${NAME}" fi fi - if [ -n "${VNET_JAIL}" ]; then + if [ "${VNET_JAIL}" -eq 1 ]; then + if [ -n "${bastille_template_vnet}" ]; then - ## rename interface to generic vnet0 + # Retrieve epair name from jail.conf uniq_epair=$(grep vnet.interface "${bastille_jailsdir}/${NAME}/jail.conf" | awk '{print $3}' | sed 's/;//; s/-/_/g') _gateway='' _gateway6='' _ifconfig_inet='' _ifconfig_inet6='' - # Determine default gateway option + # Check for DHCP if echo "${IP}" | grep -qE '(0[.]0[.]0[.]0|DHCP|SYNCDHCP)'; then - # Enable DHCP if requested - _ifconfig_inet=SYNCDHCP + _ifconfig_inet="SYNCDHCP" else - # Else apply the default gateway + # Set Gateway if [ -n "${OPT_GATEWAY}" ]; then _gateway="${OPT_GATEWAY}" elif [ -n "${bastille_network_gateway}" ]; then @@ -671,7 +672,7 @@ create_jail() { # Add IPv4 address (this is empty if DHCP is used) if [ -n "${IP4_ADDR}" ]; then - _ifconfig_inet="${_ifconfig_inet} inet ${IP4_ADDR}" + _ifconfig_inet="inet ${IP4_ADDR}" fi # Enable IPv6 if used @@ -681,7 +682,7 @@ create_jail() { # Enable SLAAC if requested _ifconfig_inet6="${_ifconfig_inet6} accept_rtadv" else - # Else apply the default gateway + # Set Gateway if [ -n "${bastille_network_gateway6}" ]; then _gateway6="${bastille_network_gateway6}" else @@ -697,29 +698,39 @@ create_jail() { # We need to pass IP4 and IP6 separately _ifconfig="${_ifconfig_inet}" - _ifconfig6="${_ifconfig_inet6}" - bastille template "${NAME}" ${bastille_template_vnet} --arg EPAIR="${uniq_epair}" --arg GATEWAY="${_gateway}" --arg GATEWAY6="${_gateway6}" --arg IFCONFIG="${_ifconfig}" --arg IFCONFIG6="${_ifconfig6}" + _ifconfig6="${_ifconfig_inet6}" + + # Use interface name as INTERFACE+VNET when PASSTHROUGH is selected + # Use default "vnet0" otherwise + if [ "${VNET_JAIL_PASSTHROUGH}" -eq 1 ]; then + bastille template "${NAME}" ${bastille_template_vnet} --arg INTERFACE="${uniq_epair}" --arg VNET="${INTERFACE}" --arg GATEWAY="${_gateway}" --arg GATEWAY6="${_gateway6}" --arg IFCONFIG="${_ifconfig}" --arg IFCONFIG6="${_ifconfig6}" + else + bastille template "${NAME}" ${bastille_template_vnet} --arg INTERFACE="${uniq_epair}" --arg VNET="vnet0" --arg GATEWAY="${_gateway}" --arg GATEWAY6="${_gateway6}" --arg IFCONFIG="${_ifconfig}" --arg IFCONFIG6="${_ifconfig6}" + fi # Add VLAN ID if it was given - if [ -n "${VLAN_ID}" ]; then + if [ -n "${VLAN_ID}" ]; then bastille template "${NAME}" ${bastille_template_vlan} --arg VLANID="${VLAN_ID}" --arg IFCONFIG="${_ifconfig}" - fi + fi + fi fi - if [ -n "${THICK_JAIL}" ]; then + + # Apply thick/clone/empty/linux/thin template + if [ "${THICK_JAIL}" -eq 1 ]; then if [ -n "${bastille_template_thick}" ]; then bastille template "${NAME}" ${bastille_template_thick} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" fi - elif [ -n "${CLONE_JAIL}" ]; then + elif [ "${CLONE_JAIL}" -eq 1 ]; then if [ -n "${bastille_template_clone}" ]; then bastille template "${NAME}" ${bastille_template_clone} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" fi - elif [ -n "${EMPTY_JAIL}" ]; then + elif [ "${EMPTY_JAIL}" -eq 1 ]; then if [ -n "${bastille_template_empty}" ]; then bastille template "${NAME}" ${bastille_template_empty} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" fi ## Using templating function to fetch necessary packges @hackacad - elif [ -n "${LINUX_JAIL}" ]; then + elif [ "${LINUX_JAIL}" -eq 1 ]; then info "\nFetching 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 dpkg --force-depends --force-confdef --force-confold -i /var/cache/apt/archives/*.deb" @@ -742,9 +753,9 @@ create_jail() { fi # Apply values changed by the template. -- cwells - if [ -z "${EMPTY_JAIL}" ] && [ -z "${LINUX_JAIL}" ]; then + if [ "${EMPTY_JAIL}" -eq 0 ] && [ "${LINUX_JAIL}" -eq 0 ]; then bastille restart "${NAME}" - elif [ -n "${EMPTY_JAIL}" ]; then + elif [ "${EMPTY_JAIL}" -eq 1 ]; then # Don't restart empty jails unless a template defined. if [ -n "${bastille_template_empty}" ]; then bastille restart "${NAME}" @@ -763,16 +774,18 @@ fi # Handle options. BOOT="on" -EMPTY_JAIL="" -THICK_JAIL="" -CLONE_JAIL="" -VNET_JAIL="" -VNET_JAIL_BRIDGE="" +EMPTY_JAIL=0 +THICK_JAIL=0 +CLONE_JAIL=0 +VNET_JAIL=0 +VNET_JAIL_STANDARD=0 +VNET_JAIL_BRIDGE=0 +VNET_JAIL_PASSTHROUGH=0 VLAN_ID="" -LINUX_JAIL="" -STATIC_MAC="" -DUAL_STACK="" -VALIDATE_RELEASE="1" +LINUX_JAIL=0 +STATIC_MAC=0 +DUAL_STACK=0 +VALIDATE_RELEASE=1 PRIORITY="99" OPT_GATEWAY="" OPT_NAMESERVER="" @@ -782,25 +795,25 @@ while [ $# -gt 0 ]; do usage ;; -B|--bridge) - VNET_JAIL="1" - VNET_JAIL_BRIDGE="1" + VNET_JAIL=1 + VNET_JAIL_BRIDGE=1 shift ;; -C|--clone) - CLONE_JAIL="1" + CLONE_JAIL=1 shift ;; -D|--dual) - DUAL_STACK="1" + DUAL_STACK=1 shift ;; -E|--empty) - EMPTY_JAIL="1" + EMPTY_JAIL=1 shift ;; -g|--gateway|--defaultrouter) OPT_GATEWAY="${2}" - # Validate gateway + # Validate gateway if [ -n "${OPT_GATEWAY}" ]; then if ! validate_ip "${OPT_GATEWAY}" >/dev/null 2>/dev/null; then error_exit "[ERROR]: Not a valid gateway: ${OPT_GATEWAY}" @@ -809,16 +822,16 @@ while [ $# -gt 0 ]; do shift 2 ;; -L|--linux) - LINUX_JAIL="1" + LINUX_JAIL=1 shift ;; -M|--static-mac) - STATIC_MAC="1" + STATIC_MAC=1 shift ;; -n|--nameserver) OPT_NAMESERVER="${2}" - # Validate nameserver + # Validate nameserver if [ -n "${OPT_NAMESERVER}" ]; then for _nameserver in $(echo ${OPT_NAMESERVER} | sed 's/,/ /g'); do if ! validate_ip "${_nameserver}" >/dev/null 2>/dev/null; then @@ -828,28 +841,34 @@ while [ $# -gt 0 ]; do fi shift 2 ;; - -p|--priority) - if echo "${2}" | grep -Eoq "^[0-9]+$"; then - PRIORITY="${2}" - shift 2 - else - error_exit "Not a valid priority value: \"${2}\"" - fi - ;; --no-boot) BOOT="off" shift ;; --no-validate|no-validate) - VALIDATE_RELEASE="" + VALIDATE_RELEASE=0 shift ;; + -P|--passthrough) + VNET_JAIL=1 + VNET_JAIL_PASSTHROUGH=1 + shift + ;; + -p|--priority) + if echo "${2}" | grep -Eoq "^[0-9]+$"; then + PRIORITY="${2}" + shift 2 + else + error_exit "Not a valid priority value: \"${2}\"" + fi + ;; -T|--thick) - THICK_JAIL="1" + THICK_JAIL=1 shift ;; -V|--vnet) - VNET_JAIL="1" + VNET_JAIL=1 + VNET_JAIL_STANDARD=1 shift ;; -v|--vlan) @@ -877,8 +896,9 @@ while [ $# -gt 0 ]; do E) EMPTY_JAIL=1 ;; L) LINUX_JAIL=1 ;; M) STATIC_MAC=1 ;; + P) VNET_JAIL=1 VNET_JAIL_PASSTHROUGH=1 ;; T) THICK_JAIL=1 ;; - V) VNET_JAIL=1 ;; + V) VNET_JAIL=1 VNET_JAIL_STANDARD=1 ;; x) enable_debug ;; *) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;; esac @@ -892,18 +912,39 @@ while [ $# -gt 0 ]; do done # Validate options -if [ -n "${EMPTY_JAIL}" ]; then - if [ -n "${CLONE_JAIL}" ] || [ -n "${THICK_JAIL}" ] || [ -n "${VNET_JAIL}" ] || [ -n "${LINUX_JAIL}" ]; then +# Do not allow EMPTY_JAIL with any other jail type +if [ "${EMPTY_JAIL}" -eq 1 ]; then + if [ "${CLONE_JAIL}" -eq 1 ] || [ "${THICK_JAIL}" -eq 1 ] || [ "${VNET_JAIL}" -eq 1 ] || [ "${LINUX_JAIL}" -eq 1 ]; then error_exit "[ERROR]: Empty jail option can't be used with other options." fi -elif [ -n "${LINUX_JAIL}" ]; then - if [ -n "${EMPTY_JAIL}" ] || [ -n "${VNET_JAIL}" ] || [ -n "${THICK_JAIL}" ] || [ -n "${CLONE_JAIL}" ]; then +# Do not allow LINUX_JAIL with any other jail type +elif [ "${LINUX_JAIL}" -eq 1 ]; then + if [ "${EMPTY_JAIL}" -eq 1 ] || [ "${VNET_JAIL}" -eq 1 ] || [ "${THICK_JAIL}" -eq 1 ] || [ "${CLONE_JAIL}" -eq 1 ]; then error_exit "[ERROR]: Linux jail option can't be used with other options." fi -elif [ -n "${CLONE_JAIL}" ] && [ -n "${THICK_JAIL}" ]; then +# Do not allow CLONE_JAIL and THICK_JAIL together +elif [ "${CLONE_JAIL}" -eq 1 ] && [ "${THICK_JAIL}" -eq 1 ]; 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." +# VLAN_ID can only be used with VNET jails +elif [ "${VNET_JAIL}" -eq 0 ] && [ -n "${VLAN_ID}" ]; then + error_exit "[ERROR]: VLANs can only be used with VNET jails." +# Don't allow multiple VNET jail types +elif { [ "${VNET_JAIL_STANDARD}" -eq 1 ] && [ "${VNET_JAIL_BRIDGE}" -eq 1 ]; } || \ + { [ "${VNET_JAIL_STANDARD}" -eq 1 ] && [ "${VNET_JAIL_PASSTHROUGH}" -eq 1 ]; } || \ + { [ "${VNET_JAIL_BRIDGE}" -eq 1 ] && [ "${VNET_JAIL_PASSTHROUGH}" -eq 1 ]; } then + error_exit "[ERROR]: Only one of [-V|--vnet], [-B|--bridge] or [-P|--passthrough] can be selected." +# Don't allow STATIC_MAC with VNET_JAIL_PASSTHROUGH +elif [ "${VNET_JAIL_PASSTHROUGH}" -eq 1 ] && [ "${STATIC_MAC}" -eq 1 ]; then + error_exit "[ERROR]: [-P|--passthrough] does not support [-M|--static-mac]." +fi + +# Set interface type for VNET jails +if [ "${VNET_JAIL_STANDARD}" -eq 1 ]; then + VNET_INTERFACE_TYPE="standard" +elif [ "${VNET_JAIL_BRIDGE}" -eq 1 ]; then + VNET_INTERFACE_TYPE="bridge" +elif [ "${VNET_JAIL_PASSTHROUGH}" -eq 1 ]; then + VNET_INTERFACE_TYPE="passthrough" fi NAME="$1" @@ -913,7 +954,7 @@ INTERFACE="$4" info "\nAttempting to create jail: ${NAME}" -if [ -n "${EMPTY_JAIL}" ]; then +if [ "${EMPTY_JAIL}" -eq 1 ]; then if [ $# -ne 1 ]; then usage fi @@ -929,22 +970,27 @@ if [ -n "${NAME}" ]; then fi # Validate interface type -if [ -n "${VNET_JAIL}" ] && [ -n "${VNET_JAIL_BRIDGE}" ]; then +if [ "${VNET_INTERFACE_TYPE}" = "bridge" ]; then if ! ifconfig -g bridge | grep -owq "${INTERFACE}"; then error_exit "[ERROR]: Interface is not a bridge: ${INTERFACE}" fi -elif [ -n "${VNET_JAIL}" ] && [ -z "${VNET_JAIL_BRIDGE}" ]; then +elif [ "${VNET_INTERFACE_TYPE}" = "standard" ]; then if ifconfig -g bridge | grep -owq "${INTERFACE}"; then error_exit "[ERROR]: Interface is a bridge: ${INTERFACE}" fi +elif [ "${VNET_INTERFACE_TYPE}" = "passthrough" ]; then + if ! ifconfig -l | grep -owq "${INTERFACE}"; then + error_exit "[ERROR]: Interface does not exist: ${INTERFACE}" + fi fi # Do not allow netgraph with -B|--bridge yet... -if [ "${bastille_network_vnet_type}" = "netgraph" ] && [ -n "${VNET_JAIL_BRIDGE}" ]; then - error_exit "[ERROR]: Netgraph does not support the [-B|--bridge] option." +if { [ "${bastille_network_vnet_type}" = "netgraph" ] && [ "${VNET_INTERFACE_TYPE}" = "bridge" ]; } || \ + { [ "${bastille_network_vnet_type}" = "netgraph" ] && [ "${VNET_INTERFACE_TYPE}" = "bridge" ]; } then + error_exit "[ERROR]: Netgraph does not support the [-B|--bridge] or [-P|--passthrough] option." fi -if [ -n "${LINUX_JAIL}" ] && [ -n "${VALIDATE_RELEASE}" ]; then +if [ "${LINUX_JAIL}" -eq 1 ] && [ "${VALIDATE_RELEASE}" -eq 1 ]; then case "${RELEASE}" in bionic|ubuntu_bionic|ubuntu|ubuntu-bionic) ## check for FreeBSD releases name @@ -977,8 +1023,8 @@ if [ -n "${LINUX_JAIL}" ] && [ -n "${VALIDATE_RELEASE}" ]; then esac fi -if [ -z "${EMPTY_JAIL}" ]; then - if [ -n "${VALIDATE_RELEASE}" ]; then +if [ "${EMPTY_JAIL}" -eq 0 ]; then + if [ "${VALIDATE_RELEASE}" -eq 1 ]; then ## verify release case "${RELEASE}" in [2-4].[0-9]*) @@ -1077,7 +1123,7 @@ if [ -z "${EMPTY_JAIL}" ]; then if [ -n "${INTERFACE}" ]; then validate_netif validate_netconf - elif [ -n "${VNET_JAIL}" ]; then + elif [ "${VNET_JAIL}" -eq 1 ]; then if [ -z "${INTERFACE}" ]; then if [ -z "${bastille_network_shared}" ]; then # User must specify interface on vnet jails. diff --git a/usr/local/share/bastille/network.sh b/usr/local/share/bastille/network.sh index 55013b1d..c0d9ba87 100644 --- a/usr/local/share/bastille/network.sh +++ b/usr/local/share/bastille/network.sh @@ -39,14 +39,14 @@ usage() { Options: - -a | --auto Start/stop jail(s) if required. - -B | --bridge Add a bridge VNET interface. - -M | --static-mac Generate a static MAC address for the interface (VNET only). - -n | --no-ip Create interface without an IP (VNET only). - -P | --passthrough Add a raw interface. - -V | --vnet Add a VNET interface. - -v | --vlan VLANID Assign VLAN ID to interface (VNET only). - -x | --debug Enable debug mode. + -a | --auto Start/stop jail(s) if required. + -B | --bridge Add a bridge VNET interface. + -M | --static-mac Generate a static MAC address for the interface (VNET only). + -n | --no-ip Create interface without an IP (VNET only). + -P | --passthrough Add a raw interface. + -V | --vnet Add a VNET interface. + -v | --vlan VLANID Assign VLAN ID to interface (VNET only). + -x | --debug Enable debug mode. EOF exit 1 @@ -443,18 +443,18 @@ EOF } EOF # Add config to /etc/rc.conf - if [ -n "${IP6_ADDR}" ]; then + if [ -n "${IP6_ADDR}" ]; then if [ "${IP6_ADDR}" = "SLAAC" ]; then - sysrc -f "${_jail_rc_config}" ifconfig_${_jail_vnet}_ipv6="inet6 -ifdisabled accept_rtadv" + sysrc -f "${_jail_rc_config}" ifconfig_${_if}_ipv6="inet6 -ifdisabled accept_rtadv" else - sysrc -f "${_jail_rc_config}" ifconfig_${_jail_vnet}_ipv6="inet6 -ifdisabled ${IP6_ADDR}" + sysrc -f "${_jail_rc_config}" ifconfig_${_if}_ipv6="inet6 -ifdisabled ${IP6_ADDR}" fi elif [ -n "${IP4_ADDR}" ]; then # If 0.0.0.0 set DHCP, else set static IP address if [ "${_ip}" = "0.0.0.0" ] || [ "${_ip}" = "DHCP" ] || [ "${_ip}" = "SYNCDHCP" ]; then - sysrc -f "${_jail_rc_config}" ifconfig_${_jail_vnet}="SYNCDHCP" + sysrc -f "${_jail_rc_config}" ifconfig_${_if}="SYNCDHCP" else - sysrc -f "${_jail_rc_config}" ifconfig_${_jail_vnet}="inet ${IP4_ADDR}" + sysrc -f "${_jail_rc_config}" ifconfig_${_if}="inet ${IP4_ADDR}" fi fi echo "Added Passthrough interface: \"${_if}\"" diff --git a/usr/local/share/bastille/templates/default/vnet/Bastillefile b/usr/local/share/bastille/templates/default/vnet/Bastillefile index e529380c..0c19d6bb 100644 --- a/usr/local/share/bastille/templates/default/vnet/Bastillefile +++ b/usr/local/share/bastille/templates/default/vnet/Bastillefile @@ -1,14 +1,15 @@ -ARG EPAIR +ARG INTERFACE +ARG VNET ARG GATEWAY ARG GATEWAY6 ARG IFCONFIG="SYNCDHCP" ARG IFCONFIG6 -SYSRC ifconfig_${EPAIR}_name=vnet0 -SYSRC ifconfig_vnet0="${IFCONFIG}" +SYSRC ifconfig_${INTERFACE}_name=${VNET} +SYSRC ifconfig_${VNET}="${IFCONFIG}" # Apply IFCONFIG6 if set -CMD if [ -n "${IFCONFIG6}" ]; then /usr/sbin/sysrc ifconfig_vnet0_ipv6="${IFCONFIG6}"; fi +CMD if [ -n "${IFCONFIG6}" ]; then /usr/sbin/sysrc ifconfig_${VNET}_ipv6="${IFCONFIG6}"; fi # GATEWAY will be empty for a DHCP config. -- cwells CMD if [ -n "${GATEWAY}" ]; then /usr/sbin/sysrc defaultrouter="${GATEWAY}"; fi