diff --git a/CHANGELOG.md b/CHANGELOG.md index ef57414d..da06f3a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,14 @@ ## v0.4.35 +FEATURE: Closed permission mode for Docker and Linux private shares + CHANGE: add example in ./etc/caddy to set X-Real-IP header to public share client IP CHANGE: auto-update the ziti CLI version that is built in to the openziti/zrok container image +CHANGE: Docker examples set HOME to enable running CLI commands in the container + ## v0.4.34 FEATURE: Linux service support for all private share modes (contribution from Stefan Adelbert @stefanadelbert) diff --git a/docker/compose/zrok-private-access/compose.yml b/docker/compose/zrok-private-access/compose.yml index e3b4adbd..c57825e0 100644 --- a/docker/compose/zrok-private-access/compose.yml +++ b/docker/compose/zrok-private-access/compose.yml @@ -17,7 +17,7 @@ services: volumes: - zrok_env:/mnt environment: - STATE_DIRECTORY: /mnt + HOME: /mnt ZROK_ENABLE_TOKEN: ZROK_API_ENDPOINT: ZROK_ENVIRONMENT_NAME: docker-private-access diff --git a/docker/compose/zrok-private-share/compose.yml b/docker/compose/zrok-private-share/compose.yml index 8ed0828c..19a7b457 100644 --- a/docker/compose/zrok-private-share/compose.yml +++ b/docker/compose/zrok-private-share/compose.yml @@ -17,30 +17,38 @@ services: volumes: - zrok_env:/mnt environment: - STATE_DIRECTORY: /mnt + HOME: /mnt ZROK_ENABLE_TOKEN: ZROK_API_ENDPOINT: ZROK_ENVIRONMENT_NAME: docker-private-share zrok-share: image: ${ZROK_CONTAINER_IMAGE:-docker.io/openziti/zrok} - restart: no - entrypoint: - - bash - - -euxc - - | - echo "DEBUG: HOME=$${HOME}" - ls -lA /mnt/.zrok/ - exec zrok $${@} - command: -- share private --headless --backend-mode proxy ${ZROK_TARGET:-http://zrok-test:9090/} + restart: unless-stopped + entrypoint: zrok-share.bash depends_on: zrok-enable: condition: service_completed_successfully volumes: - zrok_env:/mnt environment: - HOME: /mnt - PFXLOG_NO_JSON: "true" + # internal configuration + HOME: /mnt # zrok homedir in container + + # most relevant options + ZROK_UNIQUE_NAME: # name is used to construct frontend domain name, e.g. "myapp" in "myapp.share.zrok.io" + ZROK_BACKEND_MODE: # web, caddy, drive, proxy + ZROK_TARGET: # backend target, is a path in container filesystem unless proxy mode + ZROK_INSECURE: # "--insecure" if proxy target has unverifiable TLS server certificate + ZROK_BASIC_AUTH: # username:password + ZROK_PERMISSION_MODE: # if "closed" allow only your account and additional accounts in ZROK_ACCESS_GRANTS + ZROK_ACCESS_GRANTS: # space-separated list of additional zrok account emails to grant access in closed permission mode + + # least relevant options + ZROK_VERBOSE: # "--verbose" + ZROK_SHARE_OPTS: # additional arguments to "zrok reserve private" command + ZROK_FRONTEND_MODE: reserved-private + PFXLOG_NO_JSON: "true" # suppress JSON logging format # demo server you can share with zrok zrok-test: diff --git a/docker/compose/zrok-public-reserved/compose.override.yml b/docker/compose/zrok-public-reserved/compose.override.yml index e922efe8..85d54f1b 100644 --- a/docker/compose/zrok-public-reserved/compose.override.yml +++ b/docker/compose/zrok-public-reserved/compose.override.yml @@ -15,4 +15,4 @@ services: ZROK_BACKEND_MODE: caddy ZROK_TARGET: /Caddyfile # internal configuration - STATE_DIRECTORY: /mnt # zrok homedir in container + HOME: /mnt # zrok homedir in container diff --git a/docker/compose/zrok-public-reserved/compose.yml b/docker/compose/zrok-public-reserved/compose.yml index f57a3a00..6a45746e 100644 --- a/docker/compose/zrok-public-reserved/compose.yml +++ b/docker/compose/zrok-public-reserved/compose.yml @@ -18,7 +18,7 @@ services: volumes: - zrok_env:/mnt environment: - STATE_DIRECTORY: /mnt + HOME: /mnt ZROK_ENABLE_TOKEN: ZROK_API_ENDPOINT: ZROK_ENVIRONMENT_NAME: @@ -35,7 +35,7 @@ services: - zrok_env:/mnt environment: # internal configuration - STATE_DIRECTORY: /mnt # zrok homedir in container + HOME: /mnt # zrok homedir in container # most relevant options ZROK_UNIQUE_NAME: # name is used to construct frontend domain name, e.g. "myapp" in "myapp.share.zrok.io" diff --git a/docs/guides/docker-share/docker_private_share_guide.md b/docs/guides/docker-share/docker_private_share_guide.md index 0fcf9515..d9005f5f 100644 --- a/docs/guides/docker-share/docker_private_share_guide.md +++ b/docs/guides/docker-share/docker_private_share_guide.md @@ -30,7 +30,7 @@ When the project runs it will: ## Before You Begin -To follow this guide you will need [Docker](https://docs.docker.com/get-docker/) and [the Docker Compose plugin](https://docs.docker.com/compose/install/) for running `docker compose` commands in your terminal. +To follow this guide you will need [Docker](https://docs.docker.com/get-docker/). If you have installed Docker Desktop on macOS or Windows then you are all set. @@ -99,6 +99,30 @@ Now that we have a private share we can access it with the zrok command or by ru 1. Now your zrok private access proxy is ready on http://127.0.0.1:9191. You can visit the demo web server in your browser. +## Closed Permission Mode + +Normally, you need only the share token to access a private share. You can further restrict access with "closed" permission mode. + +You must set the permission mode before you reserve the share. + +Only your own account can access the private share. + +```bash +ZROK_PERMISSION_MODE=closed +``` + +Grant access to additional zrok accounts. + +```bash +ZROK_ACCESS_GRANTS="bob@example.com alice@example.org" +``` + +You can adjust the access grants by running the CLI inside the `zrok-share` container. + +```bash +docker compose exec zrok-share zrok modify ${ZROK_UNIQUE_NAME} --remove-access-grant bob@example.com +``` + ## Going Further with Private Access 1. Try changing the demo web server used in the private share project. One alternative demo server is provided: `httpbin`. diff --git a/nfpm/zrok-enable.bash b/nfpm/zrok-enable.bash index e09dae29..7c8b49ba 100644 --- a/nfpm/zrok-enable.bash +++ b/nfpm/zrok-enable.bash @@ -25,10 +25,9 @@ fi if [[ -n "${STATE_DIRECTORY:-}" ]]; then export HOME="${STATE_DIRECTORY%:*}" else - echo "ERROR: STATE_DIRECTORY is undefined. This script must be run from systemd because it runs as a"\ - "dynamically-allocated user and exclusively manages the files in STATE_DIRECTORY" >&2 - exit 1 + echo "WARNING: STATE_DIRECTORY is undefined. Using HOME=${HOME}" >&2 fi +echo "DEBUG: zrok state directory is ${HOME}/.zrok" if [[ -s ~/.zrok/environment.json ]]; then echo "INFO: zrok environment is already enabled. Delete '$(realpath ~/.zrok/environment.json)' if you want to create a"\ diff --git a/nfpm/zrok-share.bash b/nfpm/zrok-share.bash index 6f1a1de0..d245b9fb 100644 --- a/nfpm/zrok-share.bash +++ b/nfpm/zrok-share.bash @@ -23,7 +23,12 @@ if ! command -v jq &>/dev/null; then fi # set HOME to the first colon-sep dir in STATE_DIRECTORY inherited from systemd (/var/lib/zrok-share) or docker (/mnt) -export HOME="${STATE_DIRECTORY%:*}" +if [[ -n "${STATE_DIRECTORY:-}" ]]; then + export HOME="${STATE_DIRECTORY%:*}" +else + echo "WARNING: STATE_DIRECTORY is undefined. Using HOME=${HOME}" >&2 +fi +echo "DEBUG: zrok state directory is ${HOME}/.zrok" : "${ZROK_SHARE_RESERVED:=true}" @@ -155,9 +160,27 @@ case "${ZROK_BACKEND_MODE}" in ;; esac -[[ "${ZROK_FRONTEND_MODE:-}" =~ ^reserved- && -n "${ZROK_UNIQUE_NAME:-}" ]] && { +if [[ "${ZROK_FRONTEND_MODE:-}" =~ ^reserved- && -n "${ZROK_UNIQUE_NAME:-}" ]]; then ZROK_CMD+=" --unique-name ${ZROK_UNIQUE_NAME}" -} +elif [[ -n "${ZROK_UNIQUE_NAME:-}" ]]; then + echo "WARNING: ZROK_UNIQUE_NAME='${ZROK_UNIQUE_NAME}' is ignored with ZROK_FRONTEND_MODE='${ZROK_FRONTEND_MODE}'" >&2 +fi + +if [[ "${ZROK_FRONTEND_MODE:-}" =~ -private$ && "${ZROK_PERMISSION_MODE:-}" == closed ]]; then + ZROK_CMD+=" --closed" + if [[ -n "${ZROK_ACCESS_GRANTS:-}" ]]; then + for ACCESS_GRANT in ${ZROK_ACCESS_GRANTS}; do + ZROK_CMD+=" --access-grant ${ACCESS_GRANT}" + done + else + echo "WARNING: ZROK_PERMISSION_MODE='${ZROK_PERMISSION_MODE}' and no additional ZROK_ACCESS_GRANTS; will be granted access" >&2 + exit 1 + fi +elif [[ "${ZROK_FRONTEND_MODE:-}" =~ -private$ && -n "${ZROK_PERMISSION_MODE:-}" && "${ZROK_PERMISSION_MODE}" != open ]]; then + echo "WARNING: ZROK_PERMISSION_MODE='${ZROK_PERMISSION_MODE}' is not a recognized value'" >&2 +elif [[ "${ZROK_FRONTEND_MODE:-}" =~ -public$ && -n "${ZROK_PERMISSION_MODE:-}" ]]; then + echo "WARNING: ZROK_PERMISSION_MODE='${ZROK_PERMISSION_MODE}' is ignored with ZROK_FRONTEND_MODE='${ZROK_FRONTEND_MODE}'" >&2 +fi ZROK_CMD+=" --backend-mode ${ZROK_BACKEND_MODE} ${ZROK_TARGET}" diff --git a/nfpm/zrok-share.env b/nfpm/zrok-share.env index 546fd26f..c54e13a2 100644 --- a/nfpm/zrok-share.env +++ b/nfpm/zrok-share.env @@ -107,6 +107,12 @@ ZROK_TARGET="" # e.g., http://127.0.0.1:3000 # you MAY set to change the frontend mode: reserved-public (default), reserved-private, temp-public, temp-private #ZROK_FRONTEND_MODE="reserved-public" +# you MAY restrict access to a private share allowing only your own zrok account +#ZROK_PERMISSION_MODE=closed +# if permission mode "closed" - space-separated list of additional zrok account emails to grant access with the share token +#ZROK_ACCESS_GRANTS="" + + # ## OPTIONS #