From 9519d07ba2f82d94baeceaa8f1a79e154e3caefb Mon Sep 17 00:00:00 2001 From: Dimitri Huisman Date: Tue, 22 Mar 2022 09:04:56 +0000 Subject: [PATCH 1/7] Switch from RainLoop to SnappyMail --- .github/workflows/CI.yml | 12 +-- core/dovecot/Dockerfile | 2 +- core/nginx/Dockerfile | 2 +- core/nginx/conf/nginx.conf | 3 + core/postfix/Dockerfile | 2 +- core/rspamd/Dockerfile | 2 +- design/mailu-directory-structure.md | 16 ++-- docs/compose/.env | 2 +- optional/unbound/Dockerfile | 2 +- setup/flavors/compose/mailu.env | 2 +- .../templates/steps/compose/02_services.html | 6 +- setup/templates/steps/stack/02_services.html | 2 +- tests/build.yml | 6 +- tests/compose/core/mailu.env | 2 +- tests/compose/fetchmail/mailu.env | 2 +- tests/compose/filters/mailu.env | 2 +- tests/compose/roundcube/mailu.env | 2 +- .../docker-compose.yml | 2 +- .../{rainloop => snappymail}/mailu.env | 4 +- tests/compose/webdav/mailu.env | 2 +- webmails/rainloop/Dockerfile | 79 ---------------- webmails/rainloop/login/sso.php | 31 ------- webmails/snappymail/Dockerfile | 92 +++++++++++++++++++ webmails/{rainloop => snappymail}/config.py | 2 +- .../config/nginx-snappymail.conf} | 17 +++- .../config/php-snappymail.conf} | 6 +- .../defaults/application.ini | 8 +- .../defaults/default.ini | 0 .../{rainloop => snappymail}/defaults/php.ini | 0 .../login/include.php | 0 webmails/snappymail/login/sso.php | 17 ++++ webmails/{rainloop => snappymail}/start.py | 2 +- 32 files changed, 170 insertions(+), 159 deletions(-) rename tests/compose/{rainloop => snappymail}/docker-compose.yml (96%) rename tests/compose/{rainloop => snappymail}/mailu.env (97%) delete mode 100644 webmails/rainloop/Dockerfile delete mode 100644 webmails/rainloop/login/sso.php create mode 100644 webmails/snappymail/Dockerfile rename webmails/{rainloop => snappymail}/config.py (77%) rename webmails/{rainloop/config/nginx-rainloop.conf => snappymail/config/nginx-snappymail.conf} (70%) rename webmails/{rainloop/config/php-rainloop.conf => snappymail/config/php-snappymail.conf} (98%) rename webmails/{rainloop => snappymail}/defaults/application.ini (62%) rename webmails/{rainloop => snappymail}/defaults/default.ini (100%) rename webmails/{rainloop => snappymail}/defaults/php.ini (100%) rename webmails/{rainloop => snappymail}/login/include.php (100%) create mode 100644 webmails/snappymail/login/sso.php rename webmails/{rainloop => snappymail}/start.py (96%) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 8348503b..21bc70a6 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -110,7 +110,7 @@ jobs: DOCKER_ORG: ${{ env.DOCKER_ORG }} run: docker-compose -f tests/build.yml build - name: Save all docker images - run: docker save ${{ env.DOCKER_ORG }}/admin ${{ env.DOCKER_ORG }}/clamav ${{ env.DOCKER_ORG }}/docs ${{ env.DOCKER_ORG }}/dovecot ${{ env.DOCKER_ORG }}/fetchmail ${{ env.DOCKER_ORG }}/nginx ${{ env.DOCKER_ORG }}/none ${{ env.DOCKER_ORG }}/postfix ${{ env.DOCKER_ORG }}/radicale ${{ env.DOCKER_ORG }}/rainloop ${{ env.DOCKER_ORG }}/roundcube ${{ env.DOCKER_ORG }}/rspamd ${{ env.DOCKER_ORG }}/setup ${{ env.DOCKER_ORG }}/traefik-certdumper ${{ env.DOCKER_ORG }}/unbound -o /images/images.tar.gz + run: docker save ${{ env.DOCKER_ORG }}/admin ${{ env.DOCKER_ORG }}/clamav ${{ env.DOCKER_ORG }}/docs ${{ env.DOCKER_ORG }}/dovecot ${{ env.DOCKER_ORG }}/fetchmail ${{ env.DOCKER_ORG }}/nginx ${{ env.DOCKER_ORG }}/none ${{ env.DOCKER_ORG }}/postfix ${{ env.DOCKER_ORG }}/radicale ${{ env.DOCKER_ORG }}/snappymail ${{ env.DOCKER_ORG }}/roundcube ${{ env.DOCKER_ORG }}/rspamd ${{ env.DOCKER_ORG }}/setup ${{ env.DOCKER_ORG }}/traefik-certdumper ${{ env.DOCKER_ORG }}/unbound -o /images/images.tar.gz test-core: name: Perform core tests @@ -328,8 +328,8 @@ jobs: PINNED_MAILU_VERSION: ${{ env.PINNED_MAILU_VERSION }} DOCKER_ORG: ${{ env.DOCKER_ORG }} - test-rainloop: - name: Perform rainloop tests + test-snappymail: + name: Perform snappymail tests runs-on: ubuntu-latest needs: - build @@ -393,8 +393,8 @@ jobs: run: python3 -m pip install -r tests/requirements.txt - name: Copy all certs run: sudo -- sh -c 'mkdir -p /mailu && cp -r tests/certs /mailu && chmod 600 /mailu/certs/*' - - name: Test rainloop - run: python tests/compose/test.py rainloop 2 + - name: Test snappymail + run: python tests/compose/test.py snappymail 2 env: MAILU_VERSION: ${{ env.MAILU_VERSION }} PINNED_MAILU_VERSION: ${{ env.PINNED_MAILU_VERSION }} @@ -552,7 +552,7 @@ jobs: - test-core - test-fetchmail - test-filters - - test-rainloop + - test-snappymail - test-roundcube - test-webdav steps: diff --git a/core/dovecot/Dockerfile b/core/dovecot/Dockerfile index 4663d351..525db15d 100644 --- a/core/dovecot/Dockerfile +++ b/core/dovecot/Dockerfile @@ -11,7 +11,7 @@ RUN apk add --no-cache \ python3 py3-pip git bash py3-multidict py3-yarl tzdata \ && pip3 install --upgrade pip -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube +# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube RUN pip3 install socrate==0.2.0 # Shared layer between dovecot and postfix diff --git a/core/nginx/Dockerfile b/core/nginx/Dockerfile index 434f72eb..6dcf2987 100644 --- a/core/nginx/Dockerfile +++ b/core/nginx/Dockerfile @@ -11,7 +11,7 @@ RUN apk add --no-cache \ python3 py3-pip git bash py3-multidict \ && pip3 install --upgrade pip -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube +# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube RUN pip3 install socrate==0.2.0 # Image specific layers under this line diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index b9bb20b7..d3600668 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -190,6 +190,9 @@ http { {% endif %} {% if ADMIN == 'true' %} location {{ WEB_ADMIN }} { + {% if WEB_ADMIN != '/' %} + rewrite ^({{ WEB_ADMIN }})$ $1/ permanent; + {% endif %} include /etc/nginx/proxy.conf; proxy_pass http://$admin; expires $expires; diff --git a/core/postfix/Dockerfile b/core/postfix/Dockerfile index 6f2519db..6d910f16 100644 --- a/core/postfix/Dockerfile +++ b/core/postfix/Dockerfile @@ -12,7 +12,7 @@ RUN apk add --no-cache \ python3 py3-pip git bash py3-multidict py3-yarl tzdata \ && pip3 install --upgrade pip -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube +# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube RUN pip3 install socrate==0.2.0 # Shared layer between dovecot and postfix diff --git a/core/rspamd/Dockerfile b/core/rspamd/Dockerfile index 412d69db..7b89aed0 100644 --- a/core/rspamd/Dockerfile +++ b/core/rspamd/Dockerfile @@ -10,7 +10,7 @@ RUN apk add --no-cache \ python3 py3-pip git bash py3-multidict tzdata \ && pip3 install --upgrade pip -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube +# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube RUN pip3 install socrate==0.2.0 # Image specific layers under this line diff --git a/design/mailu-directory-structure.md b/design/mailu-directory-structure.md index ad75eeaa..5d62c85d 100644 --- a/design/mailu-directory-structure.md +++ b/design/mailu-directory-structure.md @@ -39,16 +39,16 @@ Postfix configuration overrides. RSpamD configuration overrides. -#### Rainloop +#### Snappymail - Old path: `/mailu/webmail/_data_/_default_/storage` (part of `/mailu/webmail` mountpoint, shared with Roundcube) -- New path: `/mailu/config/rainloop` +- New path: `/mailu/config/snappymail` User specific configs. The remaining files under the old `/mailu/webmail` don't need to be persistent. Except for `AddressBook.sqlite`, see `/mailu/data`. #### Roundcube -- Old path: `/mailu/webmail/gpg` (part of `/mailu/webmail` mountpoint, shared with Rainloop) +- Old path: `/mailu/webmail/gpg` (part of `/mailu/webmail` mountpoint, shared with Snappymail) - New path: `/mailu/config/roundcube/gpg` User configured GPG keys. @@ -108,10 +108,10 @@ This move is needed in order to be able to mount the directory without exposing Storage of Bayes and Fuzzy learning SQLite databases and caches. As future optimization we should look into moving all this into Redis. -#### Rainloop +#### SnappyMail - Old path: `/mailu/webmail/_data_/_default_/AddressBook.sqlite` (part of `/mailu/webmail` mountpoint, shared with Roundcube) -- New path: `/mailu/data/rainloop/AddressBook.sqlite` (mount on `rainloop` directory) +- New path: `/mailu/data/snappymail/AddressBook.sqlite` (mount on `snappymail` directory) Addressbook SQLite file. For future replicated deployments this might better be configured to use an external DB. @@ -119,7 +119,7 @@ For this modification, the `AddressBook.sqlite` will need to be moved to a diffe #### Roundcube -- Old path: `/mailu/webmail/roundcube.db` (part of `/mailu/webmail` mountpoint, shared with Rainloop) +- Old path: `/mailu/webmail/roundcube.db` (part of `/mailu/webmail` mountpoint, shared with SnappyMail) - New path: `/mailu/data/roundcube/roundcube.db` (mount on `roundcube` directory) User settings SQLite database file for roundcube. For future replicated deployments this might better be configured to use an external DB. @@ -163,7 +163,7 @@ The final layout of the Mailu filesystem will look like: ├── config │   ├── dovecot │   ├── postfix -│   ├── rainloop +│   ├── snappymail │   ├── redis │   ├── roundcube │   │   └── gpg @@ -173,7 +173,7 @@ The final layout of the Mailu filesystem will look like: │   └── dkim ├── data │   ├── admin -│   ├── rainloop +│   ├── snappymail │   ├── roundcube │   └── rspamd ├── local diff --git a/docs/compose/.env b/docs/compose/.env index 4df73080..fa952270 100644 --- a/docs/compose/.env +++ b/docs/compose/.env @@ -50,7 +50,7 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=false -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL=none # Dav server implementation (value: radicale, none) diff --git a/optional/unbound/Dockerfile b/optional/unbound/Dockerfile index 21ba9571..6a24459e 100644 --- a/optional/unbound/Dockerfile +++ b/optional/unbound/Dockerfile @@ -11,7 +11,7 @@ RUN apk add --no-cache \ python3 py3-pip git bash py3-multidict tzdata \ && pip3 install --upgrade pip -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube +# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube RUN pip3 install socrate==0.2.0 # Image specific layers under this line diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index ed7ecfdd..1d98c528 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -49,7 +49,7 @@ DISABLE_STATISTICS={{ disable_statistics or 'False' }} # Expose the admin interface (value: true, false) ADMIN={{ admin_enabled or 'false' }} -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL={{ webmail_type }} # Dav server implementation (value: radicale, none) diff --git a/setup/templates/steps/compose/02_services.html b/setup/templates/steps/compose/02_services.html index 5118c304..a801f807 100644 --- a/setup/templates/steps/compose/02_services.html +++ b/setup/templates/steps/compose/02_services.html @@ -10,13 +10,9 @@ the Web. By exposing a complex application such as a Webmail, you should be awar the security implications caused by such an increase of attack surface.

