diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index fee55737..f26f460a 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille clone [TARGET] [NEW_NAME] [IPADRESS]" + error_exit "Usage: bastille clone TARGET NEW_NAME IPADDRESS" } # Handle special-case commands first @@ -87,7 +87,7 @@ update_jailconf() { JAIL_CONFIG="${bastille_jailsdir}/${NEWNAME}/jail.conf" if [ -f "${JAIL_CONFIG}" ]; then if ! grep -qw "path = ${bastille_jailsdir}/${NEWNAME}/root;" "${JAIL_CONFIG}"; then - sed -i '' "s|host.hostname = ${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}" + sed -i '' "s|host.hostname = ${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}" sed -i '' "s|exec.consolelog = .*;|exec.consolelog = ${bastille_logsdir}/${NEWNAME}_console.log;|" "${JAIL_CONFIG}" sed -i '' "s|path = .*;|path = ${bastille_jailsdir}/${NEWNAME}/root;|" "${JAIL_CONFIG}" sed -i '' "s|mount.fstab = .*;|mount.fstab = ${bastille_jailsdir}/${NEWNAME}/fstab;|" "${JAIL_CONFIG}" @@ -111,20 +111,33 @@ update_jailconf_vnet() { for _num in $(seq 0 "${num_range}"); do if [ -n "${jail_list}" ]; then if ! grep -q "e0b_bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then - uniq_epair="bastille${_num}" - # Update the exec.* with uniq_epair when cloning jails. - sed -i '' "s|vnet.interface = e0b_bastille.*;|vnet.interface = e0b_${uniq_epair};|" "${JAIL_CONFIG}" - sed -i '' "s|exec.prestart += \"jib addm bastille[0-9]|exec.prestart += \"jib addm ${uniq_epair}|" "${JAIL_CONFIG}" - sed -i '' "s|exec.prestart += \"ifconfig e0a_bastille[0-9].*|exec.prestart += \"ifconfig e0a_${uniq_epair} description \\\\\"vnet host interface for Bastille jail ${NEWNAME}\\\\\"\";|" "${JAIL_CONFIG}" - sed -i '' "s|exec.poststop += \"jib destroy bastille[0-9]\";|exec.poststop += \"jib destroy ${uniq_epair}\";|" "${JAIL_CONFIG}" - break + if ! grep -q "epair${_num}" "${bastille_jailsdir}"/*/jail.conf; then + local uniq_epair="bastille${_num}" + 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}" + break + fi fi 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" @@ -137,15 +150,6 @@ update_fstab() { # Update fstab to use the new name FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab" if [ -f "${FSTAB_CONFIG}" ]; then - FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9]|-BETA[1-9]|-CURRENT)|([0-9]{1,2}(-stable-build-[0-9]{1,3}|-stable-LAST))|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)' "${FSTAB_CONFIG}" | uniq) - FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET}/root/.bastille" "${FSTAB_CONFIG}") - FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${NEWNAME}/root/.bastille nullfs ro 0 0" - if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then - # If both variables are set, update as needed - if ! grep -qw "${bastille_releasesdir}/${FSTAB_RELEASE}.*${bastille_jailsdir}/${NEWNAME}/root/.bastille" "${FSTAB_CONFIG}"; then - sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" "${FSTAB_CONFIG}" - fi - fi # Update additional fstab paths with new jail path sed -i '' "s|${bastille_jailsdir}/${TARGET}/root/|${bastille_jailsdir}/${NEWNAME}/root/|" "${FSTAB_CONFIG}" fi diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 9940d9e6..ed9e5a6a 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -70,10 +70,19 @@ warn() { echo -e "${COLOR_YELLOW}$*${COLOR_RESET}" } +generate_static_mac() { + local jail_name="${1}" + local external_interface="${2}" + local macaddr_prefix="$(ifconfig ${external_interface} | grep ether | awk '{print $2}' | cut -d':' -f1-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/')" + macaddr="${macaddr_prefix}:${macaddr_suffix}" +} + 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 ## iterate num and grep all jail configs ## define uniq_epair @@ -98,11 +107,13 @@ generate_vnet_jail_netblock() { ## generate bridge config cat <<-EOF vnet; - vnet.interface = "e${uniq_epair_bridge}b_${jail_name}"; + vnet.interface = e${uniq_epair_bridge}b_${jail_name}; 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"; EOF @@ -112,6 +123,8 @@ 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 \"vnet host interface for Bastille jail ${jail_name}\""; exec.poststop += "jib destroy ${uniq_epair}"; EOF diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index dee2b391..f278a372 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -150,7 +150,22 @@ list_all(){ JAIL_HOSTNAME=${JAIL_HOSTNAME:-${DEFAULT_VALUE}} JAIL_RELEASE=${JAIL_RELEASE:-${DEFAULT_VALUE}} JAIL_PATH=${JAIL_PATH:-${DEFAULT_VALUE}} - printf " ${JAIL_NAME}%*s${JAIL_STATE}%*s${JAIL_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JAIL_NAME} - ${#JAIL_NAME} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#JAIL_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" "" + JAIL_IP_COUNT=$(echo "${JAIL_IP}" | wc -l) + if [ ${JAIL_IP_COUNT} -gt 1 ]; then + # vnet0 has more than one IPs assigned. + # Put each IP in its own line below the jails first address. For instance: + # JID State IP Address Published Ports Hostname Release Path + # foo Up 10.10.10.10 - foo 14.0-RELEASE-p5 /usr/local/bastille/jails/foo/root + # 10.10.10.11 + # 10.10.10.12 + FIRST_IP="$(echo "${JAIL_IP}" | head -n 1)" + printf " ${JAIL_NAME}%*s${JAIL_STATE}%*s${FIRST_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JAIL_NAME} - ${#JAIL_NAME} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#FIRST_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" "" + for IP in $(echo "${JAIL_IP}" | tail -n +2); do + printf "%*s %*s${IP}\n" "$((${MAX_LENGTH_JAIL_NAME} + ${SPACER}))" "" "$((5 + ${SPACER}))" "" + done + else + printf " ${JAIL_NAME}%*s${JAIL_STATE}%*s${JAIL_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JAIL_NAME} - ${#JAIL_NAME} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#JAIL_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" "" + fi fi done else diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index f9e5a180..2eeb9e49 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -79,14 +79,14 @@ for _jail in ${JAILS}; do fi ## warn if matching configured (but not online) ip4.addr, ignore if there's no ip4.addr entry - ip=$(bastille config "${_jail}" get ip4.addr) - if [ -n "${ip}" ]; then - if ifconfig | grep -wF "${ip}" >/dev/null; then - error_notify "Error: IP address (${ip}) already in use." + _ip4=$(bastille config "${_jail}" get ip4.addr) + if [ "${_ip4}" != "not set" ]; then + if ifconfig | grep -wF "${_ip4}" >/dev/null; then + error_notify "Error: IP address (${_ip4}) already in use." continue fi ## add ip4.addr to firewall table - pfctl -q -t "${bastille_network_pf_table}" -T add "${ip}" + pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip4}" fi ## start the container diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index 49cec54d..6c4b7c1d 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -52,10 +52,10 @@ for _jail in ${JAILS}; do ## test if running if [ "$(/usr/sbin/jls name | awk "/^${_jail}$/")" ]; then ## Capture ip4.addr address while still running - _ip="$(/usr/sbin/jls -j ${_jail} ip4.addr)" + _ip4="$(bastille config ${_jail} get ip4.addr)" # Check if pfctl is present - if which -s pfctl; then + if [ "${_ip4}" != "not set" ]; then if [ "$(bastille rdr ${_jail} list)" ]; then bastille rdr ${_jail} clear fi @@ -73,9 +73,9 @@ for _jail in ${JAILS}; do jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" ## remove (captured above) ip4.addr from firewall table - if [ -n "${bastille_network_loopback}" ] && [ ! -z "${_ip}" ]; then + if [ -n "${bastille_network_loopback}" ] && [ "${_ip4}" != "not set" ]; then if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then - pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" + pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip4}" fi fi fi