diff --git a/LICENSE b/LICENSE
index 7ccaf14b7..2f34d728e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 BSD 3-Clause License
 
-Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/docs/chapters/installation.rst b/docs/chapters/installation.rst
index 1a7b239af..232988c9c 100644
--- a/docs/chapters/installation.rst
+++ b/docs/chapters/installation.rst
@@ -4,7 +4,7 @@ Bastille is available in the official FreeBSD ports tree at
 `sysutils/bastille`. Binary packages available in `quarterly` and `latest`
 repositories.
 
-Current version is `0.12.20241124`.
+Current version is `0.12.20250111`.
 
 To install from the FreeBSD package repository:
 
diff --git a/docs/chapters/subcommands/htop.rst b/docs/chapters/subcommands/htop.rst
index d3493be23..1fcb8bdbe 100644
--- a/docs/chapters/subcommands/htop.rst
+++ b/docs/chapters/subcommands/htop.rst
@@ -2,8 +2,8 @@
 htop
 ====
 
-This one runs `htop` inside the container.
-note: won't work if you don't have htop installed in the container.
+This command runs `htop` in the targeted jail.
+Requires htop to be installed in the jail.
 
 
 .. image:: ../../images/htop.png
diff --git a/docs/chapters/subcommands/top.rst b/docs/chapters/subcommands/top.rst
index 16df8682a..77e7f831f 100644
--- a/docs/chapters/subcommands/top.rst
+++ b/docs/chapters/subcommands/top.rst
@@ -2,7 +2,7 @@
 top
 ===
 
-This one runs `top` in that container.
+This command runs `top` in the targeted jail.
 
 
 .. image:: ../../images/top.png
diff --git a/docs/chapters/subcommands/umount.rst b/docs/chapters/subcommands/umount.rst
index cdcdabdb3..2dbfdafa8 100644
--- a/docs/chapters/subcommands/umount.rst
+++ b/docs/chapters/subcommands/umount.rst
@@ -19,7 +19,7 @@ Syntax requires only the jail path to unmount.
 
   Usage: bastille umount TARGET JAIL_PATH
 
-If the directory you are unmounting has spaces, make sure to escape them with a backslash \, and enclode the mount point in quotes "".
+If the directory you are unmounting has spaces, make sure to escape them with a backslash \, and enclose the mount point in quotes "".
 
 .. code-block:: shell
 
diff --git a/docs/conf.py b/docs/conf.py
index 1c3f2c770..964515107 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -8,13 +8,13 @@
 # -- Project information -----------------------------------------------------
 
 project = 'Bastille'
-copyright = '2018-2024, Christer Edwards'
+copyright = '2018-2025, Christer Edwards'
 author = 'Christer Edwards'
 
 # The short X.Y version
-version = '0.12.20241124'
+version = '0.12.20250111'
 # The full version, including alpha/beta/rc tags
-release = '0.12.20241124-beta'
+release = '0.12.20250111-beta'
 
 
 # -- General configuration ---------------------------------------------------
diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille
index 5c78318a7..ba831d07f 100755
--- a/usr/local/bin/bastille
+++ b/usr/local/bin/bastille
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -30,20 +32,23 @@
 
 PATH=${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
 
-. /usr/local/share/bastille/common.sh
-
 ## check for config existence
 bastille_conf_check() {
     if [ ! -r "/usr/local/etc/bastille/bastille.conf" ]; then
-        warn "Configuration file not found. Do yu want to create it with default values? [y/N]"
+        echo "[INFO] Configuration file not found. Do you want to create it with default values? [y/N]"
         read  answer
             case "${answer}" in
                 [Nn][Oo]|[Nn]|"")
-                    error_exit "No configuration file has been generated. Exiting."
+                    echo "[INFO] No configuration file has been generated. Exiting."
+                    exit
                 ;;
                 [Yy][Ee][Ss]|[Yy])
                     cp /usr/local/etc/bastille/bastille.conf.sample /usr/local/etc/bastille/bastille.conf
-                    info "Configuration file has been generated. Continuing with default values"
+                    echo "[INFO] Configuration file has been generated. Continuing with default values"
+                ;;
+                *)
+                  echo "[ERROR] Invalid option. Please answer with 'y' or 'N'."
+                  exit 1
                 ;;
             esac
     fi
@@ -51,7 +56,8 @@ bastille_conf_check() {
 
 bastille_conf_check
 
-## we only load the config if conf_check passes
+## we only load this if conf_check passes
+. /usr/local/share/bastille/common.sh
 . /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}"
@@ -72,7 +78,7 @@ bastille_perms_check() {
 bastille_perms_check
 
 ## version
-BASTILLE_VERSION="0.12.20241124"
+BASTILLE_VERSION="0.12.20250111"
 
 usage() {
     cat << EOF
@@ -93,6 +99,7 @@ Available Commands:
   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).
+  etcupdate   Update /etc directory to specified release.
   export      Exports a specified container.
   help        Help about any command.
   htop        Interactive process viewer (requires htop).
@@ -157,7 +164,7 @@ version|-v|--version)
 help|-h|--help)
     usage
     ;;
-bootstrap|create|destroy|export|htop|import|list|mount|rdr|restart|setup|start|top|umount|update|upgrade|verify)
+bootstrap|create|destroy|etcupdate|export|htop|import|list|mount|rdr|restart|setup|start|top|umount|update|upgrade|verify)
     # Nothing "extra" to do for these commands. -- cwells
     ;;
 clone|config|cmd|console|convert|cp|edit|limits|pkg|rcp|rename|service|stop|sysrc|tags|template|zfs)
diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh
index 295ebf676..b981e9abb 100644
--- a/usr/local/share/bastille/bootstrap.sh
+++ b/usr/local/share/bastille/bootstrap.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh
index e11bd701e..428bf9c80 100644
--- a/usr/local/share/bastille/clone.sh
+++ b/usr/local/share/bastille/clone.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -103,47 +105,77 @@ update_jailconf() {
 
 update_jailconf_vnet() {
     bastille_jail_rc_conf="${bastille_jailsdir}/${NEWNAME}/root/etc/rc.conf"
-
-    # Determine number of containers and define an uniq_epair
-    local list_jails_num="$(bastille list jails | wc -l | awk '{print $1}')"
-    local num_range="$(expr "${list_jails_num}" + 1)"
-    jail_list=$(bastille list jail)
-    for _num in $(seq 0 "${num_range}"); do
-        if [ -n "${jail_list}" ]; then
-            if ! grep -q "e0b_bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then
-                if ! grep -q "epair${_num}" "${bastille_jailsdir}"/*/jail.conf; then
-                    local uniq_epair="bastille${_num}"
+    # Determine number of interfaces and define a uniq_epair
+    local _if_list="$(grep -Eo 'epair[0-9]+|bastille[0-9]+' ${JAIL_CONFIG} | sort -u)"
+    for _if in ${_if_list}; do
+        local _epair_if_count="$(grep -Eo 'epair[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')"
+        local _bastille_if_count="$(grep -Eo 'bastille[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')"
+        local epair_num_range=$((_epair_if_count + 1))
+        local bastille_num_range=$((_bastille_if_count + 1))
+        if echo ${_if} | grep -Eoq 'epair[0-9]+'; then
+            # Update bridged VNET config
+            for _num in $(seq 0 "${epair_num_range}"); do
+                if ! grep -oq "epair${_num}" ${bastille_jailsdir}/*/jail.conf; then
+                    # Update jail.conf epair name
                     local uniq_epair_bridge="${_num}"
-	            # since we don't have access to the external_interface variable, we cat the jail.conf file to retrieve the mac prefix
-                    # we also do not use the main generate_static_mac function here
-                    local macaddr_prefix="$(cat ${JAIL_CONFIG} | grep -m 1 ether | grep -oE '([0-9a-f]{2}(:[0-9a-f]{2}){5})' | awk -F: '{print $1":"$2":"$3}')"
-    	            local macaddr_suffix="$(echo -n ${NEWNAME} | 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/')"
-                    local macaddr="${macaddr_prefix}:${macaddr_suffix}"
-	            # Update the exec.* with uniq_epair when cloning jails.
-                    # for VNET jails
-                    sed -i '' "s|bastille\([0-9]\{1,\}\)|${uniq_epair}|g" "${JAIL_CONFIG}"
-                    sed -i '' "s|e\([0-9]\{1,\}\)a_${NEWNAME}|e${uniq_epair_bridge}a_${NEWNAME}|g" "${JAIL_CONFIG}"
-                    sed -i '' "s|e\([0-9]\{1,\}\)b_${NEWNAME}|e${uniq_epair_bridge}b_${NEWNAME}|g" "${JAIL_CONFIG}"
-                    sed -i '' "s|epair\([0-9]\{1,\}\)|epair${uniq_epair_bridge}|g" "${JAIL_CONFIG}"
-		    sed -i '' "s|exec.prestart += \"ifconfig e0a_bastille\([0-9]\{1,\}\).*description.*|exec.prestart += \"ifconfig e0a_${uniq_epair} description \\\\\"vnet host interface for Bastille jail ${NEWNAME}\\\\\"\";|" "${JAIL_CONFIG}"
-                    sed -i '' "s|ether.*:.*:.*:.*:.*:.*a\";|ether ${macaddr}a\";|" "${JAIL_CONFIG}"
-                    sed -i '' "s|ether.*:.*:.*:.*:.*:.*b\";|ether ${macaddr}b\";|" "${JAIL_CONFIG}"
+                    local _if_epaira="${_if}a"
+                    local _if_epairb="${_if}b"
+                    local _if_vnet="$(grep ${_if_epairb} "${bastille_jail_rc_conf}" | grep -Eo -m 1 "vnet[0-9]+")"
+                    sed -i '' "s|${_if}|epair${uniq_epair_bridge}|g" "${JAIL_CONFIG}"
+                    # If jail had a static MAC, generate one for clone
+                    if grep ether ${JAIL_CONFIG} | grep -qoc epair${uniq_epair_bridge}; then
+                        local external_interface="$(grep "epair${uniq_epair_bridge}" ${JAIL_CONFIG} | grep -o '[^ ]* addm' | awk '{print $1}')"
+                        generate_static_mac "${NEWNAME}" "${external_interface}"
+                        sed -i '' "s|epair${uniq_epair_bridge}a ether.*:.*:.*:.*:.*:.*a\";|epair${uniq_epair_bridge}a ether ${macaddr}a\";|" "${JAIL_CONFIG}"
+                        sed -i '' "s|epair${uniq_epair_bridge}b ether.*:.*:.*:.*:.*:.*b\";|epair${uniq_epair_bridge}b ether ${macaddr}b\";|" "${JAIL_CONFIG}"
+                    fi
+                    sed -i '' "s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|g" "${JAIL_CONFIG}"
+                    # Update /etc/rc.conf
+                    sed -i '' "s|${_if_epairb}_name|epair${uniq_epair_bridge}b_name|" "${bastille_jail_rc_conf}"
+                    if grep "vnet0" "${bastille_jail_rc_conf}" | grep -q "epair${uniq_epair_bridge}b_name"; then
+                        if [ "${IP}" = "0.0.0.0" ]; then
+                            sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="SYNCDHCP"
+                        else
+                            sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}"
+                        fi
+                    else
+                        sysrc -f "${bastille_jail_rc_conf}" ifconfig_${_if_vnet}="SYNCDHCP"
+                    fi
                     break
                 fi
-            fi
+            done
+        elif echo ${_if} | grep -Eoq 'bastille[0-9]+'; then
+            # Update VNET config
+            for _num in $(seq 0 "${bastille_num_range}"); do
+                if ! grep -oq "bastille${_num}" ${bastille_jailsdir}/*/jail.conf; then
+                    # Update jail.conf epair name
+                    local uniq_epair="bastille${_num}"
+                    local _if_vnet="$(grep ${_if} "${bastille_jail_rc_conf}" | grep -Eo -m 1 "vnet[0-9]+")"
+                    sed -i '' "s|${_if}|${uniq_epair}|g" "${JAIL_CONFIG}"
+                    # If jail had a static MAC, generate one for clone
+                    if grep ether ${JAIL_CONFIG} | grep -qoc ${uniq_epair}; then
+                        local external_interface="$(grep ${uniq_epair} ${JAIL_CONFIG} | grep -o 'addm.*' | awk '{print $3}' | sed 's/["|;]//g')"
+                        generate_static_mac "${NEWNAME}" "${external_interface}"
+                        sed -i '' "s|${uniq_epair} ether.*:.*:.*:.*:.*:.*a\";|${uniq_epair} ether ${macaddr}a\";|" "${JAIL_CONFIG}"
+                        sed -i '' "s|${uniq_epair} ether.*:.*:.*:.*:.*:.*b\";|${uniq_epair} ether ${macaddr}b\";|" "${JAIL_CONFIG}"
+                    fi
+                    sed -i '' "s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|g" "${JAIL_CONFIG}"
+                    # Update /etc/rc.conf
+                    sed -i '' "s|ifconfig_e0b_${_if}_name|ifconfig_e0b_${uniq_epair}_name|" "${bastille_jail_rc_conf}"
+                    if grep "vnet0" "${bastille_jail_rc_conf}" | grep -q ${uniq_epair}; then
+                        if [ "${IP}" = "0.0.0.0" ]; then
+                            sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="SYNCDHCP"
+                        else
+                            sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0=" inet ${IP} "
+                        fi
+                    else
+                        sysrc -f "${bastille_jail_rc_conf}" ifconfig_${_if_vnet}="SYNCDHCP"
+                    fi
+                    break
+                fi
+            done
         fi
     done
-
-    # Rename interface to new uniq_epair
-    sed -i '' "s|ifconfig_e0b_bastille.*_name|ifconfig_e0b_${uniq_epair}_name|" "${bastille_jail_rc_conf}"
-    sed -i '' "s|ifconfig_e.*b_${TARGET}_name|ifconfig_e${uniq_epair_bridge}b_${NEWNAME}_name|" "${bastille_jail_rc_conf}"
-    
-    # If 0.0.0.0 set DHCP, else set static IP address
-    if [ "${IP}" = "0.0.0.0" ]; then
-        sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="SYNCDHCP"
-    else
-        sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}"
-    fi
 }
 
 update_fstab() {
diff --git a/usr/local/share/bastille/cmd.sh b/usr/local/share/bastille/cmd.sh
index a1f423472..277791d13 100644
--- a/usr/local/share/bastille/cmd.sh
+++ b/usr/local/share/bastille/cmd.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/colors.pre.sh b/usr/local/share/bastille/colors.pre.sh
index 0d5614201..9074e2d15 100644
--- a/usr/local/share/bastille/colors.pre.sh
+++ b/usr/local/share/bastille/colors.pre.sh
@@ -1,5 +1,7 @@
 #!/bin/sh
 #
+# SPDX-License-Identifier: BSD-3-Clause
+#
 # Copyright (c) 2014-2015 Bryan Drewery <bdrewery@FreeBSD.org>
 # All rights reserved.
 #
diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh
index b9b0986fc..654ff026b 100644
--- a/usr/local/share/bastille/common.sh
+++ b/usr/local/share/bastille/common.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -110,9 +112,11 @@ check_target_is_stopped() {
 generate_static_mac() {
     local jail_name="${1}"
     local external_interface="${2}"
-    local external_interface_mac="$(ifconfig ${external_interface} | grep ether | awk '{print $2}' | sed 's#:##g')"
-    local macaddr_prefix="$(echo -n "${external_interface_mac}" | sha256 | cut -b -6 | 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/')"
-    local macaddr_suffix="$(echo -n "${jail_name}" | 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/')"
+    local external_interface_mac="$(ifconfig ${external_interface} | grep ether | awk '{print $2}')"
+    # Use the FreeBSD vendor MAC prefix for jail MAC prefix "58:9c:fc"
+    local macaddr_prefix="58:9c:fc"
+    # Hash interface+jailname for jail MAC suffix
+    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
@@ -121,47 +125,73 @@ generate_static_mac() {
 }
 
 generate_vnet_jail_netblock() {
-    local jail_name="$1"
-    local use_unique_bridge="$2"
-    local external_interface="$3"
-    generate_static_mac "${jail_name}" "${external_interface}"
-    ## determine number of containers + 1
+    local jail_name="${1}"
+    local use_unique_bridge="${2}"
+    local external_interface="${3}"
+    local static_mac="${4}"
+    ## determine number of interfaces + 1
     ## iterate num and grep all jail configs
     ## define uniq_epair
-    local jail_list="$(bastille list jails)"
-    if [ -n "${jail_list}" ]; then
-        local list_jails_num="$(echo "${jail_list}" | wc -l | awk '{print $1}')"
-        local num_range=$((list_jails_num + 1))
-        for _num in $(seq 0 "${num_range}"); do
-            if ! grep -q "e[0-9]b_bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then
-                if ! grep -q "epair${_num}" "${bastille_jailsdir}"/*/jail.conf; then
-                    local uniq_epair="bastille${_num}"
+    local _epair_if_count="$(grep -Eos 'epair[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')"
+    local _bastille_if_count="$(grep -Eos 'bastille[0-9]+' ${bastille_jailsdir}/*/jail.conf | sort -u | wc -l | awk '{print $1}')"
+    local epair_num_range=$((_epair_if_count + 1))
+    local bastille_num_range=$((_bastille_if_count + 1))
+    if [ -n "${use_unique_bridge}" ]; then
+        if [ "${_epair_if_count}" -gt 0 ]; then  
+            for _num in $(seq 0 "${epair_num_range}"); do
+                if ! grep -Eosq "epair${_num}" ${bastille_jailsdir}/*/jail.conf; then
                     local uniq_epair_bridge="${_num}"
                     break
                 fi
-            fi
-        done
+            done
+        else
+            local uniq_epair_bridge="0"
+        fi
     else
-        local uniq_epair="bastille0"
-        local uniq_epair_bridge="0"
+        if [ "${_bastille_if_count}" -gt 0 ]; then  
+            for _num in $(seq 0 "${bastille_num_range}"); do
+                if ! grep -Eosq "bastille${_num}" ${bastille_jailsdir}/*/jail.conf; then
+                    local uniq_epair="bastille${_num}"
+                    break
+                fi
+            done
+        else
+            local uniq_epair="bastille0"
+        fi
     fi
+    ## If BRIDGE is enabled, generate bridge config, else generate VNET config
     if [ -n "${use_unique_bridge}" ]; then
-        ## generate bridge config
-        cat <<-EOF
+        if [ -n "${static_mac}" ]; then
+            ## Generate bridged VNET config with static MAC address
+            generate_static_mac "${jail_name}" "${external_interface}"
+            cat <<-EOF
+  vnet;
+  vnet.interface = epair${uniq_epair_bridge}b;
+  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 ether ${macaddr}a";
+  exec.prestart += "ifconfig epair${uniq_epair_bridge}b ether ${macaddr}b";
+  exec.prestart += "ifconfig epair${uniq_epair_bridge}a description \"vnet host interface for Bastille jail ${jail_name}\"";
+  exec.poststop += "ifconfig ${external_interface} deletem epair${uniq_epair_bridge}a";
+  exec.poststop += "ifconfig epair${uniq_epair_bridge}a destroy";
+EOF
+        else
+            ## Generate bridged VNET config without static MAC address
+            cat <<-EOF
   vnet;
-  vnet.interface = e${uniq_epair_bridge}b_${jail_name};
+  vnet.interface = epair${uniq_epair_bridge}b;
   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.prestart += "ifconfig e${uniq_epair_bridge}a_${jail_name} ether ${macaddr}a";
-  exec.prestart += "ifconfig e${uniq_epair_bridge}b_${jail_name} ether ${macaddr}b";
-  exec.poststop += "ifconfig ${external_interface} deletem e${uniq_epair_bridge}a_${jail_name}";
-  exec.poststop += "ifconfig e${uniq_epair_bridge}a_${jail_name} destroy";
+  exec.prestart += "ifconfig epair${uniq_epair_bridge}a description \"vnet host interface for Bastille jail ${jail_name}\"";
+  exec.poststop += "ifconfig ${external_interface} deletem epair${uniq_epair_bridge}a";
+  exec.poststop += "ifconfig epair${uniq_epair_bridge}a destroy";
 EOF
+        fi
     else
-        ## generate config
-        cat <<-EOF
+        if [ -n "${static_mac}" ]; then
+            ## Generate VNET config with static MAC address
+            generate_static_mac "${jail_name}" "${external_interface}"
+            cat <<-EOF
   vnet;
   vnet.interface = e0b_${uniq_epair};
   exec.prestart += "jib addm ${uniq_epair} ${external_interface}";
@@ -170,6 +200,16 @@ EOF
   exec.prestart += "ifconfig e0a_${uniq_epair} description \"vnet host interface for Bastille jail ${jail_name}\"";
   exec.poststop += "jib destroy ${uniq_epair}";
 EOF
+        else
+            ## Generate VNET config without static MAC address
+            cat <<-EOF
+  vnet;
+  vnet.interface = e0b_${uniq_epair};
+  exec.prestart += "jib addm ${uniq_epair} ${external_interface}";
+  exec.prestart += "ifconfig e0a_${uniq_epair} description \"vnet host interface for Bastille jail ${jail_name}\"";
+  exec.poststop += "jib destroy ${uniq_epair}";
+EOF
+        fi
     fi
 }
 
