mirror of
https://github.com/zokradonh/kopano-docker
synced 2025-06-07 07:56:12 +00:00
Adapt Konnect Container for Univention (#236)
* precreate meet keys in ssl, but do the actual action in konnect * generate all keys for meet within Konnect * incorporate explicit logging and settings set by ucs app * make konnect container more dynamic * set default oidc_issuer_identifier * print size of container * builder image is not required for security scanning * define entrypoint instead of using command * more cleanup of testing containers * give logs in case of error
This commit is contained in:
parent
f6074c65b1
commit
68c691acbd
8
Makefile
8
Makefile
@ -70,6 +70,7 @@ endif
|
|||||||
--build-arg ADDITIONAL_KOPANO_WEBAPP_PLUGINS=$(ADDITIONAL_KOPANO_WEBAPP_PLUGINS) \
|
--build-arg ADDITIONAL_KOPANO_WEBAPP_PLUGINS=$(ADDITIONAL_KOPANO_WEBAPP_PLUGINS) \
|
||||||
--cache-from $(docker_repo)/kopano_$(component):builder \
|
--cache-from $(docker_repo)/kopano_$(component):builder \
|
||||||
-t $(docker_repo)/kopano_$(component) $(component)/
|
-t $(docker_repo)/kopano_$(component) $(component)/
|
||||||
|
@echo "The image is $(shell docker image inspect $(docker_repo)/kopano_$(component) --format='{{.Size}}') bytes"
|
||||||
|
|
||||||
.PHONY: build-simple
|
.PHONY: build-simple
|
||||||
build-simple: component ?= ssl
|
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 VCS_REF=$(vcf_ref) \
|
||||||
--build-arg docker_repo=$(docker_repo) \
|
--build-arg docker_repo=$(docker_repo) \
|
||||||
-t $(docker_repo)/kopano_$(component) $(component)/
|
-t $(docker_repo)/kopano_$(component) $(component)/
|
||||||
|
@echo "The image is $(shell docker image inspect $(docker_repo)/kopano_$(component) --format='{{.Size}}') bytes"
|
||||||
|
|
||||||
|
|
||||||
.PHONY: build-builder
|
.PHONY: build-builder
|
||||||
build-builder: component ?= kdav
|
build-builder: component ?= kdav
|
||||||
@ -104,7 +107,6 @@ endif
|
|||||||
--build-arg ADDITIONAL_KOPANO_WEBAPP_PLUGINS="$(ADDITIONAL_KOPANO_WEBAPP_PLUGINS)" \
|
--build-arg ADDITIONAL_KOPANO_WEBAPP_PLUGINS="$(ADDITIONAL_KOPANO_WEBAPP_PLUGINS)" \
|
||||||
--cache-from $(docker_repo)/kopano_$(component):builder \
|
--cache-from $(docker_repo)/kopano_$(component):builder \
|
||||||
-t $(docker_repo)/kopano_$(component):builder $(component)/
|
-t $(docker_repo)/kopano_$(component):builder $(component)/
|
||||||
@echo $(docker_repo)/kopano_$(component):builder >> $(TAG_FILE)
|
|
||||||
|
|
||||||
build-base: ## Build new base image.
|
build-base: ## Build new base image.
|
||||||
docker pull debian:stretch
|
docker pull debian:stretch
|
||||||
@ -336,6 +338,7 @@ lint:
|
|||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
docker ps --filter name=kopano_test* -aq | xargs docker rm -f || true
|
||||||
docker-compose -f $(DOCKERCOMPOSE_FILE) down -v --remove-orphans || true
|
docker-compose -f $(DOCKERCOMPOSE_FILE) down -v --remove-orphans || true
|
||||||
|
|
||||||
.PHONY: test
|
.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) ps
|
||||||
docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml run test || \
|
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 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-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)
|
exit 1)
|
||||||
docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml stop 2>/dev/null
|
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
|
docker ps --filter name=kopano_test* -aq | xargs docker rm -f
|
||||||
|
@ -434,7 +434,6 @@ services:
|
|||||||
kopano_konnect:
|
kopano_konnect:
|
||||||
image: ${docker_repo:-zokradonh}/kopano_konnect:${KONNECT_VERSION:-latest}
|
image: ${docker_repo:-zokradonh}/kopano_konnect:${KONNECT_VERSION:-latest}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: wrapper.sh
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- kopano_ssl
|
- kopano_ssl
|
||||||
- web
|
- web
|
||||||
@ -444,6 +443,12 @@ services:
|
|||||||
- kopanosocket/:/run/kopano
|
- kopanosocket/:/run/kopano
|
||||||
environment:
|
environment:
|
||||||
- FQDN=${FQDN}
|
- 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_client_guests=yes
|
||||||
- allow_dynamic_client_registration=yes
|
- allow_dynamic_client_registration=yes
|
||||||
env_file:
|
env_file:
|
||||||
|
@ -4,8 +4,16 @@ FROM kopano/konnectd:${CODE_VERSION}
|
|||||||
ARG VCS_REF
|
ARG VCS_REF
|
||||||
ARG CODE_VERSION
|
ARG CODE_VERSION
|
||||||
|
|
||||||
ENV CODE_VERSION="${CODE_VERSION}"
|
ENV CODE_VERSION="${CODE_VERSION}" \
|
||||||
ENV KONNECT_BACKEND="kc"
|
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 \
|
LABEL maintainer=az@zok.xyz \
|
||||||
org.label-schema.name="Kopano Konnect container" \
|
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.version=$CODE_VERSION \
|
||||||
org.label-schema.schema-version="1.0"
|
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 \
|
RUN apk add --no-cache \
|
||||||
jq \
|
jq \
|
||||||
moreutils \
|
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 --chown=nobody:nogroup konnectd-identifier-registration.yaml konnectd-identifier-scopes.yaml /etc/kopano/
|
||||||
COPY wrapper.sh /usr/local/bin
|
COPY wrapper.sh /usr/local/bin
|
||||||
|
|
||||||
|
ENTRYPOINT ["wrapper.sh"]
|
||||||
|
@ -1,42 +1,61 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
set -e
|
set -eu
|
||||||
|
[ "$DEBUG" ] && set -x
|
||||||
|
|
||||||
# TODO since this file is only used here, also generate it here.
|
|
||||||
dockerize \
|
dockerize \
|
||||||
-wait file:///kopano/ssl/meet-kwmserver.pem \
|
-wait file://"${ecparam:?}" \
|
||||||
|
-wait file://"${eckey:?}" \
|
||||||
-timeout 360s
|
-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
|
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\": \"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
|
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
|
yq -y . $CONFIG_JSON | sponge /kopano/ssl/konnectd-identifier-registration.yaml
|
||||||
|
|
||||||
# shellcheck disable=SC2154
|
# source additional configuration from Konnect cfg (potentially overwrites env vars)
|
||||||
if [ -n "$log_level" ]; then
|
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"
|
set -- "$@" --log-level="$log_level"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# shellcheck disable=SC2154
|
if [ "${allow_client_guests:-}" = "yes" ]; then
|
||||||
if [ "$allow_client_guests" = "yes" ]; then
|
|
||||||
set -- "$@" "--allow-client-guests"
|
set -- "$@" "--allow-client-guests"
|
||||||
fi
|
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"
|
set -- "$@" "--allow-dynamic-client-registration"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dockerize \
|
dockerize \
|
||||||
-wait file:///kopano/ssl/konnectd-tokens-signing-key.pem \
|
-wait file://"${signing_private_key:?}" \
|
||||||
-wait file:///kopano/ssl/konnectd-encryption.key \
|
-wait file://"${encryption_secret_key:?}" \
|
||||||
-timeout 360s
|
-timeout 360s
|
||||||
exec konnectd serve \
|
exec konnectd serve \
|
||||||
--signing-private-key=/kopano/ssl/konnectd-tokens-signing-key.pem \
|
--signing-private-key="${signing_private_key:?}" \
|
||||||
--encryption-secret=/kopano/ssl/konnectd-encryption.key \
|
--encryption-secret="${encryption_secret_key:?}" \
|
||||||
--iss=https://"$FQDN" \
|
--identifier-registration-conf "${identifier_registration_conf:?}" \
|
||||||
--identifier-registration-conf /kopano/ssl/konnectd-identifier-registration.yaml \
|
--identifier-scopes-conf "${identifier_scopes_conf:?}" \
|
||||||
--identifier-scopes-conf /etc/kopano/konnectd-identifier-scopes.yaml \
|
|
||||||
"$@" "$KONNECT_BACKEND"
|
"$@" "$KONNECT_BACKEND"
|
||||||
|
@ -2,7 +2,7 @@ FROM alpine:3.9
|
|||||||
|
|
||||||
ARG VCS_REF
|
ARG VCS_REF
|
||||||
|
|
||||||
ENV CODE_VERSION=1.0.1 \
|
ENV CODE_VERSION=1.1.0 \
|
||||||
PKI_ROOT=/kopano/easypki \
|
PKI_ROOT=/kopano/easypki \
|
||||||
PKI_ORGANIZATION="Internal Kopano System" \
|
PKI_ORGANIZATION="Internal Kopano System" \
|
||||||
PKI_COUNTRY=DE
|
PKI_COUNTRY=DE
|
||||||
|
27
ssl/start.sh
27
ssl/start.sh
@ -7,6 +7,12 @@ set -euo pipefail
|
|||||||
# clean out any potential port numbers
|
# clean out any potential port numbers
|
||||||
FQDN=${FQDN%:*}
|
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
|
if [ ! -f /kopano/ssl/ca.pem ]; then
|
||||||
# https://github.com/google/easypki
|
# https://github.com/google/easypki
|
||||||
echo "Creating CA certificate..."
|
echo "Creating CA certificate..."
|
||||||
@ -53,27 +59,6 @@ if [ ! -f $secretkey ]; then
|
|||||||
mv $secretkey.tmp $secretkey
|
mv $secretkey.tmp $secretkey
|
||||||
fi
|
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:"
|
echo "SSL certs:"
|
||||||
ls -l /kopano/ssl/*.*
|
ls -l /kopano/ssl/*.*
|
||||||
|
|
||||||
|
@ -4,4 +4,3 @@ FROM ${docker_repo}/kopano_scheduler
|
|||||||
COPY test.sh /start.sh
|
COPY test.sh /start.sh
|
||||||
|
|
||||||
CMD ["/start.sh"]
|
CMD ["/start.sh"]
|
||||||
|
|
||||||
|
@ -21,6 +21,9 @@ dockerize \
|
|||||||
-wait tcp://kopano_zpush:80 \
|
-wait tcp://kopano_zpush:80 \
|
||||||
-timeout 120s
|
-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-cli --list-users
|
||||||
docker exec kopano_server kopano-admin -l
|
docker exec kopano_server kopano-admin -l
|
||||||
docker exec kopano_zpush z-push-admin -a list
|
docker exec kopano_zpush z-push-admin -a list
|
||||||
|
Loading…
x
Reference in New Issue
Block a user