Merge pull request #978 from BastilleBSD/netgraph-support

bastille: Initial support for netgraph
This commit is contained in:
Barry McCormick
2025-04-30 08:39:11 -07:00
committed by GitHub
8 changed files with 351 additions and 143 deletions

View File

@@ -52,6 +52,7 @@ bastille_decompress_gz_options="-k -d -c -v" ## default
bastille_export_options="" ## default "" predefined export options, e.g. "--safe --gz" bastille_export_options="" ## default "" predefined export options, e.g. "--safe --gz"
## Networking ## Networking
bastille_network_vnet_type="if_bridge" ## default: "if_bridge"
bastille_network_loopback="bastille0" ## default: "bastille0" bastille_network_loopback="bastille0" ## default: "bastille0"
bastille_network_pf_ext_if="ext_if" ## default: "ext_if" bastille_network_pf_ext_if="ext_if" ## default: "ext_if"
bastille_network_pf_table="jails" ## default: "jails" bastille_network_pf_table="jails" ## default: "jails"

View File

@@ -150,6 +150,7 @@ update_jailconf() {
fi fi
if grep -qw "vnet;" "${JAIL_CONFIG}"; then if grep -qw "vnet;" "${JAIL_CONFIG}"; then
validate_netconf
update_jailconf_vnet update_jailconf_vnet
else else
_ip4="$(bastille config ${TARGET} get ip4.addr | sed 's/,/ /g')" _ip4="$(bastille config ${TARGET} get ip4.addr | sed 's/,/ /g')"
@@ -192,18 +193,28 @@ update_jailconf() {
} }
update_jailconf_vnet() { update_jailconf_vnet() {
local _jail_conf="${bastille_jailsdir}/${NEWNAME}/jail.conf" local _jail_conf="${bastille_jailsdir}/${NEWNAME}/jail.conf"
local _rc_conf="${bastille_jailsdir}/${NEWNAME}/root/etc/rc.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 for _if in ${_if_list}; do
# Get number of epairs on the system
get_epair_count # Get number of interfaces manged by Bastille
local _epair_num_range=$((_epair_count + 1)) get_bastille_if_count
if echo ${_if} | grep -Eoq 'epair[0-9]+'; then
local _bastille_if_num_range=$((_bastille_if_count + 1))
# Update bridged VNET config # Update bridged VNET config
for _num in $(seq 0 "${_epair_num_range}"); do if echo ${_if} | grep -Eoq 'epair[0-9]+'; then
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 # Generate new epair name
if [ "$(echo -n "e${_num}a_${NEWNAME}" | awk '{print length}')" -lt 16 ]; then if [ "$(echo -n "e${_num}a_${NEWNAME}" | awk '{print length}')" -lt 16 ]; then
local _new_host_epair="e${_num}a_${NEWNAME}" local _new_host_epair="e${_num}a_${NEWNAME}"
@@ -269,26 +280,70 @@ update_jailconf_vnet() {
break break
fi fi
done 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 # Update VNET config
for _num in $(seq 0 "${_epair_num_range}"); do _if="$(echo ${_if} | grep -Eo 'bastille[0-9]+')"
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
# Update jail.conf epair name # 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="$(grep ${_if} "${_rc_conf}" | grep -Eo -m 1 "vnet[0-9]+")"
local _jail_vnet_vlan="$(grep "vlans_${_jail_vnet}" "${_rc_conf}" | sed 's/.*=//g')" 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 jail had a static MAC, generate one for clone
if grep ether ${_jail_conf} | grep -qoc ${uniq_epair}; then if grep ether ${_jail_conf} | grep -qoc ${_jail_if}; then
local external_interface="$(grep ${uniq_epair} ${_jail_conf} | grep -o 'addm.*' | awk '{print $3}' | sed 's/["|;]//g')" local external_interface="$(grep ${_jail_if} ${_jail_conf} | grep -o 'addm.*' | awk '{print $3}' | sed 's/["|;]//g')"
generate_static_mac "${NEWNAME}" "${external_interface}" generate_static_mac "${NEWNAME}" "${external_interface}"
sed -i '' "s|${uniq_epair} ether.*:.*:.*:.*:.*:.*a\";|${uniq_epair} ether ${macaddr}a\";|" "${_jail_conf}" sed -i '' "s|${_jail_if} ether.*:.*:.*:.*:.*:.*a\";|${_jail_if} 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.*:.*:.*:.*:.*:.*b\";|${_jail_if} ether ${macaddr}b\";|" "${_jail_conf}"
fi 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 # Update /etc/rc.conf
sed -i '' "s|ifconfig_e0b_${_if}_name|ifconfig_e0b_${uniq_epair}_name|" "${_rc_conf}" sed -i '' "s|ifconfig_e0b_${_if}_name|ifconfig_e0b_${_jail_if}_name|" "${_rc_conf}"
if grep "vnet0" "${_rc_conf}" | grep -q ${uniq_epair}; then 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 [ -n "${_jail_vnet_vlan}" ]; then
if [ "${IP}" = "0.0.0.0" ] || [ "${IP}" = "DHCP" ]; then if [ "${IP}" = "0.0.0.0" ] || [ "${IP}" = "DHCP" ]; then
sysrc -f "${_rc_conf}" ifconfig_vnet0_${_jail_vnet_vlan}="SYNCDHCP" sysrc -f "${_rc_conf}" ifconfig_vnet0_${_jail_vnet_vlan}="SYNCDHCP"

View File

@@ -130,14 +130,24 @@ check_target_is_stopped() {
fi fi
} }
get_epair_count() { get_bastille_if_count() {
if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then
for _config in /usr/local/etc/bastille/*.conf; do for _config in /usr/local/etc/bastille/*.conf; do
local bastille_jailsdir="$(sysrc -f "${_config}" -n bastille_jailsdir)" 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}")" _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 done
_epair_count=$(printf '%s' "${_epair_list}" | sort -u | wc -l | awk '{print $1}') _bastille_if_count=$(printf '%s' "${_bastille_if_list}" | sort -u | wc -l | awk '{print $1}')
export _epair_list export _bastille_if_list
export _epair_count 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() { get_jail_name() {
@@ -300,12 +310,12 @@ generate_vnet_jail_netblock() {
local external_interface="${3}" local external_interface="${3}"
local static_mac="${4}" local static_mac="${4}"
# Get number of epairs on the system # Get number of epairs on the system
get_epair_count get_bastille_if_count
local _epair_num_range=$((_epair_count + 1)) local _bastille_if_num_range=$((_bastille_if_count + 1))
if [ -n "${use_unique_bridge}" ]; then if [ -n "${use_unique_bridge}" ]; then
if [ "${_epair_count}" -gt 0 ]; then if [ "${_bastille_if_count}" -gt 0 ]; then
for _num in $(seq 0 "${_epair_num_range}"); do for _num in $(seq 0 "${_bastille_if_num_range}"); do
if ! echo "${_epair_list}" | grep -oqswx "${_num}"; then if ! echo "${_bastille_if_list}" | grep -oqswx "${_num}"; then
if [ "$(echo -n "e${_num}a_${jail_name}" | awk '{print length}')" -lt 16 ]; then if [ "$(echo -n "e${_num}a_${jail_name}" | awk '{print length}')" -lt 16 ]; then
local host_epair=e${_num}a_${jail_name} local host_epair=e${_num}a_${jail_name}
local jail_epair=e${_num}b_${jail_name} local jail_epair=e${_num}b_${jail_name}
@@ -328,15 +338,15 @@ generate_vnet_jail_netblock() {
fi fi
fi fi
else else
if [ "${_epair_count}" -gt 0 ]; then if [ "${_bastille_if_count}" -gt 0 ]; then
for _num in $(seq 0 "${_epair_num_range}"); do for _num in $(seq 0 "${_bastille_if_num_range}"); do
if ! echo "${_epair_list}" | grep -oqswx "${_num}"; then if ! echo "${_bastille_if_list}" | grep -oqswx "${_num}"; then
local uniq_epair="bastille${_num}" local _jail_if="bastille${_num}"
break break
fi fi
done done
else else
local uniq_epair="bastille0" local _jail_if="bastille0"
fi fi
fi fi
## If BRIDGE is enabled, generate bridge config, else generate VNET config ## If BRIDGE is enabled, generate bridge config, else generate VNET config
@@ -372,28 +382,59 @@ EOF
EOF EOF
fi fi
else else
if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then
if [ -n "${static_mac}" ]; then if [ -n "${static_mac}" ]; then
## Generate VNET config with static MAC address ## Generate VNET config with static MAC address
generate_static_mac "${jail_name}" "${external_interface}" generate_static_mac "${jail_name}" "${external_interface}"
cat <<-EOF cat <<-EOF
vnet; vnet;
vnet.interface = e0b_${uniq_epair}; vnet.interface = e0b_${_jail_if};
exec.prestart += "jib addm ${uniq_epair} ${external_interface}"; exec.prestart += "jib addm ${_jail_if} ${external_interface}";
exec.prestart += "ifconfig e0a_${uniq_epair} ether ${macaddr}a"; exec.prestart += "ifconfig e0a_${_jail_if} ether ${macaddr}a";
exec.prestart += "ifconfig e0b_${uniq_epair} ether ${macaddr}b"; exec.prestart += "ifconfig e0b_${_jail_if} ether ${macaddr}b";
exec.prestart += "ifconfig e0a_${uniq_epair} description \"vnet0 host interface for Bastille jail ${jail_name}\""; exec.prestart += "ifconfig e0a_${_jail_if} description \"vnet0 host interface for Bastille jail ${jail_name}\"";
exec.poststop += "jib destroy ${uniq_epair}"; exec.poststop += "jib destroy ${_jail_if}";
EOF EOF
else else
## Generate VNET config without static MAC address ## Generate VNET config without static MAC address
cat <<-EOF cat <<-EOF
vnet; vnet;
vnet.interface = e0b_${uniq_epair}; vnet.interface = e0b_${_jail_if};
exec.prestart += "jib addm ${uniq_epair} ${external_interface}"; exec.prestart += "jib addm ${_jail_if} ${external_interface}";
exec.prestart += "ifconfig e0a_${uniq_epair} description \"vnet0 host interface for Bastille jail ${jail_name}\""; exec.prestart += "ifconfig e0a_${_jail_if} description \"vnet0 host interface for Bastille jail ${jail_name}\"";
exec.poststop += "jib destroy ${uniq_epair}"; exec.poststop += "jib destroy ${_jail_if}";
EOF EOF
fi 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;
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_${_jail_if};
exec.prestart += "jng bridge ${_jail_if} ${external_interface}";
exec.poststop += "jng shutdown ${_jail_if}";
EOF
fi
fi
fi
}
validate_netconf() {
if [ -n "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
error_exit "[ERROR]: 'bastille_network_loopback' and 'bastille_network_shared' cannot both be set."
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 fi
} }

View File

@@ -168,12 +168,6 @@ validate_netif() {
fi fi
} }
validate_netconf() {
if [ -n "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
error_exit "Invalid network configuration."
fi
}
validate_release() { validate_release() {
## ensure the user set the Linux(experimental) option explicitly ## ensure the user set the Linux(experimental) option explicitly
if [ -n "${UBUNTU}" ]; then if [ -n "${UBUNTU}" ]; then
@@ -528,12 +522,20 @@ create_jail() {
## VNET specific ## VNET specific
if [ -n "${VNET_JAIL}" ]; then if [ -n "${VNET_JAIL}" ]; then
## VNET requires jib script ## VNET requires jib or jng script
if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then
if [ ! "$(command -v jib)" ]; then if [ ! "$(command -v jib)" ]; then
if [ -f /usr/share/examples/jails/jib ] && [ ! -f /usr/local/bin/jib ]; then if [ -f /usr/share/examples/jails/jib ] && [ ! -f /usr/local/bin/jib ]; then
install -m 0544 /usr/share/examples/jails/jib /usr/local/bin/jib install -m 0544 /usr/share/examples/jails/jib /usr/local/bin/jib
fi fi
fi fi
elif [ "${bastille_network_vnet_type}" = "netgraph" ]; 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
fi
fi
fi fi
elif [ -n "${LINUX_JAIL}" ]; then elif [ -n "${LINUX_JAIL}" ]; then
## Generate configuration for Linux jail ## Generate configuration for Linux jail
@@ -819,6 +821,11 @@ elif [ -n "${VNET_JAIL}" ] && [ -z "${VNET_JAIL_BRIDGE}" ]; then
fi fi
fi fi
# Do not allow netgraph with -B|--bridge yet...
if [ "${bastille_network_vnet_type}" = "netgraph" ] && [ -n "${VNET_JAIL_BRIDGE}" ]; then
error_exit "[ERROR]: Netgraph does not support the [-B|--bridge] option."
fi
if [ -n "${LINUX_JAIL}" ] && [ -n "${VALIDATE_RELEASE}" ]; then if [ -n "${LINUX_JAIL}" ] && [ -n "${VALIDATE_RELEASE}" ]; then
case "${RELEASE}" in case "${RELEASE}" in
bionic|ubuntu_bionic|ubuntu|ubuntu-bionic) bionic|ubuntu_bionic|ubuntu|ubuntu-bionic)
@@ -999,4 +1006,5 @@ fi
if check_target_exists "${NAME}"; then if check_target_exists "${NAME}"; then
error_exit "Error: Existing jail found: ${NAME}" error_exit "Error: Existing jail found: ${NAME}"
fi fi
create_jail "${NAME}" "${RELEASE}" "${IP}" "${INTERFACE}" create_jail "${NAME}" "${RELEASE}" "${IP}" "${INTERFACE}"

View File

@@ -236,8 +236,8 @@ generate_config() {
# See if we need to generate a vnet network section # See if we need to generate a vnet network section
if [ "${IS_VNET_JAIL:-0}" = "1" ]; then if [ "${IS_VNET_JAIL:-0}" = "1" ]; then
NETBLOCK=$(generate_vnet_jail_netblock "${TARGET_TRIM}" "" "${VNET_DEFAULT_INTERFACE}" "${OPT_STATIC_MAC}")
vnet_requirements vnet_requirements
NETBLOCK=$(generate_vnet_jail_netblock "${TARGET_TRIM}" "" "${VNET_DEFAULT_INTERFACE}" "${OPT_STATIC_MAC}")
else else
# If there are multiple IP/NIC let the user configure network # If there are multiple IP/NIC let the user configure network
IP4_DEFINITION="" IP4_DEFINITION=""
@@ -443,6 +443,7 @@ workout_components() {
vnet_requirements() { vnet_requirements() {
# VNET jib script requirement # VNET jib script requirement
if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then
if [ ! "$(command -v jib)" ]; then if [ ! "$(command -v jib)" ]; then
if [ -f "/usr/share/examples/jails/jib" ] && [ ! -f "/usr/local/bin/jib" ]; then if [ -f "/usr/share/examples/jails/jib" ] && [ ! -f "/usr/local/bin/jib" ]; then
install -m 0544 /usr/share/examples/jails/jib /usr/local/bin/jib install -m 0544 /usr/share/examples/jails/jib /usr/local/bin/jib
@@ -450,6 +451,15 @@ vnet_requirements() {
warn "Warning: Unable to locate/install jib script required by VNET jails." warn "Warning: Unable to locate/install jib script required by VNET jails."
fi fi
fi fi
elif [ "${bastille_network_vnet_type}" = "netgraph" ]; 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
else
warn "Warning: Unable to locate/install jng script required by VNET jails."
fi
fi
fi
} }
config_netif() { config_netif() {

View File

@@ -148,16 +148,14 @@ if [ "${ACTION}" = "add" ]; then
{ [ "${BRIDGE}" -eq 1 ] && [ "${PASSTHROUGH}" -eq 1 ]; } || \ { [ "${BRIDGE}" -eq 1 ] && [ "${PASSTHROUGH}" -eq 1 ]; } || \
{ [ "${CLASSIC}" -eq 1 ] && [ "${PASSTHROUGH}" -eq 1 ]; } then { [ "${CLASSIC}" -eq 1 ] && [ "${PASSTHROUGH}" -eq 1 ]; } then
error_notify "Error: Only one of [-B|--bridge], [-C|--classic], [-P|--passthrough] or [-V|--vnet] should be set." error_notify "Error: Only one of [-B|--bridge], [-C|--classic], [-P|--passthrough] or [-V|--vnet] should be set."
usage
elif [ "${VNET}" -eq 0 ] && [ "${BRIDGE}" -eq 0 ] && [ "${CLASSIC}" -eq 0 ] && [ "${PASSTHROUGH}" -eq 0 ]; then elif [ "${VNET}" -eq 0 ] && [ "${BRIDGE}" -eq 0 ] && [ "${CLASSIC}" -eq 0 ] && [ "${PASSTHROUGH}" -eq 0 ]; then
error_notify "Error: [-B|--bridge], [-C|--classic], [-P|--passthrough] or [-V|--vnet] must be set." error_notify "Error: [-B|--bridge], [-C|--classic], [-P|--passthrough] or [-V|--vnet] must be set."
usage
elif [ "${VNET}" -eq 0 ] && [ "${BRIDGE}" -eq 0 ] && [ "${PASSTHROUGH}" -eq 0 ] && [ -n "${VLAN_ID}" ]; then elif [ "${VNET}" -eq 0 ] && [ "${BRIDGE}" -eq 0 ] && [ "${PASSTHROUGH}" -eq 0 ] && [ -n "${VLAN_ID}" ]; then
error_notify "VLANs can only be used with VNET interfaces." error_notify "VLANs can only be used with VNET interfaces."
usage
elif [ "${VNET}" -eq 0 ] && [ "${BRIDGE}" -eq 0 ] && [ "${NO_IP}" -eq 1 ]; then elif [ "${VNET}" -eq 0 ] && [ "${BRIDGE}" -eq 0 ] && [ "${NO_IP}" -eq 1 ]; then
error_notify "[-n|--no-ip] can only be used with VNET jails." error_notify "[-n|--no-ip] can only be used with VNET jails."
usage elif [ "${bastille_network_vnet_type}" = "netgraph" ] && [ "${BRIDGE}" -eq 1 ]; then
error_notify "[-B|--bridge] cannot be used with Netgraph."
fi fi
fi fi
@@ -210,12 +208,6 @@ validate_netif() {
fi fi
} }
validate_netconf() {
if [ -n "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
error_exit "Invalid network configuration."
fi
}
check_interface_added() { check_interface_added() {
local _jailname="${1}" local _jailname="${1}"
local _if="${2}" local _if="${2}"
@@ -233,15 +225,15 @@ add_interface() {
local _ip="${3}" local _ip="${3}"
local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf" local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf"
local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf"
# Get number of epairs on the system # Get number of interfaces manged by Bastille
get_epair_count get_bastille_if_count
local _vnet_if_count="$(grep -Eo 'vnet[1-9]+' ${_jail_rc_config} | sort -u | wc -l | awk '{print $1}')" local _vnet_if_count="$(grep -Eo 'vnet[1-9]+' ${_jail_rc_config} | sort -u | wc -l | awk '{print $1}')"
local _if_vnet="vnet$((_vnet_if_count + 1))" local _if_vnet="vnet$((_vnet_if_count + 1))"
local _epair_num_range=$((_epair_count + 1)) local _bastille_if_num_range=$((_bastille_if_count + 1))
if [ "${BRIDGE}" -eq 1 ]; then if [ "${BRIDGE}" -eq 1 ]; then
if [ "${_epair_count}" -gt 0 ]; then if [ "${_bastille_if_count}" -gt 0 ]; then
for _num in $(seq 0 "${_epair_num_range}"); do for _num in $(seq 0 "${_bastille_if_num_range}"); do
if ! echo "${_epair_list}" | grep -oqswx "${_num}"; then if ! echo "${_bastille_if_list}" | grep -oqswx "${_num}"; then
if [ "$(echo -n "e${_num}a_${jail_name}" | awk '{print length}')" -lt 16 ]; then if [ "$(echo -n "e${_num}a_${jail_name}" | awk '{print length}')" -lt 16 ]; then
local host_epair=e${_num}a_${_jailname} local host_epair=e${_num}a_${_jailname}
local jail_epair=e${_num}b_${_jailname} local jail_epair=e${_num}b_${_jailname}
@@ -313,9 +305,10 @@ EOF
echo "Added interface: \"${_if}\"" echo "Added interface: \"${_if}\""
elif [ "${VNET}" -eq 1 ]; then elif [ "${VNET}" -eq 1 ]; then
for _num in $(seq 0 "${_epair_num_range}"); do if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then
if ! echo "${_epair_list}" | grep -oqswx "${_num}"; then for _num in $(seq 0 "${_bastille_if_num_range}"); do
local bastille_epair="bastille${_num}" if ! echo "${_bastille_if_list}" | grep -oqswx "${_num}"; then
local _jail_if="bastille${_num}"
break break
fi fi
done done
@@ -325,28 +318,28 @@ EOF
# Generate NETBLOCK with static MAC # Generate NETBLOCK with static MAC
generate_static_mac "${_jailname}" "${_if}" generate_static_mac "${_jailname}" "${_if}"
cat << EOF >> "${_jail_config}" cat << EOF >> "${_jail_config}"
## ${bastille_epair} interface ## ${_jail_if} interface
vnet.interface += e0b_${bastille_epair}; vnet.interface += e0b_${_jail_if};
exec.prestart += "jib addm ${bastille_epair} ${_if}"; exec.prestart += "jib addm ${_jail_if} ${_if}";
exec.prestart += "ifconfig e0a_${bastille_epair} ether ${macaddr}a"; exec.prestart += "ifconfig e0a_${_jail_if} ether ${macaddr}a";
exec.prestart += "ifconfig e0b_${bastille_epair} ether ${macaddr}b"; exec.prestart += "ifconfig e0b_${_jail_if} ether ${macaddr}b";
exec.prestart += "ifconfig e0a_${bastille_epair} description \"${_if_vnet} host interface for Bastille jail ${_jailname}\""; exec.prestart += "ifconfig e0a_${_jail_if} description \"${_if_vnet} host interface for Bastille jail ${_jailname}\"";
exec.poststop += "jib destroy ${bastille_epair}"; exec.poststop += "jib destroy ${_jail_if}";
} }
EOF EOF
else else
# Generate NETBLOCK without static MAC # Generate NETBLOCK without static MAC
cat << EOF >> "${_jail_config}" cat << EOF >> "${_jail_config}"
## ${bastille_epair} interface ## ${_jail_if} interface
vnet.interface += e0b_${bastille_epair}; vnet.interface += e0b_${_jail_if};
exec.prestart += "jib addm ${bastille_epair} ${_if}"; exec.prestart += "jib addm ${_jail_if} ${_if}";
exec.prestart += "ifconfig e0a_${bastille_epair} description \"${_if_vnet} host interface for Bastille jail ${_jailname}\""; exec.prestart += "ifconfig e0a_${_jail_if} description \"${_if_vnet} host interface for Bastille jail ${_jailname}\"";
exec.poststop += "jib destroy ${bastille_epair}"; exec.poststop += "jib destroy ${_jail_if}";
} }
EOF EOF
fi fi
# Add config to /etc/rc.conf # Add config to /etc/rc.conf
sysrc -f "${_jail_rc_config}" ifconfig_e0b_${bastille_epair}_name="${_if_vnet}" sysrc -f "${_jail_rc_config}" ifconfig_e0b_${_jail_if}_name="${_if_vnet}"
if [ -n "${_ip}" ]; then if [ -n "${_ip}" ]; then
# If 0.0.0.0 set DHCP, else set static IP address # If 0.0.0.0 set DHCP, else set static IP address
if [ "${_ip}" = "0.0.0.0" ] || [ "${_ip}" = "DHCP" ]; then if [ "${_ip}" = "0.0.0.0" ] || [ "${_ip}" = "DHCP" ]; then
@@ -358,7 +351,50 @@ EOF
info "[${_jailname}]:" info "[${_jailname}]:"
echo "Added VNET interface: \"${_if}\"" echo "Added VNET interface: \"${_if}\""
elif [ "${bastille_network_vnet_type}" = "netgraph" ]; 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
# Remove ending brace (it is added again with the netblock)
sed -i '' '/}/d' "${_jail_config}"
if [ "${STATIC_MAC}" -eq 1 ]; then
# Generate NETBLOCK with static MAC
generate_static_mac "${_jailname}" "${_if}"
cat << EOF >> "${_jail_config}"
## ${_jail_if} interface
vnet.interface += ng0_${_jail_if};
exec.prestart += "jng bridge ${_jail_if} ${_if}";
exec.prestart += "ifconfig ng0_${_jail_if} ether ${macaddr}a";
exec.poststop += "jng shutdown ${_jail_if}";
}
EOF
else
# Generate NETBLOCK without static MAC
cat << EOF >> "${_jail_config}"
## ${_jail_if} interface
vnet.interface += e0b_${_jail_if};
exec.prestart += "jng bridge ${_jail_if} ${_if}";
exec.poststop += "jng shutdown ${_jail_if}";
}
EOF
fi
# Add config to /etc/rc.conf
sysrc -f "${_jail_rc_config}" ifconfig_jng_${_jail_if}_name="${_if_vnet}"
if [ -n "${_ip}" ]; then
# If 0.0.0.0 set DHCP, else set static IP address
if [ "${_ip}" = "0.0.0.0" ] || [ "${_ip}" = "DHCP" ]; then
sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}="SYNCDHCP"
else
sysrc -f "${_jail_rc_config}" ifconfig_${_if_vnet}="inet ${_ip}"
fi
fi
info "[${_jailname}]:"
echo "Added VNET interface: \"${_if}\""
fi
elif [ "${PASSTHROUGH}" -eq 1 ]; then elif [ "${PASSTHROUGH}" -eq 1 ]; then
# Remove ending brace (it is added again with the netblock) # Remove ending brace (it is added again with the netblock)
sed -i '' '/}/d' "${_jail_config}" sed -i '' '/}/d' "${_jail_config}"
@@ -402,7 +438,11 @@ remove_interface() {
local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf" local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf"
if grep -q ${_if} ${_jail_config} | grep -Eoq -m 1 'bastille[0-9]+'; then if grep -q ${_if} ${_jail_config} | grep -Eoq -m 1 'bastille[0-9]+'; then
local _if_bastille_num="$(grep ${_if} ${_jail_config} | grep -Eo -m 1 "bastille[0-9]+" | grep -Eo "[0-9]+")" local _if_bastille_num="$(grep ${_if} ${_jail_config} | grep -Eo -m 1 "bastille[0-9]+" | grep -Eo "[0-9]+")"
if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then
local _if_jail="e0b_bastille${_if_bastille_num}" local _if_jail="e0b_bastille${_if_bastille_num}"
elif [ "${bastille_network_vnet_type}" = "netgraph" ]; then
local _if_jail="ng0_bastille${_if_bastille_num}"
fi
_if_type="bastille" _if_type="bastille"
elif grep -q ${_if} ${_jail_config} | grep -Eoq -m 1 "epair[0-9]+"; then elif grep -q ${_if} ${_jail_config} | grep -Eoq -m 1 "epair[0-9]+"; then
local _if_epair_num="$(grep ${_if} ${_jail_config} | grep -Eo -m 1 "epair[0-9]+" | grep -Eo "[0-9]+")" local _if_epair_num="$(grep ${_if} ${_jail_config} | grep -Eo -m 1 "epair[0-9]+" | grep -Eo "[0-9]+")"

View File

@@ -114,10 +114,18 @@ update_jailconf() {
} }
update_jailconf_vnet() { update_jailconf_vnet() {
local _jail_conf="${bastille_jailsdir}/${NEWNAME}/jail.conf" local _jail_conf="${bastille_jailsdir}/${NEWNAME}/jail.conf"
local _rc_conf="${bastille_jailsdir}/${NEWNAME}/root/etc/rc.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 for _if in ${_if_list}; do
if echo ${_if} | grep -Eoq 'epair[0-9]+'; then if echo ${_if} | grep -Eoq 'epair[0-9]+'; then
# Check if epair name = jail name # Check if epair name = jail name

View File

@@ -41,6 +41,31 @@ if [ $# -gt 1 ]; then
usage usage
fi fi
# Configure netgraph
configure_netgraph() {
if [ ! "$(kldstat -m netgraph)" ]; then
sysrc -f "${BASTILLE_CONFIG}" bastille_network_vnet_type="netgraph"
info "Configuring netgraph modules..."
kldload netgraph
kldload ng_netflow
kldload ng_ksocket
kldload ng_ether
kldload ng_bridge
kldload ng_eiface
kldload ng_socket
sysrc -f /boot/loader.conf netgraph_load="YES"
sysrc -f /boot/loader.conf ng_netflow_load="YES"
sysrc -f /boot/loader.conf ng_ksocket_load="YES"
sysrc -f /boot/loader.conf ng_ether_load="YES"
sysrc -f /boot/loader.conf ng_bridge_load="YES"
sysrc -f /boot/loader.conf ng_eiface_load="YES"
sysrc -f /boot/loader.conf ng_socket_load="YES"
info "Netgraph has been successfully configured!"
else
info "Netgraph has already been configured!"
fi
}
# Configure bastille loopback network interface # Configure bastille loopback network interface
configure_loopback_interface() { configure_loopback_interface() {
if [ -z "$(sysrc -f ${BASTILLE_CONFIG} -n bastille_network_loopback)" ] || ! sysrc -n cloned_interfaces | grep -oq "lo1"; then if [ -z "$(sysrc -f ${BASTILLE_CONFIG} -n bastille_network_loopback)" ] || ! sysrc -n cloned_interfaces | grep -oq "lo1"; then
@@ -224,6 +249,26 @@ case "$1" in
-p|pf|firewall) -p|pf|firewall)
configure_pf configure_pf
;; ;;
-n|netgraph)
warn "[WARNING] Bastille only allows using either 'if_bridge' or 'netgraph'"
warn "as VNET network options. You CANNOT use both on the same system. If you have"
warn "already started using bastille with 'if_bridge' do not continue."
# shellcheck disable=SC3045
read -p "Do you really want to continue setting up netgraph for Bastille? [y|n]:" _answer
case "${_answer}" in
[Yy]|[Yy][Ee][Ss])
configure_vnet
configure_netgraph
;;
[Nn]|[Nn][Oo])
error_exit "Netgraph setup cancelled."
;;
*)
error_exit "Invalid selection. Please answer 'y' or 'n'"
;;
esac
;;
-l|loopback) -l|loopback)
warn "[WARNING] Bastille only allows using either the 'loopback' or 'shared'" warn "[WARNING] Bastille only allows using either the 'loopback' or 'shared'"
warn "interface to be configured ant one time. If you continue, the 'shared'" warn "interface to be configured ant one time. If you continue, the 'shared'"