@@ -190,13 +230,28 @@ set_target_single() {
     local _TARGET="${1}"
     if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then
         error_exit "[all|ALL] not supported with this command."
-    else
-        check_target_exists "${_TARGET}" || error_exit "Jail not found \"${_TARGET}\""
-        JAILS="${_TARGET}"
-        TARGET="${_TARGET}"
-        export JAILS
-        export TARGET
+    elif [ "$(echo ${_TARGET} | wc -w)" -gt 1 ]; then
+        error_exit "Error: Command only supports a single TARGET."
+    elif echo "${_TARGET}" | grep -Eq '^[0-9]+$'; then
+        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
+    elif
+        ! check_target_exists "${_TARGET}"; then
+            if jail_autocomplete "${_TARGET}" > /dev/null; then
+                _TARGET="$(jail_autocomplete ${_TARGET})"
+            elif [ $? -eq 2 ]; then
+                error_exit "Jail not found \"${_TARGET}\""
+            else
+                exit 1
+            fi
     fi
+    TARGET="${_TARGET}"
+    JAILS="${_TARGET}"
+    export TARGET
+    export JAILS
 }
 
 target_all_jails() {
diff --git a/usr/local/share/bastille/config.sh b/usr/local/share/bastille/config.sh
index 9b39f6bce..68fe1135d 100644
--- a/usr/local/share/bastille/config.sh
+++ b/usr/local/share/bastille/config.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/console.sh b/usr/local/share/bastille/console.sh
index b15865cc9..9131b221b 100644
--- a/usr/local/share/bastille/console.sh
+++ b/usr/local/share/bastille/console.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh
index 0290f3553..d22c97083 100644
--- a/usr/local/share/bastille/convert.sh
+++ b/usr/local/share/bastille/convert.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh
index 0d027f7d2..d7fc174bb 100644
--- a/usr/local/share/bastille/cp.sh
+++ b/usr/local/share/bastille/cp.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh
index f0a1250fe..0f47f17c1 100644
--- a/usr/local/share/bastille/create.sh
+++ b/usr/local/share/bastille/create.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -39,12 +41,13 @@ usage() {
     cat << EOF
     Options:
 
-    -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.
+    -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.
 
 EOF
     exit 1
@@ -227,7 +230,7 @@ generate_vnet_jail_conf() {
     else
         devfs_ruleset_value=13
     fi
-    NETBLOCK=$(generate_vnet_jail_netblock "$NAME" "${VNET_JAIL_BRIDGE}" "${bastille_jail_conf_interface}")
+    NETBLOCK=$(generate_vnet_jail_netblock "$NAME" "${VNET_JAIL_BRIDGE}" "${bastille_jail_conf_interface}" "${STATIC_MAC}")
     cat << EOF > "${bastille_jail_conf}"
 ${NAME} {
   enforce_statfs = 2;
@@ -628,10 +631,15 @@ THICK_JAIL=""
 CLONE_JAIL=""
 VNET_JAIL=""
 LINUX_JAIL=""
+STATIC_MAC=""
 
 # Handle and parse options
 while [ $# -gt 0 ]; do
     case "${1}" in
+        -M|--static-mac)
+            STATIC_MAC="1"
+            shift
+            ;;
         -E|--empty)
             EMPTY_JAIL="1"
             shift
diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh
index d95a4429d..56d8d7f3e 100644
--- a/usr/local/share/bastille/destroy.sh
+++ b/usr/local/share/bastille/destroy.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/edit.sh b/usr/local/share/bastille/edit.sh
index 79677e5b9..4442cad0d 100644
--- a/usr/local/share/bastille/edit.sh
+++ b/usr/local/share/bastille/edit.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh
new file mode 100644
index 000000000..9e4f6c684
--- /dev/null
+++ b/usr/local/share/bastille/etcupdate.sh
@@ -0,0 +1,197 @@
+#!/bin/sh
+# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * 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.
+
+. /usr/local/share/bastille/common.sh
+. /usr/local/etc/bastille/bastille.conf
+
+usage() {
+    error_notify "Usage: bastille etcupdate [option(s)] [bootstrap|TARGET] [diff|resolve|update RELEASE]"
+    cat << EOF
+    Options:
+
+    -d | --dry-run          Show output, but do not apply.
+    -f | --force            Force a re-bootstrap of a RELEASE.
+    -x | --debug            Enable debug mode.
+
+EOF
+    exit 1
+}
+
+bootstrap_etc_release() {
+    local _release="${1}"
+    local _current="$(sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives | awk -F': ' '{print $2}')"
+    if ! ls -A "${bastille_releasesdir}/${_release}/usr/src" 2>/dev/null; then
+        sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives=src
+        if ! bastille bootstrap "${_release}" > /dev/null; then
+            sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives="${_current}"
+            error_exit "Failed to bootstrap etcupdate: ${_release}"
+        else
+            sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives="${_current}"
+        fi
+    fi
+}
+
+bootstrap_etc_tarball() {
+    local _release="${1}"
+    if [ ! -f ${bastille_cachedir}/${_release}.tbz2 ]; then
+        echo "Building tarball, please wait..."
+        if ! etcupdate build -d /tmp/etcupdate -s ${bastille_releasesdir}/${_release}/usr/src ${bastille_cachedir}/${_release}.tbz2; then
+            error_exit "Failed to build etcupdate tarball \"${_release}.tbz2\""
+        else
+            info "Etcupdate bootstrap complete: ${_release}"
+        fi
+    elif [ -f ${bastille_cachedir}/${_release}.tbz2 ] && [ "${FORCE}" -eq 1 ]; then
+        rm -f "${bastille_cachedir}/${_release}.tbz2"
+        echo "Building tarball, please wait..."
+        if ! etcupdate build -d /tmp/etcupdate -s ${bastille_releasesdir}/${_release}/usr/src ${bastille_cachedir}/${_release}.tbz2; then
+            error_exit "Failed to build etcupdate tarball: ${_release}.tbz2"
+        else
+            info "Etcupdate bootstrap complete: ${_release}"
+        fi
+    else
+        info "Etcupdate release has already been prepared for application: ${_release}"
+    fi
+}
+
+diff_review() {
+    local _jail="${1}"
+    if [ "${DRY_RUN}" -eq 1 ]; then
+        warn "Warning: diff mode does not support [-d|--dryrun]"
+    fi
+    info "[${_jail}]: etcupdate --diff mode"
+    etcupdate diff -D "${bastille_jailsdir}/${_jail}/root"  
+}
+
+resolve_conflicts() {
+    local _jail="${1}"
+    if [ "${DRY_RUN}" -eq 1 ]; then
+        warn "Warning: resolve mode does not support [-d|--dryrun]"
+    fi
+    info "[${_jail}]: etcupdate resolve"
+    etcupdate resolve -D "${bastille_jailsdir}/${_jail}/root"  
+}
+
+update_jail_etc() {
+    local _jail="${1}"
+    local _release="${2}"
+    if [ ! -f ${bastille_cachedir}/${_release}.tbz2 ]; then
+        error_exit "Error: Please run \"bastille etcupdate bootstrap RELEASE\" first."
+    fi
+    if [ "${DRY_RUN}" -eq 1 ]; then
+        info "[${_jail}]: etcupdate update --dry-run"
+        etcupdate -n -D "${bastille_jailsdir}/${_jail}/root" -t ${bastille_cachedir}/${_release}.tbz2
+    else
+        info "[${_jail}]: etcupdate update"
+        etcupdate -D "${bastille_jailsdir}/${_jail}/root" -t ${bastille_cachedir}/${_release}.tbz2
+    fi
+}
+
+# Handle options.
+DRY_RUN=0
+FORCE=0
+while [ "$#" -gt 0 ]; do
+    case "${1}" in
+        -h|--help|help)
+            usage
+            ;;
+        -d|--dry-run)
+            DRY_RUN=1
+            shift
+            ;;
+        -f|--force)
+            FORCE=1
+            shift
+            ;;
+        -x|--debug)
+            enable_debug
+            shift
+            ;;
+        -*) 
+            for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do
+                case ${_opt} in
+                    d) DRY_RUN=1 ;;
+                    f) FORCE=1 ;;
+                    x) enable_debug ;;
+                    *) error_exit "Unknown Option: \"${1}\"" ;; 
+                esac
+            done
+            shift
+            ;;
+        *)
+            break
+            ;;
+    esac
+done
+
+if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then
+    usage
+fi
+
+# Main commands
+while [ "$#" -gt 0 ]; do
+    case "${1}" in
+        bootstrap)
+            if [ -z "${2}" ]; then
+                usage
+            else
+                RELEASE="${2}"
+                bootstrap_etc_release "${RELEASE}"
+                bootstrap_etc_tarball "${RELEASE}"
+                shift "$#"
+            fi
+            ;;
+        *)
+            TARGET="${1}"
+            ACTION="${2}"
+            RELEASE="${3}"
+            set_target_single "${TARGET}"
+            case "${ACTION}" in
+                diff)
+                    diff_review "${TARGET}"
+                    shift "$#"
+                    ;;
+                resolve)
+                    resolve_conflicts "${TARGET}"
+                    shift "$#"
+                    ;;
+                update)
+                    if [ -z "${RELEASE}" ]; then
+                        usage
+                    else
+                        update_jail_etc "${TARGET}" "${RELEASE}"
+                        shift "$#"
+                    fi
+                    ;;
+                *)
+                    error_exit "Unknown action: \"${ACTION}\""
+                    ;;
+            esac
+            ;;
+    esac
+done
diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh
index 123db04ba..86898b52c 100644
--- a/usr/local/share/bastille/export.sh
+++ b/usr/local/share/bastille/export.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh
index 10795da15..d6b108d89 100644
--- a/usr/local/share/bastille/htop.sh
+++ b/usr/local/share/bastille/htop.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -32,29 +34,41 @@
 . /usr/local/etc/bastille/bastille.conf
 
 usage() {
-    error_exit "Usage: bastille htop [option(s)] TARGET"
+    error_notify "Usage: bastille htop [option(s)] TARGET"
     cat << EOF
     Options:
 
-    -f | --force -- Start the jail if it is stopped.
+    -a | --auto           Auto mode. Start/stop jail(s) if required.
+    -x | --debug          Enable debug mode.
 
 EOF
     exit 1
 }
 
 # Handle options.
