diff --git a/Makefile b/Makefile index d32804f..a65c856 100644 --- a/Makefile +++ b/Makefile @@ -163,7 +163,7 @@ build-playground: build-python: build-base component=python make build -build-kdav: +build-kdav: build-php docker pull composer:1.9 component=kdav make build-builder component=kdav make build diff --git a/docker-compose.yml b/docker-compose.yml index 3c68c08..b3bdc13 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -259,7 +259,7 @@ services: - kopano-net - web-net tmpfs: - - /run/apache2/ + - /run/php/ - /run/sessions/ - /tmp - /var/log/kdav/ diff --git a/kdav/Dockerfile b/kdav/Dockerfile index 993f90f..b111e85 100644 --- a/kdav/Dockerfile +++ b/kdav/Dockerfile @@ -2,11 +2,11 @@ ARG docker_repo=zokradonh FROM composer:1.9 as builder -RUN git clone --depth 1 https://stash.kopano.io/scm/kc/kdav.git /usr/share/kdav -WORKDIR /usr/share/kdav +RUN git clone --depth 1 https://stash.kopano.io/scm/kc/kdav.git /usr/share/kopano-kdav +WORKDIR /usr/share/kopano-kdav RUN composer install -FROM ${docker_repo}/kopano_base +FROM ${docker_repo}/kopano_php ARG ADDITIONAL_KOPANO_PACKAGES="" ARG DOWNLOAD_COMMUNITY_PACKAGES=1 @@ -30,18 +30,11 @@ LABEL maintainer=az@zok.xyz \ org.label-schema.schema-version="1.0" # install Kopano kDAV -# hadolint ignore=SC2215 -RUN --mount=type=secret,id=repocred,target=/etc/apt/auth.conf.d/kopano.conf \ - # apt key for this repo has already been installed in base - echo "deb [${KOPANO_REPOSITORY_FLAGS}] ${KOPANO_CORE_REPOSITORY_URL} ./" > /etc/apt/sources.list.d/kopano.list; \ +RUN \ set -x && \ apt-get update && apt-get install -y --no-install-recommends \ - apache2 \ - libapache2-mod-php7.3 \ - crudini \ - php7-mapi \ - php-xml \ php-mbstring \ + php-xml \ php-zip \ sqlite \ php-sqlite3 \ @@ -49,40 +42,21 @@ RUN --mount=type=secret,id=repocred,target=/etc/apt/auth.conf.d/kopano.conf \ ${ADDITIONAL_KOPANO_PACKAGES} \ && rm -rf /var/cache/apt /var/lib/apt/lists/* -COPY apache2-kopano-kdav.conf /etc/apache2/sites-available/kopano-kdav.conf - -# configure basics +# ensure right permissions of folders RUN \ - # configure apache - rm /etc/apache2/sites-enabled/* && \ - sed -e 's,^ErrorLog.*,ErrorLog "|/bin/cat",' -i /etc/apache2/apache2.conf && \ - sed -e "s,MaxSpareServers[^:].*,MaxSpareServers 5," -i /etc/apache2/mods-available/mpm_prefork.conf && \ - a2disconf other-vhosts-access-log && \ - a2ensite kopano-kdav && \ - echo "Listen 80" > /etc/apache2/ports.conf && \ - # configure mod_php - a2enmod rewrite && \ - crudini --set /etc/php/7.3/apache2/php.ini PHP upload_max_filesize 500M && \ - crudini --set /etc/php/7.3/apache2/php.ini PHP post_max_size 500M && \ - crudini --set /etc/php/7.3/apache2/php.ini PHP max_input_vars 1800 && \ - crudini --set /etc/php/7.3/apache2/php.ini Session session.save_path /run/sessions && \ - mkdir -p /var/lib/kopano/kdav && \ - chown www-data:www-data /var/lib/kopano/kdav && \ - mkdir -p /var/log/kdav && \ - chown www-data:www-data /var/log/kdav + mkdir -p /var/lib/kopano/kdav /var/log/kdav && \ + chown www-data:www-data /var/lib/kopano/kdav /var/log/kdav -COPY --from=builder /usr/share/kdav /usr/share/kdav +COPY --from=builder /usr/share/kopano-kdav /usr/share/kopano-kdav # tweaks to make the container read-only RUN \ - mv /usr/share/kdav/config.php /usr/share/kdav/config.php.dist && \ - ln -s /tmp/config.php /usr/share/kdav/config.php - -EXPOSE 80/tcp + mv /usr/share/kopano-kdav/config.php /usr/share/kopano-kdav/config.php.dist && \ + ln -s /tmp/config.php /usr/share/kopano-kdav/config.php +COPY kopano-kdav.conf /etc/php/7.3/fpm/pool.d/ COPY start.sh /kopano/start.sh - -ENV LANG en_US.UTF-8 +COPY kweb.cfg /etc/kweb.cfg ENTRYPOINT ["/usr/bin/dumb-init", "--"] CMD [ "/kopano/start.sh" ] diff --git a/kdav/apache2-kopano-kdav.conf b/kdav/apache2-kopano-kdav.conf deleted file mode 100644 index f0abea6..0000000 --- a/kdav/apache2-kopano-kdav.conf +++ /dev/null @@ -1,29 +0,0 @@ - - DocumentRoot /usr/share/kdav/ - - LogFormat "%{X-Forwarded-For}i %{%a %b %d %T %Y}t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy - ErrorLog "|/bin/cat" - CustomLog "|/bin/cat" proxy - - RewriteEngine On - # redirect well-known url http://sabre.io/dav/service-discovery/ - # (redirect may need to be done to the absolute external url) - RewriteRule ^/.well-known/carddav$ / [R] - RewriteRule ^/.well-known/caldav$ / [R] - # This makes every request go to server.php - RewriteRule ^/(.*)$ /server.php [L] - - # Output buffering needs to be off, to prevent high memory usage - php_flag output_buffering off - - # This is also to prevent high memory usage - php_flag always_populate_raw_post_data off - - # SabreDAV is not compatible with mbstring function overloading - php_flag mbstring.func_overload off - - # set higher limits by default - php_value memory_limit 256M - php_value max_execution_time 259200 - - diff --git a/kdav/kopano-kdav.conf b/kdav/kopano-kdav.conf new file mode 100644 index 0000000..5152404 --- /dev/null +++ b/kdav/kopano-kdav.conf @@ -0,0 +1,53 @@ +[kopano-kdav] +; Unix user/group of processes +; Note: The user is mandatory. If the group is not set, the default user's group +; will be used. +user = www-data +group = www-data + +; Set permissions for unix socket, if one is used. In Linux, read/write +; permissions must be set in order to allow connections from a web server. Many +; BSD-derived systems allow connections regardless of permissions. +; Default Values: user and group are set as the running user +; mode is set to 0660 +listen.owner = www-data +listen.group = www-data + +listen = /run/php/php-fpm-kopano-kdav.sock + +; Pool configuration intended for up to 500 users. +pm = dynamic +pm.max_children = 100 +pm.start_servers = 10 +pm.min_spare_servers = 10 +pm.max_spare_servers = 50 +pm.process_idle_timeout = 60s +pm.max_requests = 200 +pm.status_path = /status + +ping.path = /ping +ping.response = pong + +security.limit_extensions = .php + +php_flag[display_errors] = off + +php_admin_value[max_execution_time] = 60 +php_admin_value[post_max_size] = 20M +php_admin_value[upload_max_filesize] = 20M +php_admin_value[memory_limit] = 64M + +php_admin_flag[log_errors] = on + +; Redirect worker stdout and stderr into main error log. If not set, stdout and +; stderr will be redirected to /dev/null according to FastCGI specs. +; Note: on highloaded environement, this can cause some delay in the page +; process time (several ms). +; Default Value: no +catch_workers_output = no + +; KDAV specifics, to reduce memory usage. +php_flag[output_buffering] = off + +; SabreDAV is not compatible with mbstring function overloading. +php_flag[mbstring.func_overload] = off \ No newline at end of file diff --git a/kdav/kweb.cfg b/kdav/kweb.cfg new file mode 100644 index 0000000..d8c58d3 --- /dev/null +++ b/kdav/kweb.cfg @@ -0,0 +1,30 @@ +:9080 { + log stdout + errors stderr + + # healthcheck + status 200 /status + + rewrite /kdav/ { + to /kdav/server.php + } + + fastcgi2 /kdav/ /run/php/php-fpm-kopano-kdav.sock php { + without /kdav/ + root /usr/share/kopano-kdav + read_timeout 259200s + } + + redir 302 { + /.well-known/carddav /kdav/ + /.well-known/caldav /kdav/ + } + + status 403 { + /kdav/config.php + /kdav/lib + /kdav/mapi + /kdav/vendor + /kdav/version.php + } +} diff --git a/kdav/start.sh b/kdav/start.sh index 525be4b..1a12967 100755 --- a/kdav/start.sh +++ b/kdav/start.sh @@ -34,7 +34,7 @@ if [ "${AUTOCONFIGURE}" == true ]; then CONFIG_PHP=/tmp/config.php # copy latest config template. This should be the mount point for preexisting config files. - cp /usr/share/kdav/config.php.dist $CONFIG_PHP + cp /usr/share/kopano-kdav/config.php.dist $CONFIG_PHP if [ "$KCCONF_SERVERHOSTNAME" == "127.0.0.1" ]; then echo "kDAV is using the default: connection" @@ -60,11 +60,9 @@ touch /var/log/kdav/kdav.log chown www-data:www-data /var/log/kdav/kdav.log tail --pid=$$ -F --lines=0 -q /var/log/kdav/kdav.log & -echo "Starting Apache" -rm -f /run/apache2/apache2.pid set +u -# shellcheck disable=SC1091 -source /etc/apache2/envvars # cleaning up env variables unset "${!KCCONF_@}" -exec /usr/sbin/apache2 -DFOREGROUND +echo "Starting php-fpm" +php-fpm7.3 -F & +exec /usr/libexec/kopano/kwebd caddy -conf /etc/kweb.cfg diff --git a/php/Dockerfile b/php/Dockerfile index 9deb865..b5f801f 100644 --- a/php/Dockerfile +++ b/php/Dockerfile @@ -34,19 +34,17 @@ RUN --mount=type=secret,id=repocred,target=/etc/apt/auth.conf.d/kopano.conf \ # install set -x && \ apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + crudini \ kopano-kwebd \ php-fpm \ - crudini \ - ca-certificates \ + php7-mapi \ ${ADDITIONAL_KOPANO_PACKAGES} \ && rm -rf /var/cache/apt /var/lib/apt/lists # configure php-fpm RUN \ mkdir -p /run/php && chown www-data:www-data /run/php && \ - crudini --set /etc/php/7.3/fpm/php.ini PHP upload_max_filesize 500M && \ - crudini --set /etc/php/7.3/fpm/php.ini PHP post_max_size 500M && \ - crudini --set /etc/php/7.3/fpm/php.ini PHP max_input_vars 1800 && \ crudini --set /etc/php/7.3/fpm/php.ini Session session.save_path /run/sessions EXPOSE 9080/tcp diff --git a/php/php-fpm.conf b/php/php-fpm.conf index c2ef64e..686c002 100644 --- a/php/php-fpm.conf +++ b/php/php-fpm.conf @@ -1,2 +1,3 @@ +[global] ;output errors on stderr error_log = /proc/self/fd/2 diff --git a/web/kweb.cfg b/web/kweb.cfg index b4f1648..d83a6c9 100644 --- a/web/kweb.cfg +++ b/web/kweb.cfg @@ -202,7 +202,7 @@ } folderish /caldav - proxy /kdav/ {%KWEBD_DNS_KDAV%}:80 { + proxy /kdav/ {%KWEBD_DNS_KDAV%}:9080 { transparent keepalive 0 fail_timeout 10s diff --git a/webapp/Dockerfile b/webapp/Dockerfile index 90cfe44..fda654e 100644 --- a/webapp/Dockerfile +++ b/webapp/Dockerfile @@ -70,6 +70,7 @@ RUN mkdir -p /tmp/webapp/ && \ ln -s /tmp/webapp/"$(basename "$i")" "$i"; \ done +COPY kopano-webapp.conf /etc/php/7.3/fpm/pool.d/ COPY kweb.cfg /etc/kweb.cfg COPY start.sh /kopano/start.sh COPY goss* /goss/ diff --git a/webapp/kopano-webapp.conf b/webapp/kopano-webapp.conf new file mode 100644 index 0000000..adec64b --- /dev/null +++ b/webapp/kopano-webapp.conf @@ -0,0 +1,47 @@ +[kopano-webapp] +; Unix user/group of processes +; Note: The user is mandatory. If the group is not set, the default user's group +; will be used. +user = www-data +group = www-data + +; Set permissions for unix socket, if one is used. In Linux, read/write +; permissions must be set in order to allow connections from a web server. Many +; BSD-derived systems allow connections regardless of permissions. +; Default Values: user and group are set as the running user +; mode is set to 0660 +listen.owner = www-data +listen.group = www-data + +listen = /run/php/php-fpm-kopano-webapp.sock + +; Pool configuration intended for up to 500 users. +pm = dynamic +pm.max_children = 100 +pm.start_servers = 10 +pm.min_spare_servers = 10 +pm.max_spare_servers = 50 +pm.process_idle_timeout = 60s +pm.max_requests = 500 +pm.status_path = /status + +ping.path = /ping +ping.response = pong + +security.limit_extensions = .php + +php_flag[display_errors] = off + +php_admin_value[max_execution_time] = 60 +php_admin_value[post_max_size] = 20M +php_admin_value[upload_max_filesize] = 20M +php_admin_value[memory_limit] = 32M + +php_admin_flag[log_errors] = on + +; Redirect worker stdout and stderr into main error log. If not set, stdout and +; stderr will be redirected to /dev/null according to FastCGI specs. +; Note: on highloaded environement, this can cause some delay in the page +; process time (several ms). +; Default Value: no +catch_workers_output = no \ No newline at end of file diff --git a/webapp/kweb.cfg b/webapp/kweb.cfg index 04b1016..f6577f5 100644 --- a/webapp/kweb.cfg +++ b/webapp/kweb.cfg @@ -6,9 +6,26 @@ status 200 /status alias /webapp/ /usr/share/kopano-webapp/ - fastcgi2 /webapp/ /run/php/php7.3-fpm.sock php { + fastcgi2 /webapp/ /run/php/php-fpm-kopano-webapp.sock php { without /webapp/ root /usr/share/kopano-webapp/ } + + status 403 { + /webapp/config.php + /webapp/debug.php + /webapp/defaults.php + /webapp/init.php + /webapp/server + /webapp/version + + /webapp/plugins/forbidden + } + + rewrite /webapp/plugins/ { + regexp config.php + to /webapp/plugins/forbidden + } + folderish /webapp } diff --git a/zpush/Dockerfile b/zpush/Dockerfile index 3c1ef82..e21c76d 100644 --- a/zpush/Dockerfile +++ b/zpush/Dockerfile @@ -47,7 +47,6 @@ RUN --mount=type=secret,id=repocred,target=/etc/apt/auth.conf.d/kopano.conf \ # TODO remove php-mbstring once https://jira.z-hub.io/browse/ZP-1541 is resolved # TODO remove php-xml once https://jira.z-hub.io/projects/ZP/issues/ZP-1558 is resolved apt-get update && apt-get install -y --no-install-recommends \ - crudini \ php-mbstring \ php-xml \ z-push-autodiscover \ @@ -76,6 +75,7 @@ RUN \ mkdir -p /var/lib/z-push /var/log/z-push && \ chown www-data:www-data /var/lib/z-push /var/log/z-push +COPY kopano-z-push.conf /etc/php/7.3/fpm/pool.d/ COPY kweb.cfg /etc/kweb.cfg COPY start.sh /kopano/start.sh diff --git a/zpush/kopano-z-push.conf b/zpush/kopano-z-push.conf new file mode 100644 index 0000000..89ae376 --- /dev/null +++ b/zpush/kopano-z-push.conf @@ -0,0 +1,47 @@ +[kopano-z-push] +; Unix user/group of processes +; Note: The user is mandatory. If the group is not set, the default user's group +; will be used. +user = www-data +group = www-data + +; Set permissions for unix socket, if one is used. In Linux, read/write +; permissions must be set in order to allow connections from a web server. Many +; BSD-derived systems allow connections regardless of permissions. +; Default Values: user and group are set as the running user +; mode is set to 0660 +listen.owner = www-data +listen.group = www-data + +listen = /run/php/php-fpm-kopano-z-push.sock + +; Pool configuration intended for up to 500 users. +pm = dynamic +pm.max_children = 200 +pm.start_servers = 10 +pm.min_spare_servers = 10 +pm.max_spare_servers = 200 +pm.process_idle_timeout = 3540s +pm.max_requests = 200 +pm.status_path = /status + +ping.path = /ping +ping.response = pong + +security.limit_extensions = .php + +php_flag[display_errors] = off + +php_admin_value[max_execution_time] = 3540 +php_admin_value[post_max_size] = 20M +php_admin_value[upload_max_filesize] = 20M +php_admin_value[memory_limit] = 25M + +php_admin_flag[log_errors] = on + +; Redirect worker stdout and stderr into main error log. If not set, stdout and +; stderr will be redirected to /dev/null according to FastCGI specs. +; Note: on highloaded environement, this can cause some delay in the page +; process time (several ms). +; Default Value: no +catch_workers_output = no \ No newline at end of file diff --git a/zpush/kweb.cfg b/zpush/kweb.cfg index 330eb6e..c33cc10 100644 --- a/zpush/kweb.cfg +++ b/zpush/kweb.cfg @@ -5,23 +5,40 @@ # healthcheck status 200 /status - rewrite /Microsoft-Server-ActiveSync /Microsoft-Server-ActiveSync/index.php + rewrite /Microsoft-Server-ActiveSync { + regexp ^$ + to /z-push/index.php + } - fastcgi2 /Microsoft-Server-ActiveSync /run/php/php7.3-fpm.sock php { - without /Microsoft-Server-ActiveSync/ - root /usr/share/z-push/ + fastcgi2 /z-push/ /run/php/php-fpm-kopano-z-push.sock php { + without /z-push/ + root /usr/share/z-push read_timeout 3605s } - # Case insensitive path rewrite. - rewrite / { - regexp (?i)^/Autodiscover/Autodiscover.xml - to /Autodiscover/autodiscover.php + status 403 { + /z-push/autodiscover + /z-push/backend + /z-push/config.php + /z-push/include + /z-push/lib + /z-push/vendor + /z-push/version.php + /z-push/z-push-admin.php + /z-push/z-push-top.php } - fastcgi2 /Autodiscover/ /run/php/php7.3-fpm.sock php { - without /Autodiscover/ + rewrite / { + regexp (?i)^/Autodiscover/Autodiscover.xml + to /z-push-autodiscover/autodiscover.php + } + + fastcgi2 /z-push-autodiscover/ /run/php/php-fpm-kopano-z-push.sock php { + without /z-push-autodiscover/ root /usr/share/z-push/autodiscover } + status 403 { + /z-push-autodiscover/config.php + } }