From 7e55510e6882f4e8719644b8de8076203458986b Mon Sep 17 00:00:00 2001 From: tschettervictor Date: Fri, 25 Apr 2025 20:33:09 -0600 Subject: [PATCH] netgraph: Add clone, rename --- usr/local/share/bastille/clone.sh | 96 ++++++++++++++++++++++------- usr/local/share/bastille/common.sh | 80 +++++++++++++----------- usr/local/share/bastille/create.sh | 5 +- usr/local/share/bastille/destroy.sh | 2 +- usr/local/share/bastille/rename.sh | 14 ++++- 5 files changed, 135 insertions(+), 62 deletions(-) diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index cb24c9fa..2a71f9ed 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -192,18 +192,28 @@ update_jailconf() { } update_jailconf_vnet() { + local _jail_conf="${bastille_jailsdir}/${NEWNAME}/jail.conf" local _rc_conf="${bastille_jailsdir}/${NEWNAME}/root/etc/rc.conf" - # Determine number of interfaces and define a uniq_epair - local _if_list="$(grep -Eo 'epair[0-9]+|bastille[0-9]+' ${_jail_conf} | sort -u)" + + # Determine number of interfaces + if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then + local _if_list="$(grep -Eo 'epair[0-9]+|e[0-9]+b_bastille[0-9]+' ${_jail_conf} | sort -u)" + elif [ "${bastille_network_vnet_type}" = "netgraph" ]; then + local _if_list="$(grep -Eo 'ng[0-9]+_bastille[0-9]+' ${_jail_conf} | sort -u)" + fi + for _if in ${_if_list}; do - # Get number of epairs on the system - get_epair_count - local _epair_num_range=$((_epair_count + 1)) + + # Get number of interfaces manged by Bastille + get_bastille_if_count + + local _bastille_if_num_range=$((_bastille_if_count + 1)) + + # Update bridged VNET config if echo ${_if} | grep -Eoq 'epair[0-9]+'; then - # Update bridged VNET config - for _num in $(seq 0 "${_epair_num_range}"); do - if ! echo "${_epair_list}" | grep -oqswx "${_num}"; then + for _num in $(seq 0 "${_bastille_if_num_range}"); do + if ! echo "${_bastille_if_list}" | grep -oqswx "${_num}"; then # Generate new epair name if [ "$(echo -n "e${_num}a_${NEWNAME}" | awk '{print length}')" -lt 16 ]; then local _new_host_epair="e${_num}a_${NEWNAME}" @@ -269,26 +279,70 @@ update_jailconf_vnet() { break fi done - elif echo ${_if} | grep -Eoq 'bastille[0-9]+'; then + # Update VNET (non-bridged) config + elif echo ${_if} | grep -Eoq 'e[0-9]+b_bastille[0-9]+'; then # Update VNET config - for _num in $(seq 0 "${_epair_num_range}"); do - if ! echo "${_epair_list}" | grep -oqswx "${_num}"; then + _if="$(echo ${_if} | grep -Eo 'bastille[0-9]+')" + for _num in $(seq 0 "${_bastille_if_num_range}"); do + if ! echo "${_bastille_if_list}" | grep -oqswx "${_num}"; then # Update jail.conf epair name - local uniq_epair="bastille${_num}" + local _jail_if="bastille${_num}" local _jail_vnet="$(grep ${_if} "${_rc_conf}" | grep -Eo -m 1 "vnet[0-9]+")" local _jail_vnet_vlan="$(grep "vlans_${_jail_vnet}" "${_rc_conf}" | sed 's/.*=//g')" - sed -i '' "s|${_if}|${uniq_epair}|g" "${_jail_conf}" + sed -i '' "s|${_if}|${_jail_if}|g" "${_jail_conf}" # If jail had a static MAC, generate one for clone - if grep ether ${_jail_conf} | grep -qoc ${uniq_epair}; then - local external_interface="$(grep ${uniq_epair} ${_jail_conf} | grep -o 'addm.*' | awk '{print $3}' | sed 's/["|;]//g')" + if grep ether ${_jail_conf} | grep -qoc ${_jail_if}; then + local external_interface="$(grep ${_jail_if} ${_jail_conf} | 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_conf}" - sed -i '' "s|${uniq_epair} ether.*:.*:.*:.*:.*:.*b\";|${uniq_epair} ether ${macaddr}b\";|" "${_jail_conf}" + sed -i '' "s|${_jail_if} ether.*:.*:.*:.*:.*:.*a\";|${_jail_if} ether ${macaddr}a\";|" "${_jail_conf}" + sed -i '' "s|${_jail_if} ether.*:.*:.*:.*:.*:.*b\";|${_jail_if} ether ${macaddr}b\";|" "${_jail_conf}" fi - sed -i '' "/${uniq_epair}/ s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|g" "${_jail_conf}" + sed -i '' "/${_jail_if}/ s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|g" "${_jail_conf}" # Update /etc/rc.conf - sed -i '' "s|ifconfig_e0b_${_if}_name|ifconfig_e0b_${uniq_epair}_name|" "${_rc_conf}" - if grep "vnet0" "${_rc_conf}" | grep -q ${uniq_epair}; then + sed -i '' "s|ifconfig_e0b_${_if}_name|ifconfig_e0b_${_jail_if}_name|" "${_rc_conf}" + if grep "vnet0" "${_rc_conf}" | grep -q ${_jail_if}; then + if [ -n "${_jail_vnet_vlan}" ]; then + if [ "${IP}" = "0.0.0.0" ] || [ "${IP}" = "DHCP" ]; then + sysrc -f "${_rc_conf}" ifconfig_vnet0_${_jail_vnet_vlan}="SYNCDHCP" + else + sysrc -f "${_rc_conf}" ifconfig_vnet0_${_jail_vnet_vlan}="inet ${IP}" + fi + else + if [ "${IP}" = "0.0.0.0" ] || [ "${IP}" = "DHCP" ]; then + sysrc -f "${_rc_conf}" ifconfig_vnet0="SYNCDHCP" + else + sysrc -f "${_rc_conf}" ifconfig_vnet0="inet ${IP}" + fi + fi + else + if [ -n "${_jail_vnet_vlan}" ]; then + sysrc -f "${_rc_conf}" ifconfig_${_jail_vnet}_${_jail_vnet_vlan}="SYNCDHCP" + else + sysrc -f "${_rc_conf}" ifconfig_${_jail_vnet}="SYNCDHCP" + fi + fi + break + fi + done + # Update netgraph VNET (non-bridged) config + elif echo ${_if} | grep -Eoq 'ng[0-9]+_bastille[0-9]+'; then + _if="$(echo ${_if} | grep -Eo 'bastille[0-9]+')" + for _num in $(seq 0 "${_bastille_if_num_range}"); do + if ! echo "${_bastille_if_list}" | grep -oqswx "${_num}"; then + # Update jail.conf epair name + local _jail_if="bastille${_num}" + local _jail_vnet="$(grep ${_if} "${_rc_conf}" | grep -Eo -m 1 "vnet[0-9]+")" + local _jail_vnet_vlan="$(grep "vlans_${_jail_vnet}" "${_rc_conf}" | sed 's/.*=//g')" + sed -i '' "s|${_if}|${_jail_if}|g" "${_jail_conf}" + # If jail had a static MAC, generate one for clone + if grep ether ${_jail_conf} | grep -qoc ${_jail_if}; then + local external_interface="$(grep ${_jail_if} ${_jail_conf} | grep -o 'jng bridge.*' | awk '{print $4}' | sed 's/["|;]//g')" + generate_static_mac "${NEWNAME}" "${external_interface}" + sed -i '' "s|${_jail_if} ether.*:.*:.*:.*:.*:.*a\";|${_jail_if} ether ${macaddr}a\";|" "${_jail_conf}" + fi + # Update /etc/rc.conf + sed -i '' "s|ifconfig_ng0_${_if}_name|ifconfig_ng0_${_jail_if}_name|" "${_rc_conf}" + if grep "vnet0" "${_rc_conf}" | grep -q ${_jail_if}; then if [ -n "${_jail_vnet_vlan}" ]; then if [ "${IP}" = "0.0.0.0" ] || [ "${IP}" = "DHCP" ]; then sysrc -f "${_rc_conf}" ifconfig_vnet0_${_jail_vnet_vlan}="SYNCDHCP" @@ -381,4 +435,4 @@ else usage fi -clone_jail +clone_jail \ No newline at end of file diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index b1e3cbba..95ccec12 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -118,14 +118,24 @@ check_target_is_stopped() { fi } -get_epair_count() { - for _config in /usr/local/etc/bastille/*.conf; do - local bastille_jailsdir="$(sysrc -f "${_config}" -n bastille_jailsdir)" - _epair_list="$(printf '%s\n%s' "$( (grep -Ehos '(epair[0-9]+|bastille[0-9]+)' ${bastille_jailsdir}/*/jail.conf; ifconfig -g epair | grep -Eos "_bastille[0-9]+$"; ifconfig -g epair | grep -vs 'bastille' | grep -Eos 'e[0-9]+a_') | grep -Eos '[0-9]+')" "${_epair_list}")" - done - _epair_count=$(printf '%s' "${_epair_list}" | sort -u | wc -l | awk '{print $1}') - export _epair_list - export _epair_count +get_bastille_if_count() { + if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then + for _config in /usr/local/etc/bastille/*.conf; do + local bastille_jailsdir="$(sysrc -f "${_config}" -n bastille_jailsdir)" + _bastille_if_list="$(printf '%s\n%s' "$( (grep -Ehos '(epair[0-9]+|bastille[0-9]+)' ${bastille_jailsdir}/*/jail.conf; ifconfig -g epair | grep -Eos "_bastille[0-9]+$"; ifconfig -g epair | grep -vs 'bastille' | grep -Eos 'e[0-9]+a_') | grep -Eos '[0-9]+')" "${_bastille_if_list}")" + done + _bastille_if_count=$(printf '%s' "${_bastille_if_list}" | sort -u | wc -l | awk '{print $1}') + export _bastille_if_list + export _bastille_if_count + elif [ "${bastille_network_vnet_type}" = "netgraph" ]; then + for _config in /usr/local/etc/bastille/*.conf; do + local bastille_jailsdir="$(sysrc -f "${_config}" -n bastille_jailsdir)" + _bastille_if_list="$(printf '%s\n%s' "$( (grep -Ehos 'ng[0-9]+_bastille[0-9]+' ${bastille_jailsdir}/*/jail.conf | grep -Eos 'bastille[0-9]+'; ngctl list -n | grep "eiface" | grep -Eos 'ng[0-9]+_bastille[0-9]+' | grep -Eos 'bastille[0-9]+') | grep -Eos '[0-9]+')" "${_bastille_if_list}")" + done + _bastille_if_count=$(printf '%s' "${_bastille_if_list}" | sort -u | wc -l | awk '{print $1}') + export _bastille_if_list + export _bastille_if_count + fi } get_jail_name() { @@ -288,12 +298,12 @@ generate_vnet_jail_netblock() { local external_interface="${3}" local static_mac="${4}" # Get number of epairs on the system - get_epair_count - local _epair_num_range=$((_epair_count + 1)) + get_bastille_if_count + local _bastille_if_num_range=$((_bastille_if_count + 1)) if [ -n "${use_unique_bridge}" ]; then - if [ "${_epair_count}" -gt 0 ]; then - for _num in $(seq 0 "${_epair_num_range}"); do - if ! echo "${_epair_list}" | grep -oqswx "${_num}"; then + if [ "${_bastille_if_count}" -gt 0 ]; then + for _num in $(seq 0 "${_bastille_if_num_range}"); do + if ! echo "${_bastille_if_list}" | grep -oqswx "${_num}"; then if [ "$(echo -n "e${_num}a_${jail_name}" | awk '{print length}')" -lt 16 ]; then local host_epair=e${_num}a_${jail_name} local jail_epair=e${_num}b_${jail_name} @@ -316,15 +326,15 @@ generate_vnet_jail_netblock() { fi fi else - if [ "${_epair_count}" -gt 0 ]; then - for _num in $(seq 0 "${_epair_num_range}"); do - if ! echo "${_epair_list}" | grep -oqswx "${_num}"; then - local uniq_epair="bastille${_num}" + if [ "${_bastille_if_count}" -gt 0 ]; then + for _num in $(seq 0 "${_bastille_if_num_range}"); do + if ! echo "${_bastille_if_list}" | grep -oqswx "${_num}"; then + local _jail_if="bastille${_num}" break fi done else - local uniq_epair="bastille0" + local _jail_if="bastille0" fi fi ## If BRIDGE is enabled, generate bridge config, else generate VNET config @@ -366,21 +376,21 @@ EOF generate_static_mac "${jail_name}" "${external_interface}" cat <<-EOF vnet; - vnet.interface = e0b_${uniq_epair}; - exec.prestart += "jib addm ${uniq_epair} ${external_interface}"; - exec.prestart += "ifconfig e0a_${uniq_epair} ether ${macaddr}a"; - exec.prestart += "ifconfig e0b_${uniq_epair} ether ${macaddr}b"; - exec.prestart += "ifconfig e0a_${uniq_epair} description \"vnet0 host interface for Bastille jail ${jail_name}\""; - exec.poststop += "jib destroy ${uniq_epair}"; + vnet.interface = e0b_${_jail_if}; + exec.prestart += "jib addm ${_jail_if} ${external_interface}"; + exec.prestart += "ifconfig e0a_${_jail_if} ether ${macaddr}a"; + exec.prestart += "ifconfig e0b_${_jail_if} ether ${macaddr}b"; + exec.prestart += "ifconfig e0a_${_jail_if} description \"vnet0 host interface for Bastille jail ${jail_name}\""; + exec.poststop += "jib destroy ${_jail_if}"; 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 \"vnet0 host interface for Bastille jail ${jail_name}\""; - exec.poststop += "jib destroy ${uniq_epair}"; + vnet.interface = e0b_${_jail_if}; + exec.prestart += "jib addm ${_jail_if} ${external_interface}"; + exec.prestart += "ifconfig e0a_${_jail_if} description \"vnet0 host interface for Bastille jail ${jail_name}\""; + exec.poststop += "jib destroy ${_jail_if}"; EOF fi elif [ "${bastille_network_vnet_type}" = "netgraph" ]; then @@ -389,18 +399,18 @@ EOF generate_static_mac "${jail_name}" "${external_interface}" cat <<-EOF vnet; - vnet.interface = ng0_${uniq_epair}; - exec.prestart += "jng bridge ${uniq_epair} ${external_interface}"; - exec.prestart += "ifconfig ng0_${uniq_epair} ether ${macaddr}a"; - exec.poststop += "jng shutdown ${uniq_epair}"; + vnet.interface = ng0_${_jail_if}; + exec.prestart += "jng bridge ${_jail_if} ${external_interface}"; + exec.prestart += "ifconfig ng0_${_jail_if} ether ${macaddr}a"; + exec.poststop += "jng shutdown ${_jail_if}"; EOF else ## Generate VNET config without static MAC address cat <<-EOF vnet; - vnet.interface = ng0_${uniq_epair}; - exec.prestart += "jng bridge ${uniq_epair} ${external_interface}"; - exec.poststop += "jng shutdown ${uniq_epair}"; + vnet.interface = ng0_${_jail_if}; + exec.prestart += "jng bridge ${_jail_if} ${external_interface}"; + exec.poststop += "jng shutdown ${_jail_if}"; EOF fi else diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index 95710294..a16dcd1d 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -536,7 +536,7 @@ create_jail() { fi fi elif [ "${bastille_network_vnet_type}" = "netgraph" ]; then - if [ ! "$(command -v jib)" ]; then + if [ ! "$(command -v jng)" ]; then if [ -f /usr/share/examples/jails/jng ] && [ ! -f /usr/local/bin/jng ]; then install -m 0544 /usr/share/examples/jails/jng /usr/local/bin/jng fi @@ -828,7 +828,7 @@ elif [ -n "${VNET_JAIL}" ] && [ -z "${VNET_JAIL_BRIDGE}" ]; then fi # Do not allow netgraph with -B|--bridge yet... -if [ "${bastille_network_vnet_type}" = "netgraph" ] && [ "${VNET_JAIL_BRIDGE}" -eq 1 ]; then +if [ "${bastille_network_vnet_type}" = "netgraph" ] && [ -n "${VNET_JAIL_BRIDGE}" ]; then error_exit "[ERROR]: Netgraph does not support the [-B|--bridge] option." fi @@ -1012,4 +1012,5 @@ fi if check_target_exists "${NAME}"; then error_exit "Error: Existing jail found: ${NAME}" fi + create_jail "${NAME}" "${RELEASE}" "${IP}" "${INTERFACE}" \ No newline at end of file diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index 2e68d111..07c2a06e 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -81,7 +81,7 @@ destroy_jail() { # This will deal with the common "cannot unmount 'XYZ': pool or dataset is busy" # unless the force option is defined by the user, otherwise will have a partially deleted jail. if ! zfs destroy "${OPTIONS}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"; then - error_exit "Jail dataset(s) appears to be busy, exiting." + error_continue "Jail dataset(s) appears to be busy, exiting." fi fi fi diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index 00a2e541..7dc42cf8 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -114,10 +114,18 @@ update_jailconf() { } update_jailconf_vnet() { + local _jail_conf="${bastille_jailsdir}/${NEWNAME}/jail.conf" local _rc_conf="${bastille_jailsdir}/${NEWNAME}/root/etc/rc.conf" - # Change epair name (if needed) - local _if_list="$(grep -Eo 'epair[0-9]+|bastille[0-9]+' ${_jail_conf} | sort -u)" + + # Change bastille interface name (only needed for bridged epairs) + # We still gather interface names for JIB and JNG managed interfaces (for future use) + if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then + local _if_list="$(grep -Eo 'epair[0-9]+|e[0-9]+_bastille[0-9]+' ${_jail_conf} | sort -u)" + elif [ "${bastille_network_vnet_type}" = "netgraph" ]; then + local _if_list="$(grep -Eo 'ng[0-9]+_bastille[0-9]+' ${_jail_conf} | sort -u)" + fi + for _if in ${_if_list}; do if echo ${_if} | grep -Eoq 'epair[0-9]+'; then # Check if epair name = jail name @@ -217,4 +225,4 @@ if [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then error_exit "Jail: ${NEWNAME} already exists." fi -change_name +change_name \ No newline at end of file