diff --git a/dist/dist-packages/linux/openziti-controller/bootstrap.bash b/dist/dist-packages/linux/openziti-controller/bootstrap.bash index 6b2849beb..afe5ce842 100755 --- a/dist/dist-packages/linux/openziti-controller/bootstrap.bash +++ b/dist/dist-packages/linux/openziti-controller/bootstrap.bash @@ -50,6 +50,8 @@ issueLeafCerts() { # create server and client keys # + local -a _dns_sans _ip_sans + if [[ "${ZITI_SERVER_FILE}" == "${ZITI_CLIENT_FILE}" ]]; then echo "ERROR: ZITI_SERVER_FILE and ZITI_CLIENT_FILE must be different" >&2 return 1 @@ -71,14 +73,33 @@ issueLeafCerts() { ZITI_PKI_CTRL_SERVER_CERT="${ZITI_PKI_ROOT}/${ZITI_INTERMEDIATE_FILE}/certs/${ZITI_SERVER_FILE}.chain.pem" if [[ "${ZITI_AUTO_RENEW_CERTS}" == true || ! -s "$ZITI_PKI_CTRL_SERVER_CERT" ]]; then # server cert + # if IP address then set IP SAN, else DNS SAN + if [[ "${ZITI_CTRL_ADVERTISED_ADDRESS}" =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)$|^::([0-9a-fA-F]{1,4}:){0,6}([0-9a-fA-F]{1,4}|:)$|^([0-9a-fA-F]{1,4}:){1,7}:$|^([0-9a-fA-F]{1,4}:){1,6}(:[0-9a-fA-F]{1,4}){1,6}$|^([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,7}$|^([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,8}$|^([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,9}$|^([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,10}$|^([0-9a-fA-F]{1,4}:){1,1}(:[0-9a-fA-F]{1,4}){1,11}$|^:((:[0-9a-fA-F]{1,4}){1,12}|:)$|^fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|^::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ]]; then + _dns_sans=("localhost") + if [[ "${ZITI_CTRL_ADVERTISED_ADDRESS}" =~ ^(127\.0\.0\.1|::1)$ ]]; then + _ip_sans=("127.0.0.1" "::1") + else + _ip_sans=("${ZITI_CTRL_ADVERTISED_ADDRESS}" "127.0.0.1" "::1") + fi + else + _ip_sans=("127.0.0.1" "::1") + if [[ "${ZITI_CTRL_ADVERTISED_ADDRESS}" == "localhost" ]]; then + _dns_sans=("localhost") + else + _dns_sans=("${ZITI_CTRL_ADVERTISED_ADDRESS}" "localhost") + fi + fi + _dns_sans_csv=$(IFS=,; echo "${_dns_sans[*]}") + _ip_sans_csv=$(IFS=,; echo "${_ip_sans[*]}") ziti pki create server \ --pki-root "${ZITI_PKI_ROOT}" \ --ca-name "${ZITI_INTERMEDIATE_FILE}" \ --key-file "${ZITI_SERVER_FILE}" \ --server-file "${ZITI_SERVER_FILE}" \ - --dns "localhost,${ZITI_CTRL_ADVERTISED_ADDRESS}" \ - --ip "127.0.0.1,::1" \ + --dns "${_dns_sans_csv}" \ + --ip "${_ip_sans_csv}" \ --allow-overwrite >&3 # write to debug fd because this runs every startup + echo "DEBUG: issued server cert with DNS SANs '${_dns_sans_csv}' and IP SANs '${_ip_sans_csv}'" >&3 fi # client cert @@ -284,13 +305,9 @@ loadEnvFiles() { } promptCtrlAddress() { - if [[ -z "${ZITI_CTRL_ADVERTISED_ADDRESS:-}" || "${ZITI_CTRL_ADVERTISED_ADDRESS}" =~ ^[:0-9] ]]; then - if ! ZITI_CTRL_ADVERTISED_ADDRESS="$(prompt "Enter DNS name of the controller [required]: ")"; then - echo "ERROR: missing required DNS name ZITI_CTRL_ADVERTISED_ADDRESS in ${BOOT_ENV_FILE}" >&2 - return 1 - # if an IP address - elif [[ "${ZITI_CTRL_ADVERTISED_ADDRESS}" =~ ^[:0-9] ]]; then - echo "ERROR: ZITI_CTRL_ADVERTISED_ADDRESS must be a DNS name" >&2 + if [[ -z "${ZITI_CTRL_ADVERTISED_ADDRESS:-}" ]]; then + if ! ZITI_CTRL_ADVERTISED_ADDRESS="$(prompt "Enter DNS name or IP address of the controller [required]: ")"; then + echo "ERROR: missing required DNS name or IP address ZITI_CTRL_ADVERTISED_ADDRESS in ${BOOT_ENV_FILE}" >&2 return 1 else setAnswer "ZITI_CTRL_ADVERTISED_ADDRESS=${ZITI_CTRL_ADVERTISED_ADDRESS}" "${BOOT_ENV_FILE}" diff --git a/dist/dist-packages/linux/openziti-router/bootstrap.bash b/dist/dist-packages/linux/openziti-router/bootstrap.bash index e14546ba6..00660d90f 100755 --- a/dist/dist-packages/linux/openziti-router/bootstrap.bash +++ b/dist/dist-packages/linux/openziti-router/bootstrap.bash @@ -31,6 +31,16 @@ makeConfig() { ZITI_ROUTER_PORT \ ZITI_ROUTER_LISTENER_BIND_PORT="${ZITI_ROUTER_PORT}" + # if the address is an IP address then set an IP SAN, else DNS SAN + if [[ "${ZITI_ROUTER_ADVERTISED_ADDRESS}" =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)$|^::([0-9a-fA-F]{1,4}:){0,6}([0-9a-fA-F]{1,4}|:)$|^([0-9a-fA-F]{1,4}:){1,7}:$|^([0-9a-fA-F]{1,4}:){1,6}(:[0-9a-fA-F]{1,4}){1,6}$|^([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,7}$|^([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,8}$|^([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,9}$|^([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,10}$|^([0-9a-fA-F]{1,4}:){1,1}(:[0-9a-fA-F]{1,4}){1,11}$|^:((:[0-9a-fA-F]{1,4}){1,12}|:)$|^fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|^::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ]]; then + echo "DEBUG: ZITI_ROUTER_ADVERTISED_ADDRESS is an IP address, setting ZITI_ROUTER_IP_OVERRIDE" >&3 + export ZITI_ROUTER_IP_OVERRIDE="${ZITI_ROUTER_ADVERTISED_ADDRESS}" \ + ZITI_NETWORK_NAME="localhost" + unset ZITI_ROUTER_ADVERTISED_ADDRESS + else + export ZITI_NETWORK_NAME="${ZITI_ROUTER_ADVERTISED_ADDRESS}" + fi + if [[ ! -s "${_config_file}" || "${1:-}" == --force ]]; then # build config command local -a _command=("ziti create config router ${ZITI_ROUTER_TYPE}" \ @@ -52,12 +62,17 @@ makeConfig() { _command+=("${ZITI_BOOTSTRAP_CONFIG_ARGS}") fi + # if the advertised address is localhost and the private flag is not already + # set, then add it to avoid advertising unreachable link listeners + if [[ "${ZITI_ROUTER_ADVERTISED_ADDRESS:-}" == localhost && ! "${_command[@]}" =~ "--private" ]]; then + _command+=("--private") + fi + if [[ -s "${_config_file}" && "${1:-}" == --force ]]; then echo "INFO: recreating config file: ${_config_file}" mv --no-clobber "${_config_file}"{,".${ZITI_BOOTSTRAP_NOW}.old"} fi - exportZitiVars # export all ZITI_ vars to be used in bootstrap # shellcheck disable=SC2068 ${_command[@]}