mirror of
				https://github.com/zokradonh/kopano-docker
				synced 2025-10-31 02:17:47 +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