-FORCE=0
+AUTO=0
 while [ "$#" -gt 0 ]; do
     case "${1}" in
         -h|--help|help)
             usage
             ;;
-        -f|--force)
-            FORCE=1
+        -a|--auto)
+            AUTO=1
+            shift
+            ;;
+        -x|--debug)
+            enable_debug
             shift
             ;;
         -*)
-            error_exit "Unknown option: \"${1}\""
+            for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do
+                case ${_opt} in
+                    a) AUTO=1 ;;
+                    x) enable_debug ;;
+                    *) error_exit "Unknown Option: \"${1}\""
+                esac
+            done
+            shift
             ;;
         *)
             break
@@ -72,15 +86,14 @@ bastille_root_check
 set_target_single "${TARGET}"
 
 info "[${TARGET}]:"
-check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then
+check_target_is_running "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then
     bastille start "${TARGET}"
 else   
     error_notify "Jail is not running."
-    error_continue "Use [-f|--force] to force start the jail."
+    error_continue "Use [-a|--auto] to auto-start the jail."
 fi
 
-bastille_jail_path="${bastille_jailsdir}/${TARGET}/root"
-if [ ! -x "${bastille_jail_path}/usr/local/bin/htop" ]; then
+if [ ! -x "${bastille_jailsdir}/${TARGET}/root/usr/local/bin/htop" ]; then
     error_notify "htop not found on ${TARGET}."
 elif [ -x "${bastille_jail_path}/usr/local/bin/htop" ]; then
     jexec -l ${TARGET} /usr/local/bin/htop
