diff --git a/.travis.yml b/.travis.yml index 1980e55..5af1575 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,8 @@ env: - DOCKER_COMPOSE_VERSION=1.23.2 - TRIVY_VERSION=0.1.1 - GOSS_VERSION=0.3.7 - - COMMANDER_VERSION=1.1.0 + - COMMANDER_VERSION=1.2.0 + services: - docker before_install: diff --git a/core/Dockerfile b/core/Dockerfile index bdc4c10..909409a 100644 --- a/core/Dockerfile +++ b/core/Dockerfile @@ -17,7 +17,11 @@ ENV \ KOPANO_CORE_VERSION=$KOPANO_CORE_VERSION \ KOPANO_REPOSITORY_FLAGS=$KOPANO_REPOSITORY_FLAGS \ RELEASE_KEY_DOWNLOAD=$RELEASE_KEY_DOWNLOAD \ - GRAPI_BACKEND="kopano" + GRAPI_BACKEND="kopano" \ + KCCONF_GRAPI_LDAP_URI="" \ + KCCONF_GRAPI_LDAP_BASEDN="" \ + KCCONF_GRAPI_LDAP_BINDDN="" \ + KCCONF_GRAPI_LDAP_BINDPW_FILE="" LABEL maintainer=az@zok.xyz \ org.label-schema.name="Kopano core container" \ diff --git a/core/start-service.sh b/core/start-service.sh index 4670563..1603341 100755 --- a/core/start-service.sh +++ b/core/start-service.sh @@ -87,11 +87,13 @@ grapi) # TODO there could be a case where multiple backends are desired case $GRAPI_BACKEND in ldap) - export LDAP_URI="${KCCONF_GRAPI_LDAP_URI}" - export LDAP_BASEDN="${KCCONF_GRAPI_LDAP_BASEDN}" - export LDAP_BINDDN="${KCCONF_GRAPI_LDAP_BINDDN}" - bindpw="$(cat "${KCCONF_GRAPI_LDAP_BINDPW_FILE}")" - export LDAP_BINDPW="${bindpw}" + [ -n "$KCCONF_GRAPI_LDAP_URI" ] && export LDAP_URI="${KCCONF_GRAPI_LDAP_URI}" + [ -n "$KCCONF_GRAPI_LDAP_BASEDN" ] && export LDAP_BASEDN="${KCCONF_GRAPI_LDAP_BASEDN}" + [ -n "$KCCONF_GRAPI_LDAP_BINDDN" ] && export LDAP_BINDDN="${KCCONF_GRAPI_LDAP_BINDDN}" + if [ -n "$KCCONF_GRAPI_LDAP_BINDPW_FILE" ]; then + bindpw="$(cat "${KCCONF_GRAPI_LDAP_BINDPW_FILE}")" + export LDAP_BINDPW="${bindpw}" + fi ;; esac # cleaning up env variables diff --git a/examples/meet-kopano.env b/examples/meet-kopano.env deleted file mode 100644 index 00f4ddf..0000000 --- a/examples/meet-kopano.env +++ /dev/null @@ -1,8 +0,0 @@ -FQDN=kopano.demo:2015 -FQDNCLEANED=kopano-demo -INSECURE=yes -TZ=Europe/Berlin -HTTP=10080 -HTTPS=10443 - -# TODO add reverse proxy example, make sure that requests go through reverse proxy diff --git a/examples/meet-kopano.yml b/examples/meet-kopano.yml deleted file mode 100644 index 9f72d33..0000000 --- a/examples/meet-kopano.yml +++ /dev/null @@ -1,113 +0,0 @@ -version: "3.5" - -services: - web: - image: ${docker_repo:-zokradonh}/kopano_web - container_name: web - restart: always - ports: - - "2015:2015" - - "${HTTP:-80}:80" - - "${HTTPS:-443}:443" - environment: - - EMAIL=${EMAIL:-off} - - FQDN=${FQDN?err} - command: wrapper.sh - cap_drop: - - ALL - cap_add: - - NET_BIND_SERVICE - - CHOWN - - SETGID - - SETUID - volumes: - - web:/.kweb - networks: - web-net: - aliases: - - ${FQDNCLEANED?err} - - kopano_ssl: - image: ${docker_repo:-zokradonh}/kopano_ssl - container_name: kopano_ssl - environment: - - FQDN=${FQDN} - - PKI_COUNTRY=NL - volumes: - - /etc/kopano/ssl/:/kopano/ssl - - kopano_grapi: - image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest} - container_name: kopano_grapi - volumes: - - /run/kopano:/run/kopano - environment: - - SERVICE_TO_START=grapi - - TZ=${TZ} - networks: - - kopano-net - - kopano_kapi: - image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest} - container_name: kopano_kapi - depends_on: - - kopano_grapi - volumes: - - /etc/kopano/ssl:/kopano/ssl - - /run/kopano:/run/kopano - environment: - - SERVICE_TO_START=kapid - - TZ=${TZ} - - KCCONF_KAPID_LOG_LEVEL=DEBUG - - KCCONF_KAPID_OIDC_ISSUER_IDENTIFIER=https://${FQDN} - - KCCONF_KAPID_INSECURE=${INSECURE} - networks: - - kopano-net - - web-net - - kopano_konnect: - image: ${docker_repo:-zokradonh}/kopano_konnect:${KONNECT_VERSION:-latest} - container_name: kopano_konnect - command: wrapper.sh - volumes: - - /etc/kopano/ssl:/kopano/ssl - - /run/kopano:/run/kopano - environment: - - FQDN=${FQDN} - networks: - - web-net - - kopano_kwmserver: - image: ${docker_repo:-zokradonh}/kopano_kwmserver:${KWM_VERSION:-latest} - container_name: kopano_kwmserver - command: wrapper.sh - environment: - - INSECURE=${INSECURE} - - oidc_issuer_identifier=https://${FQDN} - volumes: - - /etc/kopano/ssl:/kopano/ssl - networks: - - web-net - - kopano_meet: - image: ${docker_repo:-zokradonh}/kopano_meet:${MEET_VERSION:-latest} - container_name: kopano_meet - environment: - - SERVICE_TO_START=meet - - KCCONF_KWEBD_TLS=no - depends_on: - - kopano_kapi - - kopano_konnect - - kopano_kwmserver - - web - networks: - - web-net - -volumes: - web: - kopanossl: - -networks: - web-net: - kopano-net: - driver: bridge diff --git a/examples/meet/README.md b/examples/meet/README.md new file mode 100644 index 0000000..ba5ae3b --- /dev/null +++ b/examples/meet/README.md @@ -0,0 +1,12 @@ +# Running Kopano Meet without Kopano (with only the LDAP backend) + +The docker-compose.yml file in this directory can be used as a template to run Kopano Meet against a LDAP user directory. The file as it is starts a demo deployment of Meet including some pre created users to explore Kopano Meet. + +Check https://github.com/zokradonh/kopano-docker/blob/master/ldap_demo/README.md to learn more about the included demo users. + +## Instructions + +1. run `setup.sh` +2. check `.env` for any required customisation (port 443 already in use?) +3. run `docker-compose up` to start +4. navigate to https://your-domain to login to Kopano Meet \ No newline at end of file diff --git a/examples/meet/docker-compose.yml b/examples/meet/docker-compose.yml new file mode 100644 index 0000000..72d5f21 --- /dev/null +++ b/examples/meet/docker-compose.yml @@ -0,0 +1,173 @@ +version: "3.5" + +services: + web: + image: ${docker_repo:-kopano}/kopano_web:${KWEB_VERSION:-latest} + restart: unless-stopped + ports: + - "${CADDY:-2015}:2015" + - "${HTTP:-80}:80" + - "${HTTPS:-443}:443" + environment: + - EMAIL=${EMAIL:-off} + - FQDN=${FQDNCLEANED?err} + - DEFAULTREDIRECT=/meet + command: wrapper.sh + cap_drop: + - ALL + cap_add: + - NET_BIND_SERVICE + - CHOWN + - SETGID + - SETUID + volumes: + - web:/.kweb + networks: + web-net: + aliases: + - ${FQDNCLEANED?err} + + ldap: + image: ${docker_repo:-kopano}/${LDAP_CONTAINER:-kopano_ldap_demo}:${LDAP_VERSION:-latest} + restart: unless-stopped + container_name: ${COMPOSE_PROJECT_NAME}_ldap + environment: + - LDAP_ORGANISATION=${LDAP_ORGANISATION} + - LDAP_DOMAIN=${LDAP_DOMAIN} + - LDAP_BASE_DN=${LDAP_BASE_DN} + - LDAP_ADMIN_PASSWORD=${LDAP_ADMIN_PASSWORD} + - LDAP_READONLY_USER=true + - LDAP_READONLY_USER_PASSWORD=${LDAP_READONLY_USER_PASSWORD} + command: "--loglevel info --copy-service" + volumes: + - ldap:/var/lib/ldap + - slapd:/etc/ldap/slapd.d + networks: + - ldap-net + + kopano_ssl: + image: ${docker_repo:-kopano}/kopano_ssl:${SSL_VERSION:-latest} + environment: + - FQDN=${FQDN} + - PKI_COUNTRY=NL + volumes: + - kopanossl/:/kopano/ssl + + kopano_grapi: + image: ${docker_repo:-kopano}/kopano_core:${CORE_VERSION:-latest} + restart: unless-stopped + container_name: ${COMPOSE_PROJECT_NAME}_grapi + volumes: + - kopanosocket/:/run/kopano + environment: + - SERVICE_TO_START=grapi + - TZ=${TZ} + - ADDITIONAL_KOPANO_PACKAGES=python3-grapi.backend.ldap + - GRAPI_BACKEND=ldap + - LDAP_URI=${LDAP_SERVER} + - LDAP_BINDDN=${LDAP_BIND_DN} + - LDAP_BINDPW=${LDAP_BIND_PW} + - LDAP_BASEDN=${LDAP_SEARCH_BASE} + networks: + - kopano-net + - ldap-net + + kopano_kapi: + image: ${docker_repo:-kopano}/kopano_core:${CORE_VERSION:-latest} + restart: unless-stopped + container_name: ${COMPOSE_PROJECT_NAME}_kapi + depends_on: + - kopano_grapi + volumes: + - kopanodata/:/kopano/data + - kopanossl/:/kopano/ssl + - kopanosocket/:/run/kopano + environment: + - SERVICE_TO_START=kapi + - TZ=${TZ} + - KCCONF_KAPID_LOG_LEVEL=DEBUG + - KCCONF_KAPID_OIDC_ISSUER_IDENTIFIER=https://${FQDN} + - KCCONF_KAPID_INSECURE=${INSECURE} + networks: + - kopano-net + - web-net + + kopano_konnect: + image: ${docker_repo:-kopano}/kopano_konnect:${KONNECT_VERSION:-latest} + restart: unless-stopped + command: wrapper.sh + depends_on: + - kopano_ssl + - web + volumes: + - kopanossl/:/kopano/ssl + environment: + - FQDN=${FQDN} + - allow_client_guests=yes + - allow_dynamic_client_registration=yes + - KONNECT_BACKEND=ldap + - LDAP_URI=${LDAP_SERVER} + - LDAP_BINDDN=${LDAP_BIND_DN} + - LDAP_BINDPW=${LDAP_BIND_PW} + - LDAP_BASEDN=${LDAP_SEARCH_BASE} + - LDAP_SCOPE=sub + - LDAP_LOGIN_ATTRIBUTE=uid + - LDAP_EMAIL_ATTRIBUTE=mail + - LDAP_NAME_ATTRIBUTE=cn + - LDAP_UUID_ATTRIBUTE=uidNumber + - LDAP_UUID_ATTRIBUTE_TYPE=text + - LDAP_FILTER=(objectClass=organizationalPerson) + networks: + - kopano-net + - ldap-net + - web-net + + kopano_kwmserver: + image: ${docker_repo:-kopano}/kopano_kwmserver:${KWM_VERSION:-latest} + restart: unless-stopped + command: wrapper.sh + depends_on: + - kopano_kapi + - kopano_konnect + environment: + - INSECURE=${INSECURE} + - oidc_issuer_identifier=https://${FQDN} + - enable_guest_api=yes + - public_guest_access_regexp=^group/public/.* + - turn_service_credentials_user=${TURN_USER} + - turn_service_credentials_password=${TURN_PASSWORD} + volumes: + - kopanossl/:/kopano/ssl + networks: + - web-net + + kopano_meet: + image: ${docker_repo:-kopano}/kopano_meet:${MEET_VERSION:-latest} + restart: unless-stopped + environment: + - SERVICE_TO_START=meet + - KCCONF_MEET_disableFullGAB=false + - KCCONF_MEET_guests_enabled=true + - KCCONF_MEET_useIdentifiedUser=true + depends_on: + - kopano_kapi + - kopano_konnect + - kopano_kwmserver + - web + networks: + - web-net + +volumes: + web: + ldap: + slapd: + kopanodata: + kopanossl: + kopanosocket: + +networks: + web-net: + kopano-net: + driver: bridge + ldap-net: + driver: bridge diff --git a/examples/meet/env-example b/examples/meet/env-example new file mode 100644 index 0000000..49291d5 --- /dev/null +++ b/examples/meet/env-example @@ -0,0 +1,34 @@ +# please consult https://github.com/zokradonh/kopano-docker +# for possible configuration values and their impact + +LDAP_ORGANISATION="Kopano Demo" +LDAP_DOMAIN=kopano.demo +LDAP_BASE_DN=dc=kopano,dc=demo +LDAP_SERVER=ldap://ldap:389 +LDAP_ADMIN_PASSWORD=adminpassword +LDAP_READONLY_USER_PASSWORD=readonlypassword +LDAP_BIND_DN=cn=readonly,dc=kopano,dc=demo +LDAP_BIND_PW=readonlypassword +LDAP_SEARCH_BASE=dc=kopano,dc=demo + +TZ=Europe/Berlin + +# Defines how Kopano can be accessed from the outside world +FQDN=kopano.demo +FQDNCLEANED=kopano.demo +DEFAULTREDIRECT=/meet +EMAIL=self_signed +CADDY=2015 +HTTP=1080 +HTTPS=10443 + +# Settings for test environments +INSECURE=yes + +# Docker and docker-compose settings +# Docker Repository to push to/pull from +docker_repo=zokradonh +COMPOSE_PROJECT_NAME=kopano + +# Additional packages to install +ADDITIONAL_KOPANO_PACKAGES=python3-grapi.backend.ldap \ No newline at end of file diff --git a/examples/meet/setup.sh b/examples/meet/setup.sh new file mode 100755 index 0000000..86a2598 --- /dev/null +++ b/examples/meet/setup.sh @@ -0,0 +1,144 @@ +#!/bin/bash + +set -e + +fqdn_to_dn() { + printf 'dc=%s' "$1" | sed -E 's/\./,dc=/g' +} + +random_string() { + hexdump -n 16 -v -e '/1 "%02X"' /dev/urandom +} + +if [ ! -e ./.env ]; then + PRINT_SETUP_SUCCESS="" + + echo "Creating an .env file for you" + + value_default="Kopano Demo" + read -r -p "Name of the Organisation for LDAP [$value_default]: " new_value + LDAP_ORGANISATION=${new_value:-$value_default} + + value_default="kopano.demo" + read -r -p "FQDN to be used (for reverse proxy). + Hint: use port 2015 in case port 443 is already in use on the system. + [$value_default]: " new_value + FQDN=${new_value:-$value_default} + + value_default="self_signed" + read -r -p "Email address to use for Lets Encrypt. + Use 'self_signed' as your email to create self signed certificates. + Use 'off' if you want to run the service without tls encryption. Make sure to use an ssl-terminating reverse proxy in front in this case. + [$value_default]: " new_value + EMAIL=${new_value:-$value_default} + + # Let Kapi accept self signed certs if required + if [ "$EMAIL" == "self_signed" ]; then + INSECURE="yes" + else + INSECURE="no" + fi + + LDAP_BASE_DN=$(fqdn_to_dn "${FQDN%:*}") + value_default="$LDAP_BASE_DN" + read -r -p "Name of the BASE DN for LDAP [$value_default]: " new_value + LDAP_BASE_DN=${new_value:-$value_default} + + value_default="ldap://ldap:389" + read -r -p "LDAP server to be used (defaults to the bundled OpenLDAP) [$value_default]: " new_value + LDAP_SERVER=${new_value:-$value_default} + + if [ "$LDAP_SERVER" != "$value_default" ]; then + # We don't need an admin password in case we don't use the bundled LDAP server + LDAP_ADMIN_PASSWORD="" + + value_default="$LDAP_BASE_DN" + read -r -p "LDAP search base [$value_default]: " new_value + LDAP_SEARCH_BASE=${new_value:-$value_default} + + value_default="cn=readonly,$LDAP_BASE_DN" + read -r -p "LDAP bind user (needs read permissions) [$value_default]: " new_value + LDAP_BIND_DN=${new_value:-$value_default} + + value_default="kopano123" + read -r -p "LDAP bind password to be used [$value_default]: " new_value + LDAP_BIND_PW=${new_value:-$value_default} + + PRINT_SETUP_SUCCESS="$PRINT_SETUP_SUCCESS \n!! You have specified the LDAP server '${LDAP_SERVER}', don't forget to remove the bundled ldap and ldap-admin services in docker-compose.yml\n" + else + value_default="yes" + read -r -p "Use bundled LDAP with demo users? yes/no [$value_default]: " new_value + LDAP_CONTAINER_QUESTION=${new_value:-$value_default} + + if [ "${LDAP_CONTAINER_QUESTION}" == "yes" ]; then + LDAP_CONTAINER="kopano_ldap_demo" + else + LDAP_CONTAINER="kopano_ldap" + fi + + LDAP_ADMIN_PASSWORD=$(random_string) + LDAP_SEARCH_BASE="$LDAP_BASE_DN" + LDAP_BIND_DN="cn=readonly,$LDAP_BASE_DN" + LDAP_BIND_PW=$(random_string) + fi + + if [ -f /etc/timezone ]; then + value_default=$(cat /etc/timezone) + elif [ -f /etc/localtime ]; then + value_default=$(readlink /etc/localtime|sed -n 's|^.*zoneinfo/||p') + else + value_default="Europe/Berlin" + fi + + read -r -p "Timezone to be used [$value_default]: " new_value + TZ=${new_value:-$value_default} + + echo "${PRINT_SETUP_SUCCESS}" + + cat < "./.env" +# please consult https://github.com/kopano-dev/kopano-docker +# for possible configuration values and their impact + +# Access to the Kopano Turn service can be requested at https://portal.kopano.com/content/turn-server-access-request +TURN_USER= +TURN_PASSWORD= + +# Defines how Kopano can be accessed from the outside world +FQDN=$FQDN +FQDNCLEANED=${FQDN%:*} +DEFAULTREDIRECT=/webapp +EMAIL=$EMAIL +CADDY=2015 +HTTP=80 +HTTPS=443 + +TZ=$TZ + +LDAP_CONTAINER=$LDAP_CONTAINER +LDAP_ORGANISATION="$LDAP_ORGANISATION" +LDAP_DOMAIN=${FQDN%:*} +LDAP_BASE_DN=$LDAP_BASE_DN +LDAP_SERVER=$LDAP_SERVER +LDAP_ADMIN_PASSWORD=$LDAP_ADMIN_PASSWORD +LDAP_READONLY_USER_PASSWORD=$LDAP_BIND_PW +LDAP_BIND_DN=$LDAP_BIND_DN +LDAP_BIND_PW=$LDAP_BIND_PW +LDAP_SEARCH_BASE=$LDAP_SEARCH_BASE + +# Settings for test environments +INSECURE=$INSECURE + +# Docker and docker-compose settings +# Docker Repository to push to/pull from +docker_repo=kopano +COMPOSE_PROJECT_NAME=kopano + +# Additional packages to install +ADDITIONAL_KOPANO_PACKAGES=python3-grapi.backend.ldap + +EOF +else + echo ".env already exists with initial configuration" + echo "If you want to change the configuration, please edit .env directly" + exit 1 +fi diff --git a/konnect/Dockerfile b/konnect/Dockerfile index d2bc522..4ed80fe 100644 --- a/konnect/Dockerfile +++ b/konnect/Dockerfile @@ -5,6 +5,7 @@ ARG VCS_REF ARG CODE_VERSION ENV CODE_VERSION="${CODE_VERSION}" +ENV KONNECT_BACKEND="kc" LABEL maintainer=az@zok.xyz \ org.label-schema.name="Kopano Konnect container" \ diff --git a/konnect/wrapper.sh b/konnect/wrapper.sh index 9a9a181..24cf5fa 100755 --- a/konnect/wrapper.sh +++ b/konnect/wrapper.sh @@ -39,4 +39,4 @@ exec konnectd serve \ --iss=https://"$FQDN" \ --identifier-registration-conf /kopano/ssl/konnectd-identifier-registration.yaml \ --identifier-scopes-conf /etc/kopano/konnectd-identifier-scopes.yaml \ - "$@" kc + "$@" "$KONNECT_BACKEND" diff --git a/setup.sh b/setup.sh index 5f2ec29..e628f7f 100755 --- a/setup.sh +++ b/setup.sh @@ -92,7 +92,7 @@ if [ ! -e ./.env ]; then value_default="kopano.demo" read -r -p "FQDN to be used (for reverse proxy). - Tipp: use port 2015 in case port 443 is already in use on the system. + Hint: use port 2015 in case port 443 is already in use on the system. [$value_default]: " new_value FQDN=${new_value:-$value_default} @@ -110,7 +110,7 @@ if [ ! -e ./.env ]; then INSECURE="no" fi - LDAP_BASE_DN=$(fqdn_to_dn "$FQDN") + LDAP_BASE_DN=$(fqdn_to_dn "${FQDN%:*}") value_default="$LDAP_BASE_DN" read -r -p "Name of the BASE DN for LDAP [$value_default]: " new_value LDAP_BASE_DN=${new_value:-$value_default} @@ -164,7 +164,7 @@ if [ ! -e ./.env ]; then read -r -p "Timezone to be used [$value_default]: " new_value TZ=${new_value:-$value_default} - value_default="postmaster@$FQDN" + value_default="postmaster@${FQDN%:*}" read -r -p "E-Mail Address displayed for the 'postmaster' [$value_default]: " new_value POSTMASTER_ADDRESS=${new_value:-$value_default} @@ -256,7 +256,7 @@ KDAV_VERSION=$KDAV_VERSION LDAP_CONTAINER=$LDAP_CONTAINER LDAP_ORGANISATION="$LDAP_ORGANISATION" -LDAP_DOMAIN=$FQDN +LDAP_DOMAIN=${FQDN%:*} LDAP_BASE_DN=$LDAP_BASE_DN LDAP_SERVER=$LDAP_SERVER LDAP_ADMIN_PASSWORD=$LDAP_ADMIN_PASSWORD