Merge #2295
2295: Switch from Rainloop to SnappyMail r=mergify[bot] a=Diman0 ## What type of PR? Feature ## What does this PR do? As discussed in the project meeting (#1582), we decided we want to switch from Rainloop to an alternative. Rainloop has multiple open security issues which were not patched for a long time. We decided to switch to SnappyMail because it is more secure and based on RainLoop. This means that users using RainLoop will still have a webmail that looks familiar for them. This PR replaces RainLoop with SnappyMail. ### Related issue(s) - #2215 - #1582 ## Prerequisites Before we can consider review and merge, please make sure the following list is done and checked. If an entry in not applicable, you can check it or remove it from the list. - [x] In case of feature or enhancement: documentation updated accordingly - [x] Unless it's docs or a minor change: add [changelog](https://mailu.io/master/contributors/workflow.html#changelog) entry file. Co-authored-by: Dimitri Huisman <diman@huisman.xyz> Co-authored-by: Florent Daigniere <nextgens@users.noreply.github.com>master
commit
238daef6d8
@ -0,0 +1 @@
|
||||
Switch from RainLoop to SnappyMail. SnappyMail has better performance and is more secure.
|
@ -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
|
@ -1,41 +0,0 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
root /var/www/rainloop;
|
||||
|
||||
# /dev/stdout (Default), <path>, off
|
||||
access_log off;
|
||||
|
||||
# /dev/stderr (Default), <path>, debug, info, notice, warn, error, crit, alert, emerg
|
||||
error_log /dev/stderr warn;
|
||||
|
||||
index index.php;
|
||||
|
||||
# set maximum body size to configured limit
|
||||
client_max_body_size {{ MESSAGE_SIZE_LIMIT|int + 8388608 }};
|
||||
|
||||
location / {
|
||||
try_files $uri /index.php?$query_string;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
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;
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location ^~ /data {
|
||||
deny all;
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
$_ENV['RAINLOOP_INCLUDE_AS_API'] = true;
|
||||
if (!defined('APP_VERSION')) {
|
||||
$version = file_get_contents('/data/VERSION');
|
||||
if ($version) {
|
||||
define('APP_VERSION', $version);
|
||||
define('APP_INDEX_ROOT_FILE', __FILE__);
|
||||
define('APP_INDEX_ROOT_PATH', str_replace('\\', '/', rtrim(dirname(__FILE__), '\\/').'/'));
|
||||
}
|
||||
}
|
||||
|
||||
if (file_exists(APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/include.php')) {
|
||||
include APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/include.php';
|
||||
} else {
|
||||
echo '[105] Missing version directory';
|
||||
exit(105);
|
||||
}
|
||||
|
||||
// Retrieve email and password
|
||||
if (isset($_SERVER['HTTP_X_REMOTE_USER']) && isset($_SERVER['HTTP_X_REMOTE_USER_TOKEN'])) {
|
||||
$email = $_SERVER['HTTP_X_REMOTE_USER'];
|
||||
$password = $_SERVER['HTTP_X_REMOTE_USER_TOKEN'];
|
||||
$ssoHash = \RainLoop\Api::GetUserSsoHash($email, $password);
|
||||
|
||||
// redirect to webmail sso url
|
||||
header('Location: index.php?sso&hash='.$ssoHash);
|
||||
}
|
||||
else {
|
||||
header('HTTP/1.0 403 Forbidden');
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
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 snappymail and roundloop
|
||||
RUN apk add --no-cache \
|
||||
python3 py3-pip tzdata \
|
||||
&& pip3 install socrate==0.2.0
|
||||
|
||||
# https://github.com/the-djmaze/snappymail/wiki/Installation-instructions#requirements
|
||||
# SnappyMail:
|
||||
# SnappyMail requires PHP 7.4 (or a newer version) with the following extensions:
|
||||
#
|
||||
# mbstring php7-mbstring
|
||||
# Zlib built-in OR php7-zip????
|
||||
# json php7-json
|
||||
# libxml php7-xml
|
||||
# dom php7-dom
|
||||
|
||||
# Optional extensions:
|
||||
|
||||
# cURL php7-curl
|
||||
# exif php7-exif
|
||||
# gd, gmagick or imagemagick gd and php7-gd
|
||||
# gnupg gpgme and alpine has no php7-gnupg library :(
|
||||
# iconv php7-iconv
|
||||
# intl php7-intl
|
||||
# ldap we don't use ldap
|
||||
# openssl php7-openssl
|
||||
# PDO (MySQL/PostgreSQL/SQLite) (for contacts) php7-pdo_sqlite and php7-pdo
|
||||
# redis NOT USED
|
||||
# Sodium php7-sodium and libsodium
|
||||
# Tidy php7-tidy
|
||||
# uuid (PECL) php7-pecl-uuid
|
||||
# xxtea (PECL) not found on alpine repo
|
||||
# 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 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 \
|
||||
&& rm /etc/nginx/http.d/default.conf \
|
||||
&& rm /etc/php7/php-fpm.d/www.conf \
|
||||
&& mkdir -p /run/nginx \
|
||||
&& mkdir -p /var/www/webmail \
|
||||
&& mkdir -p /config
|
||||
|
||||
# nginx / PHP config files
|
||||
COPY config/nginx-snappymail.conf /config/nginx-snappymail.conf
|
||||
COPY config/php-snappymail.conf /etc/php7/php-fpm.d/snappymail.conf
|
||||
|
||||
# Parsed and 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 Snappymail from source
|
||||
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 - \
|
||||
&& 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
|
||||
COPY login/sso.php /var/www/webmail/sso.php
|
||||
|
||||
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/ping || exit 1
|
||||
RUN echo $VERSION >> /version
|
@ -0,0 +1,62 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
root /var/www/webmail;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
|
||||
# /dev/stdout (Default), <path>, off
|
||||
access_log off;
|
||||
|
||||
# /dev/stderr (Default), <path>, debug, info, notice, warn, error, crit, alert, emerg
|
||||
error_log /dev/stderr notice;
|
||||
|
||||
index index.php;
|
||||
|
||||
# set maximum body size to configured limit
|
||||
client_max_body_size {{ MESSAGE_SIZE_LIMIT|int + 8388608 }};
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php$args;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
if (!-f $document_root$fastcgi_script_name) {
|
||||
return 404;
|
||||
}
|
||||
include /etc/nginx/fastcgi_params;
|
||||
|
||||
fastcgi_intercept_errors on;
|
||||
fastcgi_index index.php;
|
||||
|
||||
fastcgi_keep_conn on;
|
||||
|
||||
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 ~ /\. {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location ^~ /data {
|
||||
deny all;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
$_ENV['SNAPPYMAIL_INCLUDE_AS_API'] = true;
|
||||
require 'index.php';
|
||||
// Retrieve email and password
|
||||
if (isset($_SERVER['HTTP_X_REMOTE_USER']) && isset($_SERVER['HTTP_X_REMOTE_USER_TOKEN'])) {
|
||||
$email = $_SERVER['HTTP_X_REMOTE_USER'];
|
||||
$password = $_SERVER['HTTP_X_REMOTE_USER_TOKEN'];
|
||||
$ssoHash = \RainLoop\Api::CreateUserSsoHash($email, $password);
|
||||
|
||||
// redirect to webmail sso url
|
||||
header('Location: index.php?sso&hash='.$ssoHash);
|
||||
}
|
||||
else {
|
||||
header('HTTP/1.0 403 Forbidden');
|
||||
}
|
||||
?>
|
Loading…
Reference in New Issue