diff --git a/usr/local/share/bastille/import.sh b/usr/local/share/bastille/import.sh
index 34cda5fc0..ade9f648b 100644
--- a/usr/local/share/bastille/import.sh
+++ b/usr/local/share/bastille/import.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/limits.sh b/usr/local/share/bastille/limits.sh
index 29f631a17..03af4690d 100644
--- a/usr/local/share/bastille/limits.sh
+++ b/usr/local/share/bastille/limits.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 # Ressource limits added by Sven R github.com/hackacad
 #
diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh
index 49534e2df..23f13d071 100644
--- a/usr/local/share/bastille/list.sh
+++ b/usr/local/share/bastille/list.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -62,7 +64,8 @@ list_all(){
             MAX_LENGTH_JID=${MAX_LENGTH_JID:-3}
             MAX_LENGTH_JAIL_IP=$(find ${bastille_jailsdir}/*/jail.conf -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 sed -n "s/^[ ]*ip[4,6].addr[ ]*=[ ]*\(.*\);$/\1 /p" | sed 's/\// /g' | awk '{ print length($1) }' | sort -nr | head -n 1)
             MAX_LENGTH_JAIL_IP=${MAX_LENGTH_JAIL_IP:-10}
-            MAX_LENGTH_JAIL_VNET_IP=$(find ${bastille_jailsdir}/*/jail.conf -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -l "vnet;" | grep -h "ifconfig_vnet0=" "$(sed -n "s/\(.*\)jail.conf$/\1root\/etc\/rc.conf/p")" | sed -n "s/^ifconfig_vnet0=\"\(.*\)\"$/\1/p"| sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print length($2); else print 15 }' | sort -nr | head -n 1)
+            # shellcheck disable=SC2046
+            MAX_LENGTH_JAIL_VNET_IP="$(find ${bastille_jailsdir}/*/jail.conf -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -l "vnet;" | grep -h "ifconfig_vnet0=" $(sed -n "s/\(.*\)jail.conf$/\1root\/etc\/rc.conf/p") | sed -n "s/^ifconfig_vnet0=\"\(.*\)\"$/\1/p"| sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print length($2); else print 15 }' | sort -nr | head -n 1)"
             MAX_LENGTH_JAIL_VNET_IP=${MAX_LENGTH_JAIL_VNET_IP:-10}
             if [ "${MAX_LENGTH_JAIL_VNET_IP}" -gt "${MAX_LENGTH_JAIL_IP}" ]; then MAX_LENGTH_JAIL_IP=${MAX_LENGTH_JAIL_VNET_IP}; fi
             if [ "${MAX_LENGTH_JAIL_IP}" -lt 10 ]; then MAX_LENGTH_JAIL_IP=10; fi
