2020-08-30 10:57:14 -04:00
#!/bin/sh
#
2025-01-15 14:33:22 -07:00
# SPDX-License-Identifier: BSD-3-Clause
#
# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
2020-08-30 10:57:14 -04:00
# 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.
2025-03-02 11:23:35 -07:00
# Load config. This only has to be done here
2025-03-02 13:19:26 -07:00
# because all commands load this file
2025-03-02 11:23:35 -07:00
# shellcheck disable=SC1090
. ${ BASTILLE_CONFIG }
2021-07-13 09:02:55 -04:00
COLOR_RED =
COLOR_GREEN =
COLOR_YELLOW =
COLOR_RESET =
2021-07-13 04:49:25 -04:00
2023-03-16 20:58:11 +01:00
bastille_root_check( ) {
if [ " $( id -u) " -ne 0 ] ; then
## permission denied
error_notify "Bastille: Permission Denied"
error_exit "root / sudo / doas required"
fi
}
2021-07-13 09:02:55 -04:00
enable_color( ) {
. /usr/local/share/bastille/colors.pre.sh
}
2025-01-05 19:14:15 -07:00
enable_debug( ) {
# Enable debug mode.
2025-01-07 15:42:44 -07:00
warn "***DEBUG MODE***"
2025-01-05 19:14:15 -07:00
set -x
}
2022-07-24 22:16:04 +00:00
# If "NO_COLOR" environment variable is present, or we aren't speaking to a
# tty, disable output colors.
2024-12-08 20:37:02 -05:00
if [ -z " ${ NO_COLOR } " ] && [ -t 1 ] ; then
2021-07-13 09:02:55 -04:00
enable_color
fi
2020-08-30 10:57:14 -04:00
2025-04-30 08:19:50 -06:00
# Notify message on error
# Do not echo blank line
2024-12-23 18:23:31 -07:00
error_continue( ) {
error_notify " $@ "
2025-04-30 08:19:50 -06:00
# shellcheck disable=SC2104
continue
}
2025-01-05 19:14:15 -07:00
# Notify message on error, but do not exit
error_notify( ) {
echo -e " ${ COLOR_RED } $* ${ COLOR_RESET } " 1>& 2
}
2020-08-30 10:57:14 -04:00
# Notify message on error and exit
2025-04-30 11:21:41 -06:00
# Echo blank line when exiting
2020-08-30 10:57:14 -04:00
error_exit( ) {
2024-11-24 20:49:06 -05:00
error_notify " $@ "
2025-04-30 08:19:50 -06:00
echo
2020-08-30 10:57:14 -04:00
exit 1
}
2020-11-25 21:19:08 -05:00
info( ) {
echo -e " ${ COLOR_GREEN } $* ${ COLOR_RESET } "
}
warn( ) {
echo -e " ${ COLOR_YELLOW } $* ${ COLOR_RESET } "
}
2022-01-09 19:22:16 -08:00
2025-06-22 11:12:09 -06:00
# This function checks and adds any error code
# that is not "0" to the tmp file
bastille_check_exit_code( ) {
local jail = " ${ 1 } "
local exit_code = " ${ 2 } "
# Set exit code variable
if [ -z " ${ TMP_BASTILLE_EXIT_CODE } " ] ; then
error_exit "[ERROR]: Exit code status not set."
else
local old_exit_code = " $( cat ${ TMP_BASTILLE_EXIT_CODE } ) "
fi
if [ " ${ exit_code } " -ne 0 ] ; then
local new_exit_code = " $(( ${ old_exit_code } + ${ exit_code } )) "
echo " ${ new_exit_code } " > " ${ TMP_BASTILLE_EXIT_CODE } "
error_notify " [ERROR CODE]: ${ exit_code } "
fi
}
# This needs to be the last function called
# if used on any command
2025-06-22 11:25:23 -06:00
bastille_return_exit_code( ) {
2025-06-22 11:12:09 -06:00
local exit_code = " $( cat ${ TMP_BASTILLE_EXIT_CODE } ) "
rm -f ${ TMP_BASTILLE_EXIT_CODE }
return " ${ exit_code } "
}
2025-05-04 12:11:16 -06:00
# Parallel mode, don't exceed process limit
bastille_running_jobs( ) {
_process_limit = " ${ 1 } "
_running_jobs = $(( _running_jobs + 1 ))
if [ " ${ _running_jobs } " -ge " ${ _process_limit } " ] ; then
# Wait for at least one process to finish
2025-05-04 12:42:58 -06:00
wait 2>/dev/null || wait
2025-05-04 12:11:16 -06:00
_running_jobs = $(( _running_jobs - 1 ))
fi
}
2024-12-16 12:27:07 -07:00
check_target_exists( ) {
2024-12-19 16:55:01 -07:00
local _TARGET = " ${ 1 } "
2025-01-05 19:14:15 -07:00
local _jaillist = " $( bastille list jails) "
2025-01-18 10:08:02 -07:00
if ! echo " ${ _jaillist } " | grep -Eq " ^ ${ _TARGET } $" ; then
2024-12-19 16:55:01 -07:00
return 1
2024-12-16 12:18:40 -07:00
else
2024-12-19 16:55:01 -07:00
return 0
2024-12-16 12:18:40 -07:00
fi
}
check_target_is_running( ) {
2025-04-29 21:16:15 -06:00
_TARGET = " ${ 1 } "
2025-01-18 10:08:02 -07:00
if ! jls name | grep -Eq " ^ ${ _TARGET } $" ; then
2024-12-19 16:55:01 -07:00
return 1
2024-12-16 19:22:46 -07:00
else
return 0
2024-12-16 16:58:41 -07:00
fi
2024-12-16 12:18:40 -07:00
}
2024-12-19 16:55:01 -07:00
check_target_is_stopped( ) {
2025-04-29 21:16:15 -06:00
_TARGET = " ${ 1 } "
2025-01-18 10:08:02 -07:00
if jls name | grep -Eq " ^ ${ _TARGET } $" ; then
2024-12-19 16:55:01 -07:00
return 1
2024-12-16 17:44:36 -07:00
else
2024-12-19 16:55:01 -07:00
return 0
2024-12-16 17:44:36 -07:00
fi
}
2025-01-05 19:14:15 -07:00
get_jail_name( ) {
local _JID = " ${ 1 } "
local _jailname = " $( jls -j ${ _JID } name 2>/dev/null) "
if [ -z " ${ _jailname } " ] ; then
return 1
else
echo " ${ _jailname } "
fi
}
jail_autocomplete( ) {
local _TARGET = " ${ 1 } "
local _jaillist = " $( bastille list jails) "
local _AUTOTARGET = " $( echo " ${ _jaillist } " | grep -E " ^ ${ _TARGET } " ) "
if [ -n " ${ _AUTOTARGET } " ] ; then
if [ " $( echo " ${ _AUTOTARGET } " | wc -l) " -eq 1 ] ; then
echo " ${ _AUTOTARGET } "
else
error_continue " Multiple jails found for ${ _TARGET } :\n ${ _AUTOTARGET } "
return 1
fi
else
return 2
fi
}
2025-03-19 10:24:50 -06:00
list_jail_priority( ) {
2025-03-19 15:25:15 -06:00
local _jail_list = " ${ 1 } "
2025-03-19 10:24:50 -06:00
if [ -d " ${ bastille_jailsdir } " ] ; then
for _jail in ${ _jail_list } ; do
2025-05-02 10:27:00 -06:00
# Remove boot.conf in favor of settings.conf
if [ -f ${ bastille_jailsdir } /${ _jail } /boot.conf ] ; then
rm -f ${ bastille_jailsdir } /${ _jail } /boot.conf >/dev/null 2>& 1
2025-03-19 10:24:50 -06:00
fi
2025-05-02 10:27:00 -06:00
local _settings_file = ${ bastille_jailsdir } /${ _jail } /settings.conf
# Set defaults if settings file does not exist
if [ ! -f ${ _settings_file } ] ; then
sysrc -f ${ _settings_file } boot = on >/dev/null 2>& 1
sysrc -f ${ _settings_file } depend = "" >/dev/null 2>& 1
sysrc -f ${ _settings_file } priority = 99 >/dev/null 2>& 1
fi
2025-05-02 11:01:26 -06:00
# Add defaults if they dont exist
if ! grep -oq "boot=" ${ _settings_file } ; then
sysrc -f ${ _settings_file } boot = on >/dev/null 2>& 1
fi
if ! grep -oq "depend=" ${ _settings_file } ; then
sysrc -f ${ _settings_file } depend = "" >/dev/null 2>& 1
fi
if ! grep -oq "priority=" ${ _settings_file } ; then
sysrc -f ${ _settings_file } priority = 99 >/dev/null 2>& 1
fi
2025-05-02 10:27:00 -06:00
_priority = " $( sysrc -f ${ _settings_file } -n priority) "
2025-03-19 10:24:50 -06:00
echo " ${ _jail } ${ _priority } "
done
fi
}
2025-01-05 19:14:15 -07:00
set_target( ) {
local _TARGET = ${ 1 }
2025-03-17 19:54:34 -06:00
if [ " ${ 2 } " = "reverse" ] ; then
local _order = " ${ 2 } "
else
local _order = "forward"
fi
2025-01-05 19:14:15 -07:00
JAILS = ""
TARGET = ""
if [ " ${ _TARGET } " = ALL ] || [ " ${ _TARGET } " = all ] ; then
target_all_jails
else
for _jail in ${ _TARGET } ; do
2025-07-16 18:47:54 -06:00
if [ ! -d " ${ bastille_jailsdir } / ${ _TARGET } " ] && echo " ${ _jail } " | grep -Eq '^[0-9]+$' ; then
2025-01-05 19:14:15 -07:00
if get_jail_name " ${ _jail } " > /dev/null; then
_jail = " $( get_jail_name ${ _jail } ) "
else
2025-04-30 11:21:41 -06:00
error_continue " Error: JID \" ${ _jail } \" not found. Is jail running? "
2025-01-05 19:14:15 -07:00
fi
elif ! check_target_exists " ${ _jail } " ; then
if jail_autocomplete " ${ _jail } " > /dev/null; then
_jail = " $( jail_autocomplete ${ _jail } ) "
elif [ $? -eq 2 ] ; then
2025-07-16 18:47:54 -06:00
if grep -Ehoqw ${ _jail } ${ bastille_jailsdir } /*/tags; then
_jail = " $( grep -Eow ${ _jail } ${ bastille_jailsdir } /*/tags | awk -F"/tags" '{print $1}' | sed " s# ${ bastille_jailsdir } /##g " | tr '\n' ' ' ) "
else
error_continue " Jail not found \" ${ _jail } \" "
fi
2025-01-05 19:14:15 -07:00
else
2025-04-30 11:21:41 -06:00
echo
2025-01-05 19:14:15 -07:00
exit 1
fi
fi
TARGET = " ${ TARGET } ${ _jail } "
JAILS = " ${ JAILS } ${ _jail } "
done
2025-05-05 17:58:37 -06:00
# Exit if no jails
if [ -z " ${ TARGET } " ] && [ -z " ${ JAILS } " ] ; then
exit 1
fi
2025-03-17 19:54:34 -06:00
if [ " ${ _order } " = "forward" ] ; then
2025-03-19 10:24:50 -06:00
TARGET = " $( list_jail_priority " ${ TARGET } " | sort -k2 -n | awk '{print $1}' ) "
JAILS = " $( list_jail_priority " ${ TARGET } " | sort -k2 -n | awk '{print $1}' ) "
2025-03-17 19:54:34 -06:00
elif [ " ${ _order } " = "reverse" ] ; then
2025-03-19 10:24:50 -06:00
TARGET = " $( list_jail_priority " ${ TARGET } " | sort -k2 -nr | awk '{print $1}' ) "
JAILS = " $( list_jail_priority " ${ TARGET } " | sort -k2 -nr | awk '{print $1}' ) "
2025-03-17 19:54:34 -06:00
fi
2025-01-05 20:15:01 -07:00
export TARGET
export JAILS
2025-01-05 19:14:15 -07:00
fi
}
set_target_single( ) {
local _TARGET = " ${ 1 } "
if [ " ${ _TARGET } " = ALL ] || [ " ${ _TARGET } " = all ] ; then
error_exit "[all|ALL] not supported with this command."
2025-01-08 12:59:55 -07:00
elif [ " $( echo ${ _TARGET } | wc -w) " -gt 1 ] ; then
error_exit "Error: Command only supports a single TARGET."
2025-01-09 23:31:23 -07:00
elif [ ! -d " ${ bastille_jailsdir } / ${ _TARGET } " ] && echo " ${ _TARGET } " | grep -Eq '^[0-9]+$' ; then
2025-01-05 19:14:15 -07:00
if get_jail_name " ${ _TARGET } " > /dev/null; then
_TARGET = " $( get_jail_name ${ _TARGET } ) "
else
error_exit " Error: JID \" ${ _TARGET } \" not found. Is jail running? "
fi
2025-01-18 10:08:02 -07:00
elif ! check_target_exists " ${ _TARGET } " ; then
2025-01-05 19:14:15 -07:00
if jail_autocomplete " ${ _TARGET } " > /dev/null; then
_TARGET = " $( jail_autocomplete ${ _TARGET } ) "
elif [ $? -eq 2 ] ; then
2025-01-09 20:47:39 -07:00
error_exit " Jail not found \" ${ _TARGET } \" "
2025-01-05 19:14:15 -07:00
else
2025-04-30 11:21:41 -06:00
echo
2025-01-05 19:14:15 -07:00
exit 1
fi
fi
2025-05-05 17:58:37 -06:00
# Exit if no jails
2025-05-12 19:36:44 -06:00
if [ -z " ${ _TARGET } " ] && [ -z " ${ _JAILS } " ] ; then
2025-05-05 17:58:37 -06:00
exit 1
fi
2025-03-19 05:59:22 -06:00
TARGET = " ${ _TARGET } "
2025-01-05 20:10:37 -07:00
JAILS = " ${ _TARGET } "
export TARGET
export JAILS
2025-01-05 19:14:15 -07:00
}
2025-05-17 18:57:09 -06:00
# This function is run immediately
2025-05-17 20:06:12 -06:00
set_bastille_mountpoints( ) {
if checkyesno bastille_zfs_enable; then
# We have to do this if ALTROOT is enabled/present
local _altroot = " $( zpool get -Ho value altroot ${ bastille_zfs_zpool } ) "
# Set mountpoints to *bastille*dir*
# shellcheck disable=SC2034
bastille_prefix_mountpoint = " ${ bastille_prefix } "
# shellcheck disable=SC2034
bastille_backupsdir_mountpoint = " ${ bastille_backupsdir } "
# shellcheck disable=SC2034
bastille_cachedir_mountpoint = " ${ bastille_cachedir } "
# shellcheck disable=SC2034
bastille_jailsdir_mountpoint = " ${ bastille_jailsdir } "
# shellcheck disable=SC2034
bastille_releasesdir_mountpoint = " ${ bastille_releasesdir } "
# shellcheck disable=SC2034
bastille_templatesdir_mountpoint = " ${ bastille_templatesdir } "
# shellcheck disable=SC2034
bastille_logsdir_mountpoint = " ${ bastille_logsdir } "
# Add _altroot to *dir* if set
if [ " ${ _altroot } " != "-" ] ; then
# Set *dir* to include ALTROOT
bastille_prefix = " ${ _altroot } ${ bastille_prefix } "
bastille_backupsdir = " ${ _altroot } ${ bastille_backupsdir } "
bastille_cachedir = " ${ _altroot } ${ bastille_cachedir } "
bastille_jailsdir = " ${ _altroot } ${ bastille_jailsdir } "
bastille_releasesdir = " ${ _altroot } ${ bastille_releasesdir } "
bastille_templatesdir = " ${ _altroot } ${ bastille_templatesdir } "
bastille_logsdir = " ${ _altroot } ${ bastille_logsdir } "
fi
2025-05-17 18:46:36 -06:00
fi
}
2025-01-05 19:14:15 -07:00
target_all_jails( ) {
local _JAILS = " $( bastille list jails) "
JAILS = ""
for _jail in ${ _JAILS } ; do
if [ -d " ${ bastille_jailsdir } / ${ _jail } " ] ; then
JAILS = " ${ JAILS } ${ _jail } "
fi
done
2025-05-05 17:58:37 -06:00
# Exit if no jails
if [ -z " ${ JAILS } " ] ; then
exit 1
fi
2025-03-17 19:54:34 -06:00
if [ " ${ _order } " = "forward" ] ; then
2025-03-19 15:25:15 -06:00
JAILS = " $( list_jail_priority " ${ JAILS } " | sort -k2 -n | awk '{print $1}' ) "
2025-03-17 19:54:34 -06:00
elif [ " ${ _order } " = "reverse" ] ; then
2025-03-19 15:25:15 -06:00
JAILS = " $( list_jail_priority " ${ JAILS } " | sort -k2 -nr | awk '{print $1}' ) "
2025-03-17 19:54:34 -06:00
fi
2025-01-05 19:14:15 -07:00
export JAILS
}
2025-01-18 16:32:40 -07:00
update_fstab( ) {
2025-01-18 10:08:02 -07:00
local _oldname = " ${ 1 } "
local _newname = " ${ 2 } "
local _fstab = " ${ bastille_jailsdir } / ${ _newname } /fstab "
if [ -f " ${ _fstab } " ] ; then
sed -i '' " s| ${ bastille_jailsdir } / ${ _oldname } /root/| ${ bastille_jailsdir } / ${ _newname } /root/| " " ${ _fstab } "
else
error_notify " Error: Failed to update fstab: ${ _newmane } "
fi
}
generate_static_mac( ) {
local jail_name = " ${ 1 } "
local external_interface = " ${ 2 } "
local external_interface_mac = " $( ifconfig ${ external_interface } | grep ether | awk '{print $2}' ) "
2025-01-24 06:49:19 -07:00
# Use FreeBSD vendor MAC prefix (58:9c:fc) for jail MAC prefix
2025-01-18 10:08:02 -07:00
local macaddr_prefix = "58:9c:fc"
2025-01-24 06:49:19 -07:00
# Use hash of interface+jailname for jail MAC suffix
2025-01-18 10:08:02 -07:00
local macaddr_suffix = " $( echo -n " ${ external_interface_mac } ${ jail_name } " | sed 's#:##g' | sha256 | cut -b -5 | sed 's/\([0-9a-fA-F][0-9a-fA-F]\)\([0-9a-fA-F][0-9a-fA-F]\)\([0-9a-fA-F]\)/\1:\2:\3/' ) "
if [ -z " ${ macaddr_prefix } " ] || [ -z " ${ macaddr_suffix } " ] ; then
error_notify "Failed to generate MAC address."
fi
macaddr = " ${ macaddr_prefix } : ${ macaddr_suffix } "
export macaddr
}
2022-01-09 19:22:16 -08:00
generate_vnet_jail_netblock( ) {
2025-06-11 18:59:32 -06:00
2025-01-15 14:33:22 -07:00
local jail_name = " ${ 1 } "
local use_unique_bridge = " ${ 2 } "
local external_interface = " ${ 3 } "
local static_mac = " ${ 4 } "
2025-06-11 18:59:32 -06:00
if [ " ${ bastille_network_vnet_type } " = "if_bridge" ] ; then
if [ -n " ${ use_unique_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 } "
local jail_epair = " e0b_ ${ name_prefix } xx ${ name_suffix } "
2025-06-09 16:55:04 -06:00
fi
2025-06-11 18:59:32 -06:00
else
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 }
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 } "
local jail_epair = " e0b_ ${ name_prefix } xx ${ name_suffix } "
local jib_epair = " ${ name_prefix } xx ${ name_suffix } "
fi
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 }
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 } "
local jng_if = " ${ name_prefix } xx ${ name_suffix } "
fi
2022-01-09 19:22:16 -08:00
fi
2025-06-11 18:59:32 -06:00
2025-01-15 14:33:22 -07:00
## If BRIDGE is enabled, generate bridge config, else generate VNET config
2022-01-09 19:22:16 -08:00
if [ -n " ${ use_unique_bridge } " ] ; then
2025-01-15 14:33:22 -07:00
if [ -n " ${ static_mac } " ] ; then
## Generate bridged VNET config with static MAC address
generate_static_mac " ${ jail_name } " " ${ external_interface } "
cat <<-EOF
vnet;
2025-01-18 10:08:02 -07:00
vnet.interface = ${ jail_epair } ;
2025-06-11 19:33:28 -06:00
exec.prestart += " epair0=\\\$(ifconfig epair create) && ifconfig \\\${epair0} up name ${ host_epair } && ifconfig \\\${epair0%a}b up name ${ jail_epair } " ;
2025-06-11 18:59:32 -06:00
exec.prestart += " ifconfig ${ external_interface } addm ${ host_epair } " ;
2025-01-18 10:08:02 -07:00
exec.prestart += " ifconfig ${ host_epair } ether ${ macaddr } a " ;
exec.prestart += " ifconfig ${ jail_epair } ether ${ macaddr } b " ;
2025-03-11 14:18:28 -06:00
exec.prestart += " ifconfig ${ host_epair } description \"vnet0 host interface for Bastille jail ${ jail_name } \" " ;
2025-01-18 10:08:02 -07:00
exec.poststop += " ifconfig ${ host_epair } destroy " ;
2025-01-15 14:33:22 -07:00
EOF
else
## Generate bridged VNET config without static MAC address
cat <<-EOF
2025-01-05 19:14:15 -07:00
vnet;
2025-01-18 10:08:02 -07:00
vnet.interface = ${ jail_epair } ;
2025-06-11 19:33:28 -06:00
exec.prestart += " epair0=\\\$(ifconfig epair create) && ifconfig \\\${epair0} up name ${ host_epair } && ifconfig \\\${epair0%a}b up name ${ jail_epair } " ;
2025-06-11 18:59:32 -06:00
exec.prestart += " ifconfig ${ external_interface } addm ${ host_epair } " ;
2025-03-11 14:18:28 -06:00
exec.prestart += " ifconfig ${ host_epair } description \"vnet0 host interface for Bastille jail ${ jail_name } \" " ;
2025-01-18 10:08:02 -07:00
exec.poststop += " ifconfig ${ host_epair } destroy " ;
2025-01-05 19:14:15 -07:00
EOF
2025-01-15 14:33:22 -07:00
fi
2022-01-09 19:22:16 -08:00
else
2025-04-25 14:33:38 -06:00
if [ " ${ bastille_network_vnet_type } " = "if_bridge" ] ; then
if [ -n " ${ static_mac } " ] ; then
## Generate VNET config with static MAC address
generate_static_mac " ${ jail_name } " " ${ external_interface } "
cat <<-EOF
2022-01-09 19:22:16 -08:00
vnet;
2025-06-11 18:59:32 -06:00
vnet.interface = ${ jail_epair } ;
exec.prestart += " jib addm ${ jib_epair } ${ external_interface } " ;
exec.prestart += " ifconfig ${ host_epair } ether ${ macaddr } a " ;
exec.prestart += " ifconfig ${ jail_epair } ether ${ macaddr } b " ;
exec.prestart += " ifconfig ${ host_epair } description \"vnet0 host interface for Bastille jail ${ jail_name } \" " ;
2025-06-12 12:49:53 -06:00
exec.poststop += " ifconfig ${ host_epair } destroy " ;
2022-01-09 19:22:16 -08:00
EOF
2025-04-25 14:33:38 -06:00
else
## Generate VNET config without static MAC address
cat <<-EOF
2025-01-15 14:33:22 -07:00
vnet;
2025-06-11 18:59:32 -06:00
vnet.interface = ${ jail_epair } ;
exec.prestart += " jib addm ${ jib_epair } ${ external_interface } " ;
exec.prestart += " ifconfig ${ host_epair } description \"vnet0 host interface for Bastille jail ${ jail_name } \" " ;
2025-06-12 12:49:53 -06:00
exec.poststop += " ifconfig ${ host_epair } destroy " ;
2025-01-15 14:33:22 -07:00
EOF
2025-04-25 14:33:38 -06:00
fi
elif [ " ${ bastille_network_vnet_type } " = "netgraph" ] ; then
if [ -n " ${ static_mac } " ] ; then
## Generate VNET config with static MAC address
generate_static_mac " ${ jail_name } " " ${ external_interface } "
cat <<-EOF
vnet;
2025-06-11 18:59:32 -06:00
vnet.interface = ${ ng_if } ;
exec.prestart += " jng bridge ${ jng_if } ${ external_interface } " ;
exec.prestart += " ifconfig ${ ng_if } ether ${ macaddr } b " ;
exec.poststop += " jng shutdown ${ jng_if } " ;
2025-04-25 14:33:38 -06:00
EOF
else
## Generate VNET config without static MAC address
cat <<-EOF
2025-01-15 14:33:22 -07:00
vnet;
2025-06-11 18:59:32 -06:00
vnet.interface = ${ ng_if } ;
exec.prestart += " jng bridge ${ jng_if } ${ external_interface } " ;
exec.poststop += " jng shutdown ${ jng_if } " ;
2025-01-15 14:33:22 -07:00
EOF
2025-04-25 14:33:38 -06:00
fi
2025-01-15 14:33:22 -07:00
fi
2025-01-05 19:14:15 -07:00
fi
2024-12-31 15:00:12 -07:00
}
2024-12-31 14:58:50 -07:00
2025-04-26 14:58:26 -06:00
validate_netconf( ) {
2025-05-02 11:59:42 -06:00
# Add default 'bastille_network_vnet_type' on old config file
# This is so we don't have to indtroduce a 'breaking change' statement
if ! grep -oq "bastille_network_vnet_type=" " ${ BASTILLE_CONFIG } " ; then
sed -i '' "s|## Networking|&\nbastille_network_vnet_type=\"if_bridge\" ## default: \"if_bridge\"|" ${ BASTILLE_CONFIG }
# shellcheck disable=SC1090
. ${ BASTILLE_CONFIG }
fi
# Validate that 'bastille_network_vnet_type' has been set
2025-04-26 14:58:26 -06:00
if [ -n " ${ bastille_network_loopback } " ] && [ -n " ${ bastille_network_shared } " ] ; then
2025-04-26 15:01:56 -06:00
error_exit "[ERROR]: 'bastille_network_loopback' and 'bastille_network_shared' cannot both be set."
2025-04-26 14:58:26 -06:00
fi
if [ " ${ bastille_network_vnet_type } " != "if_bridge" ] && [ " ${ bastille_network_vnet_type } " != "netgraph" ] ; then
error_exit " [ERROR]: 'bastille_network_vnet_type' not set properly: ${ bastille_network_vnet_type } "
fi
}
2023-11-25 15:09:11 -07:00
checkyesno( ) {
## copied from /etc/rc.subr -- cedwards (20231125)
## issue #368 (lowercase values should be parsed)
## now used for all bastille_zfs_enable=YES|NO tests
## example: if checkyesno bastille_zfs_enable; then ...
## returns 0 for enabled; returns 1 for disabled
eval _value = \$ ${ 1 }
case $_value in
[ Yy] [ Ee] [ Ss] | [ Tt] [ Rr] [ Uu] [ Ee] | [ Oo] [ Nn] | 1)
return 0
; ;
[ Nn] [ Oo] | [ Ff] [ Aa] [ Ll] [ Ss] [ Ee] | [ Oo] [ Ff] [ Ff] | 0)
return 1
; ;
*)
warn " \$ ${ 1 } is not set properly - see rc.conf(5). "
return 1
; ;
esac
2025-05-17 18:57:09 -06:00
}
2025-05-17 20:06:12 -06:00
2025-06-13 19:36:01 -06:00
update_jail_syntax_v1( ) {
local jail = " ${ 1 } "
local jail_config = " ${ bastille_jailsdir } / ${ jail } /jail.conf "
local jail_rc_config = " ${ bastille_jailsdir } / ${ jail } /root/etc/rc.conf "
# Only apply if old syntax is found
if grep -Eoq "exec.prestart.*ifconfig epair[0-9]+ create.*" " ${ jail_config } " ; then
if [ " $( echo -n " e0a_ ${ jail } " | awk '{print length}' ) " -lt 16 ] ; then
local new_host_epair = e0a_${ jail }
local new_jail_epair = e0b_${ jail }
else
name_prefix = " $( echo ${ jail } | cut -c1-7) "
name_suffix = " $( echo ${ jail } | rev | cut -c1-2 | rev) "
local new_host_epair = " e0a_ ${ name_prefix } xx ${ name_suffix } "
local new_jail_epair = " e0b_ ${ name_prefix } xx ${ name_suffix } "
fi
# Delete unneeded lines
sed -i '' "/.*exec.prestart.*ifconfig.*up name.*;/d" " ${ jail_config } "
sed -i '' "/.*exec.poststop.*ifconfig.*deletem.*;/d" " ${ jail_config } "
2025-06-13 20:22:49 -06:00
# Change jail.conf
2025-06-13 19:36:01 -06:00
sed -i '' " s|.*vnet.interface =.*| vnet.interface = ${ new_jail_epair } ;|g " " ${ jail_config } "
sed -i '' " s|.*ifconfig epair.*create.*| exec.prestart += \"epair0=\\\\\$(ifconfig epair create) \&\& ifconfig \\\\\${epair0} up name ${ new_host_epair } \&\& ifconfig \\\\\${epair0%a}b up name ${ new_jail_epair } \";|g " " ${ jail_config } "
sed -i '' " s|addm.*|addm ${ new_host_epair } \";|g " " ${ jail_config } "
sed -i '' " /ether.*:.*:.*:.*:.*:.*a/ s|ifconfig.*ether|ifconfig ${ new_host_epair } ether|g " " ${ jail_config } "
sed -i '' " /ether.*:.*:.*:.*:.*:.*b/ s|ifconfig.*ether|ifconfig ${ new_jail_epair } ether|g " " ${ jail_config } "
sed -i '' " s|ifconfig.*description|ifconfig ${ new_host_epair } description|g " " ${ jail_config } "
sed -i '' " s|ifconfig.*destroy|ifconfig ${ new_host_epair } destroy|g " " ${ jail_config } "
2025-06-13 20:22:49 -06:00
# Change rc.conf
2025-06-13 20:26:47 -06:00
sed -i '' " /ifconfig_.*_name.*vnet.*/ s|ifconfig_.*_name|ifconfig_ ${ new_jail_epair } _name|g " " ${ jail_rc_config } "
2025-06-13 20:22:49 -06:00
2025-06-13 19:36:01 -06:00
elif grep -Eoq "exec.poststop.*jib destroy.*" " ${ jail_config } " ; then
2025-07-20 14:33:07 -06:00
warn "\n[WARNING]\n"
warn "Updating jail.conf file..."
warn "Please review your jail.conf file after completion."
warm "VNET jails created without -M will be assigned a new MAC address."
2025-06-13 19:36:01 -06:00
local external_interface = " $( grep -Eo "jib addm.*" " ${ jail_config } " | awk '{print $4}' ) "
if [ " $( echo -n " e0a_ ${ jail } " | awk '{print length}' ) " -lt 16 ] ; then
local new_host_epair = e0a_${ jail }
local new_jail_epair = e0b_${ jail }
local jib_epair = " ${ jail } "
else
name_prefix = " $( echo ${ jail } | cut -c1-7) "
name_suffix = " $( echo ${ jail } | rev | cut -c1-2 | rev) "
local new_host_epair = " e0a_ ${ name_prefix } xx ${ name_suffix } "
local new_jail_epair = " e0b_ ${ name_prefix } xx ${ name_suffix } "
local jib_epair = " ${ name_prefix } xx ${ name_suffix } "
fi
2025-06-13 20:22:49 -06:00
# Change jail.conf
2025-06-13 19:36:01 -06:00
sed -i '' " s|.*vnet.interface =.*| vnet.interface = ${ new_jail_epair } ;|g " " ${ jail_config } "
sed -i '' " s|jib addm.*|jib addm ${ jib_epair } ${ external_interface } |g " " ${ jail_config } "
sed -i '' " /ether.*:.*:.*:.*:.*:.*a/ s|ifconfig.*ether|ifconfig ${ new_host_epair } ether|g " " ${ jail_config } "
sed -i '' " /ether.*:.*:.*:.*:.*:.*b/ s|ifconfig.*ether|ifconfig ${ new_jail_epair } ether|g " " ${ jail_config } "
sed -i '' " s|ifconfig.*description|ifconfig ${ new_host_epair } description|g " " ${ jail_config } "
sed -i '' " s|jib destroy.*|ifconfig ${ new_host_epair } destroy\";|g " " ${ jail_config } "
2025-06-13 20:22:49 -06:00
# Change rc.conf
2025-06-13 20:26:47 -06:00
sed -i '' " /ifconfig_.*_name.*vnet.*/ s|ifconfig_.*_name|ifconfig_ ${ new_jail_epair } _name|g " " ${ jail_rc_config } "
2025-06-13 20:22:49 -06:00
2025-06-13 19:36:01 -06:00
fi
}
2025-05-20 12:10:35 -06:00
set_bastille_mountpoints