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..15ca66635 --- /dev/null +++ b/dist/dist-packages/linux/nfpm-openziti-router.yaml @@ -0,0 +1,50 @@ +# 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 + +# Umask to be used on files without explicit mode set. (overridable) +umask: 0o002 + +# Package version within this release version. +release: 1 + +# Section. +section: default + +# Priority. +priority: optional + +depends: + - openziti # ziti CLI + +# 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 + 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..2ad3bf98e --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/bootstrap.bash @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# +# bootstrap the OpenZiti Router with a config file and identity +# + +set -o errexit +set -o nounset +set -o pipefail + +# use the ziti executable that the 'openziti' package installed +PATH=/opt/openziti/bin:$PATH + +# +# defaults +# + +# used by "ziti create config router" as DNS SAN and advertised address +: "${ZITI_ROUTER_ADVERTISED_ADDRESS:=$(hostname -f)}" + +function makeConfig() { + # + # create config file + # + + export ZITI_ROUTER_PORT="${ZITI_ROUTER_ADVERTISED_PORT}" + export ZITI_ROUTER_LISTENER_BIND_PORT="${ZITI_ROUTER_ADVERTISED_PORT}" + + if [[ ! -s "./${ZITI_ROUTER_CONFIG_FILE}" || "${1:-}" == --force ]]; then + ziti create config router "${ZITI_ROUTER_TYPE}" \ + --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 + ziti router enroll "./${ZITI_ROUTER_CONFIG_FILE}" \ + --jwt "<(<<< ${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 + +} + +# 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 \ No newline at end of file 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..5fc533ec7 --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/entrypoint.bash @@ -0,0 +1,15 @@ +#!/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 + +# shellcheck disable=SC1091 +source /opt/openziti/etc/router/bootstrap.bash + +# shellcheck disable=SC2068 # because we must +# shellcheck disable=SC2086 # word-split args +exec /opt/openziti/bin/ziti router run ${ZITI_ROUTER_CONFIG_FILE} ${ZITI_ROUTER_RUN_ARGS} $@ diff --git a/dist/dist-packages/linux/openziti-router/env b/dist/dist-packages/linux/openziti-router/env new file mode 100644 index 000000000..98f5b0d2e --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/env @@ -0,0 +1,45 @@ +# +# this is a systemd env file allowing simple assignments for ziti-controller.service environment +# + +ZITI_ROUTER_RUN_ARGS="--log-formatter text" +# ZITI_ROUTER_RUN_ARGS="--log-formatter text --verbose" + +# disable JSON logging +PFXLOG_NO_JSON=true + +# +# for "ziti create config router edge" commands in bootstrap.bash +# + +# set "ctrl.endpoint: {address}:{port}" in config.yml (required) +ZITI_CTRL_ADVERTISED_ADDRESS= +ZITI_CTRL_ADVERTISED_PORT= + +# name this router (default: hostname -s) +ZITI_ROUTER_NAME= +# the advertised address of the router is a domain name that can be resolved by all devices (default: hostname -f) +ZITI_ROUTER_ADVERTISED_ADDRESS= +# the advertised and listening port of the router (default: 80) +ZITI_ROUTER_ADVERTISED_PORT=80 +# the interface address on which to listen (default: 0.0.0.0) +ZITI_ROUTER_BIND_ADDRESS=0.0.0.0 + +# 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 + +# create a config file unless it exists if "true", set "force" to overwrite +ZITI_BOOTSTRAP_CONFIG=true +# relative to WorkingDirectory; e.g., /var/lib/ziti-router +ZITI_ROUTER_CONFIG_FILE=config.yml + +# enroll unless already enrolled if "true", set "force" to overwrite key and cert (requires new enrollment token) +ZITI_BOOTSTRAP_ENROLLMENT=true +# 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= \ No newline at end of file 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..43141101f --- /dev/null +++ b/dist/dist-packages/linux/openziti-router/ziti-router.service @@ -0,0 +1,38 @@ +[Unit] +Description=OpenZiti Router +After=network-online.target + +[Service] +# "ziti router run" is the main process managed by this service and replaces entrypoint.bash +Type=simple + +# manage the user and permissions for the service automatically +DynamicUser=yes + +# allow binding low ports, e.g., 443/tcp +AmbientCapabilities=CAP_NET_BIND_SERVICE + +# load enrollment token from a file readable only by root for better security +LoadCredential=ZITI_ENROLL_TOKEN:/opt/openziti/etc/router/.token +# or set one-time enrollment token as literal string +# SetCredential=ZITI_ENROLL_TOKEN: + +UMask=0007 +Restart=always +RestartSec=3 +LimitNOFILE=65535 + +# relative to /var/lib +StateDirectory=ziti-router + +# absolute path where service will be run +WorkingDirectory=/var/lib/ziti-router + +# used by bootstrap.bash to look up /run/credentials/$UNIT_NAME/$CREDENTIAL_NAME +Environment="UNIT_NAME=ziti-router.service" +EnvironmentFile=/opt/openziti/etc/router/env + +ExecStart=/opt/openziti/etc/router/entrypoint.bash + +[Install] +WantedBy=multi-user.target