@@ -73,11 +76,13 @@ list_all(){
             MAX_LENGTH_JAIL_PORTS=${MAX_LENGTH_JAIL_PORTS:-15}
             if [ "${MAX_LENGTH_JAIL_PORTS}" -lt 15 ]; then MAX_LENGTH_JAIL_PORTS=15; fi
             if [ "${MAX_LENGTH_JAIL_PORTS}" -gt 30 ]; then MAX_LENGTH_JAIL_PORTS=30; fi
-            MAX_LENGTH_JAIL_RELEASE=$(find ${bastille_jailsdir}/*/fstab -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/releases/.*/root/.bastille.*nullfs" | grep -hE "^USERLAND_VERSION=" "$(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++')" | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1)
+            # shellcheck disable=SC2046
+            MAX_LENGTH_JAIL_RELEASE="$(find ${bastille_jailsdir}/*/fstab -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/releases/.*/root/.bastille.*nullfs" | grep -hE "^USERLAND_VERSION=" $(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++') | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1)"
             MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_JAIL_RELEASE:-7}
             MAX_LENGTH_THICK_JAIL_RELEASE=$(find ${bastille_jailsdir}/*/root/bin/freebsd-version -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -hE "^USERLAND_VERSION=" | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1)
             MAX_LENGTH_THICK_JAIL_RELEASE=${MAX_LENGTH_THICK_JAIL_RELEASE:-7}
-            MAX_LENGTH_LINUX_JAIL_RELEASE=$(find ${bastille_jailsdir}/*/fstab -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/jails/.*/root/proc.*linprocfs" | grep -hE "^NAME=|^VERSION_ID=|^VERSION_CODENAME=" "$(sed -n "s/^linprocfs *\(.*\)\/.*$/\1\/etc\/os-release/p")" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | sed "N;N;s/\n/;/g" | sed -n "s/^NAME=\(.*\);VERSION_ID=\(.*\);VERSION_CODENAME=\(.*\)$/\1 \2 (\3)/p" | awk '{ print length($0) }' | sort -nr | head -n 1)
+            # shellcheck disable=SC2046
+            MAX_LENGTH_LINUX_JAIL_RELEASE="$(find ${bastille_jailsdir}/*/fstab -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/jails/.*/root/proc.*linprocfs" | grep -hE "^NAME=|^VERSION_ID=|^VERSION_CODENAME=" $(sed -n "s/^linprocfs *\(.*\)\/.*$/\1\/etc\/os-release/p") 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | sed "N;N;s/\n/;/g" | sed -n "s/^NAME=\(.*\);VERSION_ID=\(.*\);VERSION_CODENAME=\(.*\)$/\1 \2 (\3)/p" | awk '{ print length($0) }' | sort -nr | head -n 1)"
             MAX_LENGTH_LINUX_JAIL_RELEASE=${MAX_LENGTH_LINUX_JAIL_RELEASE:-7}
             if [ "${MAX_LENGTH_THICK_JAIL_RELEASE}" -gt "${MAX_LENGTH_JAIL_RELEASE}" ]; then MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_THICK_JAIL_RELEASE}; fi
             if [ "${MAX_LENGTH_LINUX_JAIL_RELEASE}" -gt "${MAX_LENGTH_JAIL_RELEASE}" ]; then MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_LINUX_JAIL_RELEASE}; fi
diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh
index 604a70d7d..1c2a8efb1 100644
--- a/usr/local/share/bastille/mount.sh
+++ b/usr/local/share/bastille/mount.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/pkg.sh b/usr/local/share/bastille/pkg.sh
index 4e537a4d8..e7cf23d75 100644
--- a/usr/local/share/bastille/pkg.sh
+++ b/usr/local/share/bastille/pkg.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh
index fe3d48db9..a3b1cda1c 100644
--- a/usr/local/share/bastille/rcp.sh
+++ b/usr/local/share/bastille/rcp.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh
index 63df78394..f5f426d58 100644
--- a/usr/local/share/bastille/rdr.sh
+++ b/usr/local/share/bastille/rdr.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh
index e83d22840..20fb80212 100644
--- a/usr/local/share/bastille/rename.sh
+++ b/usr/local/share/bastille/rename.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/restart.sh b/usr/local/share/bastille/restart.sh
index f443a7821..ffdb16506 100644
--- a/usr/local/share/bastille/restart.sh
+++ b/usr/local/share/bastille/restart.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/service.sh b/usr/local/share/bastille/service.sh
index 92fa4f272..76d1edadc 100644
--- a/usr/local/share/bastille/service.sh
+++ b/usr/local/share/bastille/service.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/setup.sh b/usr/local/share/bastille/setup.sh
index b069ea325..020d2cf4b 100644
--- a/usr/local/share/bastille/setup.sh
+++ b/usr/local/share/bastille/setup.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh
index 2eeb9e497..375d49c22 100644
--- a/usr/local/share/bastille/start.sh
+++ b/usr/local/share/bastille/start.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh
index 6c4b7c1d5..efec51e11 100644
--- a/usr/local/share/bastille/stop.sh
+++ b/usr/local/share/bastille/stop.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/sysrc.sh b/usr/local/share/bastille/sysrc.sh
index db1c8a01a..baf0d7ae1 100644
--- a/usr/local/share/bastille/sysrc.sh
+++ b/usr/local/share/bastille/sysrc.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/tags.sh b/usr/local/share/bastille/tags.sh
index 65ed802ff..4457f03d1 100644
--- a/usr/local/share/bastille/tags.sh
+++ b/usr/local/share/bastille/tags.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 # Ressource limits added by Lars Engels github.com/bsdlme
 #
diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh
index 203dc1092..3aed8664c 100644
--- a/usr/local/share/bastille/template.sh
+++ b/usr/local/share/bastille/template.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh
index 669c11646..ef2a8bcbf 100644
--- a/usr/local/share/bastille/top.sh
+++ b/usr/local/share/bastille/top.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -36,25 +38,37 @@ usage() {
     cat << EOF
     Options:
 
-    -f | --force -- Start the jail if it is stopped.
+    -a | --auto           Auto mode. Start/stop jail(s) if required.
+    -x | --debug          Enable debug mode.
 
 EOF
     exit 1
 }
 
 # Handle options.
-FORCE=0
+AUTO=0
 while [ "$#" -gt 0 ]; do
     case "${1}" in
         -h|--help|help)
             usage
             ;;
