diff --git a/docs/chapters/networking.rst b/docs/chapters/networking.rst index cf40ad9c..6420c716 100644 --- a/docs/chapters/networking.rst +++ b/docs/chapters/networking.rst @@ -107,8 +107,10 @@ Bastille includes a number of IP options for IPv4 networking. The IP address specified above can be any of the following options. * An IP in your local subnet should be chosen if you create your jail using - ``-V``, ``-B`` or ``-P`` (VNET jail). It is also preferable to add the - subnet mask (/24 or whaterver your subnet is) to the IP. + ``-V``, ``-B`` or ``-P`` (VNET jail). + + Note: It is mandatory to add the subnet mask (/24 or whaterver your subnet is) + to the IP for any types of VNET jail. See below... * DHCP, SYNCDHCP, or 0.0.0.0 will configure your jail to use DHCP to obtain an address from your router. This should only be used with VNET jails. @@ -130,9 +132,10 @@ The IP address specified above can be any of the following options. resolves to. This is an advanced option and should only be used if you know what you are doing. -Note that jails support specifying an IP without the subnet (/24 or whatever -yours is) but we highly recommend setting it, especially on VNET jails. Not -doing so can cause issues in some rare cases. +Standard (non-VNET) jails support specifying an IP without the subnet (/24 or whatever +yours is), but for VNET jails it is mandatory. If none is supplied, it will +default to /24. This is because FreeBSD does not support adding an IP to an interface +without a subnet. IPv6 Network ^^^^^^^^^^^^ @@ -146,7 +149,8 @@ IPv6 address when creating a jail to use IPv6. The IP address specified above can be any of the following options. -* A valid IPv6 address including the subnet. +* A valid IPv6 address including the subnet. If not subnet is given, it + will defalut to /64. * SLAAC will configure your jail to use router advertisement to obtain an address from your router. This should only be used with VNET jails. diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index fcedcb40..ba6bc32d 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -49,6 +49,7 @@ EOF # Handle options. AUTO=0 LIVE=0 +VNET_JAIL=0 while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) @@ -109,122 +110,89 @@ clone_validate_jail_name() { fi } -validate_ip() { - - local _ip="${1}" - local _ip6="$(echo ${_ip} | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)')" - - if [ -n "${_ip6}" ]; then - if [ "${_ip6}" = "SLAAC" ] && [ "$(bastille config ${TARGET} get vnet)" != "enabled" ]; then - error_exit "[ERROR]: Unsupported IP option for standard jail: (${_ip6})." - fi - info "\nValid: (${_ip6})." - IP6_ADDR="${_ip6}" - elif [ "${_ip}" = "inherit" ] || [ "${_ip}" = "ip_hostname" ]; then - if [ "$(bastille config ${TARGET} get vnet)" = "enabled" ]; then - error_exit "[ERROR]: Unsupported IP option for VNET jail: (${_ip})." - else - info "\nValid: (${_ip})." - IP4_ADDR="${_ip}" - IP6_ADDR="${_ip}" - fi - elif [ "${_ip}" = "0.0.0.0" ] || [ "${_ip}" = "DHCP" ] || [ "${_ip}" = "SYNCDHCP" ]; then - if [ "$(bastille config ${TARGET} get vnet)" = "enabled" ]; then - info "\nValid: (${_ip})." - IP4_ADDR="${_ip}" - else - error_exit "[ERROR]: Unsupported IP option for standard jail: (${_ip})." - fi - else - local IFS - if echo "${_ip}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then - TEST_IP=$(echo "${_ip}" | cut -d / -f1) - IFS=. - set ${TEST_IP} - for quad in 1 2 3 4; do - if eval [ \$$quad -gt 255 ]; then - error_continue "Invalid: (${TEST_IP})" - fi - done - - if ifconfig | grep -qwF "${TEST_IP}"; then - warn "\nWarning: IP address already in use (${TEST_IP})." - IP4_ADDR="${_ip}" - else - info "\nValid: (${_ip})." - IP4_ADDR="${_ip}" - fi - - else - error_continue "Invalid: (${_ip})." - fi - fi -} - -validate_ips() { +define_ips() { IP4_ADDR="" IP6_ADDR="" for ip in ${IP}; do - validate_ip "${ip}" + validate_ip "${ip}" "${VNET_JAIL}" done + + if [ -n "${IP4_ADDR}" ]; then + if [ "${IP4_ADDR}" = "inherit" ] || [ "${IP4_ADDR}" = "ip_hostname" ]; then + if [ "$(bastille config ${TARGET} get vnet)" = "enabled" ]; then + error_exit "[ERROR]: Unsupported IP option for VNET jail: ${IP4_ADDR}" + fi + elif [ "${IP4_ADDR}" = "0.0.0.0" ] || [ "${IP4_ADDR}" = "DHCP" ] || [ "${IP4_ADDR}" = "SYNCDHCP" ]; then + if [ "$(bastille config ${TARGET} get vnet)" != "enabled" ]; then + error_exit "[ERROR]: Unsupported IP option for standard jail: ${IP4_ADDR}" + fi + elif ifconfig | grep -qwF "${IP4_ADDR}"; then + warn "\n[WARNING]: IP address already in use: ${TEST_IP}" + fi + fi + + if [ -n "${IP6_ADDR}" ]; then + if [ "${IP6_ADDR}" = "SLAAC" ] && [ "$(bastille config ${TARGET} get vnet)" != "enabled" ]; then + error_exit "[ERROR]: Unsupported IP option for standard jail: ${IP6_ADDR}" + fi + fi } update_jailconf() { - # Update jail.conf - JAIL_CONFIG="${bastille_jailsdir}/${NEWNAME}/jail.conf" + local 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|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}" - sed -i '' "s|^${TARGET}.*{$|${NEWNAME} {|" "${JAIL_CONFIG}" + 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|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}" + sed -i '' "s|^${TARGET}.*{$|${NEWNAME} {|" "${jail_config}" fi fi - if grep -qw "vnet;" "${JAIL_CONFIG}"; then + if [ "${VNET_JAIL}" -eq 1 ]; then validate_netconf update_jailconf_vnet else - _ip4="$(bastille config ${TARGET} get ip4.addr | sed 's/,/ /g')" - _ip6="$(bastille config ${TARGET} get ip6.addr | sed 's/,/ /g')" - _interface="$(bastille config ${TARGET} get interface)" + ip4="$(bastille config ${TARGET} get ip4.addr | sed 's/,/ /g')" + ip6="$(bastille config ${TARGET} get ip6.addr | sed 's/,/ /g')" + interface="$(bastille config ${TARGET} get interface)" # Remove old style interface naming in place of new if|ip style - if [ "${_interface}" != "not set" ]; then - sed -i '' "/.*interface = .*/d" "${JAIL_CONFIG}" + if [ "${interface}" != "not set" ]; then + sed -i '' "/.*interface = .*/d" "${jail_config}" fi # IP4 - if [ "${_ip4}" != "not set" ]; then - for _ip in ${_ip4}; do - if echo ${_ip} | grep -q "|"; then - _ip="$(echo ${_ip} | awk -F"|" '{print $2}')" + if [ "${ip4}" != "not set" ]; then + for ip in ${ip4}; do + if echo ${ip} | grep -q "|"; then + ip="$(echo ${ip} | awk -F"|" '{print $2}')" fi - if [ "${_interface}" != "not set" ]; then - sed -i '' "s#.*ip4.addr = .*# ip4.addr = ${_interface}|${IP4_ADDR};#" "${JAIL_CONFIG}" + if [ "${interface}" != "not set" ]; then + sed -i '' "s#.*ip4.addr = .*# ip4.addr = ${interface}|${IP4_ADDR};#" "${jail_config}" else - sed -i '' "\#ip4.addr = .*# s#${_ip}#${IP4_ADDR}#" "${JAIL_CONFIG}" + sed -i '' "\#ip4.addr = .*# s#${ip}#${IP4_ADDR}#" "${jail_config}" fi - sed -i '' "\#ip4.addr += .*# s#${_ip}#127.0.0.1#" "${JAIL_CONFIG}" + sed -i '' "\#ip4.addr += .*# s#${ip}#127.0.0.1#" "${jail_config}" done fi # IP6 - if [ "${_ip6}" != "not set" ]; then - for _ip in ${_ip6}; do - if echo ${_ip} | grep -q "|"; then - _ip="$(echo ${_ip} | awk -F"|" '{print $2}')" + if [ "${ip6}" != "not set" ]; then + for ip in ${ip6}; do + if echo ${ip} | grep -q "|"; then + ip="$(echo ${ip} | awk -F"|" '{print $2}')" fi - if [ "${_interface}" != "not set" ]; then - sed -i '' "s#.*${_interface} = .*# ip6.addr = ${_interface}|${IP6_ADDR};/" "${JAIL_CONFIG}" + if [ "${interface}" != "not set" ]; then + sed -i '' "s#.*${interface} = .*# ip6.addr = ${interface}|${IP6_ADDR};/" "${jail_config}" else - sed -i '' "\#ip6.addr = .*# s#${_ip}#${IP6_ADDR}#" "${JAIL_CONFIG}" + sed -i '' "\#ip6.addr = .*# s#${ip}#${IP6_ADDR}#" "${jail_config}" fi - sed -i '' "\#ip6.addr += .*# s#${_ip}#::1#" "${JAIL_CONFIG}" + sed -i '' "\#ip6.addr += .*# s#${ip}#::1#" "${jail_config}" done fi fi @@ -348,12 +316,14 @@ update_jailconf_vnet() { if [ -n "${jail_vnet_vlan}" ]; then if [ "${IP4_ADDR}" = "0.0.0.0" ] || [ "${IP4_ADDR}" = "DHCP" ] || [ "${IP4_ADDR}" = "SYNCDHCP" ]; then sysrc -f "${jail_rc_config}" ifconfig_vnet0_${jail_vnet_vlan}="SYNCDHCP" + sysrc -f "${jail_rc_config}" defaultrouter="NO" else sysrc -f "${jail_rc_config}" ifconfig_vnet0_${jail_vnet_vlan}="inet ${IP4_ADDR}" fi else if [ "${IP4_ADDR}" = "0.0.0.0" ] || [ "${IP4_ADDR}" = "DHCP" ] || [ "${IP4_ADDR}" = "SYNCDHCP" ]; then sysrc -f "${jail_rc_config}" ifconfig_vnet0="SYNCDHCP" + sysrc -f "${jail_rc_config}" defaultrouter="NO" else sysrc -f "${jail_rc_config}" ifconfig_vnet0="inet ${IP4_ADDR}" fi @@ -372,13 +342,16 @@ update_jailconf_vnet() { if grep "vnet0" "${jail_rc_config}" | grep -q "${new_jail_epair}_name"; then if [ "${IP6_ADDR}" = "SLAAC" ]; then sysrc -f "${jail_rc_config}" ifconfig_vnet0_ipv6="inet6 -ifdisabled accept_rtadv" + sysrc -f "${jail_rc_config}" ipv6_defaultrouter="NO" else sysrc -f "${jail_rc_config}" ifconfig_vnet0_ipv6="inet6 -ifdisabled ${IP6_ADDR}" fi else if [ "${IP6_ADDR}" = "SLAAC" ]; then sysrc -f "${jail_rc_config}" ifconfig_${jail_vnet}_ipv6="inet6 -ifdisabled accept_rtadv" - fi + else + sysrc -f "${jail_rc_config}" ifconfig_${jail_vnet}_ipv6="inet6 -ifdisabled" + fi fi fi @@ -458,8 +431,17 @@ clone_jail() { if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then + local jail_config="${bastille_jailsdir}/${TARGET}/jail.conf" + local jail_rc_config="${bastille_jailsdir}/${TARGET}/root/etc/rc.conf" + + if grep -qw "vnet;" "${jail_config}"; then + VNET_JAIL=1 + else + VNET_JAIL=0 + fi + if [ -n "${IP}" ]; then - validate_ips + define_ips else usage fi @@ -467,12 +449,12 @@ clone_jail() { # Validate proper IP settings if [ "$(bastille config ${TARGET} get vnet)" != "not set" ]; then # VNET - if grep -Eoq "ifconfig_vnet0=" "${bastille_jailsdir}/${TARGET}/root/etc/rc.conf"; then + if grep -Eoqx 'ifconfig_vnet0="[^"]+"' "${jail_rc_config}"; then if [ -z "${IP4_ADDR}" ]; then error_exit "[ERROR]: IPv4 not set. Retry with a proper IPv4 address." fi fi - if grep -Eoq "ifconfig_vnet0_ipv6=" "${bastille_jailsdir}/${TARGET}/root/etc/rc.conf"; then + if grep -Eoqx 'ifconfig_vnet0_ipv6="[^"]+"' "${jail_rc_config}"; then if [ -z "${IP6_ADDR}" ]; then error_exit "[ERROR]: IPv6 not set. Retry with a proper IPv6 address." fi diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index f56968d4..7d7f95c3 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -327,13 +327,72 @@ target_all_jails() { } update_fstab() { - local _oldname="${1}" - local _newname="${2}" - local _fstab="${bastille_jailsdir}/${_newname}/fstab" - if [ -f "${_fstab}" ]; then - sed -i '' "s|${bastille_jailsdir}/${_oldname}/root/|${bastille_jailsdir}/${_newname}/root/|" "${_fstab}" + + local oldname="${1}" + local newname="${2}" + local fstab="${bastille_jailsdir}/${newname}/fstab" + + if [ -f "${fstab}" ]; then + sed -i '' "s|${bastille_jailsdir}/${oldname}/root/|${bastille_jailsdir}/${newname}/root/|" "${fstab}" else - error_notify "Error: Failed to update fstab: ${_newmane}" + error_notify "Error: Failed to update fstab: ${newmane}" + fi +} + +validate_ip() { + + local ip="${1}" + local vnet_jail="${2}" + local ip4="$(echo ${ip} | awk -F"/" '{print $1}')" + local ip6="$(echo ${ip} | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)')" + local subnet="$(echo ${ip} | awk -F"/" '{print $2}')" + local IFS + + if [ -n "${ip6}" ]; then + if [ "${vnet_jail}" -eq 1 ]; then + if [ -z "${subnet}" ]; then + subnet="64" + ip6="${ip6}/${subnet}" + elif ! echo "${subnet}" | grep -Eq '^[0-9]+$'; then + error_exit "[ERROR]: Invalid subnet: /${subnet}" + elif [ "${subnet}" -lt 1 ] || [ "${subnet}" -gt 128 ]; then + error_exit "[ERROR]: Invalid subnet: /${subnet}" + fi + fi + info "\nValid IP: ${ip6}" + export IP6_ADDR="${ip6}" + elif [ "${ip}" = "inherit" ] || [ "${ip}" = "ip_hostname" ] || [ "${ip}" = "0.0.0.0" ] || [ "${ip}" = "DHCP" ] || [ "${ip}" = "SYNCDHCP" ]; then + info "\nValid IP: ${ip}" + export IP4_ADDR="${ip}" + export IP6_ADDR="${ip}" + elif [ -n "${ip4}" ]; then + if [ "${vnet_jail}" -eq 1 ]; then + if [ -z "${subnet}" ]; then + subnet="24" + ip4="${ip4}/${subnet}" + elif ! echo "${subnet}" | grep -Eq '^[0-9]+$'; then + error_exit "[ERROR]: Invalid subnet: /${subnet}" + elif [ "${subnet}" -lt 1 ] || [ "${subnet}" -gt 32 ]; then + error_exit "[ERROR]: Invalid subnet: /${subnet}" + fi + fi + if echo "${ip4}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then + test_ip=$(echo "${ip4}" | cut -d / -f1) + IFS=. + set ${test_ip} + for quad in 1 2 3 4; do + if eval [ \$$quad -gt 255 ]; then + error_exit "[ERROR]: Invalid IP: ${ip4}" + fi + done + + info "\nValid IP: ${ip4}" + export IP4_ADDR="${ip4}" + else + error_exit "[ERROR]: Invalid IP: ${ip4}" + fi + else + error_exit "[ERROR]: IP incorrectly formatted: ${ip}" fi } diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index 94df0b45..2f41e0bb 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -111,50 +111,40 @@ validate_release() { OS_RELEASE="$( ${bastille_releasesdir}/${RELEASE}/bin/freebsd-version )" } -validate_ip() { +define_ips() { - local ip="${1}" - local ip6="$(echo ${ip} | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)')" + IP6_MODE="disable" + IP4_DEFINITION="" + IP6_DEFINITION="" + IP4_ADDR="" + IP6_ADDR="" + IP_HOSTNAME="" - if [ -n "${ip6}" ]; then - info "\nValid: (${ip6})." - # This is only used in this function to set IPX_DEFINITION - local ipx_addr="ip6.addr" - else - if [ "${ip}" = "inherit" ] || [ "${ip}" = "ip_hostname" ]; then + for ip in ${IP}; do + validate_ip "${ip}" "${VNET_JAIL}" + done + + if [ -n "${IP4_ADDR}" ]; then + if [ "${IP4_ADDR}" = "inherit" ] || [ "${IP4_ADDR}" = "ip_hostname" ]; then if [ "${VNET_JAIL}" -eq 1 ]; then - error_exit "[ERROR]: Unsupported IP option for VNET jail: (${ip})." - else - info "\nValid: (${ip})." + error_exit "[ERROR]: Unsupported IP option for VNET jail: ${IP4_ADDR}" fi - elif [ "${ip}" = "DHCP" ] || [ "${ip}" = "SYNCDHCP" ] || [ "${ip}" = "0.0.0.0" ]; then + elif [ "${IP4_ADDR}" = "DHCP" ] || [ "${IP4_ADDR}" = "SYNCDHCP" ] || [ "${IP4_ADDR}" = "0.0.0.0" ]; then if [ "${VNET_JAIL}" -eq 0 ]; then - error_exit "[ERROR]: Unsupported IP option for non-VNET jail: (${ip})." - else - info "\nValid: (${ip})." + error_exit "[ERROR]: Unsupported IP option for non-VNET jail: ${IP4_ADDR}" fi - else - local IFS - if echo "${ip}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then - TEST_IP=$(echo "${ip}" | cut -d / -f1) - IFS=. - set ${TEST_IP} - for quad in 1 2 3 4; do - if eval [ \$$quad -gt 255 ]; then - error_continue "Invalid: (${TEST_IP})" - fi - done - ipx_addr="ip4.addr" - info "\nValid: (${ip})." - else - error_continue "Invalid: (${ip})." - fi + # Warn if IP is in use + elif ifconfig | grep -qwF "${IP4_ADDR}"; then + warn "[WARNING]: IP address in use: ${IP4_ADDR}" fi + local ipx_addr="ip4.addr" fi - # Warn if IP is in use - if ifconfig | grep -qwF "${TEST_IP}"; then - warn "[WARNING]: IP address in use (${TEST_IP})." + if [ -n "${IP6_ADDR}" ]; then + if [ "${IP6_ADDR}" = "SLAAC" ] && [ "${VNET_JAIL}" -eq 0 ]; then + error_exit "[ERROR]: Unsupported IP option for standard jail: ${IP6_ADDR}" + fi + local ipx_addr="ip6.addr" fi # Set interface value @@ -171,24 +161,24 @@ validate_ip() { fi # Determine IP/Interface mode - if [ "${ip}" = "inherit" ]; then + if [ "${IP4_ADDR}" = "inherit" ]; then if [ "${DUAL_STACK}" -eq 1 ]; then - IP4_DEFINITION="ip4 = ${ip};" - IP6_DEFINITION="ip6 = ${ip};" + IP4_DEFINITION="ip4 = ${IP4_ADDR};" + IP6_DEFINITION="ip6 = ${IP6_ADDR};" IP6_MODE="new" else - IP4_DEFINITION="ip4 = ${ip};" + IP4_DEFINITION="ip4 = ${IP4_ADDR};" IP6_DEFINITION="" IP6_MODE="disable" fi - elif [ "${ip}" = "ip_hostname" ]; then + elif [ "${IP4_ADDR}" = "ip_hostname" ]; then if [ "${DUAL_STACK}" -eq 1 ]; then - IP_HOSTNAME="${ip}" + IP_HOSTNAME="${IP4_ADDR}" IP4_DEFINITION="${IP_HOSTNAME};" IP6_DEFINITION="${IP_HOSTNAME};" IP6_MODE="new" else - IP_HOSTNAME="${ip}" + IP_HOSTNAME="${IP4_ADDR}" IP4_DEFINITION="${IP_HOSTNAME};" IP6_DEFINITION="" IP6_MODE="disable" @@ -201,54 +191,40 @@ validate_ip() { IP6_ADDR="${ip}" fi else - error_exit "[ERROR]: Unsupported IP option for standard jail: (${ip})." + error_exit "[ERROR]: Unsupported IP option for standard jail: ${ip}" fi else - if [ "${ipx_addr}" = "ip4.addr" ]; then - IP4_ADDR="${ip}" - IP4_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${ip};" - elif [ "${ipx_addr}" = "ip6.addr" ]; then - IP6_ADDR="${ip}" - IP6_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${ip};" - IP6_MODE="new" + if [ "${VNET_JAIL}" -eq 0 ]; then + if [ "${ipx_addr}" = "ip4.addr" ]; then + IP4_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${IP4_ADDR};" + elif [ "${ipx_addr}" = "ip6.addr" ]; then + IP6_DEFINITION="${ipx_addr} = ${bastille_jail_conf_interface}|${IP6_ADDR};" + IP6_MODE="new" + fi fi fi } -validate_ips() { - - IP6_MODE="disable" - IP4_DEFINITION="" - IP6_DEFINITION="" - IP4_ADDR="" - IP6_ADDR="" - IP_HOSTNAME="" - - for ip in ${IP}; do - validate_ip "${ip}" - done -} - validate_netif() { local LIST_INTERFACES="$(ifconfig -l)" if ! echo "${LIST_INTERFACES} VNET" | grep -qwo "${INTERFACE}"; then - error_exit "[ERROR]: Invalid: (${INTERFACE})." + error_exit "[ERROR]: Invalid interface: ${INTERFACE}" elif [ "${VNET_JAIL_STANDARD}" -eq 1 ]; then for _bridge in $(ifconfig -g bridge | grep -vw "${INTERFACE}bridge"); do if ifconfig ${_bridge} | grep "member" | grep -owq "${INTERFACE}"; then - error_exit "[ERROR]: Interface (${INTERFACE}) is already a member of bridge: ${_bridge}" + error_exit "[ERROR]: Interface '${INTERFACE}' is already a member of bridge: ${_bridge}" fi done else - info "\nValid: (${INTERFACE})." + info "\nValid interface: ${INTERFACE}" fi # Don't allow dots in INTERFACE for -V|--vnet jails if [ "${VNET_JAIL_STANDARD}" -eq 1 ]; then if echo "${INTERFACE}" | grep -q "\."; then - error_exit "[ERROR]: [-V|--vnet] does not support dots (.) in interface names." + error_exit "[ERROR]: [-V|--vnet] does not support dots (.) in interface names." fi fi } @@ -671,33 +647,33 @@ create_jail() { ifconfig_inet="" ifconfig_inet6="" - # Check for DHCP - if echo "${IP}" | grep -qE '(0[.]0[.]0[.]0|DHCP|SYNCDHCP)'; then - ifconfig_inet="SYNCDHCP" - else - # Set Gateway - if [ -n "${OPT_GATEWAY}" ]; then - gateway="${OPT_GATEWAY}" - elif [ -n "${bastille_network_gateway}" ]; then - gateway="${bastille_network_gateway}" + # Enable IPv4 if set + if [ -n "${IP4_ADDR}" ]; then + if echo "${IP4_ADDR}" | grep -qE '(0[.]0[.]0[.]0|DHCP|SYNCDHCP)'; then + ifconfig_inet="SYNCDHCP" else - gateway="$(netstat -4rn | awk '/default/ {print $2}')" + # Set IP and Gateway + ifconfig_inet="inet ${IP4_ADDR}" + if [ -n "${OPT_GATEWAY}" ]; then + gateway="${OPT_GATEWAY}" + elif [ -n "${bastille_network_gateway}" ]; then + gateway="${bastille_network_gateway}" + else + gateway="$(netstat -4rn | awk '/default/ {print $2}')" + fi + fi fi - # Add IPv4 address (this is empty if DHCP is used) - if [ -n "${IP4_ADDR}" ]; then - ifconfig_inet="inet ${IP4_ADDR}" - fi - - # Enable IPv6 if used + # Enable IPv6 if set if [ -n "${IP6_ADDR}" ]; then ifconfig_inet6="inet6 -ifdisabled" - if echo "${IP}" | grep -qE 'SLAAC'; then + if echo "${IP6_ADDR}" | grep -qE 'SLAAC'; then # Enable SLAAC if requested ifconfig_inet6="${ifconfig_inet6} accept_rtadv" else - # Set Gateway + # Set IP and Gateway + ifconfig_inet6="${ifconfig_inet6} ${IP6_ADDR}" if [ -n "${bastille_network_gateway6}" ]; then gateway6="${bastille_network_gateway6}" else @@ -706,11 +682,6 @@ create_jail() { fi fi - # Add IPv6 address (this is empty if SLAAC is used) - if [ -n "${IP6_ADDR}" ]; then - ifconfig_inet6="${ifconfig_inet6} ${IP6_ADDR}" - fi - # We need to pass IP4 and IP6 separately ifconfig="${ifconfig_inet}" ifconfig6="${ifconfig_inet6}" @@ -966,10 +937,10 @@ elif [ "${VNET_JAIL_PASSTHROUGH}" -eq 1 ]; then VNET_INTERFACE_TYPE="passthrough" fi -NAME="$1" -RELEASE="$2" -IP="$3" -INTERFACE="$4" +NAME="${1}" +RELEASE="${2}" +IP="${3}" +INTERFACE="${4}" info "\nAttempting to create jail: ${NAME}" @@ -1094,7 +1065,7 @@ if [ "${EMPTY_JAIL}" -eq 0 ]; then # Validate IP address if [ -n "${IP}" ]; then - validate_ips + define_ips else usage fi diff --git a/usr/local/share/bastille/network.sh b/usr/local/share/bastille/network.sh index 73db036e..72f050fb 100644 --- a/usr/local/share/bastille/network.sh +++ b/usr/local/share/bastille/network.sh @@ -140,6 +140,9 @@ fi # Default is standard interface if [ "${VNET}" -eq 0 ] && [ "${BRIDGE}" -eq 0 ] && [ "${PASSTHROUGH}" -eq 0 ]; then STANDARD=1 + VNET_JAIL=0 +else + VNET_JAIL=1 fi if [ "${ACTION}" = "add" ]; then @@ -175,32 +178,32 @@ else error_exit "Use [-a|--auto] to auto-stop the jail." fi -validate_ip() { +define_ips() { - local ip="${1}" - local ip6="$( echo "${ip}" 2>/dev/null | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )" + IP4_ADDR="" + IP6_ADDR="" - if [ -n "${ip6}" ]; then - info "\nValid: (${ip6})." - IP6_ADDR="${ip6}" - elif [ "${ip}" = "0.0.0.0" ] || [ "${ip}" = "DHCP" ] || [ "${ip}" = "SYNCDHCP" ]; then - info "\nValid: (${ip})." - IP4_ADDR="${ip}" - else - local IFS - if echo "${ip}" 2>/dev/null | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then - TEST_IP=$(echo "${ip}" | cut -d / -f1) - IFS=. - set ${TEST_IP} - for quad in 1 2 3 4; do - if eval [ \$$quad -gt 255 ]; then - error_exit "Invalid: (${TEST_IP})" - fi - done - info "\nValid: (${ip})." - IP4_ADDR="${ip}" - else - error_exit "Invalid: (${ip})." + for ip in ${IP}; do + validate_ip "${ip}" "${VNET_JAIL}" + done + + if [ -n "${IP4_ADDR}" ]; then + if [ "${IP4_ADDR}" = "inherit" ] || [ "${IP4_ADDR}" = "ip_hostname" ]; then + if [ "$(bastille config ${TARGET} get vnet)" = "enabled" ]; then + error_exit "[ERROR]: Unsupported IP option for VNET jail: ${IP4_ADDR}" + fi + elif [ "${IP4_ADDR}" = "0.0.0.0" ] || [ "${IP4_ADDR}" = "DHCP" ] || [ "${IP4_ADDR}" = "SYNCDHCP" ]; then + if [ "$(bastille config ${TARGET} get vnet)" != "enabled" ]; then + error_exit "[ERROR]: Unsupported IP option for standard jail: ${IP4_ADDR}" + fi + elif ifconfig | grep -qwF "${IP4_ADDR}"; then + warn "\n[WARNING]: IP address already in use: ${TEST_IP}" + fi + fi + + if [ -n "${IP6_ADDR}" ]; then + if [ "${IP6_ADDR}" = "SLAAC" ] && [ "$(bastille config ${TARGET} get vnet)" != "enabled" ]; then + error_exit "[ERROR]: Unsupported IP option for standard jail: ${IP6_ADDR}" fi fi } @@ -210,9 +213,9 @@ validate_netif() { local interface="${1}" if ifconfig -l | grep -qwo ${interface}; then - info "\nValid: (${interface})." + info "\nValid interface: ${interface}" else - error_exit "Invalid: (${interface})." + error_exit "[ERROR]: Invalid interface: ${interface}" fi # Don't allow dots in INTERFACE if -V @@ -448,7 +451,7 @@ EOF } EOF # Add config to /etc/rc.conf - if [ -n "${IP6_ADDR}" ]; then + if [ -n "${IP6_ADDR}" ]; then if [ "${IP6_ADDR}" = "SLAAC" ]; then sysrc -f "${jail_rc_config}" ifconfig_${if}_ipv6="inet6 -ifdisabled accept_rtadv" else @@ -466,9 +469,9 @@ EOF elif [ "${STANDARD}" -eq 1 ]; then if [ -n "${IP6_ADDR}" ]; then - sed -i '' "s/interface = .*/&\n ip6.addr += ${if}|${ip};/" ${jail_config} + sed -i '' "s/ip6.addr = .*/&\n ip6.addr += ${if}|${ip};/" ${jail_config} else - sed -i '' "s/interface = .*/&\n ip4.addr += ${if}|${ip};/" ${jail_config} + sed -i '' "s/ip4.addr = .*/&\n ip4.addr += ${if}|${ip};/" ${jail_config} fi fi } @@ -635,7 +638,8 @@ case "${ACTION}" in validate_netif "${INTERFACE}" if check_interface_added "${TARGET}" "${INTERFACE}" && [ -z "${VLAN_ID}" ]; then - error_exit "Interface is already added: \"${INTERFACE}\"" + info "\nInterface already added: ${INTERFACE}" + exit 0 elif { [ "${VNET}" -eq 1 ] || [ "${BRIDGE}" -eq 1 ] || [ "${PASSTHROUGH}" -eq 1 ]; } && [ -n "${VLAN_ID}" ]; then add_vlan "${TARGET}" "${INTERFACE}" "${IP}" "${VLAN_ID}" echo @@ -644,7 +648,7 @@ case "${ACTION}" in ## validate IP if not empty if [ -n "${IP}" ]; then - validate_ip "${IP}" + define_ips "${IP}" fi if [ "${VNET}" -eq 1 ]; then @@ -680,7 +684,7 @@ case "${ACTION}" in elif [ "${PASSTHROUGH}" -eq 1 ]; then if [ "$(bastille config ${TARGET} get vnet)" = "not set" ]; then error_exit "[ERROR]: ${TARGET} is not a VNET jail." - else + else add_interface "${TARGET}" "${INTERFACE}" "${IP}" fi if [ -n "${VLAN_ID}" ]; then @@ -704,10 +708,10 @@ case "${ACTION}" in remove|delete) - check_interface_added "${TARGET}" "${INTERFACE}" || error_exit "Interface not found in jail.conf: \"${INTERFACE}\"" + check_interface_added "${TARGET}" "${INTERFACE}" || error_exit "Interface not found in jail.conf: ${INTERFACE}" validate_netif "${INTERFACE}" if ! grep -q "${INTERFACE}" ${bastille_jailsdir}/${TARGET}/jail.conf; then - error_exit "[ERROR]: Interface not found in jail.conf: \"${INTERFACE}\"" + error_exit "[ERROR]: Interface not found in jail.conf: ${INTERFACE}" else remove_interface "${TARGET}" "${INTERFACE}" if [ "${AUTO}" -eq 1 ]; then