diff --git a/.github/workflows/publish-docker-images.yml b/.github/workflows/publish-docker-images.yml index d2d29ac27..28688ce0f 100644 --- a/.github/workflows/publish-docker-images.yml +++ b/.github/workflows/publish-docker-images.yml @@ -116,19 +116,20 @@ jobs: if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then DOCKER_TAGS+=",${IMAGE_REPO}:latest" fi - echo "DEBUG: DOCKER_TAGS=${DOCKER_TAGS}" - echo DOCKER_TAGS="${DOCKER_TAGS}" >> $GITHUB_OUTPUT + echo DOCKER_TAGS="${DOCKER_TAGS}" | tee -a $GITHUB_OUTPUT - name: Build & Push Multi-Platform Router Container Image to Hub uses: docker/build-push-action@v3 with: builder: ${{ steps.buildx.outputs.name }} - context: ${{ github.workspace }}/dist/docker-images/ziti-router/ + context: ${{ github.workspace }}/ + file: ${{ github.workspace }}/dist/docker-images/ziti-router/Dockerfile platforms: linux/amd64,linux/arm64 tags: ${{ steps.tagprep_router.outputs.DOCKER_TAGS }} build-args: | ZITI_CLI_TAG=${{ env.ZITI_CLI_TAG }} ZITI_CLI_IMAGE=${{ env.ZITI_CLI_IMAGE }} + DOCKER_BUILD_DIR=./dist/docker-images/ziti-router push: true - name: Set Up Container Image Tags for Go Tunneler Container diff --git a/dist/cloudfront/get.openziti.io/routes.yml b/dist/cloudfront/get.openziti.io/routes.yml index b6e5a1d75..e893bb4e5 100644 --- a/dist/cloudfront/get.openziti.io/routes.yml +++ b/dist/cloudfront/get.openziti.io/routes.yml @@ -38,3 +38,7 @@ - get: /zdew/ raw: /openziti/desktop-edge-win/main/release-streams/ file: latest.json + +- get: /dist/ + raw: /openziti/ziti/{{GITHUB_SHA}}/dist/ + file: /docker-images/ziti-router/compose.yml diff --git a/dist/dist-packages/linux/nfpm-openziti-router.yaml b/dist/dist-packages/linux/nfpm-openziti-router.yaml new file mode 100644 index 000000000..bce61b2db --- /dev/null +++ b/dist/dist-packages/linux/nfpm-openziti-router.yaml @@ -0,0 +1,40 @@ +# nfpm configuration file +# +# check https://nfpm.goreleaser.com/configuration for detailed usage +# +name: openziti-router +arch: ${GOARCH} +platform: linux +version: ${ZITI_VERSION} +maintainer: ${ZITI_MAINTAINER} +description: > + Provides a system service for running an OpenZiti Router +vendor: ${ZITI_VENDOR} +homepage: ${ZITI_HOMEPAGE} +license: Apache-2.0 +# Contents to add to the package. +contents: + - dst: /lib/systemd/system/ + src: ./dist/dist-packages/linux/openziti-router/ziti-router.service + + - dst: /opt/openziti/etc/router + type: dir + file_info: + mode: 0755 + + - dst: /opt/openziti/etc/router/ + src: ./dist/dist-packages/linux/openziti-router/env + type: config|noreplace + + - dst: /opt/openziti/etc/router/ + src: ./dist/dist-packages/linux/openziti-router/bootstrap.bash + + - dst: /opt/openziti/etc/router/ + src: ./dist/dist-packages/linux/openziti-router/entrypoint.bash + +scripts: + postinstall: ./dist/dist-packages/linux/openziti-router/postinstall.bash + preremove: ./dist/dist-packages/linux/openziti-router/preremove.bash + +depends: + - openziti # ziti CLI diff --git a/dist/dist-packages/linux/openziti-router/bootstrap.bash b/dist/dist-packages/linux/openziti-router/bootstrap.bash new file mode 100755 index 000000000..2aa51bed9 --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/bootstrap.bash @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# +# bootstrap the OpenZiti Router with a config file and identity +# + +function makeConfig() { + # + # create config file + # + + if [[ ! -s "${ZITI_ROUTER_CONFIG_FILE}" || "${1:-}" == --force ]]; then + ziti create config router "${ZITI_ROUTER_TYPE}" \ + --tunnelerMode "${ZITI_ROUTER_MODE}" \ + --routerName "${ZITI_ROUTER_NAME}" \ + --output "${ZITI_ROUTER_CONFIG_FILE}" + fi + +} + +function enroll() { + + # shellcheck disable=SC1090 # find the identity file path + source <(ziti create config environment | grep ZITI_ROUTER) + + if [[ ! -s "${ZITI_ROUTER_IDENTITY_CERT}" || "${1:-}" == --force ]]; then + if [ -n "${ZITI_ENROLL_TOKEN:-}" ]; then + # shellcheck disable=SC2188 + ziti router enroll "${ZITI_ROUTER_CONFIG_FILE}" \ + --jwt <(echo "${ZITI_ENROLL_TOKEN}") + elif [ -s "/run/credentials/${UNIT_NAME:=ziti-router.service}/ZITI_ENROLL_TOKEN" ]; then + ziti router enroll "${ZITI_ROUTER_CONFIG_FILE}" \ + --jwt "/run/credentials/${UNIT_NAME}/ZITI_ENROLL_TOKEN" + else + echo "ERROR: use SetCredential or LoadCredential in"\ + " /lib/systemd/system/ziti-router.service or set env var ZITI_ENROLL_TOKEN" >&2 + fi + fi + +} + +function bootstrap() { + + if [ -n "${1:-}" ]; then + ZITI_ROUTER_CONFIG_FILE="${1}" + else + echo "ERROR: no config file path provided" >&2 + return 1 + fi + + # make config file unless it exists if true, set force to overwrite + if [ "${ZITI_BOOTSTRAP_CONFIG}" == true ]; then + makeConfig + elif [ "${ZITI_BOOTSTRAP_CONFIG}" == force ]; then + makeConfig --force + fi + + # enroll unless certificate exists, set "force" to overwrite key and cert (requires new enrollment token) + if [ "${ZITI_BOOTSTRAP_ENROLLMENT}" == true ]; then + enroll + elif [ "${ZITI_BOOTSTRAP_ENROLLMENT}" == force ]; then + enroll --force + fi +} + +# +# defaults +# + +# used by "ziti create config router" and "ziti create config environment" +: "${ZITI_ROUTER_ADVERTISED_ADDRESS:=${HOSTNAME:=$(hostname -f)}}" +: "${ZITI_ROUTER_NAME:=${HOSTNAME%%.*}}" +: "${ZITI_CTRL_ADVERTISED_PORT:=1280}" +export ZITI_ROUTER_NAME \ + ZITI_ROUTER_ADVERTISED_ADDRESS \ + ZITI_CTRL_ADVERTISED_PORT \ + ZITI_ROUTER_PORT \ + ZITI_ROUTER_LISTENER_BIND_PORT="${ZITI_ROUTER_PORT}" diff --git a/dist/dist-packages/linux/openziti-router/entrypoint.bash b/dist/dist-packages/linux/openziti-router/entrypoint.bash new file mode 100755 index 000000000..11dac254e --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/entrypoint.bash @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# +# this thin wrapper script for the OpenZiti Router uses variable assignments from the systemd env file +# + +set -o errexit +set -o nounset +set -o pipefail + +if ! (( $# )); then + # if no args, run the router with the default config file + set -- run config.yml +elif [[ "${1}" == run && -z "${2:-}" ]]; then + # if first arg is "run" and second arg is empty, run the router with the default config file + set -- run config.yml +fi + +# shellcheck disable=SC1090 # default path is assigned in env file +source "${ZITI_ROUTER_BOOTSTRAP_BASH:-/opt/openziti/etc/router/bootstrap.bash}" + +# if first arg is "run", bootstrap the router with the config file +if [ "${1}" == run ]; then + bootstrap "${2}" +fi + +# optionally renew certs at startup +if [ "${ZITI_AUTO_RENEW_CERTS:-}" == true ]; then + # shellcheck disable=SC2068 + set -- ${@} --extend +fi + +# shellcheck disable=SC2068 +exec ziti router ${@} diff --git a/dist/dist-packages/linux/openziti-router/env b/dist/dist-packages/linux/openziti-router/env new file mode 100644 index 000000000..896120c4b --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/env @@ -0,0 +1,39 @@ +# +# this is a systemd env file allowing simple assignments for ziti-controller.service environment and serves as an answer +# file for first run prompts and unattended installations; only variables that are consumed by the ziti binary are +# expected here to preserve the separation between the service unit and the binary +# + +# +# for "ziti create config router edge" commands in bootstrap.bash +# + +# address of the controller (required) +ZITI_CTRL_ADVERTISED_ADDRESS= +# tcp port of the controller (default: 1280) +ZITI_CTRL_ADVERTISED_PORT=1280 + +# for better security, leave this assignment empty and create a file readable only by root containing the +# token and set "LoadCredential=ZITI_ENROLL_TOKEN:/opt/openziti/etc/router/.token" in +# /lib/systemd/system/ziti-router.service +ZITI_ENROLL_TOKEN= + +# the router's address must be resolvable by other routers and edge identities (default: qualified hostname) +ZITI_ROUTER_ADVERTISED_ADDRESS= +# the advertised and listening port of the router (default: 3022) +ZITI_ROUTER_PORT=3022 + +# the interface address on which to listen (default: 0.0.0.0) +ZITI_ROUTER_BIND_ADDRESS="0.0.0.0" + +# where to listen for DNS requests in tproxy mode (default: udp://127.0.0.1:53) +ZITI_ROUTER_TPROXY_RESOLVER="udp://127.0.0.1:53" + +# set identity filenames (default: unqualified hostname) +# ZITI_ROUTER_NAME= + +# type of router (default: edge, options: edge, fabric) +ZITI_ROUTER_TYPE=edge +# the mode of the router (default: host) requires that the router is administratively created with flag +# --tunneler-enabled +ZITI_ROUTER_MODE=host diff --git a/dist/dist-packages/linux/openziti-router/postinstall.bash b/dist/dist-packages/linux/openziti-router/postinstall.bash new file mode 100755 index 000000000..cfb59d6b2 --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/postinstall.bash @@ -0,0 +1,215 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail +# set -o xtrace + +install() { + checkSystemdVersion $MINIMUM_SYSTEMD_VERSION + commonActions + +} + +upgrade() { + # Step 2(upgrade), do what you need + commonActions + +} + +commonActions() { + makeTokenFile + loadEnv + promptCtrlAdvertisedAddress + promptRouterAdvertisedAddress + promptEnrollToken + promptRouterMode + promptRouterPort +} + +checkSystemdVersion() { + # Step 2 (clean install), enable the service in the proper way for this platform + if ! command -V systemctl &>/dev/null; then + echo "ERROR: required command 'systemctl' is missing" >&2 + return 1 + else + systemd_version=$(systemctl --version | awk '/^systemd/ {print $2}') + fi + + if [ "${systemd_version}" -lt "$1" ]; then + printf "\033[31m systemd version %s is less then 232, aborting \033[0m\n" "${systemd_version}" + return 1 + fi +} + +makeTokenFile() { + # unless it exists, create an empty enrollment token file with restrictive permissions so the service can start with + # LoadCredential enabled + ZITI_ENROLL_TOKEN_FILE=/opt/openziti/etc/router/.token + if ! [ -s "${ZITI_ENROLL_TOKEN_FILE}" ]; then + umask 0177 + touch "${ZITI_ENROLL_TOKEN_FILE}" + fi +} + +prompt() { + # return true if interactive and response is not empty + if [[ "${DEBIAN_FRONTEND:-}" != "noninteractive" && -t 0 ]]; then + read -r -p "$1" response + if [ -n "${response:-}" ]; then + echo "${response}" + else + return 1 + fi + else + echo "ERROR: non-interactive, unable prompt '$1'" >&2 + return 1 + fi +} + +loadEnv() { + # shellcheck disable=SC1091 + source /opt/openziti/etc/router/env +} + +promptCtrlAdvertisedAddress() { + if [ -z "${ZITI_CTRL_ADVERTISED_ADDRESS:-}" ]; then + if ZITI_CTRL_ADVERTISED_ADDRESS="$(prompt 'Enter the advertised address for the controller: ')"; then + if [ -n "${ZITI_CTRL_ADVERTISED_ADDRESS:-}" ]; then + sed -Ei "s/^(ZITI_CTRL_ADVERTISED_ADDRESS)=.*/\1=${ZITI_CTRL_ADVERTISED_ADDRESS}/" /opt/openziti/etc/router/env + fi + else + echo "WARN: missing ZITI_CTRL_ADVERTISED_ADDRESS in /opt/openziti/etc/router/env" >&2 + fi + fi +} + +promptRouterAdvertisedAddress() { + if [ -z "${ZITI_ROUTER_ADVERTISED_ADDRESS:-}" ]; then + DEFAULT_ADDR="${HOSTNAME:=$(hostname -f)}}" + if ZITI_ROUTER_ADVERTISED_ADDRESS="$(prompt "Enter the advertised address for this router [$DEFAULT_ADDR]: " || echo "$DEFAULT_ADDR")"; then + sed -Ei "s/^(ZITI_ROUTER_ADVERTISED_ADDRESS)=.*/\1=${ZITI_ROUTER_ADVERTISED_ADDRESS}/" /opt/openziti/etc/router/env + fi + fi +} + +promptEnrollToken() { + # make ziti vars available in "ziti create config environment" + exportZitiVars + # shellcheck disable=SC1090 # compute the path to the identity file + source <(ZITI_HOME=/var/lib/ziti-router ziti create config environment) + # do nothing if identity file has stuff in it + if [ -s "${ZITI_ROUTER_IDENTITY_CERT}" ]; then + echo "INFO: enrolled identity exists in ${ZITI_ROUTER_IDENTITY_CERT}" + # prompt for enrollment token if interactive, unless already answered + else + ZITI_BOOTSTRAP_ENROLLMENT=$(awk -F= '/^Environment=ZITI_BOOTSTRAP_ENROLLMENT=/ {print $3}' /lib/systemd/system/ziti-router.service) + if ! [[ "${ZITI_BOOTSTRAP_ENROLLMENT:-}" == true ]]; then + echo "INFO: ZITI_BOOTSTRAP_ENROLLMENT is not true in /lib/systemd/system/ziti-router.service" >&2 + # do nothing if enrollment token is already defined in env file + elif [[ -n "${ZITI_ENROLL_TOKEN:-}" ]]; then + echo "INFO: ZITI_ENROLL_TOKEN is defined in /opt/openziti/etc/router/env and will be used to enroll during"\ + "next startup" + elif grep -qE "^LoadCredential=ZITI_ENROLL_TOKEN=${ZITI_ENROLL_TOKEN_FILE}" \ + /lib/systemd/system/ziti-router.service \ + && [[ -s "${ZITI_ENROLL_TOKEN_FILE}" ]]; then + echo "INFO: ZITI_ENROLL_TOKEN is defined in ${ZITI_ENROLL_TOKEN_FILE} and will be used to"\ + "enroll during next startup " + elif grep -qE '^SetCredential=ZITI_ENROLL_TOKEN:.+' /lib/systemd/system/ziti-router.service; then + echo "INFO: ZITI_ENROLL_TOKEN is defined in /lib/systemd/system/ziti-router.service and will be used to"\ + "enroll during next startup" + else + if ZITI_ENROLL_TOKEN=$(prompt "Enter the enrollment token: "); then + if [ -n "${ZITI_ENROLL_TOKEN:-}" ]; then + echo "$ZITI_ENROLL_TOKEN" >| /opt/openziti/etc/router/.token + fi + else + echo "WARN: missing ZITI_ENROLL_TOKEN; use LoadCredential or SetCredential in"\ + "/lib/systemd/system/ziti-router.service or set in /opt/openziti/etc/router/env" >&2 + fi + fi + fi +} + +promptRouterMode() { + # if undefined or default value in env file, prompt for router mode, preserving default if no answer + if [[ -z "${ZITI_ROUTER_MODE:-}" || "${ZITI_ROUTER_MODE}" == host ]]; then + if ZITI_ROUTER_MODE="$(prompt 'Enter the router mode (eg. host, tproxy, proxy) [host]: ' || echo 'host')"; then + sed -Ei "s/^(ZITI_ROUTER_MODE)=.*/\1=${ZITI_ROUTER_MODE}/" /opt/openziti/etc/router/env + fi + fi + if [[ "${ZITI_ROUTER_MODE}" == tproxy ]]; then + grantNetAdmin + fi +} + +grantNetAdmin() { + # grant ambient capabilities to the router process if not already granted + if ! grep -qE '^AmbientCapabilities=CAP_NET_ADMIN' /lib/systemd/system/ziti-router.service; then + # uncomment the line + sed -Ei 's/.*AmbientCapabilities=CAP_NET_ADMIN/AmbientCapabilities=CAP_NET_ADMIN/' /lib/systemd/system/ziti-router.service + fi + systemctl daemon-reload +} + +promptRouterPort() { + # if undefined or default value in env file, prompt for router port, preserving default if no answer + if [[ -z "${ZITI_ROUTER_PORT:-}" || "${ZITI_ROUTER_PORT}" == 3022 ]]; then + if ZITI_ROUTER_PORT="$(prompt 'Enter the router port [3022]: ' || echo '3022')"; then + sed -Ei "s/^(ZITI_ROUTER_PORT)=.*/\1=${ZITI_ROUTER_PORT}/" /opt/openziti/etc/router/env + fi + fi + if [[ "${ZITI_ROUTER_PORT}" -le 1024 ]]; then + grantNetBindService + fi +} + +grantNetBindService() { + # grant binding privileged low ports unless already granted + if ! grep -qE '^AmbientCapabilities=CAP_NET_BIND_SERVICE' /lib/systemd/system/ziti-router.service; then + # uncomment the line + sed -Ei 's/.*AmbientCapabilities=CAP_NET_BIND_SERVICE/AmbientCapabilities=CAP_NET_BIND_SERVICE/' /lib/systemd/system/ziti-router.service + fi + systemctl daemon-reload +} + +exportZitiVars() { + # make ziti vars available in forks like "ziti create config environment" + for line in $(set | grep -e "^ZITI_" | sort); do + # shellcheck disable=SC2013 + for var in $(awk -F= '{print $1}' <<< "$line"); do + # shellcheck disable=SC2163 + export "$var" + done + done +} + +MINIMUM_SYSTEMD_VERSION=232 + +# Step 1, check if this is a clean install or an upgrade +if (( $# )); then + if [[ $1 == 1 || ($1 == configure && -z ${2:-}) ]]; then + # deb passes $1=configure, rpm passes $1=1 + action=install + elif [[ $1 == 2 || ($1 == configure && -n ${2:-}) ]]; then + # deb passes $1=configure $2=, rpm passes $1=2 + action=upgrade + else + echo "ERROR: unexpected action '$1'" >&2 + exit 1 + fi +else + echo "ERROR: missing action" >&2 + exit 1 +fi + +case "$action" in + "install") + printf "\033[32m Post Install of an clean install\033[0m\n" + install + ;; + "upgrade") + printf "\033[32m Post Install of an upgrade\033[0m\n" + upgrade + ;; +esac diff --git a/dist/dist-packages/linux/openziti-router/preremove.bash b/dist/dist-packages/linux/openziti-router/preremove.bash new file mode 100755 index 000000000..e7d272675 --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/preremove.bash @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail +# set -o xtrace + +# if it exists and is still empty, clean up the enrollment token file that was created by postinstall.bash, allowing the +# package manager to remove the empty directory +ZITI_ENROLL_TOKEN_FILE=/opt/openziti/etc/router/.token +if [ -e "${ZITI_ENROLL_TOKEN_FILE}" ]; then + if ! [ -s "${ZITI_ENROLL_TOKEN_FILE}" ]; then + rm -f "${ZITI_ENROLL_TOKEN_FILE}" + fi +fi diff --git a/dist/dist-packages/linux/openziti-router/ziti-router.service b/dist/dist-packages/linux/openziti-router/ziti-router.service new file mode 100644 index 000000000..df9d943b4 --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/ziti-router.service @@ -0,0 +1,67 @@ +[Unit] +Description=OpenZiti Router +After=network-online.target + +[Service] + +# +## Required Configuration +# + +# you must provide an enrollment token to enroll the router at first startup in the .token file or by temporarily setting env var +# ZITI_ENROLL_TOKEN +# load enrollment token from a file readable only by root for better security; null the file after bootstrapping +LoadCredential=ZITI_ENROLL_TOKEN:/opt/openziti/etc/router/.token + +# or, temporarily set one-time enrollment token as literal string +# SetCredential=ZITI_ENROLL_TOKEN: + + +# +## extra permissions +# + +# allow binding low ports, e.g., 443/tcp +# AmbientCapabilities=CAP_NET_BIND_SERVICE +# allow adding IP routes and iptables rules; required when ZITI_ROUTER_MODE=tproxy +# AmbientCapabilities=CAP_NET_ADMIN + +# +## options +# + +# additional environment variables used by ziti commands in bootstrap.bash +EnvironmentFile=/opt/openziti/etc/router/env +# used by bootstrap.bash to look up /run/credentials/$UNIT_NAME/$CREDENTIAL_NAME +Environment=UNIT_NAME=ziti-router.service +# disable JSON logging +Environment=PFXLOG_NO_JSON=true +# create a config file unless it exists if "true", set "force" to overwrite +Environment=ZITI_BOOTSTRAP_CONFIG=true +# enroll unless already enrolled if "true", set "force" to overwrite key and cert (requires new enrollment token) +Environment=ZITI_BOOTSTRAP_ENROLLMENT=true +# set the bootstrap function definitions for entrypoint.bash to source +Environment=ZITI_ROUTER_BOOTSTRAP_BASH=/opt/openziti/etc/router/bootstrap.bash +# renew server and client certificates every startup +Environment=ZITI_AUTO_RENEW_CERTS=true + +# +## misc +# + +# manage the user and permissions for the service automatically +DynamicUser=yes +# relative to /var/lib +StateDirectory=ziti-router +# absolute path where service will be run +WorkingDirectory=/var/lib/ziti-router +# "ziti router run" is the main process managed by this service and replaces entrypoint.bash +Type=simple +UMask=0007 +Restart=always +RestartSec=3 +LimitNOFILE=65535 +ExecStart=/opt/openziti/etc/router/entrypoint.bash run config.yml + +[Install] +WantedBy=multi-user.target diff --git a/dist/docker-images/ziti-cli/Dockerfile b/dist/docker-images/ziti-cli/Dockerfile index 80da2adf2..5b193d763 100644 --- a/dist/docker-images/ziti-cli/Dockerfile +++ b/dist/docker-images/ziti-cli/Dockerfile @@ -31,7 +31,7 @@ LABEL name="openziti/ziti-cli" \ USER root ### install packages -RUN INSTALL_PKGS="python3.11 python3.11-pip tar bash-completion vim-minimal less shadow-utils jq findutils" && \ +RUN INSTALL_PKGS="python3.11 python3.11-pip tar bash-completion vim-minimal less shadow-utils jq findutils hostname" && \ microdnf -y update --setopt=install_weak_deps=0 --setopt=tsflags=nodocs && \ microdnf -y install --setopt=install_weak_deps=0 --setopt=tsflags=nodocs ${INSTALL_PKGS} @@ -57,9 +57,6 @@ RUN chmod 0755 /usr/local/bin/ziti RUN /usr/local/bin/ziti completion bash > /etc/bash_completion.d/ziti_cli -COPY ${DOCKER_BUILD_DIR}/entrypoint.sh / -RUN chmod +x /entrypoint.sh USER ziggy COPY ${DOCKER_BUILD_DIR}/bashrc /home/ziggy/.bashrc -ENTRYPOINT [ "/entrypoint.sh" ] -CMD [ "ziti" ] +ENTRYPOINT [ "ziti" ] diff --git a/dist/docker-images/ziti-cli/entrypoint.sh b/dist/docker-images/ziti-cli/entrypoint.sh deleted file mode 100644 index e6d33f04c..000000000 --- a/dist/docker-images/ziti-cli/entrypoint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -exec ziti "${@}" diff --git a/dist/docker-images/ziti-router/Dockerfile b/dist/docker-images/ziti-router/Dockerfile index 1a3a82134..1948782b2 100644 --- a/dist/docker-images/ziti-router/Dockerfile +++ b/dist/docker-images/ziti-router/Dockerfile @@ -3,19 +3,34 @@ ARG ZITI_CLI_IMAGE="docker.io/openziti/ziti-cli" # this builds docker.io/openziti/ziti-router FROM ${ZITI_CLI_IMAGE}:${ZITI_CLI_TAG} -# This build stage grabs artifacts that are copied into the final image. -# It uses the same base as the final image to maximize docker cache hits. - -### Required OpenShift Labels +### Required OpenShift Labels LABEL name="openziti/ziti-router" \ maintainer="developers@openziti.org" \ vendor="NetFoundry" \ summary="Run the OpenZiti Router" \ description="Run the OpenZiti Router" +# set up image as root, then drop privs to ziggy USER root -COPY ./entrypoint.sh / -RUN chmod +x /entrypoint.sh + +RUN INSTALL_PKGS="util-linux iptables" && \ + microdnf -y update --setopt=install_weak_deps=0 --setopt=tsflags=nodocs && \ + microdnf -y install --setopt=install_weak_deps=0 --setopt=tsflags=nodocs ${INSTALL_PKGS} + +# set a var for entrypoint.bash to find this script +ENV ZITI_ROUTER_BOOTSTRAP_BASH=/bootstrap.bash +ENV ZITI_ROUTER_TYPE=edge +ENV ZITI_ROUTER_ADVERTISED_PORT=3022 +ENV ZITI_BOOTSTRAP_CONFIG=true +ENV ZITI_BOOTSTRAP_ENROLLMENT=true +ENV PFXLOG_NO_JSON=true +COPY ./dist/dist-packages/linux/openziti-router/bootstrap.bash ${ZITI_ROUTER_BOOTSTRAP_BASH} +COPY ./dist/dist-packages/linux/openziti-router/entrypoint.bash / + +WORKDIR /ziti-router +RUN chown -R ziggy:ziggy /ziti-router + +# run as ziggy (2171:2171) by default, override run-as user with root when DOCKER_ROUTER_MODE=tproxy USER ziggy -ENTRYPOINT [ "/entrypoint.sh" ] -CMD [ "run" ] + +ENTRYPOINT [ "/entrypoint.bash" ] diff --git a/dist/docker-images/ziti-router/README.md b/dist/docker-images/ziti-router/README.md new file mode 100644 index 000000000..834c25942 --- /dev/null +++ b/dist/docker-images/ziti-router/README.md @@ -0,0 +1,92 @@ + +# Run Ziti Router in Docker + +You can use this container image to run Ziti Router in a Docker container. + +## Container Image + +The `openziti/ziti-router` image is thin and is based on the `openziti/ziti-cli` image, which only provides the `ziti` +CLI. The `ziti-router` image simply adds the `ziti router` subcommand to prefix the args you supply. + +## Docker Compose + +The included `compose.yml` demonstrates how to bootstrap a router and assumes you have the enrollment token and know the +address of the controller, i.e., the `ctrl.endpoint` of the control plane listener provided by the OpenZiti controller. + +### TPROXY Example + +This demonstrates how to use the `openziti/ziti-router` image to run a Ziti Router in a Docker container to configure +the network namespace of another container to use the Ziti network. + +```bash +# fetch the compose file for the ziti-router image +wget -O ./compose.router.yml https://get.openziti.io/dist/docker-images/ziti-router/compose.yml + +# run the quickstart network in the background to provide the ctrl.endpoint at quickstart:1280 +wget -O ./compose.quickstart.yml https://get.openziti.io/dock/all-in-one/compose.yml + +# patch the Compose project to use the quickstart network and provide a web server to test the hello service +cat <./compose.tproxy.yml +services: + # add a hello web server to use for a Ziti service target + hello: + image: openziti/hello-world + expose: + - 8000 + networks: + - quickstart + + # add a web client that waits for a healthy tproxy router + tproxy-demo-client: + image: busybox + network_mode: service:ziti-router + depends_on: + ziti-router: + condition: service_healthy + command: wget --output-document=- http://hello.internal/ + + # link the router to the quickstart network so it can reach the Ziti controller + ziti-router: + networks: + - quickstart +EOF +export COMPOSE_FILE=compose.router.yml:compose.quickstart.yml:compose.tproxy.yml + +# run the Ziti controller in the background with the all-in-one quickstart container +docker compose up quickstart-check + +# start the hello web server listening on 8000 +docker compose up hello --detach + +# log in to the Ziti controller +ziti edge login 127.0.0.1:1280 -y -u admin -p admin + +# create a Ziti service for the hello web server +ziti edge secure hello tcp:hello:8000 \ + --interceptAddress=hello.internal + +# grant the quickstart router permission to bind (provide) the hello service +ziti edge update identity quickstart-router \ + --role-attributes=hello.servers + +# create a second Ziti router to use as a tproxy client +ziti edge create edge-router "tproxy-router" \ + --jwt-output-file=./tproxy-router.jwt \ + --tunneler-enabled + +# grant the tproxy client permission to dial (consume) the hello service +ziti edge update identity tproxy-router \ + --role-attributes=hello.clients + +# simulate policies to check for authorization problems +ziti edge policy-advisor services -q + +# run the demo client which triggers the run of the tproxy router because it is a dependency +ZITI_ROUTER_JWT="$(<./tproxyRouter.jwt)" \ +ZITI_ROUTER_MODE=tproxy \ +ZITI_CTRL_ADVERTISED_ADDRESS=quickstart \ +ZITI_CTRL_ADVERTISED_PORT=1280 \ +ZITI_ROUTER_PORT=3023 \ +ZITI_ROUTER_ADVERTISED_ADDRESS=ziti-router \ + docker compose up tproxy-demo-client +``` diff --git a/dist/docker-images/ziti-router/compose.yml b/dist/docker-images/ziti-router/compose.yml new file mode 100644 index 000000000..af6ec096c --- /dev/null +++ b/dist/docker-images/ziti-router/compose.yml @@ -0,0 +1,66 @@ + +volumes: + ziti-router: + driver: local + +services: + chown-volume: + image: busybox + command: chown -R ${ZIGGY_UID:-2171} /mnt + volumes: + - ziti-router:/mnt + + ziti-router: + image: ${ZITI_ROUTER_IMAGE:-openziti/ziti-router} + depends_on: + chown-volume: + condition: service_completed_successfully + volumes: + - ziti-router:/mnt + working_dir: /mnt + # these declared vars pass through to container and should be assigned in an .env file or exported from parent env + # to ensure consistency throughout the compose project + environment: + # *** these are the important vars to set *** + ZITI_CTRL_ADVERTISED_ADDRESS: # domain name of the controller (required) + ZITI_CTRL_ADVERTISED_PORT: ${ZITI_CTRL_ADVERTISED_PORT:-1280} # exposed port of the controller + ZITI_ENROLL_TOKEN: # enrollment token for this router (required) + ZITI_ROUTER_ADVERTISED_ADDRESS: # domain name for this router (default: the container ID [hostname -f]) + ZITI_ROUTER_PORT: ${ZITI_ROUTER_PORT-3022} # exposed port for this router + ZITI_ROUTER_MODE: ${ZITI_ROUTER_MODE:-host} # host, tproxy, tproxy (tproxy requires additional config below) + # *** less relevant vars below *** + ZITI_ROUTER_TYPE: edge # edge, fabric + ZITI_ROUTER_NAME: ziti-router # ensure the computed filenames based on this var are consistent, not based on + # ephemeral container id + ZITI_BOOTSTRAP_CONFIG: true # make config file from env vars and defaults if "true," overwrite if "force" + ZITI_BOOTSTRAP_ENROLLMENT: true # enroll with controller if "true," overwrite if "force" + PFXLOG_NO_JSON: true + ZITI_TIME_FORMAT: utc + command: run config.yml + ports: + # ensure this port matches the value of ZITI_ROUTER_PORT in the container + - ${ZITI_INTERFACE:-0.0.0.0}:${ZITI_ROUTER_PORT:-3022}:${ZITI_ROUTER_PORT:-3022} + expose: + - ${ZITI_ROUTER_PORT:-3022} + restart: unless-stopped + healthcheck: + test: + - CMD + - ziti + - agent + - stats + interval: 3s + timeout: 3s + retries: 5 + start_period: 15s + + # Additional config for other containers using this router as a transparent intercepting proxy sidecar and default + # nameserver - dns, user, cap_add are required when ZITI_ROUTER_MODE=tproxy (see adjacent README.md for TPROXY + # example) + # + # dns: + # - 127.0.0.1 # this router's Ziti resolver + # - 1.1.1.1 # any recursive resolver + # user: root # required to create TPROXY routes in a container? + # cap_add: + # - NET_ADMIN # required to create TPROXY rules diff --git a/dist/docker-images/ziti-router/entrypoint.sh b/dist/docker-images/ziti-router/entrypoint.sh deleted file mode 100644 index 8bb695e7a..000000000 --- a/dist/docker-images/ziti-router/entrypoint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -exec ziti router "${@}" diff --git a/quickstart/docker/all-in-one/compose.yml b/quickstart/docker/all-in-one/compose.yml index bea573164..51cd31dda 100644 --- a/quickstart/docker/all-in-one/compose.yml +++ b/quickstart/docker/all-in-one/compose.yml @@ -39,12 +39,26 @@ services: ports: - ${ZITI_INTERFACE:-0.0.0.0}:${ZITI_CTRL_EDGE_ADVERTISED_PORT:-1280}:${ZITI_CTRL_EDGE_ADVERTISED_PORT:-1280} - ${ZITI_INTERFACE:-0.0.0.0}:${ZITI_ROUTER_PORT:-3022}:${ZITI_ROUTER_PORT:-3022} + expose: + - ${ZITI_CTRL_EDGE_ADVERTISED_PORT:-1280} + - ${ZITI_ROUTER_PORT:-3022} depends_on: - initialize: + quickstart-init: condition: service_completed_successfully + healthcheck: + test: + - CMD + - ziti + - agent + - stats + interval: 3s + timeout: 3s + retries: 5 + start_period: 30s + # this service is used to initialize the ziti_home volume by setting the owner to the UID of the user running the # quickstart container - initialize: + quickstart-init: image: busybox command: chown -Rc ${ZIGGY_UID:-1000} /home/ziggy user: root @@ -55,6 +69,14 @@ services: # directory, ZITI_HOME - ${ZITI_HOME:-ziti_home}:/home/ziggy + # add a health check for the quickstart network + quickstart-check: + image: busybox + command: echo "Ziti is cooking" + depends_on: + quickstart: + condition: service_healthy + # define a custom network so that we can also define a DNS alias for the quickstart container networks: quickstart: diff --git a/ziti/cmd/create/config_templates/router.yml b/ziti/cmd/create/config_templates/router.yml index c383e1c4f..1bcf7944a 100644 --- a/ziti/cmd/create/config_templates/router.yml +++ b/ziti/cmd/create/config_templates/router.yml @@ -40,8 +40,8 @@ link: {{ if or .Router.IsFabric (eq .Router.TunnelerMode "none") }}#{{ end }} - binding: tunnel {{ if or .Router.IsFabric (eq .Router.TunnelerMode "none") }}#{{ end }} options: {{ if or .Router.IsFabric (eq .Router.TunnelerMode "none") }}# mode: host #tproxy|host{{ else }} mode: {{ .Router.TunnelerMode }} #tproxy|host{{ end }} -{{ if and (not .Router.IsFabric) (eq .Router.TunnelerMode "tproxy") }} resolver: udp://{{ .Router.Edge.AdvertisedHost }}:53{{ end }} -{{ if and (not .Router.IsFabric) (eq .Router.TunnelerMode "tproxy") }} lanIf: {{ .Router.Edge.LanInterface }}{{ end }} +{{ if and (not .Router.IsFabric) (eq .Router.TunnelerMode "tproxy") }} resolver: {{ .Router.Edge.Resolver }}{{ end }} +{{ if and (not .Router.IsFabric) (eq .Router.TunnelerMode "tproxy") (.Router.Edge.LanInterface) }} lanIf: {{ .Router.Edge.LanInterface }}{{ end }} {{ if .Router.IsFabric -}} csr: country: US @@ -53,7 +53,7 @@ csr: dns: - localhost {{ if .Router.Edge.CsrSans }} - {{ .Router.Edge.CsrSans }}{{ end }} -{{ if ne .Router.Edge.CsrSans .Hostname }} - {{ .Hostname }}{{ end }} +{{ if ne .Router.Edge.CsrSans .HostnameOrNetworkName }} - {{ .HostnameOrNetworkName }}{{ end }} ip: - "127.0.0.1" {{ if .Router.Edge.IPOverride }} - "{{ .Router.Edge.IPOverride }}"{{ end }} @@ -69,7 +69,7 @@ edge: dns: - localhost {{ if .Router.Edge.CsrSans }} - {{ .Router.Edge.CsrSans }}{{ end }} -{{ if ne .Router.Edge.CsrSans .Hostname }} - {{ .Hostname }}{{ end }} +{{ if ne .Router.Edge.CsrSans .HostnameOrNetworkName }} - {{ .HostnameOrNetworkName }}{{ end }} ip: - "127.0.0.1" {{ if .Router.Edge.IPOverride }} - "{{ .Router.Edge.IPOverride }}"{{ end }} diff --git a/ziti/cmd/create/create_config.go b/ziti/cmd/create/create_config.go index ba4da861a..7b93d0d1d 100644 --- a/ziti/cmd/create/create_config.go +++ b/ziti/cmd/create/create_config.go @@ -52,7 +52,7 @@ type CreateConfigOptions struct { type ConfigTemplateValues struct { ZitiHome string - Hostname string + HostnameOrNetworkName string Controller ControllerTemplateValues Router RouterTemplateValues @@ -167,6 +167,7 @@ type EdgeRouterTemplateValues struct { IPOverride string AdvertisedHost string LanInterface string + Resolver string ListenerBindPort string CsrC string CsrST string @@ -230,7 +231,7 @@ func (options *CreateConfigOptions) addCreateFlags(cmd *cobra.Command) { func (data *ConfigTemplateValues) PopulateConfigValues() { // Get and add hostname to the params - data.Hostname = cmdHelper.HostnameOrNetworkName() + data.HostnameOrNetworkName = cmdHelper.HostnameOrNetworkName() // Get and add ziti home to the params zitiHome := cmdHelper.GetZitiHome() @@ -282,6 +283,7 @@ func (data *ConfigTemplateValues) PopulateConfigValues() { // ************* Router Values ************ data.Router.Edge.Port = cmdHelper.GetZitiEdgeRouterPort() data.Router.Edge.ListenerBindPort = cmdHelper.GetZitiEdgeRouterListenerBindPort() + data.Router.Edge.Resolver = cmdHelper.GetZitiEdgeRouterResolver() data.Router.Edge.CsrC = cmdHelper.GetZitiEdgeRouterC() data.Router.Edge.CsrST = cmdHelper.GetZitiEdgeRouterST() data.Router.Edge.CsrL = cmdHelper.GetZitiEdgeRouterL() diff --git a/ziti/cmd/create/create_config_environment.go b/ziti/cmd/create/create_config_environment.go index 833efd766..99e84d5ee 100644 --- a/ziti/cmd/create/create_config_environment.go +++ b/ziti/cmd/create/create_config_environment.go @@ -85,7 +85,7 @@ func NewCmdCreateConfigEnvironment() *cobra.Command { PreRun: func(cmd *cobra.Command, args []string) { data.PopulateConfigValues() // Set router identities - SetZitiRouterIdentity(&data.Router, validateRouterName("")) + SetZitiRouterIdentity(&data.Router, validateRouterName(os.Getenv(constants.ZitiEdgeRouterNameVarName))) // Set up other identity info SetControllerIdentity(&data.Controller) SetEdgeConfig(&data.Controller) @@ -93,6 +93,7 @@ func NewCmdCreateConfigEnvironment() *cobra.Command { environmentOptions.EnvVars = []EnvVar{ {constants.ZitiHomeVarName, constants.ZitiHomeVarDescription, data.ZitiHome}, + {constants.ZitiNetworkNameVarName, constants.ZitiNetworkNameVarDescription, data.HostnameOrNetworkName}, {constants.PkiCtrlCertVarName, constants.PkiCtrlCertVarDescription, data.Controller.Identity.Cert}, {constants.PkiCtrlServerCertVarName, constants.PkiCtrlServerCertVarDescription, data.Controller.Identity.ServerCert}, {constants.PkiCtrlKeyVarName, constants.PkiCtrlKeyVarDescription, data.Controller.Identity.Key}, @@ -126,6 +127,7 @@ func NewCmdCreateConfigEnvironment() *cobra.Command { {constants.ZitiRouterIdentityCAVarName, constants.ZitiRouterIdentityCAVarDescription, data.Router.IdentityCA}, {constants.ZitiEdgeRouterIPOverrideVarName, constants.ZitiEdgeRouterIPOverrideVarDescription, data.Router.Edge.IPOverride}, {constants.ZitiEdgeRouterAdvertisedAddressVarName, constants.ZitiEdgeRouterAdvertisedAddressVarDescription, data.Router.Edge.AdvertisedHost}, + {constants.ZitiEdgeRouterResolverVarName, constants.ZitiEdgeRouterResolverVarDescription, data.Router.Edge.Resolver}, {constants.ZitiEdgeRouterCsrCVarName, constants.ZitiEdgeRouterCsrCVarDescription, data.Router.Edge.CsrC}, {constants.ZitiEdgeRouterCsrSTVarName, constants.ZitiEdgeRouterCsrSTVarDescription, data.Router.Edge.CsrST}, {constants.ZitiEdgeRouterCsrLVarName, constants.ZitiEdgeRouterCsrLVarDescription, data.Router.Edge.CsrL}, @@ -174,6 +176,7 @@ func NewCmdCreateConfigEnvironment() *cobra.Command { "the config output.\n\nThe following environment variables can be set to override config values " + "(current value is displayed):\n") sb.WriteString(fmt.Sprintf("%-40s %-50s %s\n", constants.ZitiHomeVarName, constants.ZitiHomeVarDescription, data.ZitiHome)) + sb.WriteString(fmt.Sprintf("%-40s %-50s %s\n", constants.ZitiNetworkNameVarName, constants.ZitiNetworkNameVarDescription, data.HostnameOrNetworkName)) sb.WriteString(fmt.Sprintf("%-40s %-50s %s\n", constants.PkiCtrlCertVarName, constants.PkiCtrlCertVarDescription, data.Controller.Identity.Cert)) sb.WriteString(fmt.Sprintf("%-40s %-50s %s\n", constants.PkiCtrlServerCertVarName, constants.PkiCtrlServerCertVarDescription, data.Controller.Identity.ServerCert)) sb.WriteString(fmt.Sprintf("%-40s %-50s %s\n", constants.PkiCtrlKeyVarName, constants.PkiCtrlKeyVarDescription, data.Controller.Identity.Key)) @@ -205,6 +208,7 @@ func NewCmdCreateConfigEnvironment() *cobra.Command { sb.WriteString(fmt.Sprintf("%-40s %-50s %s\n", constants.ZitiRouterIdentityCAVarName, constants.ZitiRouterIdentityCAVarDescription, data.Router.IdentityCA)) sb.WriteString(fmt.Sprintf("%-40s %-50s %s\n", constants.ZitiEdgeRouterIPOverrideVarName, constants.ZitiEdgeRouterIPOverrideVarDescription, data.Router.Edge.IPOverride)) sb.WriteString(fmt.Sprintf("%-40s %-50s %s\n", constants.ZitiEdgeRouterAdvertisedAddressVarName, constants.ZitiEdgeRouterAdvertisedAddressVarDescription, data.Router.Edge.AdvertisedHost)) + sb.WriteString(fmt.Sprintf("%-40s %-50s %s\n", constants.ZitiEdgeRouterResolverVarName, constants.ZitiEdgeRouterResolverVarDescription, data.Router.Edge.Resolver)) sb.WriteString(fmt.Sprintf("%-40s %-50s %s\n", constants.ZitiEdgeRouterCsrCVarName, constants.ZitiEdgeRouterCsrCVarDescription, data.Router.Edge.CsrC)) sb.WriteString(fmt.Sprintf("%-40s %-50s %s\n", constants.ZitiEdgeRouterCsrSTVarName, constants.ZitiEdgeRouterCsrSTVarDescription, data.Router.Edge.CsrST)) sb.WriteString(fmt.Sprintf("%-40s %-50s %s\n", constants.ZitiEdgeRouterCsrLVarName, constants.ZitiEdgeRouterCsrLVarDescription, data.Router.Edge.CsrL)) diff --git a/ziti/cmd/create/create_config_router_edge.go b/ziti/cmd/create/create_config_router_edge.go index 06ad8a4d5..01cd4f84d 100644 --- a/ziti/cmd/create/create_config_router_edge.go +++ b/ziti/cmd/create/create_config_router_edge.go @@ -76,6 +76,7 @@ func NewCmdCreateConfigRouterEdge(routerOptions *CreateConfigRouterOptions, data data.Router.IsPrivate = routerOptions.IsPrivate data.Router.TunnelerMode = routerOptions.TunnelerMode data.Router.Edge.LanInterface = routerOptions.LanInterface + data.Router.Edge.Resolver = cmdhelper.GetZitiEdgeRouterResolver() }, Run: func(cmd *cobra.Command, args []string) { routerOptions.Cmd = cmd diff --git a/ziti/cmd/create/create_config_router_edge_test.go b/ziti/cmd/create/create_config_router_edge_test.go index ae642101c..68c5f05f1 100644 --- a/ziti/cmd/create/create_config_router_edge_test.go +++ b/ziti/cmd/create/create_config_router_edge_test.go @@ -238,7 +238,7 @@ func TestExecuteCreateConfigRouterEdgeHasNonBlankTemplateValues(t *testing.T) { _, data := createRouterConfig([]string{"edge", "--routerName", routerName}, routerOptions, nil) expectedNonEmptyStringFields := []string{".Router.Edge.ListenerBindPort", ".ZitiHome", ".Hostname", ".Router.Name", ".Router.IdentityCert", ".Router.IdentityServerCert", ".Router.IdentityKey", ".Router.IdentityCA", ".Router.Edge.Port"} - expectedNonEmptyStringValues := []*string{&data.Router.Edge.ListenerBindPort, &data.ZitiHome, &data.Hostname, &data.Router.Name, &data.Router.IdentityCert, &data.Router.IdentityServerCert, &data.Router.IdentityKey, &data.Router.IdentityCA, &data.Router.Edge.Port} + expectedNonEmptyStringValues := []*string{&data.Router.Edge.ListenerBindPort, &data.ZitiHome, &data.HostnameOrNetworkName, &data.Router.Name, &data.Router.IdentityCert, &data.Router.IdentityServerCert, &data.Router.IdentityKey, &data.Router.IdentityCA, &data.Router.Edge.Port} expectedNonEmptyIntFields := []string{".Router.Listener.OutQueueSize", ".Router.Wss.ReadBufferSize", ".Router.Wss.WriteBufferSize", ".Router.Forwarder.XgressDialQueueLength", ".Router.Forwarder.XgressDialWorkerCount", ".Router.Forwarder.LinkDialQueueLength", ".Router.Forwarder.LinkDialWorkerCount"} expectedNonEmptyIntValues := []*int{&data.Router.Listener.OutQueueSize, &data.Router.Wss.ReadBufferSize, &data.Router.Wss.WriteBufferSize, &data.Router.Forwarder.XgressDialQueueLength, &data.Router.Forwarder.XgressDialWorkerCount, &data.Router.Forwarder.LinkDialQueueLength, &data.Router.Forwarder.LinkDialWorkerCount} expectedNonEmptyTimeFields := []string{".Router.Listener.ConnectTimeout", "Router.Listener.GetSessionTimeout", ".Router.Wss.WriteTimeout", ".Router.Wss.ReadTimeout", ".Router.Wss.IdleTimeout", ".Router.Wss.PongTimeout", ".Router.Wss.PingInterval", ".Router.Wss.HandshakeTimeout"} diff --git a/ziti/cmd/create/create_config_router_fabric_test.go b/ziti/cmd/create/create_config_router_fabric_test.go index 3269d58b1..eaeddbff1 100644 --- a/ziti/cmd/create/create_config_router_fabric_test.go +++ b/ziti/cmd/create/create_config_router_fabric_test.go @@ -20,7 +20,7 @@ func TestExecuteCreateConfigRouterFabricHasNonBlankTemplateValues(t *testing.T) _, data := createRouterConfig([]string{"fabric", "--routerName", routerName}, routerOptions, nil) expectedNonEmptyStringFields := []string{".Router.Listener.BindPort", ".ZitiHome", ".Hostname", ".Router.Name", ".Router.IdentityCert", ".Router.IdentityServerCert", ".Router.IdentityKey", ".Router.IdentityCA", ".Router.Edge.Port"} - expectedNonEmptyStringValues := []*string{&data.Router.Edge.ListenerBindPort, &data.ZitiHome, &data.Hostname, &data.Router.Name, &data.Router.IdentityCert, &data.Router.IdentityServerCert, &data.Router.IdentityKey, &data.Router.IdentityCA, &data.Router.Edge.Port} + expectedNonEmptyStringValues := []*string{&data.Router.Edge.ListenerBindPort, &data.ZitiHome, &data.HostnameOrNetworkName, &data.Router.Name, &data.Router.IdentityCert, &data.Router.IdentityServerCert, &data.Router.IdentityKey, &data.Router.IdentityCA, &data.Router.Edge.Port} expectedNonEmptyIntFields := []string{".Router.Listener.OutQueueSize", ".Router.Wss.ReadBufferSize", ".Router.Wss.WriteBufferSize", ".Router.Forwarder.XgressDialQueueLength", ".Router.Forwarder.XgressDialWorkerCount", ".Router.Forwarder.LinkDialQueueLength", ".Router.Forwarder.LinkDialWorkerCount"} expectedNonEmptyIntValues := []*int{&data.Router.Listener.OutQueueSize, &data.Router.Wss.ReadBufferSize, &data.Router.Wss.WriteBufferSize, &data.Router.Forwarder.XgressDialQueueLength, &data.Router.Forwarder.XgressDialWorkerCount, &data.Router.Forwarder.LinkDialQueueLength, &data.Router.Forwarder.LinkDialWorkerCount} expectedNonEmptyTimeFields := []string{".Router.Listener.ConnectTimeout", "Router.Listener.GetSessionTimeout", ".Router.Wss.WriteTimeout", ".Router.Wss.ReadTimeout", ".Router.Wss.IdleTimeout", ".Router.Wss.PongTimeout", ".Router.Wss.PingInterval", ".Router.Wss.HandshakeTimeout"} diff --git a/ziti/cmd/create/create_config_test.go b/ziti/cmd/create/create_config_test.go index 1c69142a0..5b9b35271 100644 --- a/ziti/cmd/create/create_config_test.go +++ b/ziti/cmd/create/create_config_test.go @@ -45,6 +45,11 @@ func getZitiEnvironmentVariables() []string { "ZITI_CTRL_EDGE_BIND_ADDRESS", "ZITI_EDGE_IDENTITY_ENROLLMENT_DURATION", "ZITI_HOME", + "ZITI_NETWORK_NAME", + "ZITI_ROUTER_ENROLLMENT_DURATION", + "ZITI_ROUTER_ADVERTISED_ADDRESS", + "ZITI_ROUTER_LISTENER_BIND_PORT", + "ZITI_ROUTER_TPROXY_RESOLVER", "ZITI_PKI_ALT_SERVER_CERT", "ZITI_PKI_ALT_SERVER_KEY", "ZITI_PKI_CTRL_CA", diff --git a/ziti/cmd/helpers/env_helpers.go b/ziti/cmd/helpers/env_helpers.go index 424d48553..97078e25e 100644 --- a/ziti/cmd/helpers/env_helpers.go +++ b/ziti/cmd/helpers/env_helpers.go @@ -17,6 +17,7 @@ package helpers import ( + "github.com/openziti/ziti/router/xgress_edge_tunnel" edge "github.com/openziti/ziti/controller/config" "github.com/openziti/ziti/ziti/constants" "github.com/pkg/errors" @@ -202,6 +203,9 @@ func NormalizePath(input string) string { func GetRouterAdvertisedAddress() string { return getFromEnv(constants.ZitiEdgeRouterAdvertisedAddressVarName, HostnameOrNetworkName) } +func GetZitiEdgeRouterResolver() string { + return getFromEnv(constants.ZitiEdgeRouterResolverVarName, defaultValue(xgress_edge_tunnel.DefaultDnsResolver)) +} func GetRouterSans() string { return getFromEnv(constants.ZitiRouterCsrSansDnsVarName, GetRouterAdvertisedAddress) } diff --git a/ziti/constants/constants.go b/ziti/constants/constants.go index 2351aadf5..5ed057d9a 100644 --- a/ziti/constants/constants.go +++ b/ziti/constants/constants.go @@ -59,8 +59,11 @@ const ( // Env Var Constants const ( - ZitiHomeVarName = "ZITI_HOME" - ZitiHomeVarDescription = "Root home directory for Ziti-related files" + ZitiHomeVarName = "ZITI_HOME" + ZitiHomeVarDescription = "base dirname used to construct paths" + + ZitiNetworkNameVarName = "ZITI_NETWORK_NAME" + ZitiNetworkNameVarDescription = "base filename used to construct paths" PkiCtrlCertVarName = "ZITI_PKI_CTRL_CERT" PkiCtrlCertVarDescription = "Path to the controller's default identity client cert" @@ -124,6 +127,8 @@ const ( ZitiEdgeRouterAdvertisedAddressVarDescription = "The advertised address of the router" ZitiEdgeRouterListenerBindPortVarName = "ZITI_ROUTER_LISTENER_BIND_PORT" ZitiEdgeRouterListenerBindPortVarDescription = "The port a public router will advertise on" + ZitiEdgeRouterResolverVarName = "ZITI_ROUTER_TPROXY_RESOLVER" + ZitiEdgeRouterResolverVarDescription = "The bind URI to listen for DNS requests in tproxy mode" ZitiEdgeRouterCsrCVarName = "ZITI_ROUTER_CSR_C" ZitiEdgeRouterCsrCVarDescription = "The country (C) to use for router CSRs" ZitiEdgeRouterCsrSTVarName = "ZITI_ROUTER_CSR_ST"