-        -f|--force)
-            FORCE=1
+        -a|--auto)
+            AUTO=1
+            shift
+            ;;
+        -x|--debug)
+            enable_debug
             shift
             ;;
         -*)
-            error_exit "Unknown option: \"${1}\""
+            for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do
+                case ${_opt} in
+                    a) AUTO=1 ;;
+                    x) enable_debug ;;
+                    *) error_exit "Unknown Option: \"${1}\""
+                esac
+            done
+            shift
             ;;
         *)
             break
@@ -72,10 +86,10 @@ bastille_root_check
 set_target_single "${TARGET}"
 
 info "[${TARGET}]:"
-check_target_is_running "${TARGET}" || if [ "${FORCE}" -eq 1 ]; then
+check_target_is_running "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then
     bastille start "${TARGET}"
 else   
     error_notify "Jail is not running."
-    error_continue "Use [-f|--force] to force start the jail."
+    error_continue "Use [-a|--auto] to auto-start the jail."
 fi
 jexec -l "${TARGET}" /usr/bin/top
diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh
index ebbb52c5a..f5d689699 100644
--- a/usr/local/share/bastille/umount.sh
+++ b/usr/local/share/bastille/umount.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh
index 60458a811..85d632c03 100644
--- a/usr/local/share/bastille/update.sh
+++ b/usr/local/share/bastille/update.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/upgrade.sh b/usr/local/share/bastille/upgrade.sh
index 394225829..5aa06905c 100644
--- a/usr/local/share/bastille/upgrade.sh
+++ b/usr/local/share/bastille/upgrade.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh
index 8f50dffa4..ec8afa916 100644
--- a/usr/local/share/bastille/verify.sh
+++ b/usr/local/share/bastille/verify.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh
index 0bcedbecf..3ba507925 100644
--- a/usr/local/share/bastille/zfs.sh
+++ b/usr/local/share/bastille/zfs.sh
@@ -1,6 +1,8 @@
 #!/bin/sh
 #
-# Copyright (c) 2018-2024, Christer Edwards <christer.edwards@gmail.com>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2018-2025, Christer Edwards <christer.edwards@gmail.com>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without