diff --git a/Makefile b/Makefile index b4a0b31..9c5d5f1 100644 --- a/Makefile +++ b/Makefile @@ -70,6 +70,7 @@ endif --build-arg ADDITIONAL_KOPANO_WEBAPP_PLUGINS=$(ADDITIONAL_KOPANO_WEBAPP_PLUGINS) \ --cache-from $(docker_repo)/kopano_$(component):builder \ -t $(docker_repo)/kopano_$(component) $(component)/ + @echo "The image is $(shell docker image inspect $(docker_repo)/kopano_$(component) --format='{{.Size}}') bytes" .PHONY: build-simple build-simple: component ?= ssl @@ -78,6 +79,8 @@ build-simple: ## Helper target to build a simplified image (no Kopano repo integ --build-arg VCS_REF=$(vcf_ref) \ --build-arg docker_repo=$(docker_repo) \ -t $(docker_repo)/kopano_$(component) $(component)/ + @echo "The image is $(shell docker image inspect $(docker_repo)/kopano_$(component) --format='{{.Size}}') bytes" + .PHONY: build-builder build-builder: component ?= kdav @@ -104,7 +107,6 @@ endif --build-arg ADDITIONAL_KOPANO_WEBAPP_PLUGINS="$(ADDITIONAL_KOPANO_WEBAPP_PLUGINS)" \ --cache-from $(docker_repo)/kopano_$(component):builder \ -t $(docker_repo)/kopano_$(component):builder $(component)/ - @echo $(docker_repo)/kopano_$(component):builder >> $(TAG_FILE) build-base: ## Build new base image. docker pull debian:stretch @@ -336,6 +338,7 @@ lint: .PHONY: clean clean: + docker ps --filter name=kopano_test* -aq | xargs docker rm -f || true docker-compose -f $(DOCKERCOMPOSE_FILE) down -v --remove-orphans || true .PHONY: test @@ -359,8 +362,9 @@ test-startup: ## Test if all containers start up docker-compose -f $(DOCKERCOMPOSE_FILE) ps docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml run test || \ (docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml ps; \ + docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml logs -t --tail=20; \ docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml stop; \ - docker rm kopano_test_run_1 2>/dev/null; \ + docker ps --filter name=kopano_test* -aq | xargs docker rm -f; \ exit 1) docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml stop 2>/dev/null docker ps --filter name=kopano_test* -aq | xargs docker rm -f diff --git a/docker-compose.yml b/docker-compose.yml index c1b6d0a..655e2de 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -434,7 +434,6 @@ services: kopano_konnect: image: ${docker_repo:-zokradonh}/kopano_konnect:${KONNECT_VERSION:-latest} restart: unless-stopped - command: wrapper.sh depends_on: - kopano_ssl - web @@ -444,6 +443,12 @@ services: - kopanosocket/:/run/kopano environment: - FQDN=${FQDN} + - ecparam=/kopano/ssl/ecparam.pem + - eckey=/kopano/ssl/meet-kwmserver.pem + - signing_private_key=/kopano/ssl/konnectd-tokens-signing-key.pem + - encryption_secret_key=/kopano/ssl/konnectd-encryption.key + - identifier_registration_conf=/kopano/ssl/konnectd-identifier-registration.yaml + - identifier_scopes_conf=/etc/kopano/konnectd-identifier-scopes.yaml - allow_client_guests=yes - allow_dynamic_client_registration=yes env_file: diff --git a/konnect/Dockerfile b/konnect/Dockerfile index 4ed80fe..29aa5b8 100644 --- a/konnect/Dockerfile +++ b/konnect/Dockerfile @@ -4,8 +4,16 @@ FROM kopano/konnectd:${CODE_VERSION} ARG VCS_REF ARG CODE_VERSION -ENV CODE_VERSION="${CODE_VERSION}" -ENV KONNECT_BACKEND="kc" +ENV CODE_VERSION="${CODE_VERSION}" \ + DEBUG="" \ + FQDN=localhost \ + KONNECT_BACKEND="kc" \ + ecparam=/etc/kopano/ecparam.pem \ + eckey=/etc/kopano/meet-kwmserver.pem \ + signing_private_key=/etc/kopano/konnectd-signing-private-key.pem \ + encryption_secret_key=/etc/kopano/konnectd-encryption-secret.key \ + identifier_registration_conf=/etc/kopano/konnectd-identifier-registration.yaml \ + identifier_scopes_conf=/etc/kopano/konnectd-identifier-scopes.yaml LABEL maintainer=az@zok.xyz \ org.label-schema.name="Kopano Konnect container" \ @@ -16,6 +24,8 @@ LABEL maintainer=az@zok.xyz \ org.label-schema.version=$CODE_VERSION \ org.label-schema.schema-version="1.0" +# TODO use docker multistage for pip install yq https://pythonspeed.com/articles/multi-stage-docker-python/ +# TODO moreutils (required for sponge) bloats the image quite a bit RUN apk add --no-cache \ jq \ moreutils \ @@ -30,3 +40,5 @@ RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSI COPY --chown=nobody:nogroup konnectd-identifier-registration.yaml konnectd-identifier-scopes.yaml /etc/kopano/ COPY wrapper.sh /usr/local/bin + +ENTRYPOINT ["wrapper.sh"] diff --git a/konnect/wrapper.sh b/konnect/wrapper.sh index 24cf5fa..feec739 100755 --- a/konnect/wrapper.sh +++ b/konnect/wrapper.sh @@ -1,42 +1,61 @@ #!/bin/sh -set -e +set -eu +[ "$DEBUG" ] && set -x -# TODO since this file is only used here, also generate it here. dockerize \ - -wait file:///kopano/ssl/meet-kwmserver.pem \ + -wait file://"${ecparam:?}" \ + -wait file://"${eckey:?}" \ -timeout 360s -cd /kopano/ssl/ -konnectd utils jwk-from-pem --use sig /kopano/ssl/meet-kwmserver.pem > /tmp/jwk-meet.json +# Key generation for Meet guest mode +if [ ! -s "$ecparam" ]; then + echo "Creating ec param key for Meet..." + openssl ecparam -name prime256v1 -genkey -noout -out "$ecparam" >/dev/null 2>&1 +fi + +if [ ! -s "$eckey" ]; then + echo "Creating ec key for Meet..." + openssl ec -in "$ecparam" -out "$eckey" >/dev/null 2>&1 +fi + +konnectd utils jwk-from-pem --use sig "$eckey" > /tmp/jwk-meet.json CONFIG_JSON=/etc/kopano/konnectd-identifier-registration.yaml #yq -y ".clients += [{\"id\": \"grapi-explorer.js\", \"name\": \"Grapi Explorer\", \"application_type\": \"web\", \"trusted\": true, \"insecure\": true, \"redirect_uris\": [\"http://$FQDNCLEANED:3000/\"]}]" $CONFIG_JSON | sponge $CONFIG_JSON yq -y ".clients += [{\"id\": \"kpop-https://$FQDN/meet/\", \"name\": \"Kopano Meet\", \"application_type\": \"web\", \"trusted\": true, \"redirect_uris\": [\"https://$FQDN/meet/\"], \"trusted_scopes\": [\"konnect/guestok\", \"kopano/kwm\"], \"jwks\": {\"keys\": [{\"kty\": $(jq .kty /tmp/jwk-meet.json), \"use\": $(jq .use /tmp/jwk-meet.json), \"crv\": $(jq .crv /tmp/jwk-meet.json), \"d\": $(jq .d /tmp/jwk-meet.json), \"kid\": $(jq .kid /tmp/jwk-meet.json), \"x\": $(jq .x /tmp/jwk-meet.json), \"y\": $(jq .y /tmp/jwk-meet.json)}]},\"request_object_signing_alg\": \"ES256\"}]" $CONFIG_JSON | sponge $CONFIG_JSON +# TODO this last bit can likely go yq -y . $CONFIG_JSON | sponge /kopano/ssl/konnectd-identifier-registration.yaml -# shellcheck disable=SC2154 -if [ -n "$log_level" ]; then +# source additional configuration from Konnect cfg (potentially overwrites env vars) +if [ -e /etc/kopano/konnectd.cfg ]; then + # shellcheck disable=SC1091 + . /etc/kopano/konnectd.cfg +fi + +oidc_issuer_identifier=${oidc_issuer_identifier:-https://$FQDN} +set -- "$@" --iss="$oidc_issuer_identifier" +echo "Entrypoint: Issuer url (--iss): $oidc_issuer_identifier" + +if [ -n "${log_level:-}" ]; then set -- "$@" --log-level="$log_level" fi -# shellcheck disable=SC2154 -if [ "$allow_client_guests" = "yes" ]; then +if [ "${allow_client_guests:-}" = "yes" ]; then set -- "$@" "--allow-client-guests" fi -# shellcheck disable=SC2154 -if [ "$allow_dynamic_client_registration" = "yes" ]; then +if [ "${allow_dynamic_client_registration:-}" = "yes" ]; then + echo "Entrypoint: Allowing dynamic client registration" set -- "$@" "--allow-dynamic-client-registration" fi dockerize \ - -wait file:///kopano/ssl/konnectd-tokens-signing-key.pem \ - -wait file:///kopano/ssl/konnectd-encryption.key \ + -wait file://"${signing_private_key:?}" \ + -wait file://"${encryption_secret_key:?}" \ -timeout 360s exec konnectd serve \ - --signing-private-key=/kopano/ssl/konnectd-tokens-signing-key.pem \ - --encryption-secret=/kopano/ssl/konnectd-encryption.key \ - --iss=https://"$FQDN" \ - --identifier-registration-conf /kopano/ssl/konnectd-identifier-registration.yaml \ - --identifier-scopes-conf /etc/kopano/konnectd-identifier-scopes.yaml \ + --signing-private-key="${signing_private_key:?}" \ + --encryption-secret="${encryption_secret_key:?}" \ + --identifier-registration-conf "${identifier_registration_conf:?}" \ + --identifier-scopes-conf "${identifier_scopes_conf:?}" \ "$@" "$KONNECT_BACKEND" diff --git a/ssl/Dockerfile b/ssl/Dockerfile index 1917ada..65da80a 100644 --- a/ssl/Dockerfile +++ b/ssl/Dockerfile @@ -2,7 +2,7 @@ FROM alpine:3.9 ARG VCS_REF -ENV CODE_VERSION=1.0.1 \ +ENV CODE_VERSION=1.1.0 \ PKI_ROOT=/kopano/easypki \ PKI_ORGANIZATION="Internal Kopano System" \ PKI_COUNTRY=DE diff --git a/ssl/start.sh b/ssl/start.sh index a5fc6e6..8c0891e 100755 --- a/ssl/start.sh +++ b/ssl/start.sh @@ -7,6 +7,12 @@ set -euo pipefail # clean out any potential port numbers FQDN=${FQDN%:*} +# create files so that konnect can write to it +touch /kopano/ssl/konnectd-identifier-registration.yaml /kopano/ssl/ecparam.pem /kopano/ssl/meet-kwmserver.pem +# chown to the numerical representation of nobody/nogroup +chown 65534:65534 /kopano/ssl/konnectd-identifier-registration.yaml /kopano/ssl/ecparam.pem /kopano/ssl/meet-kwmserver.pem + + if [ ! -f /kopano/ssl/ca.pem ]; then # https://github.com/google/easypki echo "Creating CA certificate..." @@ -53,27 +59,6 @@ if [ ! -f $secretkey ]; then mv $secretkey.tmp $secretkey fi -# Meet guest mode -ecparam="/kopano/ssl/ecparam.pem" -if [ ! -f $ecparam ]; then - echo "Creating ec param key for Meet..." - openssl ecparam -name prime256v1 -genkey -noout -out $ecparam.tmp >/dev/null 2>&1 - mv $ecparam.tmp $ecparam -fi - -# create registration.yml so that konnect can write to it -touch /kopano/ssl/konnectd-identifier-registration.yaml -# chown to the numerical representation of nobody/nogroup -chown 65534:65534 /kopano/ssl/konnectd-identifier-registration.yaml - -eckey="/kopano/ssl/meet-kwmserver.pem" -if [ ! -f $eckey ]; then - echo "Creating ec key for Meet..." - openssl ec -in $ecparam -out $eckey.tmp >/dev/null 2>&1 - chown 65534:65534 $eckey.tmp - mv $eckey.tmp $eckey -fi - echo "SSL certs:" ls -l /kopano/ssl/*.* diff --git a/tests/startup-test/Dockerfile b/tests/startup-test/Dockerfile index d3baf73..ef3185e 100644 --- a/tests/startup-test/Dockerfile +++ b/tests/startup-test/Dockerfile @@ -4,4 +4,3 @@ FROM ${docker_repo}/kopano_scheduler COPY test.sh /start.sh CMD ["/start.sh"] - diff --git a/tests/startup-test/test.sh b/tests/startup-test/test.sh index 77a8ae7..5cd10bb 100755 --- a/tests/startup-test/test.sh +++ b/tests/startup-test/test.sh @@ -21,6 +21,9 @@ dockerize \ -wait tcp://kopano_zpush:80 \ -timeout 120s +# make sure the public store exists +docker exec kopano_server kopano-storeadm -h default: -P || true + docker exec kopano_server kopano-cli --list-users docker exec kopano_server kopano-admin -l docker exec kopano_zpush z-push-admin -a list