- - - -
diff --git a/setup/templates/steps/stack/02_services.html b/setup/templates/steps/stack/02_services.html index 6fce0ae6..68519fa8 100644 --- a/setup/templates/steps/stack/02_services.html +++ b/setup/templates/steps/stack/02_services.html @@ -12,7 +12,7 @@ the security implications caused by such an increase of attack surface.


diff --git a/tests/build.yml b/tests/build.yml index da351ac8..d693f7d1 100644 --- a/tests/build.yml +++ b/tests/build.yml @@ -72,10 +72,10 @@ services: args: VERSION: ${PINNED_MAILU_VERSION:-local} - rainloop: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rainloop:${PINNED_MAILU_VERSION:-local} + snappymail: + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}snappymail:${PINNED_MAILU_VERSION:-local} build: - context: ../webmails/rainloop + context: ../webmails/snappymail args: VERSION: ${PINNED_MAILU_VERSION:-local} diff --git a/tests/compose/core/mailu.env b/tests/compose/core/mailu.env index 254c3c7d..0b034008 100644 --- a/tests/compose/core/mailu.env +++ b/tests/compose/core/mailu.env @@ -53,7 +53,7 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=true -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL=none # Dav server implementation (value: radicale, none) diff --git a/tests/compose/fetchmail/mailu.env b/tests/compose/fetchmail/mailu.env index a015eaa8..573acf20 100644 --- a/tests/compose/fetchmail/mailu.env +++ b/tests/compose/fetchmail/mailu.env @@ -53,7 +53,7 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=true -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL=none # Dav server implementation (value: radicale, none) diff --git a/tests/compose/filters/mailu.env b/tests/compose/filters/mailu.env index 1b4fb93d..89309641 100644 --- a/tests/compose/filters/mailu.env +++ b/tests/compose/filters/mailu.env @@ -53,7 +53,7 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=true -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL=none # Dav server implementation (value: radicale, none) diff --git a/tests/compose/roundcube/mailu.env b/tests/compose/roundcube/mailu.env index 9db7fcbe..7f000f2c 100644 --- a/tests/compose/roundcube/mailu.env +++ b/tests/compose/roundcube/mailu.env @@ -53,7 +53,7 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=false -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL=roundcube # Dav server implementation (value: radicale, none) diff --git a/tests/compose/rainloop/docker-compose.yml b/tests/compose/snappymail/docker-compose.yml similarity index 96% rename from tests/compose/rainloop/docker-compose.yml rename to tests/compose/snappymail/docker-compose.yml index ca8d70ba..e92e4522 100644 --- a/tests/compose/rainloop/docker-compose.yml +++ b/tests/compose/snappymail/docker-compose.yml @@ -88,7 +88,7 @@ services: # Webmail webmail: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rainloop:${PINNED_MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}snappymail:${PINNED_MAILU_VERSION:-local} restart: always env_file: mailu.env volumes: diff --git a/tests/compose/rainloop/mailu.env b/tests/compose/snappymail/mailu.env similarity index 97% rename from tests/compose/rainloop/mailu.env rename to tests/compose/snappymail/mailu.env index 944dd376..50271fc7 100644 --- a/tests/compose/rainloop/mailu.env +++ b/tests/compose/snappymail/mailu.env @@ -53,8 +53,8 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=false -# Choose which webmail to run if any (values: roundcube, rainloop, none) -WEBMAIL=rainloop +# Choose which webmail to run if any (values: roundcube, snappymail, none) +WEBMAIL=snappymail # Dav server implementation (value: radicale, none) WEBDAV=none diff --git a/tests/compose/webdav/mailu.env b/tests/compose/webdav/mailu.env index f1de013d..c2fcc4cf 100644 --- a/tests/compose/webdav/mailu.env +++ b/tests/compose/webdav/mailu.env @@ -53,7 +53,7 @@ DISABLE_STATISTICS=False # Expose the admin interface (value: true, false) ADMIN=true -# Choose which webmail to run if any (values: roundcube, rainloop, none) +# Choose which webmail to run if any (values: roundcube, snappymail, none) WEBMAIL=none # Dav server implementation (value: radicale, none) diff --git a/webmails/rainloop/Dockerfile b/webmails/rainloop/Dockerfile deleted file mode 100644 index fd4b7549..00000000 --- a/webmails/rainloop/Dockerfile +++ /dev/null @@ -1,79 +0,0 @@ -ARG ARCH="" - -# NOTE: only add file if building for arm -FROM ${ARCH}alpine:3.14 -ARG VERSION -ONBUILD COPY --from=balenalib/rpi-alpine:3.14 /usr/bin/qemu-arm-static /usr/bin/qemu-arm-static - -ENV TZ Etc/UTC - -LABEL version=$VERSION - -# Shared later between dovecot postfix nginx rspamd rainloop and roundloop -RUN apk add --no-cache \ - python3 py3-pip tzdata \ - && pip3 install socrate==0.2.0 - -# https://www.rainloop.net/docs/system-requirements/ -# Rainloop: -# cURL Builtin -# iconv php7-iconv -# json php7-json -# libxml php7-xml -# dom php7-dom -# openssl php7-openssl -# DateTime Builtin -# PCRE Builtin -# SPL Builtin -# Recommended: -# php7-fpm FastCGI Process Manager -# Optional PHP extension (for contacts): -# php7-pdo Accessing databases in PHP -# php7-pdo_sqlite Access to SQLite 3 databases -RUN apk add --no-cache \ - nginx \ - php7 php7-fpm php7-curl php7-iconv php7-json php7-xml php7-simplexml php7-dom php7-openssl php7-pdo php7-pdo_sqlite \ - && rm /etc/nginx/http.d/default.conf \ - && rm /etc/php7/php-fpm.d/www.conf \ - && mkdir -p /run/nginx \ - && mkdir -p /var/www/rainloop \ - && mkdir -p /config - -# nginx / PHP config files -COPY config/nginx-rainloop.conf /config/nginx-rainloop.conf -COPY config/php-rainloop.conf /etc/php7/php-fpm.d/rainloop.conf - -# Rainloop login -COPY login/include.php /var/www/rainloop/include.php -COPY login/sso.php /var/www/rainloop/sso.php - -# Parsed en moved at startup -COPY defaults/php.ini /defaults/php.ini -COPY defaults/application.ini /defaults/application.ini -COPY defaults/default.ini /defaults/default.ini - -# Install Rainloop from source -ENV RAINLOOP_URL https://github.com/RainLoop/rainloop-webmail/releases/download/v1.16.0/rainloop-community-1.16.0.zip - -RUN apk add --no-cache \ - curl unzip \ - && cd /var/www/rainloop \ - && curl -L -O ${RAINLOOP_URL} \ - && unzip -q *.zip \ - && rm -f *.zip \ - && rm -rf data/ \ - && find . -type d -exec chmod 755 {} \; \ - && find . -type f -exec chmod 644 {} \; \ - && chown -R nginx:nginx /var/www/rainloop \ - && apk del unzip - -COPY start.py /start.py -COPY config.py /config.py - -EXPOSE 80/tcp -VOLUME ["/data"] - -CMD /start.py - -HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1 -RUN echo $VERSION >> /version diff --git a/webmails/rainloop/login/sso.php b/webmails/rainloop/login/sso.php deleted file mode 100644 index 0bfbe263..00000000 --- a/webmails/rainloop/login/sso.php +++ /dev/null @@ -1,31 +0,0 @@ -> /version diff --git a/webmails/rainloop/config.py b/webmails/snappymail/config.py similarity index 77% rename from webmails/rainloop/config.py rename to webmails/snappymail/config.py index 88052961..ec6f5151 100755 --- a/webmails/rainloop/config.py +++ b/webmails/snappymail/config.py @@ -10,6 +10,6 @@ args = os.environ.copy() log.basicConfig(stream=sys.stderr, level=args.get("LOG_LEVEL", "WARNING")) # Build final configuration paths -conf.jinja("/config/nginx-rainloop.conf", args, "/etc/nginx/http.d/rainloop.conf") +conf.jinja("/config/nginx-snappymail.conf", args, "/etc/nginx/http.d/snappymail.conf") if os.path.exists("/var/run/nginx.pid"): os.system("nginx -s reload") diff --git a/webmails/rainloop/config/nginx-rainloop.conf b/webmails/snappymail/config/nginx-snappymail.conf similarity index 70% rename from webmails/rainloop/config/nginx-rainloop.conf rename to webmails/snappymail/config/nginx-snappymail.conf index be40e963..ca70e4db 100644 --- a/webmails/rainloop/config/nginx-rainloop.conf +++ b/webmails/snappymail/config/nginx-snappymail.conf @@ -2,13 +2,15 @@ server { listen 80 default_server; listen [::]:80 default_server; - root /var/www/rainloop; + root /var/www/webmail; + + include /etc/nginx/mime.types; # /dev/stdout (Default), , off access_log off; # /dev/stderr (Default), , debug, info, notice, warn, error, crit, alert, emerg - error_log /dev/stderr warn; + error_log /dev/stderr notice; index index.php; @@ -16,19 +18,26 @@ server { client_max_body_size {{ MESSAGE_SIZE_LIMIT|int + 8388608 }}; location / { - try_files $uri /index.php?$query_string; + try_files $uri $uri/ /index.php$args; } location ~ \.php$ { + include /etc/nginx/fastcgi_params; + fastcgi_split_path_info ^(.+\.php)(/.*)$; fastcgi_intercept_errors on; fastcgi_index index.php; fastcgi_keep_conn on; - include /etc/nginx/fastcgi_params; + fastcgi_pass unix:/var/run/php7-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + {% if WEB_WEBMAIL == '/' %} + fastcgi_param SCRIPT_NAME $fastcgi_script_name; + {% else %} + fastcgi_param SCRIPT_NAME {{WEB_WEBMAIL}}/$fastcgi_script_name; + {% endif %} } location ~ /\.ht { diff --git a/webmails/rainloop/config/php-rainloop.conf b/webmails/snappymail/config/php-snappymail.conf similarity index 98% rename from webmails/rainloop/config/php-rainloop.conf rename to webmails/snappymail/config/php-snappymail.conf index e9906505..d6010400 100644 --- a/webmails/rainloop/config/php-rainloop.conf +++ b/webmails/snappymail/config/php-snappymail.conf @@ -1,7 +1,7 @@ -; Start a new pool named 'rainloop'. +; Start a new pool named 'snappymail'. ; the variable $pool can be used in any directive and will be replaced by the -; pool name ('rainloop' here) -[rainloop] +; pool name ('snappymail' here) +[snappymail] ; 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. diff --git a/webmails/rainloop/defaults/application.ini b/webmails/snappymail/defaults/application.ini similarity index 62% rename from webmails/rainloop/defaults/application.ini rename to webmails/snappymail/defaults/application.ini index d67ec9f0..55d0db36 100644 --- a/webmails/rainloop/defaults/application.ini +++ b/webmails/snappymail/defaults/application.ini @@ -1,4 +1,4 @@ -; RainLoop Webmail configuration file +; Snappymail Webmail configuration file [webmail] attachment_size_limit = {{ MAX_FILESIZE }} @@ -8,10 +8,14 @@ allow_admin_panel = Off [labs] allow_gravatar = Off +{% if WEB_WEBMAIL == '/' %} custom_login_link='sso.php' +{% else %} +custom_login_link='{{ WEB_WEBMAIL }}/sso.php' +{% endif %} custom_logout_link='/sso/logout' -[contacts] +[defaults] enable = On allow_sync = On diff --git a/webmails/rainloop/defaults/default.ini b/webmails/snappymail/defaults/default.ini similarity index 100% rename from webmails/rainloop/defaults/default.ini rename to webmails/snappymail/defaults/default.ini diff --git a/webmails/rainloop/defaults/php.ini b/webmails/snappymail/defaults/php.ini similarity index 100% rename from webmails/rainloop/defaults/php.ini rename to webmails/snappymail/defaults/php.ini diff --git a/webmails/rainloop/login/include.php b/webmails/snappymail/login/include.php similarity index 100% rename from webmails/rainloop/login/include.php rename to webmails/snappymail/login/include.php diff --git a/webmails/snappymail/login/sso.php b/webmails/snappymail/login/sso.php new file mode 100644 index 00000000..e3d04824 --- /dev/null +++ b/webmails/snappymail/login/sso.php @@ -0,0 +1,17 @@ + \ No newline at end of file diff --git a/webmails/rainloop/start.py b/webmails/snappymail/start.py similarity index 96% rename from webmails/rainloop/start.py rename to webmails/snappymail/start.py index 3905791f..bedde4ad 100755 --- a/webmails/rainloop/start.py +++ b/webmails/snappymail/start.py @@ -27,7 +27,7 @@ conf.jinja("/defaults/php.ini", os.environ, "/etc/php7/php.ini") os.system("php-fpm7") os.system("chown -R nginx:nginx /data") -os.system("chmod -R a+rX /var/www/rainloop/") +os.system("chmod -R a+rX /var/www/webmail/") subprocess.call(["/config.py"]) os.execv("/usr/sbin/nginx", ["nginx", "-g", "daemon off;"]) From 22010ddb4fa37b50428000d866a1c5cecbbf5b10 Mon Sep 17 00:00:00 2001 From: Dimitri Huisman Date: Tue, 22 Mar 2022 09:18:51 +0000 Subject: [PATCH 2/7] fix applications.ini --- webmails/snappymail/defaults/application.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmails/snappymail/defaults/application.ini b/webmails/snappymail/defaults/application.ini index 584dad5e..71a19f35 100644 --- a/webmails/snappymail/defaults/application.ini +++ b/webmails/snappymail/defaults/application.ini @@ -15,7 +15,7 @@ custom_login_link='{{ WEB_WEBMAIL }}/sso.php' {% endif %} custom_logout_link='/sso/logout' -[defaults] +[contacts] enable = On allow_sync = On From af1cba2b30579371030be40b22e8d4124e6afcb5 Mon Sep 17 00:00:00 2001 From: Dimitri Huisman Date: Tue, 22 Mar 2022 14:34:30 +0000 Subject: [PATCH 3/7] Add changelog --- towncrier/newsfragments/2295.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 towncrier/newsfragments/2295.feature diff --git a/towncrier/newsfragments/2295.feature b/towncrier/newsfragments/2295.feature new file mode 100644 index 00000000..e353b692 --- /dev/null +++ b/towncrier/newsfragments/2295.feature @@ -0,0 +1 @@ +Switch from RainLoop to SnappyMail. SnappyMail has better performance and is more secure. From dc7613b34a00b39dc9f206daaa3ea8b51dd5b475 Mon Sep 17 00:00:00 2001 From: Dimitri Huisman Date: Tue, 22 Mar 2022 16:01:26 +0000 Subject: [PATCH 4/7] Fix healthcheck --- webmails/snappymail/Dockerfile | 2 +- webmails/snappymail/config/nginx-snappymail.conf | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/webmails/snappymail/Dockerfile b/webmails/snappymail/Dockerfile index 142f4430..8777dd11 100644 --- a/webmails/snappymail/Dockerfile +++ b/webmails/snappymail/Dockerfile @@ -88,5 +88,5 @@ VOLUME ["/data"] CMD /start.py -HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1 +HEALTHCHECK CMD curl -f -L http://localhost/health || exit 1 RUN echo $VERSION >> /version diff --git a/webmails/snappymail/config/nginx-snappymail.conf b/webmails/snappymail/config/nginx-snappymail.conf index ca70e4db..7819125f 100644 --- a/webmails/snappymail/config/nginx-snappymail.conf +++ b/webmails/snappymail/config/nginx-snappymail.conf @@ -47,4 +47,9 @@ server { location ^~ /data { deny all; } + + location /health { + add_header Content-Type text/plain; + return 200; + } } From c5c2ee9f1c469c11b3c919c7e8227e69f63a798d Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Sun, 22 May 2022 18:02:13 +0200 Subject: [PATCH 5/7] simplify --- webmails/snappymail/Dockerfile | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/webmails/snappymail/Dockerfile b/webmails/snappymail/Dockerfile index 8777dd11..cb667e83 100644 --- a/webmails/snappymail/Dockerfile +++ b/webmails/snappymail/Dockerfile @@ -65,16 +65,10 @@ COPY defaults/default.ini /defaults/default.ini # Install Snappymail from source ENV SNAPPYMAIL_URL https://github.com/the-djmaze/snappymail/releases/download/v2.13.4/snappymail-2.13.4.zip -RUN apk add --no-cache \ - curl unzip \ - && cd /var/www/webmail \ - && curl -L -O ${SNAPPYMAIL_URL} \ - && unzip -q *.zip \ - && rm -f *.zip \ - && find . -type d -exec chmod 755 {} \; \ - && find . -type f -exec chmod 644 {} \; \ - && chown -R nginx:nginx /var/www/webmail \ - && apk del unzip +RUN cd /var/www/webmail \ + && busybox wget ${SNAPPYMAIL_URL} -O - |busybox unzip - + && chmod -R u+w,a+rX /var/www/webmail \ + && chown -R nginx:nginx /var/www/webmail # SnappyMail login COPY login/include.php /var/www/webmail/include.php From ee78a34da41e93bb5b2f732fc53d6606f9fab7a6 Mon Sep 17 00:00:00 2001 From: Dimitri Huisman Date: Wed, 6 Jul 2022 13:42:13 +0000 Subject: [PATCH 6/7] Process code review feedback Remove unneeded IF statement in /admin block in nginx.conf of front. Fix contributions made to Dockerfile, add missing trailing \ and add back curl Change healthcheck to monitoring page of fpm. Now we check nginx and fpm. --- core/nginx/conf/nginx.conf | 3 -- webmails/snappymail/Dockerfile | 6 ++-- .../snappymail/config/nginx-snappymail.conf | 19 ++++++++---- .../snappymail/config/php-snappymail.conf | 29 +++++++++++++++---- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index cc8125bf..80ebdaee 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -213,9 +213,6 @@ http { {% endif %} {% if ADMIN == 'true' %} location {{ WEB_ADMIN }} { - {% if WEB_ADMIN != '/' %} - rewrite ^({{ WEB_ADMIN }})$ $1/ permanent; - {% endif %} include /etc/nginx/proxy.conf; proxy_pass http://$admin; expires $expires; diff --git a/webmails/snappymail/Dockerfile b/webmails/snappymail/Dockerfile index cb667e83..92d48207 100644 --- a/webmails/snappymail/Dockerfile +++ b/webmails/snappymail/Dockerfile @@ -43,7 +43,7 @@ RUN apk add --no-cache \ # zip php7-zip #php7-curl php7-iconv php7-json php7-xml php7-simplexml php7-dom php7-openssl php7-pdo php7-pdo_sqlite php7-mbstring \ RUN apk add --no-cache \ - nginx \ + nginx curl \ php7 php7-fpm php7-mbstring php7-zip php7-json php7-xml php7-simplexml \ php7-dom php7-curl php7-exif gd php7-gd php7-iconv php7-intl php7-openssl \ php7-pdo_sqlite php7-pdo php7-sodium libsodium php7-tidy php7-pecl-uuid \ @@ -66,7 +66,7 @@ COPY defaults/default.ini /defaults/default.ini ENV SNAPPYMAIL_URL https://github.com/the-djmaze/snappymail/releases/download/v2.13.4/snappymail-2.13.4.zip RUN cd /var/www/webmail \ - && busybox wget ${SNAPPYMAIL_URL} -O - |busybox unzip - + && busybox wget ${SNAPPYMAIL_URL} -O - | busybox unzip - \ && chmod -R u+w,a+rX /var/www/webmail \ && chown -R nginx:nginx /var/www/webmail @@ -82,5 +82,5 @@ VOLUME ["/data"] CMD /start.py -HEALTHCHECK CMD curl -f -L http://localhost/health || exit 1 +HEALTHCHECK CMD curl -f -L http://localhost/ping || exit 1 RUN echo $VERSION >> /version diff --git a/webmails/snappymail/config/nginx-snappymail.conf b/webmails/snappymail/config/nginx-snappymail.conf index 7819125f..98ffcc7f 100644 --- a/webmails/snappymail/config/nginx-snappymail.conf +++ b/webmails/snappymail/config/nginx-snappymail.conf @@ -22,10 +22,12 @@ server { } location ~ \.php$ { + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + if (!-f $document_root$fastcgi_script_name) { + return 404; + } include /etc/nginx/fastcgi_params; - fastcgi_split_path_info ^(.+\.php)(/.*)$; - fastcgi_intercept_errors on; fastcgi_index index.php; @@ -45,11 +47,16 @@ server { } location ^~ /data { - deny all; + deny all; } - location /health { - add_header Content-Type text/plain; - return 200; + location = /ping { + allow 127.0.0.1; + deny all; + + include /etc/nginx/fastcgi_params; + fastcgi_index index.php; + fastcgi_pass unix:/var/run/php7-fpm.sock; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } diff --git a/webmails/snappymail/config/php-snappymail.conf b/webmails/snappymail/config/php-snappymail.conf index d6010400..974c00d1 100644 --- a/webmails/snappymail/config/php-snappymail.conf +++ b/webmails/snappymail/config/php-snappymail.conf @@ -3,9 +3,9 @@ ; pool name ('snappymail' here) [snappymail] -; 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. -; Default value: no. +; 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. +; Default value: no. catch_workers_output = 1 ; Unix user/group of processes @@ -87,15 +87,32 @@ pm.max_children = 5 ; Note: Mandatory when pm is set to 'dynamic' ; pm.max_spare_servers = 3 -; This sets the maximum time in seconds a script is allowed to run before it is -; terminated by the parser. This helps prevent poorly written scripts from tying up +; This sets the maximum time in seconds a script is allowed to run before it is +; terminated by the parser. This helps prevent poorly written scripts from tying up ; the server. The default setting is 30s. ; Note: Used only when pm is set to 'ondemand' pm.process_idle_timeout = 10s -; The number of requests each child process should execute before respawning. +; The number of requests each child process should execute before respawning. ; This can be useful to work around memory leaks in 3rd party libraries. For endless ; request processing specify '0'. ; Equivalent to PHP_FCGI_MAX_REQUESTS. Default value: 0. ; Noted: Used only when pm is set to 'ondemand' pm.max_requests = 200 + +; The ping URI to call the monitoring page of FPM. If this value is not set, no +; URI will be recognized as a ping page. This could be used to test from outside +; that FPM is alive and responding, or to +; - create a graph of FPM availability (rrd or such); +; - remove a server from a group if it is not responding (load balancing); +; - trigger alerts for the operating team (24/7). +; Note: The value must start with a leading slash (/). The value can be +; anything, but it may not be a good idea to use the .php extension or it +; may conflict with a real PHP file. +; Default Value: not set +ping.path = /ping + +; This directive may be used to customize the response of a ping request. The +; response is formatted as text/plain with a 200 response code. +; Default Value: pong +;ping.response = pong From 2a527a38cfbdc82344bbb8b8f2e8e5e400aa1350 Mon Sep 17 00:00:00 2001 From: Dimitri Huisman Date: Fri, 15 Jul 2022 14:34:39 +0000 Subject: [PATCH 7/7] Deny access to hidden files for snappymail --- webmails/snappymail/config/nginx-snappymail.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webmails/snappymail/config/nginx-snappymail.conf b/webmails/snappymail/config/nginx-snappymail.conf index 98ffcc7f..985f804a 100644 --- a/webmails/snappymail/config/nginx-snappymail.conf +++ b/webmails/snappymail/config/nginx-snappymail.conf @@ -42,7 +42,7 @@ server { {% endif %} } - location ~ /\.ht { + location ~ /\. { deny all; }