From 99540cd90be51a5375d80752f7c5de11fc0486ee Mon Sep 17 00:00:00 2001 From: Hans Cornelis Date: Tue, 23 Oct 2018 10:47:26 +0200 Subject: [PATCH 01/62] - Added kubernetes CNI support for Mailu Signed-off-by: Hans Cornelis --- docs/kubernetes/mailu/configmap.yaml | 5 +++++ docs/kubernetes/mailu/index.rst | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/docs/kubernetes/mailu/configmap.yaml b/docs/kubernetes/mailu/configmap.yaml index 4f8dad81..8a24ee5d 100644 --- a/docs/kubernetes/mailu/configmap.yaml +++ b/docs/kubernetes/mailu/configmap.yaml @@ -53,6 +53,11 @@ # This way we can make use of the advantages of the cert-manager deployment KUBERNETES_INGRESS: "true" + # POD_ADDRESS_RANGE is normally provided by default with Kubernetes + # Only use this value when you are using Flannel, Calico or a special kind of CNI + # Provide the IPs of your network interface or bridge which is used for VXLAN network traffic + # POD_ADDRESS_RANGE: 10.2.0.0/16,10.1.6.0/24 + ################################### # Optional features ################################### diff --git a/docs/kubernetes/mailu/index.rst b/docs/kubernetes/mailu/index.rst index ef12eb58..80af3ead 100644 --- a/docs/kubernetes/mailu/index.rst +++ b/docs/kubernetes/mailu/index.rst @@ -191,3 +191,18 @@ This problem can be easily fixed by running following commands: kubectl -n mailu-mailserver exec -it maolu-imap-... /bin/sh chmod 777 /data/main.db + +If the login problem still persists, or more specific, happens now and then and you see some Auth problems on your webmail or mail client, try following steps: + +- Add ``auth_debug=yes`` to the ``/overrides/dovecot.conf`` file and delete the pod in order to start a new one, which loads the configuration +- Depending on your network configuration you could still see some ``allow_nets check failed`` results in the logs. This means that the IP is not allowed a login +- If this is happening your network plugin has troubles with the Nginx Ingress Controller using the ``hostNetwork: true`` option. Known cases: Flannel and Calico. +- You should uncomment ``POD_ADDRESS_RANGE`` in the ``configmap.yaml`` file and add the IP range of your pod network bridge (the range that sadly has failed the ``allowed_nets`` test) +- Delete the IMAP pod and wait for it to restart + +.. code:: bash + + kubectl -n mailu-mailserver get po + kubectl -n mailu-mailserver delete po/mailu-imap... + +Happy mailing! \ No newline at end of file From 5067b5c59a1ab3c868b3414ab5b125a9d273ed5c Mon Sep 17 00:00:00 2001 From: ofthesun9 Date: Wed, 31 Oct 2018 14:27:37 +0000 Subject: [PATCH 02/62] POD_ADDRESS need to be defined for admin service (dovecot authentification) fixes #694 - updated the docs - corrected a typo --- docs/swarm/master/README.md | 8 ++++---- docs/swarm/master/README_nfs_example.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/swarm/master/README.md b/docs/swarm/master/README.md index 44c19dc7..61319cfd 100644 --- a/docs/swarm/master/README.md +++ b/docs/swarm/master/README.md @@ -30,7 +30,7 @@ mzrm9nbdggsfz4sgq6dhs5i6n flying-dutchman Ready Active ### Volume definition For data persistance (the Mailu services might be launched/relaunched on any of the swarm nodes), we need to have Mailu data stored in a manner accessible by every manager or worker in the swarm. -Hereafter we will assume that "Mailu Data" is available on every node at "$ROOT/certs:/certs" (GlusterFS and nfs shares have been successfully used). +Hereafter we will assume that "Mailu Data" is available on every node at "$ROOT" (GlusterFS and nfs shares have been successfully used). On this example, we are using: - the mesh routing mode (default mode). With this mode, each service is given a virtual IP adress and docker manages the routing between this virtual IP and the container(s) providing this service. @@ -77,7 +77,7 @@ Instead, we will use the following work-around: We need also to: - add a deploy section for every service - modify the way the ports are defined for the front service -- add the POD_ADDRESS_RANGE definition for imap, smtp and antispam services +- add the POD_ADDRESS_RANGE definition for admin (for imap), smtp and antispam services ## Docker compose An example of docker-compose-stack.yml file is available here: @@ -128,8 +128,6 @@ services: image: mailu/dovecot:$VERSION restart: always env_file: .env - environment: - - POD_ADDRESS_RANGE=10.0.1.0/24 volumes: - "$ROOT/mail:/mail" - "$ROOT/overrides:/overrides" @@ -188,6 +186,8 @@ services: image: mailu/admin:$VERSION restart: always env_file: .env + environment: + - POD_ADDRESS_RANGE=10.0.1.0/24 volumes: - "$ROOT/data:/data" - "$ROOT/dkim:/dkim" diff --git a/docs/swarm/master/README_nfs_example.md b/docs/swarm/master/README_nfs_example.md index 5cfd0a73..a091f5ba 100644 --- a/docs/swarm/master/README_nfs_example.md +++ b/docs/swarm/master/README_nfs_example.md @@ -157,8 +157,6 @@ services: image: mailu/dovecot:$VERSION restart: always env_file: .env - environment: - - POD_ADDRESS_RANGE=10.0.1.0/24 volumes: # - "$ROOT/mail:/mail" - type: volume @@ -241,6 +239,8 @@ services: image: mailu/admin:$VERSION restart: always env_file: .env + environment: + - POD_ADDRESS_RANGE=10.0.1.0/24 volumes: # - "$ROOT/data:/data" - type: volume From eac4d553a92f6c3a80f81476a41af6e5726c7cd7 Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Tue, 27 Nov 2018 00:12:12 +0100 Subject: [PATCH 03/62] nginx: Allow extending config with overrides To facilitate this, the default redirect at / can be disabled, even if the default remains at redirecting to the webmailer. The extensions are within the host scope and are read from $ROOT/overrides/nginx/*.conf. --- core/nginx/Dockerfile | 1 + core/nginx/conf/nginx.conf | 8 +++++--- docs/compose/.env | 3 +++ docs/compose/docker-compose.yml | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/core/nginx/Dockerfile b/core/nginx/Dockerfile index 7181487e..717cb225 100644 --- a/core/nginx/Dockerfile +++ b/core/nginx/Dockerfile @@ -14,6 +14,7 @@ COPY *.py / EXPOSE 80/tcp 443/tcp 110/tcp 143/tcp 465/tcp 587/tcp 993/tcp 995/tcp 25/tcp 10025/tcp 10143/tcp VOLUME ["/certs"] +VOLUME ["/overrides"] CMD /start.py diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index 17d67526..0bc6cf07 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -84,14 +84,16 @@ http { } {% else %} + include /overrides/*.conf; + # Actual logic - {% if WEBMAIL != 'none' %} - {% if WEB_WEBMAIL != '/' %} + {% if WEBROOT_REDIRECT %} location / { - return 301 {{ WEB_WEBMAIL }}; + return 301 {{ WEBROOT_REDIRECT }}; } {% endif %} + {% if WEBMAIL != 'none' %} location {{ WEB_WEBMAIL }} { {% if WEB_WEBMAIL != '/' %} rewrite ^({{ WEB_WEBMAIL }})$ $1/ permanent; diff --git a/docs/compose/.env b/docs/compose/.env index 2100e27a..bd98df31 100644 --- a/docs/compose/.env +++ b/docs/compose/.env @@ -97,6 +97,9 @@ COMPRESSION_LEVEL= # Web settings ################################### +# Path to redirect / to +WEB_DEFAULT=/webmail + # Path to the admin interface if enabled WEB_ADMIN=/admin diff --git a/docs/compose/docker-compose.yml b/docs/compose/docker-compose.yml index b8d15587..72981f81 100644 --- a/docs/compose/docker-compose.yml +++ b/docs/compose/docker-compose.yml @@ -29,6 +29,7 @@ services: - "$BIND_ADDRESS6:587:587" volumes: - "$ROOT/certs:/certs" + - "$ROOT/overrides/nginx:/overrides" redis: image: redis:alpine From 9dd447e23b7d0b8fc34c7cda6b71f2b6c644b1d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Thu, 6 Dec 2018 01:00:16 +0200 Subject: [PATCH 04/62] Add login method to smtp_auth under ssl Fixes #704 --- core/nginx/conf/nginx.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index 17d67526..eced2c46 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -245,7 +245,7 @@ mail { listen 465 ssl; listen [::]:465 ssl; protocol smtp; - smtp_auth plain; + smtp_auth plain login; } server { From fee52e87eddbf445b15359eea95cde576bc13666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Thu, 6 Dec 2018 11:34:28 +0200 Subject: [PATCH 05/62] Don't allow for 1 review when review/need2 label is set --- .mergify.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.mergify.yml b/.mergify.yml index 023bf59b..f18eec13 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -10,6 +10,7 @@ pull_request_rules: conditions: - author~=(kaiyou|muhlemmer|mildred|HorayNarea|adi90x|hoellen|ofthesun9) - status-success=continuous-integration/travis-ci/pr + - label!=["review/need2"] - "#approved-reviews-by>=1" actions: merge: From 8172f3eab87b52b6547f3e67fedfa30f06fd0d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Mon, 3 Dec 2018 03:16:53 +0200 Subject: [PATCH 06/62] Move the Mailu Docker network to a fixed subnet. This will make network configuration and host based authentication more robust, across different deployment platforms. The options `RELAYNETS` and`POD_ADDRESS_RANGE` are kept for compatibility. However, their usage have become optional. --- core/admin/mailu/configuration.py | 1 + core/admin/mailu/internal/views/dovecot.py | 9 +++------ core/postfix/conf/main.cf | 5 +++-- docs/compose/.env | 12 +++++++----- docs/compose/docker-compose.yml | 8 ++++++++ docs/configuration.rst | 11 ++++++++--- services/rspamd/conf/worker-controller.inc | 2 +- setup/flavors/compose/mailu.env | 10 +++++----- setup/flavors/stack/docker-compose.yml | 8 +------- setup/templates/steps/compose/03_expose.html | 4 ++-- setup/templates/steps/stack/03_expose.html | 4 ++-- tests/compose/core/mailu.env | 11 +++++++---- tests/compose/fetchmail/mailu.env | 8 ++++---- tests/compose/filters/mailu.env | 8 ++++---- tests/compose/rainloop/mailu.env | 8 ++++---- tests/compose/roundcube/mailu.env | 8 ++++---- tests/compose/webdav/mailu.env | 8 ++++---- 17 files changed, 68 insertions(+), 57 deletions(-) diff --git a/core/admin/mailu/configuration.py b/core/admin/mailu/configuration.py index 48599d5e..10bf22ae 100644 --- a/core/admin/mailu/configuration.py +++ b/core/admin/mailu/configuration.py @@ -50,6 +50,7 @@ DEFAULT_CONFIG = { 'HOST_WEBMAIL': 'webmail', 'HOST_FRONT': 'front', 'HOST_AUTHSMTP': os.environ.get('HOST_SMTP', 'smtp'), + 'SUBNET': '192.168.203.0/24', 'POD_ADDRESS_RANGE': None } diff --git a/core/admin/mailu/internal/views/dovecot.py b/core/admin/mailu/internal/views/dovecot.py index bf2ce2e5..762bd941 100644 --- a/core/admin/mailu/internal/views/dovecot.py +++ b/core/admin/mailu/internal/views/dovecot.py @@ -10,12 +10,9 @@ import os def dovecot_passdb_dict(user_email): user = models.User.query.get(user_email) or flask.abort(404) allow_nets = [] - allow_nets.append( - app.config.get("POD_ADDRESS_RANGE") or - socket.gethostbyname(app.config["HOST_FRONT"]) - ) - if os.environ["WEBMAIL"] != "none": - allow_nets.append(socket.gethostbyname(app.config["HOST_WEBMAIL"])) + allow_nets.append(app.config["SUBNET"]) + if app.config["POD_ADDRESS_RANGE"]: + allow_nets.append(app.config["POD_ADDRESS_RANGE"]) print(allow_nets) return flask.jsonify({ "password": None, diff --git a/core/postfix/conf/main.cf b/core/postfix/conf/main.cf index a67eb433..d5d47d19 100644 --- a/core/postfix/conf/main.cf +++ b/core/postfix/conf/main.cf @@ -14,7 +14,7 @@ queue_directory = /queue message_size_limit = {{ MESSAGE_SIZE_LIMIT }} # Relayed networks -mynetworks = 127.0.0.1/32 [::1]/128 {{ RELAYNETS }} +mynetworks = 127.0.0.1/32 [::1]/128 {{ SUBNET }} {{ RELAYNETS }} # Empty alias list to override the configuration variable and disable NIS alias_maps = @@ -32,7 +32,8 @@ relayhost = {{ RELAYHOST }} recipient_delimiter = {{ RECIPIENT_DELIMITER }} # Only the front server is allowed to perform xclient -smtpd_authorized_xclient_hosts={{ FRONT_ADDRESS }} {{ POD_ADDRESS_RANGE }} +# In kubernetes and Docker swarm, such address cannot be determined using the hostname. Allow for the whole Mailu subnet instead. +smtpd_authorized_xclient_hosts={{ POD_ADDRESS_RANGE or SUBNET }} ############### # TLS diff --git a/docs/compose/.env b/docs/compose/.env index 2100e27a..c9fce025 100644 --- a/docs/compose/.env +++ b/docs/compose/.env @@ -1,6 +1,5 @@ # Mailu main configuration file -# -# Most configuration variables can be modified through the Web interface, +## Most configuration variables can be modified through the Web interface, # these few settings must however be configured before starting the mail # server and require a restart upon change. @@ -21,6 +20,9 @@ SECRET_KEY=ChangeMeChangeMe BIND_ADDRESS4=127.0.0.1 BIND_ADDRESS6=::1 +# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!) +SUBNET=192.168.203.0/24 + # Main mail domain DOMAIN=mailu.io @@ -63,9 +65,9 @@ ANTIVIRUS=none # Default: accept messages up to 50MB MESSAGE_SIZE_LIMIT=50000000 -# Networks granted relay permissions, make sure that you include your Docker -# internal network (default to 172.17.0.0/16) -RELAYNETS=172.16.0.0/12 +# Networks granted relay permissions +# Use this with care, all hosts in this networks will be able to send mail without authentication! +RELAYNETS= # Will relay all outgoing mails if configured RELAYHOST= diff --git a/docs/compose/docker-compose.yml b/docs/compose/docker-compose.yml index b8d15587..a45e7e10 100644 --- a/docs/compose/docker-compose.yml +++ b/docs/compose/docker-compose.yml @@ -104,3 +104,11 @@ services: image: mailu/fetchmail:$VERSION restart: always env_file: .env + + networks: + default: + driver: bridge + ipam: + driver: default + config: + - subnet: $SUBNET diff --git a/docs/configuration.rst b/docs/configuration.rst index cab30072..2f44b293 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -24,6 +24,11 @@ The ``HOSTNAMES`` are all public hostnames for the mail server. Mailu supports a mail server with multiple hostnames. The first declared hostname is the main hostname and will be exposed over SMTP, IMAP, etc. +The ``SUBNET`` defines the address range of the docker network used by Mailu. +This should not conflict with any networks to which your system is connected. +(Internal and external!). Normally this does not need to be changed, +unless there is a conflict with existing networks. + The ``POSTMASTER`` is the local part of the postmaster email address. It is recommended to setup a generic value and later configure a mail alias for that address. @@ -40,9 +45,9 @@ be too low to avoid dropping legitimate emails and should not be too high to avoid filling the disks with large junk emails. The ``RELAYNETS`` are network addresses for which mail is relayed for free with -no authentication required. This should be used with great care. It is -recommended to include your Docker internal network addresses if other Docker -containers use Mailu as their mail relay. +no authentication required. This should be used with great care. If you want other +Docker services' outbound mail to be relayed, you can set this to ``172.16.0.0/12`` +to include **all** Docker networks. The default is to leave this empty. The ``RELAYHOST`` is an optional address of a mail server relaying all outgoing mail. diff --git a/services/rspamd/conf/worker-controller.inc b/services/rspamd/conf/worker-controller.inc index b630f7ad..933610ed 100644 --- a/services/rspamd/conf/worker-controller.inc +++ b/services/rspamd/conf/worker-controller.inc @@ -1,4 +1,4 @@ type = "controller"; bind_socket = "*:11334"; password = "mailu"; -secure_ip = "{% if POD_ADDRESS_RANGE %}{{ POD_ADDRESS_RANGE }}{% else %}{{ FRONT_ADDRESS }}{% endif %}"; +secure_ip = "{{ POD_ADDRESS_RANGE or SUBNET }}"; diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index 3f67b0dd..d8a99aa6 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -25,8 +25,8 @@ SECRET_KEY={{ secret(16) }} # PUBLIC_IPV4= {{ bind4 }} (default: 127.0.0.1) # PUBLIC_IPV6= {{ bind6 }} (default: ::1) -# Subnet -SUBNET={{ subnet }} +# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!) +SUBNET=192.168.203.0/24 # Main mail domain DOMAIN={{ domain }} @@ -75,9 +75,9 @@ ANTISPAM={{ antispam_enabled or 'none'}} # Default: accept messages up to 50MB MESSAGE_SIZE_LIMIT={{ message_size_limit or '50000000' }} -# Networks granted relay permissions, make sure that you include your Docker -# internal network (default to 172.17.0.0/16) -RELAYNETS={{ relaynets or '172.17.0.0/16' }} +# Networks granted relay permissions +# Use this with care, all hosts in this networks will be able to send mail without authentication! +RELAYNETS= # Will relay all outgoing mails if configured RELAYHOST={{ relayhost }} diff --git a/setup/flavors/stack/docker-compose.yml b/setup/flavors/stack/docker-compose.yml index 98ba61b1..a083a762 100644 --- a/setup/flavors/stack/docker-compose.yml +++ b/setup/flavors/stack/docker-compose.yml @@ -29,7 +29,7 @@ services: - "{{ root }}/certs:/certs" deploy: replicas: {{ front_replicas }} - + {% if resolver_enabled %} resolver: image: mailu/unbound:{{ version }} @@ -56,8 +56,6 @@ services: image: ${DOCKER_ORG:-mailu}/dovecot:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} environment: - # Default to 10.0.1.0/24 - - POD_ADDRESS_RANGE={{ subnet }} volumes: - "{{ root }}/mail:/mail" - "{{ root }}/overrides:/overrides" @@ -67,8 +65,6 @@ services: smtp: image: ${DOCKER_ORG:-mailu}/postfix:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} - environment: - - POD_ADDRESS_RANGE={{ subnet }} volumes: - "{{ root }}/overrides:/overrides" deploy: @@ -81,8 +77,6 @@ services: antispam: image: ${DOCKER_ORG:-mailu}/rspamd:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} - environment: - - POD_ADDRESS_RANGE={{ subnet }} volumes: - "{{ root }}/filter:/var/lib/rspamd" - "{{ root }}/dkim:/dkim" diff --git a/setup/templates/steps/compose/03_expose.html b/setup/templates/steps/compose/03_expose.html index 783c2037..0c912778 100644 --- a/setup/templates/steps/compose/03_expose.html +++ b/setup/templates/steps/compose/03_expose.html @@ -34,9 +34,9 @@ avoid generic all-interfaces addresses like 0.0.0.0 or ::
- + + value="192.168.203.0/24">

You server will be available under a main hostname but may expose multiple public diff --git a/setup/templates/steps/stack/03_expose.html b/setup/templates/steps/stack/03_expose.html index d47390be..820ff154 100644 --- a/setup/templates/steps/stack/03_expose.html +++ b/setup/templates/steps/stack/03_expose.html @@ -11,9 +11,9 @@ you expose it to the world.

- + + value="192.168.203.0/24">

You server will be available under a main hostname but may expose multiple public diff --git a/tests/compose/core/mailu.env b/tests/compose/core/mailu.env index 9a744e35..d77f3a2d 100644 --- a/tests/compose/core/mailu.env +++ b/tests/compose/core/mailu.env @@ -25,6 +25,9 @@ SECRET_KEY=HGZCYGVI6FVG31HS # PUBLIC_IPV4= 127.0.0.1 (default: 127.0.0.1) # PUBLIC_IPV6= (default: ::1) +# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!) +SUBNET=192.168.203.0/24 + # Main mail domain DOMAIN=mailu.io @@ -70,9 +73,9 @@ ANTISPAM=none # Default: accept messages up to 50MB MESSAGE_SIZE_LIMIT=50000000 -# Networks granted relay permissions, make sure that you include your Docker -# internal network (default to 172.17.0.0/16) -RELAYNETS=172.17.0.0/16 +# Networks granted relay permissions +# Use this with care, all hosts in this networks will be able to send mail without authentication! +RELAYNETS= # Will relay all outgoing mails if configured RELAYHOST= @@ -136,4 +139,4 @@ REAL_IP_HEADER= REAL_IP_FROM= # choose wether mailu bounces (no) or rejects (yes) mail when recipient is unknown (value: yes, no) -REJECT_UNLISTED_RECIPIENT= \ No newline at end of file +REJECT_UNLISTED_RECIPIENT= diff --git a/tests/compose/fetchmail/mailu.env b/tests/compose/fetchmail/mailu.env index a987c853..996dbb73 100644 --- a/tests/compose/fetchmail/mailu.env +++ b/tests/compose/fetchmail/mailu.env @@ -70,9 +70,9 @@ ANTISPAM=none # Default: accept messages up to 50MB MESSAGE_SIZE_LIMIT=50000000 -# Networks granted relay permissions, make sure that you include your Docker -# internal network (default to 172.17.0.0/16) -RELAYNETS=172.17.0.0/16 +# Networks granted relay permissions +# Use this with care, all hosts in this networks will be able to send mail without authentication! +RELAYNETS= # Will relay all outgoing mails if configured RELAYHOST= @@ -136,4 +136,4 @@ REAL_IP_HEADER= REAL_IP_FROM= # choose wether mailu bounces (no) or rejects (yes) mail when recipient is unknown (value: yes, no) -REJECT_UNLISTED_RECIPIENT= \ No newline at end of file +REJECT_UNLISTED_RECIPIENT= diff --git a/tests/compose/filters/mailu.env b/tests/compose/filters/mailu.env index 8609a287..c8c99d26 100644 --- a/tests/compose/filters/mailu.env +++ b/tests/compose/filters/mailu.env @@ -70,9 +70,9 @@ ANTISPAM=none # Default: accept messages up to 50MB MESSAGE_SIZE_LIMIT=50000000 -# Networks granted relay permissions, make sure that you include your Docker -# internal network (default to 172.17.0.0/16) -RELAYNETS=172.17.0.0/16 +# Networks granted relay permissions +# Use this with care, all hosts in this networks will be able to send mail without authentication! +RELAYNETS= # Will relay all outgoing mails if configured RELAYHOST= @@ -136,4 +136,4 @@ REAL_IP_HEADER= REAL_IP_FROM= # choose wether mailu bounces (no) or rejects (yes) mail when recipient is unknown (value: yes, no) -REJECT_UNLISTED_RECIPIENT= \ No newline at end of file +REJECT_UNLISTED_RECIPIENT= diff --git a/tests/compose/rainloop/mailu.env b/tests/compose/rainloop/mailu.env index 678ea048..bc9cebbb 100644 --- a/tests/compose/rainloop/mailu.env +++ b/tests/compose/rainloop/mailu.env @@ -70,9 +70,9 @@ ANTISPAM=none # Default: accept messages up to 50MB MESSAGE_SIZE_LIMIT=50000000 -# Networks granted relay permissions, make sure that you include your Docker -# internal network (default to 172.17.0.0/16) -RELAYNETS=172.17.0.0/16 +# Networks granted relay permissions +# Use this with care, all hosts in this networks will be able to send mail without authentication! +RELAYNETS= # Will relay all outgoing mails if configured RELAYHOST= @@ -136,4 +136,4 @@ REAL_IP_HEADER= REAL_IP_FROM= # choose wether mailu bounces (no) or rejects (yes) mail when recipient is unknown (value: yes, no) -REJECT_UNLISTED_RECIPIENT= \ No newline at end of file +REJECT_UNLISTED_RECIPIENT= diff --git a/tests/compose/roundcube/mailu.env b/tests/compose/roundcube/mailu.env index b8a8b266..6eac05ed 100644 --- a/tests/compose/roundcube/mailu.env +++ b/tests/compose/roundcube/mailu.env @@ -70,9 +70,9 @@ ANTISPAM=none # Default: accept messages up to 50MB MESSAGE_SIZE_LIMIT=50000000 -# Networks granted relay permissions, make sure that you include your Docker -# internal network (default to 172.17.0.0/16) -RELAYNETS=172.17.0.0/16 +# Networks granted relay permissions +# Use this with care, all hosts in this networks will be able to send mail without authentication! +RELAYNETS= # Will relay all outgoing mails if configured RELAYHOST= @@ -136,4 +136,4 @@ REAL_IP_HEADER= REAL_IP_FROM= # choose wether mailu bounces (no) or rejects (yes) mail when recipient is unknown (value: yes, no) -REJECT_UNLISTED_RECIPIENT= \ No newline at end of file +REJECT_UNLISTED_RECIPIENT= diff --git a/tests/compose/webdav/mailu.env b/tests/compose/webdav/mailu.env index 21dd3981..96c2b6e9 100644 --- a/tests/compose/webdav/mailu.env +++ b/tests/compose/webdav/mailu.env @@ -70,9 +70,9 @@ ANTISPAM=none # Default: accept messages up to 50MB MESSAGE_SIZE_LIMIT=50000000 -# Networks granted relay permissions, make sure that you include your Docker -# internal network (default to 172.17.0.0/16) -RELAYNETS=172.17.0.0/16 +# Networks granted relay permissions +# Use this with care, all hosts in this networks will be able to send mail without authentication! +RELAYNETS= # Will relay all outgoing mails if configured RELAYHOST= @@ -136,4 +136,4 @@ REAL_IP_HEADER= REAL_IP_FROM= # choose wether mailu bounces (no) or rejects (yes) mail when recipient is unknown (value: yes, no) -REJECT_UNLISTED_RECIPIENT= \ No newline at end of file +REJECT_UNLISTED_RECIPIENT= From 8acf9451fac69bccb158cbd24ecf767adff588b4 Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Fri, 23 Nov 2018 14:12:22 +0200 Subject: [PATCH 07/62] Changed admin and user creation command --- tests/compose/core/00_create_users.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/compose/core/00_create_users.sh b/tests/compose/core/00_create_users.sh index 967e13b7..43e82f3f 100755 --- a/tests/compose/core/00_create_users.sh +++ b/tests/compose/core/00_create_users.sh @@ -1,4 +1,4 @@ echo "Creating users ..." -docker-compose -f tests/compose/core/docker-compose.yml exec admin python3 manage.py admin admin mailu.io password || exit 1 -docker-compose -f tests/compose/core/docker-compose.yml exec admin python3 manage.py user --hash_scheme='SHA512-CRYPT' user mailu.io 'password' || exit 1 +docker-compose -f tests/compose/core/docker-compose.yml exec admin flask mailu admin admin mailu.io password || exit 1 +docker-compose -f tests/compose/core/docker-compose.yml exec admin flask mailu user --hash_scheme='SHA512-CRYPT' user mailu.io 'password' || exit 1 echo "Admin and user successfully created!" From 35be1710a674e5f432ba7df397724d9292322ae3 Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Fri, 23 Nov 2018 14:37:55 +0200 Subject: [PATCH 08/62] Changed user creation command --- tests/compose/core/00_create_users.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/compose/core/00_create_users.sh b/tests/compose/core/00_create_users.sh index 43e82f3f..40d0bd6e 100755 --- a/tests/compose/core/00_create_users.sh +++ b/tests/compose/core/00_create_users.sh @@ -1,4 +1,4 @@ echo "Creating users ..." docker-compose -f tests/compose/core/docker-compose.yml exec admin flask mailu admin admin mailu.io password || exit 1 -docker-compose -f tests/compose/core/docker-compose.yml exec admin flask mailu user --hash_scheme='SHA512-CRYPT' user mailu.io 'password' || exit 1 +docker-compose -f tests/compose/core/docker-compose.yml exec admin flask mailu user user mailu.io 'password' 'SHA512-CRYPT' || exit 1 echo "Admin and user successfully created!" From c0972face65dcc04c822a2f374ecb0131b6e3733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Thu, 6 Dec 2018 16:44:12 +0200 Subject: [PATCH 09/62] Correct subnetting functionality for the tests and setup --- setup/flavors/compose/docker-compose.yml | 4 +--- setup/flavors/compose/mailu.env | 2 +- tests/compose/core/docker-compose.yml | 9 +++++++++ tests/compose/fetchmail/docker-compose.yml | 9 +++++++++ tests/compose/fetchmail/mailu.env | 3 +++ tests/compose/filters/docker-compose.yml | 9 +++++++++ tests/compose/filters/mailu.env | 3 +++ tests/compose/rainloop/docker-compose.yml | 9 +++++++++ tests/compose/rainloop/mailu.env | 3 +++ tests/compose/roundcube/docker-compose.yml | 9 +++++++++ tests/compose/roundcube/mailu.env | 3 +++ tests/compose/webdav/docker-compose.yml | 9 +++++++++ tests/compose/webdav/mailu.env | 3 +++ 13 files changed, 71 insertions(+), 4 deletions(-) diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml index cc45ca99..38322cd3 100644 --- a/setup/flavors/compose/docker-compose.yml +++ b/setup/flavors/compose/docker-compose.yml @@ -146,8 +146,7 @@ services: depends_on: - imap {% endif %} - -{% if resolver_enabled %} + networks: default: driver: bridge @@ -155,4 +154,3 @@ networks: driver: default config: - subnet: {{ subnet }} -{% endif %} diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index d8a99aa6..9f3a2555 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -26,7 +26,7 @@ SECRET_KEY={{ secret(16) }} # PUBLIC_IPV6= {{ bind6 }} (default: ::1) # Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!) -SUBNET=192.168.203.0/24 +SUBNET={{ subnet }} # Main mail domain DOMAIN={{ domain }} diff --git a/tests/compose/core/docker-compose.yml b/tests/compose/core/docker-compose.yml index 397000a6..a7c803b7 100644 --- a/tests/compose/core/docker-compose.yml +++ b/tests/compose/core/docker-compose.yml @@ -78,3 +78,12 @@ services: # Webmail + + +networks: + default: + driver: bridge + ipam: + driver: default + config: + - subnet: 192.168.203.0/24 diff --git a/tests/compose/fetchmail/docker-compose.yml b/tests/compose/fetchmail/docker-compose.yml index 6b1be40e..505fe21b 100644 --- a/tests/compose/fetchmail/docker-compose.yml +++ b/tests/compose/fetchmail/docker-compose.yml @@ -82,3 +82,12 @@ services: env_file: mailu.env # Webmail + + +networks: + default: + driver: bridge + ipam: + driver: default + config: + - subnet: 192.168.203.0/24 diff --git a/tests/compose/fetchmail/mailu.env b/tests/compose/fetchmail/mailu.env index 996dbb73..c91a6deb 100644 --- a/tests/compose/fetchmail/mailu.env +++ b/tests/compose/fetchmail/mailu.env @@ -25,6 +25,9 @@ SECRET_KEY=JS48Q9KE3B6T97E6 # PUBLIC_IPV4= 127.0.0.1 (default: 127.0.0.1) # PUBLIC_IPV6= (default: ::1) +# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!) +SUBNET=192.168.203.0/24 + # Main mail domain DOMAIN=mailu.io diff --git a/tests/compose/filters/docker-compose.yml b/tests/compose/filters/docker-compose.yml index 4fbda49a..463a4384 100644 --- a/tests/compose/filters/docker-compose.yml +++ b/tests/compose/filters/docker-compose.yml @@ -84,3 +84,12 @@ services: # Webmail + + +networks: + default: + driver: bridge + ipam: + driver: default + config: + - subnet: 192.168.203.0/24 diff --git a/tests/compose/filters/mailu.env b/tests/compose/filters/mailu.env index c8c99d26..25c7c133 100644 --- a/tests/compose/filters/mailu.env +++ b/tests/compose/filters/mailu.env @@ -25,6 +25,9 @@ SECRET_KEY=11H6XURLGE7GW3U1 # PUBLIC_IPV4= 127.0.0.1 (default: 127.0.0.1) # PUBLIC_IPV6= (default: ::1) +# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!) +SUBNET=192.168.203.0/24 + # Main mail domain DOMAIN=mailu.io diff --git a/tests/compose/rainloop/docker-compose.yml b/tests/compose/rainloop/docker-compose.yml index c91a92ed..e7cd577c 100644 --- a/tests/compose/rainloop/docker-compose.yml +++ b/tests/compose/rainloop/docker-compose.yml @@ -86,3 +86,12 @@ services: - "/mailu/webmail:/data" depends_on: - imap + + +networks: + default: + driver: bridge + ipam: + driver: default + config: + - subnet: 192.168.203.0/24 diff --git a/tests/compose/rainloop/mailu.env b/tests/compose/rainloop/mailu.env index bc9cebbb..65fef5c8 100644 --- a/tests/compose/rainloop/mailu.env +++ b/tests/compose/rainloop/mailu.env @@ -25,6 +25,9 @@ SECRET_KEY=V5J4SHRYVW9PZIQU # PUBLIC_IPV4= 127.0.0.1 (default: 127.0.0.1) # PUBLIC_IPV6= (default: ::1) +# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!) +SUBNET=192.168.203.0/24 + # Main mail domain DOMAIN=mailu.io diff --git a/tests/compose/roundcube/docker-compose.yml b/tests/compose/roundcube/docker-compose.yml index 567c1c69..8c34a68b 100644 --- a/tests/compose/roundcube/docker-compose.yml +++ b/tests/compose/roundcube/docker-compose.yml @@ -86,3 +86,12 @@ services: - "/mailu/webmail:/data" depends_on: - imap + + +networks: + default: + driver: bridge + ipam: + driver: default + config: + - subnet: 192.168.203.0/24 diff --git a/tests/compose/roundcube/mailu.env b/tests/compose/roundcube/mailu.env index 6eac05ed..cadaa84a 100644 --- a/tests/compose/roundcube/mailu.env +++ b/tests/compose/roundcube/mailu.env @@ -25,6 +25,9 @@ SECRET_KEY=PGGO2JRQ59QV3DW7 # PUBLIC_IPV4= 127.0.0.1 (default: 127.0.0.1) # PUBLIC_IPV6= (default: ::1) +# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!) +SUBNET=192.168.203.0/24 + # Main mail domain DOMAIN=mailu.io diff --git a/tests/compose/webdav/docker-compose.yml b/tests/compose/webdav/docker-compose.yml index 8e0db6e3..e0d5f385 100644 --- a/tests/compose/webdav/docker-compose.yml +++ b/tests/compose/webdav/docker-compose.yml @@ -84,3 +84,12 @@ services: # Webmail + + +networks: + default: + driver: bridge + ipam: + driver: default + config: + - subnet: 192.168.203.0/24 diff --git a/tests/compose/webdav/mailu.env b/tests/compose/webdav/mailu.env index 96c2b6e9..7141bf1f 100644 --- a/tests/compose/webdav/mailu.env +++ b/tests/compose/webdav/mailu.env @@ -25,6 +25,9 @@ SECRET_KEY=XVDDSWOAGVF5J9QJ # PUBLIC_IPV4= 127.0.0.1 (default: 127.0.0.1) # PUBLIC_IPV6= (default: ::1) +# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!) +SUBNET=192.168.203.0/24 + # Main mail domain DOMAIN=mailu.io From a2a9512afaf3cc550820dc0f42c77c3b0fcd7929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 7 Dec 2018 11:53:43 +0200 Subject: [PATCH 10/62] Enable mergify strict mode In the past we had strict mode in branch protection. This didn't really work as it broke mergify. Now mergify supports this options and takes care of the merging automatically. Let's see how it goes ;) Reason is the recent build failures we had on master, during a busy merge day. This could have been prevented if sequential PR's where re-merging with master. More info: https://doc.mergify.io/strict-workflow.html --- .mergify.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mergify.yml b/.mergify.yml index 023bf59b..1cbb0999 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -6,6 +6,7 @@ pull_request_rules: actions: merge: method: merge + strict: true - name: Trusted author, successful travis and 1 approved review conditions: - author~=(kaiyou|muhlemmer|mildred|HorayNarea|adi90x|hoellen|ofthesun9) @@ -14,3 +15,4 @@ pull_request_rules: actions: merge: method: merge + strict: true From 94edb48f08653957db54a8ff6ae3a85ccb7438d1 Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Fri, 7 Dec 2018 13:37:40 +0200 Subject: [PATCH 11/62] Dynamic attachment size --- docs/compose/.env | 1 + setup/flavors/compose/mailu.env | 1 + webmails/rainloop/Dockerfile | 2 +- webmails/rainloop/config.ini | 2 +- webmails/rainloop/php.ini | 5 +++-- webmails/rainloop/start.py | 3 +++ webmails/roundcube/Dockerfile | 4 ++-- webmails/roundcube/php.ini | 5 +++-- webmails/roundcube/start.py | 7 +++++++ 9 files changed, 22 insertions(+), 8 deletions(-) diff --git a/docs/compose/.env b/docs/compose/.env index 2100e27a..7b1e6d01 100644 --- a/docs/compose/.env +++ b/docs/compose/.env @@ -61,6 +61,7 @@ ANTIVIRUS=none # Message size limit in bytes # Default: accept messages up to 50MB +# Max attachment size will be 33% smaller MESSAGE_SIZE_LIMIT=50000000 # Networks granted relay permissions, make sure that you include your Docker diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index 3f67b0dd..b4505c62 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -73,6 +73,7 @@ ANTISPAM={{ antispam_enabled or 'none'}} # Message size limit in bytes # Default: accept messages up to 50MB +# Max attachment size will be 33% smaller MESSAGE_SIZE_LIMIT={{ message_size_limit or '50000000' }} # Networks granted relay permissions, make sure that you include your Docker diff --git a/webmails/rainloop/Dockerfile b/webmails/rainloop/Dockerfile index db7403f5..92479489 100644 --- a/webmails/rainloop/Dockerfile +++ b/webmails/rainloop/Dockerfile @@ -22,7 +22,7 @@ RUN apt-get update && apt-get install -y \ && rm -rf /var/lib/apt/lists COPY include.php /var/www/html/include.php -COPY php.ini /usr/local/etc/php/conf.d/rainloop.ini +COPY php.ini /php.ini COPY config.ini /config.ini COPY default.ini /default.ini diff --git a/webmails/rainloop/config.ini b/webmails/rainloop/config.ini index 7fb13889..6ae5fff7 100644 --- a/webmails/rainloop/config.ini +++ b/webmails/rainloop/config.ini @@ -1,7 +1,7 @@ ; RainLoop Webmail configuration file [webmail] -attachment_size_limit = 25 +attachment_size_limit = {{ MAX_FILESIZE }} [security] allow_admin_panel = Off diff --git a/webmails/rainloop/php.ini b/webmails/rainloop/php.ini index 9b241b46..39abbdd5 100644 --- a/webmails/rainloop/php.ini +++ b/webmails/rainloop/php.ini @@ -1,3 +1,4 @@ date.timezone=UTC -upload_max_filesize = 25M -post_max_size = 25M +upload_max_filesize = {{ MAX_FILESIZE }}M +post_max_size = {{ MAX_FILESIZE }}M + diff --git a/webmails/rainloop/start.py b/webmails/rainloop/start.py index 9e8465a2..4c116e09 100755 --- a/webmails/rainloop/start.py +++ b/webmails/rainloop/start.py @@ -10,6 +10,8 @@ convert = lambda src, dst: open(dst, "w").write(jinja2.Template(open(src).read() os.environ["FRONT_ADDRESS"] = os.environ.get("FRONT_ADDRESS", "front") os.environ["IMAP_ADDRESS"] = os.environ.get("IMAP_ADDRESS", "imap") +os.environ["MAX_FILESIZE"] = str(int(int(os.environ.get("MESSAGE_SIZE_LIMIT"))*0.66/1048576)) + base = "/data/_data_/_default_/" shutil.rmtree(base + "domains/", ignore_errors=True) os.makedirs(base + "domains", exist_ok=True) @@ -17,6 +19,7 @@ os.makedirs(base + "configs", exist_ok=True) convert("/default.ini", "/data/_data_/_default_/domains/default.ini") convert("/config.ini", "/data/_data_/_default_/configs/config.ini") +convert("/php.ini", "/usr/local/etc/php/conf.d/rainloop.ini") os.system("chown -R www-data:www-data /data") diff --git a/webmails/roundcube/Dockerfile b/webmails/roundcube/Dockerfile index 14bee56e..00b843b2 100644 --- a/webmails/roundcube/Dockerfile +++ b/webmails/roundcube/Dockerfile @@ -7,7 +7,7 @@ RUN apt-get update && apt-get install -y \ ENV ROUNDCUBE_URL https://github.com/roundcube/roundcubemail/releases/download/1.3.8/roundcubemail-1.3.8-complete.tar.gz RUN apt-get update && apt-get install -y \ - zlib1g-dev \ + zlib1g-dev python3-jinja2 \ && docker-php-ext-install zip \ && echo date.timezone=UTC > /usr/local/etc/php/conf.d/timezone.ini \ && rm -rf /var/www/html/ \ @@ -22,7 +22,7 @@ RUN apt-get update && apt-get install -y \ && chown -R www-data: logs temp \ && rm -rf /var/lib/apt/lists -COPY php.ini /usr/local/etc/php/conf.d/roundcube.ini +COPY php.ini /php.ini COPY config.inc.php /var/www/html/config/ COPY start.py /start.py diff --git a/webmails/roundcube/php.ini b/webmails/roundcube/php.ini index 9b241b46..39abbdd5 100644 --- a/webmails/roundcube/php.ini +++ b/webmails/roundcube/php.ini @@ -1,3 +1,4 @@ date.timezone=UTC -upload_max_filesize = 25M -post_max_size = 25M +upload_max_filesize = {{ MAX_FILESIZE }}M +post_max_size = {{ MAX_FILESIZE }}M + diff --git a/webmails/roundcube/start.py b/webmails/roundcube/start.py index 07b3a567..3a0bd0bc 100755 --- a/webmails/roundcube/start.py +++ b/webmails/roundcube/start.py @@ -1,6 +1,13 @@ #!/usr/bin/python3 import os +import jinja2 + +convert = lambda src, dst: open(dst, "w").write(jinja2.Template(open(src).read()).render(**os.environ)) + +os.environ["MAX_FILESIZE"] = str(int(int(os.environ.get("MESSAGE_SIZE_LIMIT"))*0.66/1048576)) + +convert("/php.ini", "/usr/local/etc/php/conf.d/roundcube.ini") # Fix some permissions os.system("mkdir -p /data/gpg") From 626559f99bee40723ffb2e9b5e6faf88446d0db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 7 Dec 2018 13:43:53 +0200 Subject: [PATCH 12/62] Mergify dismiss reviews --- .mergify.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.mergify.yml b/.mergify.yml index 1cbb0999..f00c4086 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -7,6 +7,9 @@ pull_request_rules: merge: method: merge strict: true + dismiss_reviews: + approved: true + - name: Trusted author, successful travis and 1 approved review conditions: - author~=(kaiyou|muhlemmer|mildred|HorayNarea|adi90x|hoellen|ofthesun9) @@ -16,3 +19,5 @@ pull_request_rules: merge: method: merge strict: true + dismiss_reviews: + approved: true From 8e5ccf27541e9bda25fbf989db915dfe58dfd991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 7 Dec 2018 13:47:22 +0200 Subject: [PATCH 13/62] Don't merge when WIP or Blocked --- .mergify.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.mergify.yml b/.mergify.yml index f18eec13..d7299d36 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -2,6 +2,7 @@ pull_request_rules: - name: Successful travis and 2 approved reviews conditions: - status-success=continuous-integration/travis-ci/pr + - label!=["status"/wip","status/blocked"] - "#approved-reviews-by>=2" actions: merge: @@ -10,7 +11,7 @@ pull_request_rules: conditions: - author~=(kaiyou|muhlemmer|mildred|HorayNarea|adi90x|hoellen|ofthesun9) - status-success=continuous-integration/travis-ci/pr - - label!=["review/need2"] + - label!=["status"/wip","status/blocked","review/need2"] - "#approved-reviews-by>=1" actions: merge: From 2de4995fec6a586acd0874135da62d6ca50deb71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 7 Dec 2018 15:17:04 +0200 Subject: [PATCH 14/62] Don't redirect when webmail is served on '/' --- core/nginx/conf/nginx.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index 0bc6cf07..3e605dd2 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -87,7 +87,7 @@ http { include /overrides/*.conf; # Actual logic - {% if WEBROOT_REDIRECT %} + {% if WEBROOT_REDIRECT and WEB_WEBMAIL != '/' %} location / { return 301 {{ WEBROOT_REDIRECT }}; } From 9208d7262f1229216688050eada3eb3fa04f787e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 7 Dec 2018 15:22:01 +0200 Subject: [PATCH 15/62] Correct variable naming in .env --- docs/compose/.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/compose/.env b/docs/compose/.env index bd98df31..5264b91a 100644 --- a/docs/compose/.env +++ b/docs/compose/.env @@ -98,7 +98,7 @@ COMPRESSION_LEVEL= ################################### # Path to redirect / to -WEB_DEFAULT=/webmail +WEBROOT_REDIRECT=/webmail # Path to the admin interface if enabled WEB_ADMIN=/admin From c25ba75d68775c88ae8e9b9019e90c5e6a277b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 7 Dec 2018 15:29:33 +0200 Subject: [PATCH 16/62] Include WEBROOT_REDIRECT in setup templates --- setup/flavors/compose/docker-compose.yml | 3 ++- setup/flavors/compose/mailu.env | 3 +++ setup/flavors/stack/docker-compose.yml | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml index 81b6bcb2..1a77b1de 100644 --- a/setup/flavors/compose/docker-compose.yml +++ b/setup/flavors/compose/docker-compose.yml @@ -28,7 +28,8 @@ services: {% endfor %} volumes: - "{{ root }}/certs:/certs" - + - "{{ root }}/overrides/nginx:/overrides" + {% if resolver_enabled %} resolver: image: mailu/unbound:{{ version }} diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index 4a14de63..c7c60fdf 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -110,6 +110,9 @@ COMPRESSION_LEVEL={{ compression_level }} # Web settings ################################### +# Path to redirect / to +WEBROOT_REDIRECT=/webmail + # Path to the admin interface if enabled WEB_ADMIN={{ admin_path }} diff --git a/setup/flavors/stack/docker-compose.yml b/setup/flavors/stack/docker-compose.yml index b9537e94..6e471f39 100644 --- a/setup/flavors/stack/docker-compose.yml +++ b/setup/flavors/stack/docker-compose.yml @@ -26,9 +26,10 @@ services: {% endfor %} volumes: - "{{ root }}/certs:/certs" + - "{{ root }}/overrides/nginx:/overrides" deploy: replicas: 1 - + {% if resolver_enabled %} resolver: image: mailu/unbound:{{ version }} From 20f1faf6d03ee285ef21bf8e089815474a11f85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 7 Dec 2018 16:10:52 +0200 Subject: [PATCH 17/62] Send 404 when nothing server at '/' Prevents Nginx welcome screen --- core/nginx/conf/nginx.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index 3e605dd2..a169cd75 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -91,6 +91,8 @@ http { location / { return 301 {{ WEBROOT_REDIRECT }}; } + {% else %} + return 404 {% endif %} {% if WEBMAIL != 'none' %} From 425cdd5e7794061e09c9cd31d6cd275d6ca5ba24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 7 Dec 2018 16:29:41 +0200 Subject: [PATCH 18/62] Fix syntax errors --- core/nginx/conf/nginx.conf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index a169cd75..b016b9ca 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -87,12 +87,13 @@ http { include /overrides/*.conf; # Actual logic - {% if WEBROOT_REDIRECT and WEB_WEBMAIL != '/' %} + location / { + {% if WEBROOT_REDIRECT and WEB_WEBMAIL != '/' %} return 301 {{ WEBROOT_REDIRECT }}; - } {% else %} - return 404 + return 404; + } {% endif %} {% if WEBMAIL != 'none' %} From 97d338e68aa3d3afdb9b845530e55de610b7cbb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 7 Dec 2018 16:44:42 +0200 Subject: [PATCH 19/62] Rectify 'endif' placement --- core/nginx/conf/nginx.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index b016b9ca..2fb4b8ef 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -93,8 +93,8 @@ http { return 301 {{ WEBROOT_REDIRECT }}; {% else %} return 404; - } {% endif %} + } {% if WEBMAIL != 'none' %} location {{ WEB_WEBMAIL }} { From 1aa97c9914a4663f7478b5b6b769eb20feb587b0 Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Thu, 6 Dec 2018 16:48:26 +0100 Subject: [PATCH 20/62] Add certificate watcher for external certs to reload nginx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case of TLS_FLAVOR=[mail,cert], the user supplies their own certificates. However, since nginx is not aware of changes to these files, it cannot reload itself e.g. when the certs get renewed. To solve this, let’s add a small daemon in the place of `letsencrypt.py`, which uses a flexible file-watching framework and reloads nginx in the case the certificates change …. --- core/nginx/Dockerfile | 2 +- core/nginx/certwatcher.py | 63 +++++++++++++++++++++++++++++++++++++++ core/nginx/start.py | 2 ++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100755 core/nginx/certwatcher.py diff --git a/core/nginx/Dockerfile b/core/nginx/Dockerfile index 7181487e..37b8580b 100644 --- a/core/nginx/Dockerfile +++ b/core/nginx/Dockerfile @@ -7,7 +7,7 @@ RUN apk add --no-cache \ RUN pip3 install jinja2 # Image specific layers under this line RUN apk add --no-cache certbot nginx nginx-mod-mail openssl curl \ - && pip3 install idna requests + && pip3 install idna requests watchdog COPY conf /conf COPY *.py / diff --git a/core/nginx/certwatcher.py b/core/nginx/certwatcher.py new file mode 100755 index 00000000..3a8682f9 --- /dev/null +++ b/core/nginx/certwatcher.py @@ -0,0 +1,63 @@ +#!/usr/bin/python3 +""" +Certificate watcher which reloads nginx or reconfigures it, depending on what +happens to externally supplied certificates. Only executed by start.py in case +of TLS_FLAVOR=[mail, cert] +""" + +from os.path import exists, split as path_split +from os import system +import time +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler, FileDeletedEvent, \ + FileCreatedEvent, FileModifiedEvent, FileMovedEvent + +class ChangeHandler(FileSystemEventHandler): + "watchdog-handler listening on any event, executing the correct configuration/reload steps" + @staticmethod + def reload_nginx(): + "merely reload nginx without re-configuring everything" + if exists("/var/run/nginx.pid"): + print("Reloading a running nginx") + system("nginx -s reload") + + @staticmethod + def reexec_config(): + "execute a reconfiguration of the system, which also reloads" + print("Reconfiguring system") + system("/config.py") + + def on_any_event(self, event): + "event-listener checking if the affected files are the cert-files we're interested in" + if event.is_directory: + return + + filename = path_split(event.src_path)[-1] + if isinstance(event, FileMovedEvent): + filename = path_split(event.dest_path)[-1] + + if filename in ['cert.pem', 'key.pem']: + # all cases except for FileModified need re-configure + if isinstance(event, (FileCreatedEvent, FileMovedEvent, FileDeletedEvent)): + ChangeHandler.reexec_config() + # file modification needs only a nginx reload without config.py + elif isinstance(event, FileModifiedEvent): + ChangeHandler.reload_nginx() + # cert files have been moved away, re-configure + elif isinstance(event, FileMovedEvent) and path_split(event.src_path)[-1] in ['cert.pem', 'key.pem']: + ChangeHandler.reexec_config() + + +if __name__ == '__main__': + observer = Observer() + handler = ChangeHandler() + observer.schedule(handler, "/certs", recursive=False) + observer.start() + + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + observer.stop() + + observer.join() diff --git a/core/nginx/start.py b/core/nginx/start.py index 7c5fa71e..8673f148 100755 --- a/core/nginx/start.py +++ b/core/nginx/start.py @@ -9,6 +9,8 @@ if os.path.exists("/var/run/nginx.pid"): if os.environ["TLS_FLAVOR"] in [ "letsencrypt","mail-letsencrypt" ]: subprocess.Popen(["/letsencrypt.py"]) +elif os.environ["TLS_FLAVOR"] in [ "mail", "cert" ]: + subprocess.Popen(["/certwatcher.py"]) subprocess.call(["/config.py"]) os.execv("/usr/sbin/nginx", ["nginx", "-g", "daemon off;"]) From c1839b1ec127bfa8f87e2788aa341b6ed4f58c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sat, 8 Dec 2018 23:47:37 +0200 Subject: [PATCH 21/62] Increase health start period for clamav's DB download --- optional/clamav/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optional/clamav/Dockerfile b/optional/clamav/Dockerfile index b3df2d45..a4a889c7 100644 --- a/optional/clamav/Dockerfile +++ b/optional/clamav/Dockerfile @@ -15,4 +15,4 @@ VOLUME ["/data"] CMD /start.py -HEALTHCHECK CMD /health.sh +HEALTHCHECK --start-period=350s CMD /health.sh From 79768c09f62b6afe20fd05041147d086a48a1845 Mon Sep 17 00:00:00 2001 From: hoellen Date: Sun, 9 Dec 2018 19:49:23 +0100 Subject: [PATCH 22/62] fix alias matching behaviour --- core/admin/mailu/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 18e995bf..1463af8e 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -426,7 +426,7 @@ class Alias(Base, Email): ) ) ) - ).first() + ).order_by(sqlalchemy.func.char_length(cls.localpart).desc()).first() class Token(Base): From 8fe9e695f3abd2422271b7c72a40c2d59366ed0f Mon Sep 17 00:00:00 2001 From: hoellen Date: Mon, 10 Dec 2018 08:40:10 +0100 Subject: [PATCH 23/62] prefer non-wildcard aliases over wildcard aliases --- core/admin/mailu/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 1463af8e..a3fc15a4 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -426,7 +426,7 @@ class Alias(Base, Email): ) ) ) - ).order_by(sqlalchemy.func.char_length(cls.localpart).desc()).first() + ).order_by(cls.wildcard, sqlalchemy.func.char_length(cls.localpart).desc()).first() class Token(Base): From bb0fd896b39fce4679938c540d2f5b2119091e3f Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Tue, 11 Dec 2018 17:31:21 +0200 Subject: [PATCH 24/62] Fix some bugs in setup for stack flavor - Unbound and webmail images were hardcoded - Removed unnecesary environment keyword --- setup/flavors/stack/docker-compose.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/setup/flavors/stack/docker-compose.yml b/setup/flavors/stack/docker-compose.yml index eef8e334..217667e1 100644 --- a/setup/flavors/stack/docker-compose.yml +++ b/setup/flavors/stack/docker-compose.yml @@ -33,7 +33,7 @@ services: {% if resolver_enabled %} resolver: - image: mailu/unbound:{{ version }} + image: ${DOCKER_ORG:-mailu}/unbound:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} networks: default: @@ -56,7 +56,6 @@ services: imap: image: ${DOCKER_ORG:-mailu}/dovecot:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} - environment: volumes: - "{{ root }}/mail:/mail" - "{{ root }}/overrides:/overrides" @@ -130,7 +129,7 @@ services: {% if webmail_type != 'none' %} webmail: - image: ${DOCKER_ORG:-mailu}/roundcube:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/{{ webmail_type }}:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} volumes: - "{{ root }}/webmail:/data" From 514d179db1993d04bb033eb683cd1dce5b87eb68 Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Tue, 11 Dec 2018 17:40:36 +0200 Subject: [PATCH 25/62] Fixed networks indentation --- docs/compose/docker-compose.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/compose/docker-compose.yml b/docs/compose/docker-compose.yml index 2bda5f8c..088d6302 100644 --- a/docs/compose/docker-compose.yml +++ b/docs/compose/docker-compose.yml @@ -105,11 +105,11 @@ services: image: mailu/fetchmail:$VERSION restart: always env_file: .env - - networks: - default: - driver: bridge - ipam: + +networks: + default: + driver: bridge + ipam: driver: default config: - subnet: $SUBNET From b5f51b0e2ecdfbe8367408024b83d44dd475c54f Mon Sep 17 00:00:00 2001 From: kaiyou Date: Thu, 13 Dec 2018 14:09:46 +0100 Subject: [PATCH 26/62] Update python dependencies --- core/admin/requirements-prod.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/admin/requirements-prod.txt b/core/admin/requirements-prod.txt index 2ca59edc..a538c023 100644 --- a/core/admin/requirements-prod.txt +++ b/core/admin/requirements-prod.txt @@ -1,13 +1,13 @@ alembic==1.0.2 asn1crypto==0.24.0 Babel==2.6.0 -bcrypt==3.1.4 +bcrypt==3.1.5 blinker==1.4 cffi==1.11.5 Click==7.0 cryptography==2.3.1 decorator==4.3.0 -dnspython==1.15.0 +dnspython==1.16.0 dominate==2.3.4 Flask==1.0.2 Flask-Babel==0.12.2 @@ -15,7 +15,7 @@ Flask-Bootstrap==3.3.7.1 Flask-DebugToolbar==0.10.1 Flask-Limiter==1.0.1 Flask-Login==0.4.1 -Flask-Migrate==2.3.0 +Flask-Migrate==2.3.1 Flask-Script==2.0.6 Flask-SQLAlchemy==2.3.2 Flask-WTF==0.14.2 @@ -35,10 +35,11 @@ python-dateutil==2.7.5 python-editor==1.0.3 pytz==2018.7 PyYAML==3.13 -redis==2.10.6 +redis==3.0.1 six==1.11.0 SQLAlchemy==1.2.13 tabulate==0.8.2 +tenacity==5.0.2 validators==0.12.2 visitor==0.1.3 Werkzeug==0.14.1 From 087841d5b705942cc50d9fabf3e91e8530501d65 Mon Sep 17 00:00:00 2001 From: kaiyou Date: Thu, 13 Dec 2018 14:23:17 +0100 Subject: [PATCH 27/62] Fix the way we handle the application context The init script was pushing an application context, which maked flask.g global and persisted across requests. This was evaluated to have a minimal security impact. This explains/fixes #738: flask_wtf caches the csrf token in the application context to have a single token per request, and only sets the session attribute after the first generation. --- core/admin/mailu/__init__.py | 1 - core/admin/mailu/internal/views/auth.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/core/admin/mailu/__init__.py b/core/admin/mailu/__init__.py index 6b245c3b..4de3e580 100644 --- a/core/admin/mailu/__init__.py +++ b/core/admin/mailu/__init__.py @@ -8,7 +8,6 @@ def create_app_from_config(config): """ Create a new application based on the given configuration """ app = flask.Flask(__name__) - app.app_context().push() app.cli.add_command(manage.mailu) # Bootstrap is used for basic JS and CSS loading diff --git a/core/admin/mailu/internal/views/auth.py b/core/admin/mailu/internal/views/auth.py index 459a8e57..83a63953 100644 --- a/core/admin/mailu/internal/views/auth.py +++ b/core/admin/mailu/internal/views/auth.py @@ -9,7 +9,7 @@ import base64 @internal.route("/auth/email") @utils.limiter.limit( - app.config["AUTH_RATELIMIT"], + lambda: app.config["AUTH_RATELIMIT"], lambda: flask.request.headers["Client-Ip"] ) def nginx_authentication(): From 4060ac22237e0f0b179b9e533030092058f77d7a Mon Sep 17 00:00:00 2001 From: kaiyou Date: Thu, 13 Dec 2018 15:17:53 +0100 Subject: [PATCH 28/62] Remove some forgotten debugging --- core/admin/mailu/internal/views/dovecot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/core/admin/mailu/internal/views/dovecot.py b/core/admin/mailu/internal/views/dovecot.py index 762bd941..463ecc20 100644 --- a/core/admin/mailu/internal/views/dovecot.py +++ b/core/admin/mailu/internal/views/dovecot.py @@ -13,7 +13,6 @@ def dovecot_passdb_dict(user_email): allow_nets.append(app.config["SUBNET"]) if app.config["POD_ADDRESS_RANGE"]: allow_nets.append(app.config["POD_ADDRESS_RANGE"]) - print(allow_nets) return flask.jsonify({ "password": None, "nopassword": "Y", From a5d6acfb9641c2b415ba550e1605723d5377e886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sat, 15 Dec 2018 21:40:00 +0200 Subject: [PATCH 29/62] Use MAILU_VERSION from Travis for Docs build --- tests/build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/build.yml b/tests/build.yml index a2b4739c..0d89c5b8 100644 --- a/tests/build.yml +++ b/tests/build.yml @@ -52,7 +52,10 @@ services: docs: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}docs:${MAILU_VERSION:-local} - build: ../docs + build: + context: ../docs + args: + version: ${MAILU_VERSION:-local} setup: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}setup:${MAILU_VERSION:-local} From 9c284c4004e5451f85563e7429f8ea47ef3a5227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 16 Dec 2018 16:26:45 +0200 Subject: [PATCH 30/62] Prepare setup for multi-ver deployment on docs server --- setup/.env | 8 ++++ setup/Dockerfile | 11 ++--- setup/docker-compose.yml | 30 ++++++++++--- setup/requirements.txt | 1 - setup/server.py | 90 +++++++++++++++++---------------------- setup/setup.py | 39 ----------------- setup/templates/base.html | 4 +- setup/test | 0 8 files changed, 79 insertions(+), 104 deletions(-) create mode 100644 setup/.env delete mode 100644 setup/setup.py delete mode 100644 setup/test diff --git a/setup/.env b/setup/.env new file mode 100644 index 00000000..47db5c89 --- /dev/null +++ b/setup/.env @@ -0,0 +1,8 @@ +# Hostname passed to Traefik +HOSTNAME=setup.mailu.io + +# Current release +RELEASE=test + +# Comma separated list of versions the user can choose. +VERSIONS=test,master diff --git a/setup/Dockerfile b/setup/Dockerfile index e39d7c3b..5787c003 100644 --- a/setup/Dockerfile +++ b/setup/Dockerfile @@ -4,20 +4,17 @@ RUN mkdir -p /app WORKDIR /app COPY requirements.txt requirements.txt -RUN apk add --no-cache git curl \ +RUN apk add --no-cache curl \ && pip install -r requirements.txt COPY server.py ./server.py -COPY setup.py ./setup.py COPY main.py ./main.py -COPY flavors /data/master/flavors -COPY templates /data/master/templates +COPY flavors /data/flavors +COPY templates /data/templates COPY static ./static -#RUN python setup.py https://github.com/mailu/mailu /data - EXPOSE 80/tcp CMD gunicorn -w 4 -b :80 --access-logfile - --error-logfile - --preload main:app -HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1 +HEALTHCHECK CMD curl -f -L http://localhost/master/ || exit 1 diff --git a/setup/docker-compose.yml b/setup/docker-compose.yml index 42e7ee18..317f9fd2 100644 --- a/setup/docker-compose.yml +++ b/setup/docker-compose.yml @@ -6,9 +6,29 @@ services: redis: image: redis:alpine - setup: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}setup:${MAILU_VERSION:-master} - ports: - - "8000:80" - build: . + setup_master: + image: mailu/setup:master + env_file: .env + environment: + this_version: "master" + labels: + - traefik.enable=true + - traefik.port=80 + - traefik.main.frontend.rule=Host:${HOSTNAME};PathPrefix:/master/ + depends_on: + - redis + setup_release: + image: mailu/setup:${RELEASE} + env_file: .env + environment: + this_version: ${RELEASE} + labels: + - traefik.enable=true + - traefik.port=80 + - traefik.root.frontend.redirect.regex=.* + - traefik.root.frontend.redirect.replacement=/${RELEASE}/ + - traefik.root.frontend.rule=Host:${HOSTNAME};PathPrefix:/ + - traefik.main.frontend.rule=Host:${HOSTNAME};PathPrefix:/${RELEASE}/ + depends_on: + - redis diff --git a/setup/requirements.txt b/setup/requirements.txt index ea2a2c25..b6bf2120 100644 --- a/setup/requirements.txt +++ b/setup/requirements.txt @@ -1,5 +1,4 @@ flask flask-bootstrap redis -gitpython gunicorn diff --git a/setup/server.py b/setup/server.py index 6f60c3c0..456cb539 100644 --- a/setup/server.py +++ b/setup/server.py @@ -33,70 +33,60 @@ def secret(length=16): def build_app(path): - #Hardcoded master as the only version for test purposes - versions = [ - # version for version in os.listdir(path) - # if os.path.isdir(os.path.join(path, version)) - "master" - ] - app.jinja_env.trim_blocks = True app.jinja_env.lstrip_blocks = True @app.context_processor def app_context(): - return dict(versions=versions) + return dict(versions=os.getenv("VERSIONS","master").split(',')) - @app.route("/") - def index(): - return flask.redirect(flask.url_for('{}.wizard'.format(versions[-1]))) + version = os.getenv("this_version") - for version in versions: - bp = flask.Blueprint(version, __name__) - bp.jinja_loader = jinja2.ChoiceLoader([ - jinja2.FileSystemLoader(os.path.join(path, version, "templates")), - jinja2.FileSystemLoader(os.path.join(path, version, "flavors")) - ]) + bp = flask.Blueprint(version, __name__) + bp.jinja_loader = jinja2.ChoiceLoader([ + jinja2.FileSystemLoader(os.path.join(path, "templates")), + jinja2.FileSystemLoader(os.path.join(path, "flavors")) + ]) - @bp.context_processor - def bp_context(version=version): - return dict(version=version) + @bp.context_processor + def bp_context(version=version): + return dict(version=version) - @bp.route("/") - def wizard(): - return flask.render_template('wizard.html') + @bp.route("/") + def wizard(): + return flask.render_template('wizard.html') - @bp.route("/submit_flavor", methods=["POST"]) - def submit_flavor(): - data = flask.request.form.copy() - steps = sorted(os.listdir(path + "/" + version + "/templates/steps/" + data["flavor"])) - return flask.render_template('wizard.html', flavor=data["flavor"], steps=steps) + @bp.route("/submit_flavor", methods=["POST"]) + def submit_flavor(): + data = flask.request.form.copy() + steps = sorted(os.listdir(os.path.join(path, "templates", "steps", data["flavor"]))) + return flask.render_template('wizard.html', flavor=data["flavor"], steps=steps) - @bp.route("/submit", methods=["POST"]) - def submit(): - data = flask.request.form.copy() - data['uid'] = str(uuid.uuid4()) - data['dns'] = str(ipaddress.IPv4Network(data['subnet'])[-2]) - db.set(data['uid'], json.dumps(data)) - return flask.redirect(flask.url_for('.setup', uid=data['uid'])) + @bp.route("/submit", methods=["POST"]) + def submit(): + data = flask.request.form.copy() + data['uid'] = str(uuid.uuid4()) + data['dns'] = str(ipaddress.IPv4Network(data['subnet'])[-2]) + db.set(data['uid'], json.dumps(data)) + return flask.redirect(flask.url_for('.setup', uid=data['uid'])) - @bp.route("/setup/", methods=["GET"]) - def setup(uid): - data = json.loads(db.get(uid)) - flavor = data.get("flavor", "compose") - rendered = render_flavor(flavor, "setup.html", data) - return flask.render_template("setup.html", contents=rendered) + @bp.route("/setup/", methods=["GET"]) + def setup(uid): + data = json.loads(db.get(uid)) + flavor = data.get("flavor", "compose") + rendered = render_flavor(flavor, "setup.html", data) + return flask.render_template("setup.html", contents=rendered) - @bp.route("/file//", methods=["GET"]) - def file(uid, filepath): - data = json.loads(db.get(uid)) - flavor = data.get("flavor", "compose") - return flask.Response( - render_flavor(flavor, filepath, data), - mimetype="application/text" - ) + @bp.route("/file//", methods=["GET"]) + def file(uid, filepath): + data = json.loads(db.get(uid)) + flavor = data.get("flavor", "compose") + return flask.Response( + render_flavor(flavor, filepath, data), + mimetype="application/text" + ) - app.register_blueprint(bp, url_prefix="/{}".format(version)) + app.register_blueprint(bp, url_prefix="/{}".format(version)) if __name__ == "__main__": diff --git a/setup/setup.py b/setup/setup.py deleted file mode 100644 index e08c0092..00000000 --- a/setup/setup.py +++ /dev/null @@ -1,39 +0,0 @@ -import git -import tempfile -import argparse -import os -import shutil -import re - - -VERSION_BRANCH = re.compile("(master|\d+\.\d+)") - - -def main(upstream, dest, dev=True): - shutil.rmtree(dest, ignore_errors=True) - os.makedirs(dest, exist_ok=True) - with tempfile.TemporaryDirectory() as clone_path: - repo = git.Repo.clone_from(upstream, clone_path) - for branch in repo.refs: - if not branch.name.startswith("origin/"): - continue - name = branch.name[len("origin/"):] - if not VERSION_BRANCH.match(name): - continue - branch.checkout() - config_path = os.path.join(clone_path, "setup") - if os.path.exists(config_path): - shutil.copytree(config_path, os.path.join(dest, name)) - print("Imported branch {}".format(name)) - if dev: - shutil.copytree(".", os.path.join(dest, "dev")) - print("Imported dev") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--dev", action="store_true", help="Copy the local dir in /dev") - parser.add_argument("upstream", help="Path to Mailu git repository") - parser.add_argument("dest", help="Destination directory for data files") - args = parser.parse_args() - main(**vars(args)) diff --git a/setup/templates/base.html b/setup/templates/base.html index 5be0b1eb..c53bd1d1 100644 --- a/setup/templates/base.html +++ b/setup/templates/base.html @@ -9,8 +9,8 @@

Version

diff --git a/setup/test b/setup/test deleted file mode 100644 index e69de29b..00000000 From db9a3787b166fbccc14b50c332b79acb29103a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 16 Dec 2018 22:31:13 +0200 Subject: [PATCH 31/62] Disable healthcheck, doen't work in versioned env --- setup/Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/Dockerfile b/setup/Dockerfile index 5787c003..7c4ba773 100644 --- a/setup/Dockerfile +++ b/setup/Dockerfile @@ -16,5 +16,3 @@ COPY static ./static EXPOSE 80/tcp CMD gunicorn -w 4 -b :80 --access-logfile - --error-logfile - --preload main:app - -HEALTHCHECK CMD curl -f -L http://localhost/master/ || exit 1 From 8ef0493f53913c1a08950ce50b5312ec11458330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 16 Dec 2018 23:05:03 +0200 Subject: [PATCH 32/62] Define external web network for Traefik connections --- setup/docker-compose.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/setup/docker-compose.yml b/setup/docker-compose.yml index 317f9fd2..5a16e5b5 100644 --- a/setup/docker-compose.yml +++ b/setup/docker-compose.yml @@ -8,6 +8,8 @@ services: setup_master: image: mailu/setup:master + networks: + - web env_file: .env environment: this_version: "master" @@ -20,6 +22,8 @@ services: setup_release: image: mailu/setup:${RELEASE} + networks: + - web env_file: .env environment: this_version: ${RELEASE} @@ -32,3 +36,7 @@ services: - traefik.main.frontend.rule=Host:${HOSTNAME};PathPrefix:/${RELEASE}/ depends_on: - redis + +networks: + web: + external: true From 1df3b464547736dac5e1b8f81ad46cc6a6d37f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 16 Dec 2018 23:11:43 +0200 Subject: [PATCH 33/62] Use ADDRESS instead of HOSTNAME --- setup/.env | 2 +- setup/docker-compose.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/.env b/setup/.env index 47db5c89..9a8293fe 100644 --- a/setup/.env +++ b/setup/.env @@ -1,5 +1,5 @@ # Hostname passed to Traefik -HOSTNAME=setup.mailu.io +ADDRESS=setup.mailu.io # Current release RELEASE=test diff --git a/setup/docker-compose.yml b/setup/docker-compose.yml index 5a16e5b5..7c31d2cd 100644 --- a/setup/docker-compose.yml +++ b/setup/docker-compose.yml @@ -16,7 +16,7 @@ services: labels: - traefik.enable=true - traefik.port=80 - - traefik.main.frontend.rule=Host:${HOSTNAME};PathPrefix:/master/ + - traefik.main.frontend.rule=Host:${ADDRESS};PathPrefix:/master/ depends_on: - redis @@ -32,8 +32,8 @@ services: - traefik.port=80 - traefik.root.frontend.redirect.regex=.* - traefik.root.frontend.redirect.replacement=/${RELEASE}/ - - traefik.root.frontend.rule=Host:${HOSTNAME};PathPrefix:/ - - traefik.main.frontend.rule=Host:${HOSTNAME};PathPrefix:/${RELEASE}/ + - traefik.root.frontend.rule=Host:${ADDRESS};PathPrefix:/ + - traefik.main.frontend.rule=Host:${ADDRESS};PathPrefix:/${RELEASE}/ depends_on: - redis From e994fefb2d4e4b82ea780557f4e8aa6b8a1cc227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 16 Dec 2018 23:28:15 +0200 Subject: [PATCH 34/62] Remove the test branch --- setup/.env | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/.env b/setup/.env index 9a8293fe..2c1113ce 100644 --- a/setup/.env +++ b/setup/.env @@ -2,7 +2,7 @@ ADDRESS=setup.mailu.io # Current release -RELEASE=test +RELEASE=master # Comma separated list of versions the user can choose. -VERSIONS=test,master +VERSIONS=master From c0645eadef39abf9b58bb33d74dc67138721c36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Mon, 17 Dec 2018 00:04:55 +0200 Subject: [PATCH 35/62] Remove healthcheck Did not work correctly and prevents Traefik from serving the page. --- docs/Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/Dockerfile b/docs/Dockerfile index 828788f7..c2661262 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -18,5 +18,3 @@ RUN mkdir -p /build/$VERSION \ EXPOSE 80/tcp CMD nginx -g "daemon off;" - -HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1 From 533a6f8faa938aad8b1fc9ca3cdc1328de96ab16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Mon, 17 Dec 2018 00:12:21 +0200 Subject: [PATCH 36/62] Add deploy settings for server --- docs/.env | 2 ++ docs/docker-compose.yml | 13 ++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 docs/.env diff --git a/docs/.env b/docs/.env new file mode 100644 index 00000000..6da284ee --- /dev/null +++ b/docs/.env @@ -0,0 +1,2 @@ +# Hostname passed to Traefik +ADDRESS=docs.mailu.io diff --git a/docs/docker-compose.yml b/docs/docker-compose.yml index 0caaa7a4..b7026564 100644 --- a/docs/docker-compose.yml +++ b/docs/docker-compose.yml @@ -4,18 +4,25 @@ version: '3' services: docs_master: image: mailu/docs:master + networks: + - web labels: - traefik.enable=true - traefik.port=80 - - traefik.main.frontend.rule=Host:${hostname};PathPrefix:/master/ + - traefik.main.frontend.rule=Host:${ADDRESS};PathPrefix:/master/ docs_15: image: mailu/docs:1.5 + networks: + - web labels: - traefik.enable=true - traefik.port=80 - traefik.root.frontend.redirect.regex=.* - traefik.root.frontend.redirect.replacement=/1.5/ - - traefik.root.frontend.rule=Host:${hostname};PathPrefix:/ - - traefik.main.frontend.rule=Host:${hostname};PathPrefix:/1.5/ + - traefik.root.frontend.rule=Host:${ADDRESS};PathPrefix:/ + - traefik.main.frontend.rule=Host:${ADDRESS};PathPrefix:/1.5/ +networks: + web: + external: true From 8fc2846924f8148092926a45cf225485970b5ef9 Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Tue, 18 Dec 2018 17:06:39 +0200 Subject: [PATCH 37/62] Added regex validation for alias username --- core/admin/mailu/ui/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/admin/mailu/ui/forms.py b/core/admin/mailu/ui/forms.py index 57c106c3..40a56a82 100644 --- a/core/admin/mailu/ui/forms.py +++ b/core/admin/mailu/ui/forms.py @@ -136,7 +136,7 @@ class TokenForm(flask_wtf.FlaskForm): class AliasForm(flask_wtf.FlaskForm): - localpart = fields.StringField(_('Alias'), [validators.DataRequired()]) + localpart = fields.StringField(_('Alias'), [validators.DataRequired(), validators.Regexp(LOCALPART_REGEX)]) wildcard = fields.BooleanField( _('Use SQL LIKE Syntax (e.g. for catch-all aliases)')) destination = DestinationField(_('Destination')) From 5e2552bcd57451cc127da1b29575cddd54b95c4d Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Wed, 19 Dec 2018 12:05:50 +0200 Subject: [PATCH 38/62] Removed if block --- setup/flavors/compose/mailu.env | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index 11bdbf70..6bdc5e21 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -93,13 +93,11 @@ RECIPIENT_DELIMITER={{ recipient_delimiter or '+' }} DMARC_RUA={{ dmarc_rua or 'admin' }} DMARC_RUF={{ dmarc_ruf or 'admin' }} -{% if welcome_enabled %} # Welcome email, enable and set a topic and body if you wish to send welcome # emails to all users. WELCOME={{ welcome_enable or 'false' }} WELCOME_SUBJECT={{ welcome_subject or 'Welcome to your new email account' }} WELCOME_BODY={{ welcome_body or 'Welcome to your new email account, if you can read this, then it is configured properly!' }} -{% endif %} # Maildir Compression # choose compression-method, default: none (value: bz2, gz) From 24828615cf5cec6f0fa13cae588685b4ef9e7ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Wed, 19 Dec 2018 16:20:24 +0200 Subject: [PATCH 39/62] Webmail on root, fixes #757 --- core/nginx/conf/nginx.conf | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index 5dc4e274..c90f7806 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -87,14 +87,15 @@ http { include /overrides/*.conf; # Actual logic - + {% if WEB_WEBMAIL != '/' %} location / { - {% if WEBROOT_REDIRECT and WEB_WEBMAIL != '/' %} + {% if WEBROOT_REDIRECT %} return 301 {{ WEBROOT_REDIRECT }}; {% else %} return 404; {% endif %} } + {% endif %} {% if WEBMAIL != 'none' %} location {{ WEB_WEBMAIL }} { From c041a9d45c1e6acd6bec476800d1f09500549e45 Mon Sep 17 00:00:00 2001 From: hoellen Date: Wed, 19 Dec 2018 16:19:37 +0100 Subject: [PATCH 40/62] allow all characters for username in dovecot --- core/dovecot/conf/dovecot.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/core/dovecot/conf/dovecot.conf b/core/dovecot/conf/dovecot.conf index a9ec2676..bc5055d9 100644 --- a/core/dovecot/conf/dovecot.conf +++ b/core/dovecot/conf/dovecot.conf @@ -64,6 +64,7 @@ plugin { ############### # Authentication ############### +auth_username_chars = auth_mechanisms = plain login disable_plaintext_auth = no From af086bbdbea2756e524cca66331dbc43dd3f5e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Thu, 20 Dec 2018 17:47:15 +0200 Subject: [PATCH 41/62] Include DKIM in VOLUME --- core/admin/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/admin/Dockerfile b/core/admin/Dockerfile index 6fcb4601..95a0705a 100644 --- a/core/admin/Dockerfile +++ b/core/admin/Dockerfile @@ -20,7 +20,7 @@ COPY start.py /start.py RUN pybabel compile -d mailu/translations EXPOSE 80/tcp -VOLUME ["/data"] +VOLUME ["/data","/dkim"] ENV FLASK_APP mailu CMD /start.py From ad1ca42bde0dcbebc68209d896bca3a652d69db1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Thu, 20 Dec 2018 17:48:29 +0200 Subject: [PATCH 42/62] Remove unused docker socket mount for Admin --- docs/compose/docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/compose/docker-compose.yml b/docs/compose/docker-compose.yml index 088d6302..2cff9608 100644 --- a/docs/compose/docker-compose.yml +++ b/docs/compose/docker-compose.yml @@ -88,7 +88,6 @@ services: volumes: - "$ROOT/data:/data" - "$ROOT/dkim:/dkim" - - /var/run/docker.sock:/var/run/docker.sock:ro depends_on: - redis From 736607ab0cec4166ac0d415b9bef724b3cb18fc5 Mon Sep 17 00:00:00 2001 From: Daniel Huber Date: Fri, 21 Dec 2018 15:56:12 +0100 Subject: [PATCH 43/62] Update admin account create command in setup utility to use the flask cli --- setup/flavors/compose/setup.html | 2 +- setup/flavors/stack/setup.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/flavors/compose/setup.html b/setup/flavors/compose/setup.html index 3d87a263..0487c98f 100644 --- a/setup/flavors/compose/setup.html +++ b/setup/flavors/compose/setup.html @@ -36,7 +36,7 @@ docker-compose -p mailu up -d Before you can use Mailu, you must create the primary administrator user account. This should be {{ postmaster }}@{{ domain }}. Use the following command, changing PASSWORD to your liking: -
docker-compose -p mailu exec admin python manage.py admin {{ postmaster }} {{ domain }} PASSWORD
+
docker-compose -p mailu exec admin flask mailu admin {{ postmaster }} {{ domain }} PASSWORD
 

Login to the admin interface to change the password for a safe one, at diff --git a/setup/flavors/stack/setup.html b/setup/flavors/stack/setup.html index d68a6422..329a2cba 100644 --- a/setup/flavors/stack/setup.html +++ b/setup/flavors/stack/setup.html @@ -45,7 +45,7 @@ Command for removing docker stack is Before you can use Mailu, you must create the primary administrator user account. This should be {{ postmaster }}@{{ domain }}. Use the following command, changing PASSWORD to your liking: -

docker exec $(docker ps | grep admin | cut -d ' ' -f1) python manage.py admin {{ postmaster }} {{ domain }} PASSWORD 
+
docker exec $(docker ps | grep admin | cut -d ' ' -f1) flask mailu admin {{ postmaster }} {{ domain }} PASSWORD
 

Login to the admin interface to change the password for a safe one, at From d357ed67f5b5a4a5bf01e637eca2c32c650152d4 Mon Sep 17 00:00:00 2001 From: Daniel Huber Date: Fri, 21 Dec 2018 18:13:08 +0100 Subject: [PATCH 44/62] Add DOCKER_PREFIX in tests and setup files --- setup/flavors/compose/docker-compose.yml | 20 ++++++++-------- setup/flavors/stack/docker-compose.yml | 20 ++++++++-------- tests/build.yml | 28 +++++++++++----------- tests/compose/core/docker-compose.yml | 10 ++++---- tests/compose/fetchmail/docker-compose.yml | 12 +++++----- tests/compose/filters/docker-compose.yml | 12 +++++----- tests/compose/rainloop/docker-compose.yml | 12 +++++----- tests/compose/roundcube/docker-compose.yml | 12 +++++----- tests/compose/webdav/docker-compose.yml | 12 +++++----- 9 files changed, 69 insertions(+), 69 deletions(-) diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml index d173d4cf..579de56f 100644 --- a/setup/flavors/compose/docker-compose.yml +++ b/setup/flavors/compose/docker-compose.yml @@ -16,7 +16,7 @@ services: # Core services front: - image: ${DOCKER_ORG:-mailu}/nginx:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-{{ version }}} restart: always env_file: {{ env }} logging: @@ -36,7 +36,7 @@ services: {% if resolver_enabled %} resolver: - image: mailu/unbound:{{ version }} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} restart: always networks: @@ -45,7 +45,7 @@ services: {% endif %} admin: - image: ${DOCKER_ORG:-mailu}/admin:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-{{ version }}} restart: always env_file: {{ env }} {% if not admin_enabled %} @@ -59,7 +59,7 @@ services: - redis imap: - image: ${DOCKER_ORG:-mailu}/dovecot:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-{{ version }}} restart: always env_file: {{ env }} volumes: @@ -69,7 +69,7 @@ services: - front smtp: - image: ${DOCKER_ORG:-mailu}/postfix:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-{{ version }}} restart: always env_file: {{ env }} volumes: @@ -83,7 +83,7 @@ services: {% endif %} antispam: - image: ${DOCKER_ORG:-mailu}/rspamd:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-{{ version }}} restart: always env_file: {{ env }} volumes: @@ -101,7 +101,7 @@ services: # Optional services {% if antivirus_enabled %} antivirus: - image: ${DOCKER_ORG:-mailu}/clamav:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}clamav:${MAILU_VERSION:-{{ version }}} restart: always env_file: {{ env }} volumes: @@ -116,7 +116,7 @@ services: {% if webdav_enabled %} webdav: - image: ${DOCKER_ORG:-mailu}/radicale:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}radicale:${MAILU_VERSION:-{{ version }}} restart: always env_file: {{ env }} volumes: @@ -125,7 +125,7 @@ services: {% if fetchmail_enabled %} fetchmail: - image: ${DOCKER_ORG:-mailu}/fetchmail:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}fetchmail:${MAILU_VERSION:-{{ version }}} restart: always env_file: {{ env }} {% if resolver_enabled %} @@ -139,7 +139,7 @@ services: # Webmail {% if webmail_type != 'none' %} webmail: - image: ${DOCKER_ORG:-mailu}/{{ webmail_type }}:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}{{ webmail_type }}:${MAILU_VERSION:-{{ version }}} restart: always env_file: {{ env }} volumes: diff --git a/setup/flavors/stack/docker-compose.yml b/setup/flavors/stack/docker-compose.yml index 217667e1..c7eb5355 100644 --- a/setup/flavors/stack/docker-compose.yml +++ b/setup/flavors/stack/docker-compose.yml @@ -15,7 +15,7 @@ services: # Core services front: - image: ${DOCKER_ORG:-mailu}/nginx:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} logging: driver: {{ log_driver or 'json-file' }} @@ -33,7 +33,7 @@ services: {% if resolver_enabled %} resolver: - image: ${DOCKER_ORG:-mailu}/unbound:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} networks: default: @@ -41,7 +41,7 @@ services: {% endif %} admin: - image: ${DOCKER_ORG:-mailu}/admin:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} {% if not admin_enabled %} ports: @@ -54,7 +54,7 @@ services: replicas: {{ admin_replicas }} imap: - image: ${DOCKER_ORG:-mailu}/dovecot:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} volumes: - "{{ root }}/mail:/mail" @@ -63,7 +63,7 @@ services: replicas: {{ imap_replicas }} smtp: - image: ${DOCKER_ORG:-mailu}/postfix:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} volumes: - "{{ root }}/overrides:/overrides" @@ -75,7 +75,7 @@ services: {% endif %} antispam: - image: ${DOCKER_ORG:-mailu}/rspamd:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} volumes: - "{{ root }}/filter:/var/lib/rspamd" @@ -91,7 +91,7 @@ services: # Optional services {% if antivirus_enabled %} antivirus: - image: ${DOCKER_ORG:-mailu}/clamav:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}clamav:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} volumes: - "{{ root }}/filter:/data" @@ -105,7 +105,7 @@ services: {% if webdav_enabled %} webdav: - image: ${DOCKER_ORG:-mailu}/none:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}none:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} volumes: - "{{ root }}/dav:/data" @@ -115,7 +115,7 @@ services: {% if fetchmail_enabled %} fetchmail: - image: ${DOCKER_ORG:-mailu}/fetchmail:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}fetchmail:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} volumes: - "{{ root }}/data:/data" @@ -129,7 +129,7 @@ services: {% if webmail_type != 'none' %} webmail: - image: ${DOCKER_ORG:-mailu}/{{ webmail_type }}:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}{{ webmail_type }}:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} volumes: - "{{ root }}/webmail:/data" diff --git a/tests/build.yml b/tests/build.yml index 0d89c5b8..bec95669 100644 --- a/tests/build.yml +++ b/tests/build.yml @@ -3,61 +3,61 @@ version: '3' services: front: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}nginx:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-local} build: ../core/nginx resolver: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}unbound:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-local} build: ../services/unbound imap: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}dovecot:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-local} build: ../core/dovecot smtp: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}postfix:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-local} build: ../core/postfix antispam: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}rspamd:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-local} build: ../services/rspamd antivirus: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}clamav:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}clamav:${MAILU_VERSION:-local} build: ../optional/clamav webdav: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}radicale:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}radicale:${MAILU_VERSION:-local} build: ../optional/radicale admin: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}admin:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-local} build: ../core/admin roundcube: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}roundcube:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}roundcube:${MAILU_VERSION:-local} build: ../webmails/roundcube rainloop: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}rainloop:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rainloop:${MAILU_VERSION:-local} build: ../webmails/rainloop fetchmail: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}fetchmail:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}fetchmail:${MAILU_VERSION:-local} build: ../services/fetchmail none: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}none:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}none:${MAILU_VERSION:-local} build: ../core/none docs: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}docs:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}docs:${MAILU_VERSION:-local} build: context: ../docs args: version: ${MAILU_VERSION:-local} setup: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}setup:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}setup:${MAILU_VERSION:-local} build: ../setup diff --git a/tests/compose/core/docker-compose.yml b/tests/compose/core/docker-compose.yml index a7c803b7..f64c82b0 100644 --- a/tests/compose/core/docker-compose.yml +++ b/tests/compose/core/docker-compose.yml @@ -15,7 +15,7 @@ services: # Core services front: - image: ${DOCKER_ORG:-mailu}/nginx:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-master} restart: always env_file: mailu.env logging: @@ -34,7 +34,7 @@ services: - "/mailu/certs:/certs" admin: - image: ${DOCKER_ORG:-mailu}/admin:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -44,7 +44,7 @@ services: - redis imap: - image: ${DOCKER_ORG:-mailu}/dovecot:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -54,7 +54,7 @@ services: - front smtp: - image: ${DOCKER_ORG:-mailu}/postfix:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -63,7 +63,7 @@ services: - front antispam: - image: ${DOCKER_ORG:-mailu}/rspamd:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: diff --git a/tests/compose/fetchmail/docker-compose.yml b/tests/compose/fetchmail/docker-compose.yml index 505fe21b..49c292e9 100644 --- a/tests/compose/fetchmail/docker-compose.yml +++ b/tests/compose/fetchmail/docker-compose.yml @@ -15,7 +15,7 @@ services: # Core services front: - image: ${DOCKER_ORG:-mailu}/nginx:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-master} restart: always env_file: mailu.env logging: @@ -34,7 +34,7 @@ services: - "/mailu/certs:/certs" admin: - image: ${DOCKER_ORG:-mailu}/admin:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -44,7 +44,7 @@ services: - redis imap: - image: ${DOCKER_ORG:-mailu}/dovecot:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -54,7 +54,7 @@ services: - front smtp: - image: ${DOCKER_ORG:-mailu}/postfix:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -63,7 +63,7 @@ services: - front antispam: - image: ${DOCKER_ORG:-mailu}/rspamd:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -77,7 +77,7 @@ services: fetchmail: - image: ${DOCKER_ORG:-mailu}/fetchmail:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}fetchmail:${MAILU_VERSION:-master} restart: always env_file: mailu.env diff --git a/tests/compose/filters/docker-compose.yml b/tests/compose/filters/docker-compose.yml index 463a4384..94b97399 100644 --- a/tests/compose/filters/docker-compose.yml +++ b/tests/compose/filters/docker-compose.yml @@ -15,7 +15,7 @@ services: # Core services front: - image: ${DOCKER_ORG:-mailu}/nginx:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-master} restart: always env_file: mailu.env logging: @@ -34,7 +34,7 @@ services: - "/mailu/certs:/certs" admin: - image: ${DOCKER_ORG:-mailu}/admin:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -44,7 +44,7 @@ services: - redis imap: - image: ${DOCKER_ORG:-mailu}/dovecot:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -54,7 +54,7 @@ services: - front smtp: - image: ${DOCKER_ORG:-mailu}/postfix:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -63,7 +63,7 @@ services: - front antispam: - image: ${DOCKER_ORG:-mailu}/rspamd:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -75,7 +75,7 @@ services: # Optional services antivirus: - image: ${DOCKER_ORG:-mailu}/clamav:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}clamav:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: diff --git a/tests/compose/rainloop/docker-compose.yml b/tests/compose/rainloop/docker-compose.yml index e7cd577c..98425d7a 100644 --- a/tests/compose/rainloop/docker-compose.yml +++ b/tests/compose/rainloop/docker-compose.yml @@ -15,7 +15,7 @@ services: # Core services front: - image: ${DOCKER_ORG:-mailu}/nginx:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-master} restart: always env_file: mailu.env logging: @@ -34,7 +34,7 @@ services: - "/mailu/certs:/certs" admin: - image: ${DOCKER_ORG:-mailu}/admin:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -44,7 +44,7 @@ services: - redis imap: - image: ${DOCKER_ORG:-mailu}/dovecot:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -54,7 +54,7 @@ services: - front smtp: - image: ${DOCKER_ORG:-mailu}/postfix:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -63,7 +63,7 @@ services: - front antispam: - image: ${DOCKER_ORG:-mailu}/rspamd:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -79,7 +79,7 @@ services: # Webmail webmail: - image: ${DOCKER_ORG:-mailu}/rainloop:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rainloop:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: diff --git a/tests/compose/roundcube/docker-compose.yml b/tests/compose/roundcube/docker-compose.yml index 8c34a68b..b2f415df 100644 --- a/tests/compose/roundcube/docker-compose.yml +++ b/tests/compose/roundcube/docker-compose.yml @@ -15,7 +15,7 @@ services: # Core services front: - image: ${DOCKER_ORG:-mailu}/nginx:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-master} restart: always env_file: mailu.env logging: @@ -34,7 +34,7 @@ services: - "/mailu/certs:/certs" admin: - image: ${DOCKER_ORG:-mailu}/admin:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -44,7 +44,7 @@ services: - redis imap: - image: ${DOCKER_ORG:-mailu}/dovecot:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -54,7 +54,7 @@ services: - front smtp: - image: ${DOCKER_ORG:-mailu}/postfix:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -63,7 +63,7 @@ services: - front antispam: - image: ${DOCKER_ORG:-mailu}/rspamd:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -79,7 +79,7 @@ services: # Webmail webmail: - image: ${DOCKER_ORG:-mailu}/roundcube:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}roundcube:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: diff --git a/tests/compose/webdav/docker-compose.yml b/tests/compose/webdav/docker-compose.yml index e0d5f385..adc094a8 100644 --- a/tests/compose/webdav/docker-compose.yml +++ b/tests/compose/webdav/docker-compose.yml @@ -15,7 +15,7 @@ services: # Core services front: - image: ${DOCKER_ORG:-mailu}/nginx:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-master} restart: always env_file: mailu.env logging: @@ -34,7 +34,7 @@ services: - "/mailu/certs:/certs" admin: - image: ${DOCKER_ORG:-mailu}/admin:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -44,7 +44,7 @@ services: - redis imap: - image: ${DOCKER_ORG:-mailu}/dovecot:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -54,7 +54,7 @@ services: - front smtp: - image: ${DOCKER_ORG:-mailu}/postfix:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -63,7 +63,7 @@ services: - front antispam: - image: ${DOCKER_ORG:-mailu}/rspamd:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: @@ -76,7 +76,7 @@ services: # Optional services webdav: - image: ${DOCKER_ORG:-mailu}/radicale:${MAILU_VERSION:-master} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}radicale:${MAILU_VERSION:-master} restart: always env_file: mailu.env volumes: From 3a5b763018d6c2bdda28244901b1e383e6bdfede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Tue, 25 Dec 2018 13:52:12 +0200 Subject: [PATCH 45/62] Option to disable full text search (lucene) This is a workaround for the bug in issue #751 --- core/dovecot/conf/dovecot.conf | 2 ++ docs/compose/.env | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/core/dovecot/conf/dovecot.conf b/core/dovecot/conf/dovecot.conf index bc5055d9..83c78f16 100644 --- a/core/dovecot/conf/dovecot.conf +++ b/core/dovecot/conf/dovecot.conf @@ -7,6 +7,7 @@ postmaster_address = {{ POSTMASTER }}@{{ DOMAIN }} hostname = {{ HOSTNAMES.split(",")[0] }} submission_host = {{ FRONT_ADDRESS }} +{% if DISABLE_FTS_LUCENE != 'true' %} ############### # Full-text search ############### @@ -20,6 +21,7 @@ plugin { fts_lucene = whitespace_chars=@. } +{% endif %} ############### # Mailboxes diff --git a/docs/compose/.env b/docs/compose/.env index 73964e3a..836e9dbf 100644 --- a/docs/compose/.env +++ b/docs/compose/.env @@ -3,6 +3,10 @@ # these few settings must however be configured before starting the mail # server and require a restart upon change. +# Set this to `true` to disable full text search by lucene (value: true, false) +# This is a workaround for the bug in issue #751 (indexer-worker crashes) +DISABLE_FTS_LUCENE=false + ################################### # Common configuration variables ################################### From e128d8e975529485e7533766e43e93d1e4376bbc Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Wed, 5 Dec 2018 21:50:07 +0100 Subject: [PATCH 46/62] Add documentation for usage behind traefik --- docs/reverse.rst | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/docs/reverse.rst b/docs/reverse.rst index ca68fd7f..cd23aad1 100644 --- a/docs/reverse.rst +++ b/docs/reverse.rst @@ -8,6 +8,7 @@ In such a configuration, one would usually run a frontend reverse proxy to serve There are basically three options, from the most to the least recommended one: - have Mailu Web frontend listen locally and use your own Web frontend on top of it +- use ``Traefik`` in another container as central system-reverse-proxy - override Mailu Web frontend configuration - disable Mailu Web frontend completely and use your own @@ -114,6 +115,72 @@ Depending on how you access the front server, you might want to add a ``proxy_re This will stop redirects (301 and 302) sent by the Webmail, nginx front and admin interface from sending you to ``localhost``. +use ``traefik`` in another container as central system-reverse-proxy +-------------------------------------------------------------------- + +``traefik`` is a popular reverse-proxy aimed at containerized systems. As such, many may wish to integrate ``Mailu`` into a system which already uses ``traefik`` as its sole ingress/reverse-proxy. + +As the ``mailu/front`` container uses ``nginx`` not only for ``HTTP`` forwarding, but also for the mail-protocols like ``SMTP``, ``IMAP``, etc, we need to keep this container around even when using another ``HTTP`` reverse-proxy. Furthermore, ``traefik`` is neither able to forward non-HTTP, nor can it easily forward HTTPS-to-HTTPS. This, however, means 3 things: + +- ``mailu/front`` needs to listen internally on ``HTTP`` rather than ``HTTPS`` +- ``mailu/front`` is not exposed to the outside world on ``HTTP`` +- ``mailu/front`` still needs ``SSL`` certificates (here, we assume ``letsencrypt``) for a well-behaved mail service + +This makes the setup with ``traefik`` a bit harder: ``traefik`` saves its certificates in a proprietary ``JSON`` file, which is not readable by the ``nginx`` in the ``front``-container. To solve this, your ``acme.json`` needs to be exposed to the host or a ``docker-volume``. It will then be read by a script in another container, which will dump the certificates as ``PEM`` files, making them readable for ``nginx``. The `front` container will make sure to reload `nginx` whenever these certificates change. + +To set this up, first set ``TLS_FLAVOR=mail`` in your ``.env``. This tells ``mailu/front`` not to try to request certificates using ``letsencrypt``, but to read provided certificates, and use them only for mail-protocols, not for ``HTTP``. +Next, in your ``docker-compose.yml``, comment out the ``port`` lines of the ``front`` section for port ``…:80`` and ``…:440``. Add the respective traefik labels for your domain/configuration, like + +.. code-block:: yaml + + labels: + - "traefik.enable=true" + - "traefik.port=80" + - "traefik.frontend.rule=Host:$TRAEFIK_DOMAIN" + +**Please don’t forget to add ``TRAEFIK_DOMAIN=[...]`` TO YOUR ``.env``** + +If your ``traefik`` is configured to automatically request certificates from ``letsencrypt``, then you’ll have a certificate for ``mail.your.doma.in`` now. However, ``mail.your.doma.in`` might only be the location where you want the ``Mailu`` web-interfaces to live — your mail should be sent/received from ``your.doma.in``, and this is the ``DOMAIN`` in your ``.env``? +To support that use-case, ``traefik`` can request ``SANs`` for your domain. Lets add something like + +.. code-block:: toml + + [acme] + [[acme.domains]] + main = "your.doma.in" # this is the same as $TRAEFIK_DOMAIN! + sans = ["mail.your.doma.in", "webmail.your.doma.in", "smtp.your.doma.in"] + +to your ``traefik.toml``. You might need to clear your ``acme.json``, if a certificate for one of these domains already exists. + +For the last part, you’re still a bit on your own. You need some solution which dumps the certificates in ``acme.json``, so you can include them in the ``mailu/front`` container. One such example is `traefik-certdumper `, which has been adapted for use in Mailu. You can add it to your ``docker-compose.yml`` like: + +.. code-block:: yaml + + certdumper: + restart: always + image: nebukadneza/traefik-certdumper:latest + environment: + # Make sure this is the same as the main=-domain in traefik.toml + # !!! Also don’t forget to add "TRAEFIK_DOMAIN=[...]" to your .env! + - DOMAIN=$TRAEFIK_DOMAIN + volumes: + - "/data/traefik:/traefik" + - "$ROOT/certs:/output" + + + +assuming you have ``volume-mounted`` your ``acme.json`` put to ``/data/traefik`` on your host. The dumper will then write out ``/data/traefik/ssl/your.doma.in.crt`` and ``/data/traefik/ssl/your.doma.in.key`` whenever ``acme.json`` is updated. Yay! Now let’s mount this to our ``front`` container like: + +.. code-block:: yaml + + volumes: + - "$ROOT/certs:/certs" # Mount both certs directory (for dhparams.pem) and your domains key + - "$ROOT/overrides/nginx:/overrides" + - /data/traefik/ssl/$TRAEFIK_DOMAIN.crt:/certs/cert.pem + - /data/traefik/ssl/$TRAEFIK_DOMAIN.key:/certs/key.pem + + +Note that we still keep the ``$ROOT/certs`` directory-mount there, where ``dhparams.pem`` is going to be placed. Override Mailu configuration ---------------------------- From dc5f5bb023a33d55b1b99a1a4f30407d68390ddf Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Thu, 6 Dec 2018 09:38:28 +0100 Subject: [PATCH 47/62] Traefik configuration examples --- docs/compose/treafik/docker-compose.yml | 145 ++++++++++++++++++++++++ docs/compose/treafik/traefik.toml | 33 ++++++ 2 files changed, 178 insertions(+) create mode 100644 docs/compose/treafik/docker-compose.yml create mode 100644 docs/compose/treafik/traefik.toml diff --git a/docs/compose/treafik/docker-compose.yml b/docs/compose/treafik/docker-compose.yml new file mode 100644 index 00000000..0dc8369f --- /dev/null +++ b/docs/compose/treafik/docker-compose.yml @@ -0,0 +1,145 @@ +version: '2' + +services: + + # This would normally not be here, but where you define your system services + traefik: + image: traefik:alpine + command: --docker + restart: always + ports: + - "80:80" + - "443:443" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + - "/data/traefik/acme.json:/acme.json" + - "/data/traefik/traefik.toml:/traefik.toml" + # This may be needed (plus defining mailu_default external: true) if traefik lives elsewhere + # networks: + # - mailu_default + + certdumper: + restart: always + image: nebukadneza/traefik-certdumper:latest + environment: + # Make sure this is the same as the main=-domain in traefik.toml + # !!! Also don’t forget to add "TRAEFIK_DOMAIN=[...]" to your .env! + - DOMAIN=$TRAEFIK_DOMAIN + volumes: + - "/data/traefik:/traefik" + - "$ROOT/certs:/output" + + front: + image: mailu/nginx:$VERSION + restart: always + env_file: .env + logging: + driver: $LOG_DRIVER + labels: # Traefik labels for simple reverse-proxying + - "traefik.enable=true" + - "traefik.port=80" + - "traefik.frontend.rule=Host:$TRAEFIK_DOMAIN" + - "traefik.docker.network=mailu_default" + ports: + - "80" # Let’s not expose 80 or 443 on host, since that’s taken by traefik + - "$BIND_ADDRESS4:110:110" + - "$BIND_ADDRESS4:143:143" + - "$BIND_ADDRESS4:993:993" + - "$BIND_ADDRESS4:995:995" + - "$BIND_ADDRESS4:25:25" + - "$BIND_ADDRESS4:465:465" + - "$BIND_ADDRESS4:587:587" + - "$BIND_ADDRESS6:110:110" + - "$BIND_ADDRESS6:143:143" + - "$BIND_ADDRESS6:993:993" + - "$BIND_ADDRESS6:995:995" + - "$BIND_ADDRESS6:25:25" + - "$BIND_ADDRESS6:465:465" + - "$BIND_ADDRESS6:587:587" + volumes: + - "$ROOT/certs:/certs" # Mount both certs directory (for dhparams.pem) and your domains key + - "$ROOT/overrides/nginx:/overrides" + - /data/traefik/ssl/$TRAEFIK_DOMAIN.crt:/certs/cert.pem + - /data/traefik/ssl/$TRAEFIK_DOMAIN.key:/certs/key.pem + + redis: + image: redis:alpine + restart: always + volumes: + - "$ROOT/redis:/data" + + imap: + image: mailu/dovecot:$VERSION + restart: always + env_file: .env + volumes: + - "$ROOT/mail:/mail" + - "$ROOT/overrides:/overrides" + depends_on: + - front + + smtp: + image: mailu/postfix:$VERSION + restart: always + env_file: .env + volumes: + - "$ROOT/overrides:/overrides" + depends_on: + - front + + antispam: + image: mailu/rspamd:$VERSION + restart: always + env_file: .env + volumes: + - "$ROOT/filter:/var/lib/rspamd" + - "$ROOT/dkim:/dkim" + - "$ROOT/overrides/rspamd:/etc/rspamd/override.d" + depends_on: + - front + + antivirus: + image: mailu/$ANTIVIRUS:$VERSION + restart: always + env_file: .env + volumes: + - "$ROOT/filter:/data" + + webdav: + image: mailu/$WEBDAV:$VERSION + restart: always + env_file: .env + volumes: + - "$ROOT/dav:/data" + + admin: + image: mailu/admin:$VERSION + restart: always + env_file: .env + volumes: + - "$ROOT/data:/data" + - "$ROOT/dkim:/dkim" + depends_on: + - redis + + webmail: + image: "mailu/$WEBMAIL:$VERSION" + restart: always + env_file: .env + volumes: + - "$ROOT/webmail:/data" + depends_on: + - imap + + fetchmail: + image: mailu/fetchmail:$VERSION + restart: always + env_file: .env + +networks: + default: + driver: bridge + ipam: + driver: default + config: + - subnet: $SUBNET diff --git a/docs/compose/treafik/traefik.toml b/docs/compose/treafik/traefik.toml new file mode 100644 index 00000000..c09cf42a --- /dev/null +++ b/docs/compose/treafik/traefik.toml @@ -0,0 +1,33 @@ +# This is just boilerplate stuff you probably have in your own config +logLevel = "INFO" +defaultEntryPoints = ["https","http"] + +[entryPoints] + [entryPoints.http] + address = ":80" + [entryPoints.http.redirect] + entryPoint = "https" + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + +[docker] +endpoint = "unix:///var/run/docker.sock" +watch = true +exposedByDefault = false + +# Make sure we get acme.json saved, and onHostRule enabled +[acme] +email = "your@mail.tld" +storage = "acme.json" +entryPoint = "https" +onHostRule = true + +[acme.httpChallenge] +entryPoint = "http" + +# This should include all of your mail domains, and main= should be your $TRAEFIK_DOMAIN +[[acme.domains]] + main = "mail.your.doma.in" + sans = ["web.mail.your.doma.in", "smtp.mail.doma.in", "imap.mail.doma.in"] + From 633919e97cb638125ae82626bcb0596ca20a498c Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Wed, 26 Dec 2018 11:42:48 +0100 Subject: [PATCH 48/62] Add docker to dump traefiks certificates to pem This is required since traefik sitting on HTTP is able to grab LetsEncrypt certificates which then need to be injected into the front container. --- optional/traefik-certdumper/.dockerignore | 2 ++ optional/traefik-certdumper/Dockerfile | 8 ++++++ optional/traefik-certdumper/LICENSE | 21 ++++++++++++++++ optional/traefik-certdumper/README.md | 27 ++++++++++++++++++++ optional/traefik-certdumper/run.sh | 30 +++++++++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 optional/traefik-certdumper/.dockerignore create mode 100644 optional/traefik-certdumper/Dockerfile create mode 100644 optional/traefik-certdumper/LICENSE create mode 100644 optional/traefik-certdumper/README.md create mode 100755 optional/traefik-certdumper/run.sh diff --git a/optional/traefik-certdumper/.dockerignore b/optional/traefik-certdumper/.dockerignore new file mode 100644 index 00000000..9b54c5ba --- /dev/null +++ b/optional/traefik-certdumper/.dockerignore @@ -0,0 +1,2 @@ +README.md +Dockerfile diff --git a/optional/traefik-certdumper/Dockerfile b/optional/traefik-certdumper/Dockerfile new file mode 100644 index 00000000..c8a3aa3f --- /dev/null +++ b/optional/traefik-certdumper/Dockerfile @@ -0,0 +1,8 @@ +FROM alpine + +RUN apk --no-cache add inotify-tools jq openssl util-linux bash docker +# while not strictly documented, this script seems to always(?) support previous acme.json versions too +RUN wget https://raw.githubusercontent.com/containous/traefik/master/contrib/scripts/dumpcerts.sh -O dumpcerts.sh + +COPY run.sh / +ENTRYPOINT ["/run.sh"] diff --git a/optional/traefik-certdumper/LICENSE b/optional/traefik-certdumper/LICENSE new file mode 100644 index 00000000..259ccd34 --- /dev/null +++ b/optional/traefik-certdumper/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Sven Dowideit + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/optional/traefik-certdumper/README.md b/optional/traefik-certdumper/README.md new file mode 100644 index 00000000..f5434f62 --- /dev/null +++ b/optional/traefik-certdumper/README.md @@ -0,0 +1,27 @@ +# Single-domain traefik-certdumper for mailu + +This is based on the work by Sven Dowideit on https://github.com/SvenDowideit/traefik-certdumper + +## Fork? +This is a slight modification that is less flexible, but is adapted to the +usecase in mailu. If you wish to deploy mailu behind a traefik, you face many +problems. One of these is that you need to get the certificates into mailu in a +very defined manner. This will copy the certificate for the **Main:**-domain +given in the DOMAIN-environment onto `output`. + +If your output happens to be mailu-front-`/certs`, the certificate-watcher in +the front-container will catch it and reload nginx. This works for mailu +`TLS_FLAVOR=[mail, cert]` + + +``` + certdumper: + restart: always + image: Mailu/traefik-certdumper:$VERSION + environment: + - DOMAIN=$DOMAIN + volumes: + # your traefik data-volume is probably declared outside of the mailu composefile + - /data/traefik:/traefik + - $ROOT/certs/:/output/ +``` diff --git a/optional/traefik-certdumper/run.sh b/optional/traefik-certdumper/run.sh new file mode 100755 index 00000000..2f73eaf7 --- /dev/null +++ b/optional/traefik-certdumper/run.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +function dump() { + echo "$(date) Dumping certificates" + bash dumpcerts.sh /traefik/acme.json /tmp/work/ + + for crt_file in $(ls /tmp/work/certs/*); do + pem_file=$(echo $crt_file | sed 's/certs/pem/g' | sed 's/.crt/-public.pem/g') + echo "openssl x509 -inform PEM -in $crt_file > $pem_file" + openssl x509 -inform PEM -in $crt_file > $pem_file + done + for key_file in $(ls /tmp/work/private/*); do + pem_file=$(echo $key_file | sed 's/private/pem/g' | sed 's/.key/-private.pem/g') + echo "openssl rsa -in $key_file -text > $pem_file" + openssl rsa -in $key_file -text > $pem_file + done + + echo "$(date) Copying certificates" + cp -v /tmp/work/pem/${DOMAIN}-private.pem /output/key.pem + cp -v /tmp/work/pem/${DOMAIN}-public.pem /output/cert.pem +} + +mkdir -p /tmp/work/pem /tmp/work/certs +# run once on start to make sure we have any old certs +dump + +while true; do + inotifywait -e modify /traefik/acme.json && \ + dump +done From 19bd90f581d799f9150fad5ee48b645f58f366b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Thu, 27 Dec 2018 11:50:34 +0200 Subject: [PATCH 49/62] Fix usage of radicale image instead of none I just noticed that the `none` image was used in place where `radicale` should be used. Fixed in this commit. --- setup/flavors/stack/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/flavors/stack/docker-compose.yml b/setup/flavors/stack/docker-compose.yml index c7eb5355..38c07a40 100644 --- a/setup/flavors/stack/docker-compose.yml +++ b/setup/flavors/stack/docker-compose.yml @@ -105,7 +105,7 @@ services: {% if webdav_enabled %} webdav: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}none:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}radicale:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} volumes: - "{{ root }}/dav:/data" From 5bdbbf60d7874fd45732efd021d57785b20bfa7a Mon Sep 17 00:00:00 2001 From: TheLegend875 <40040530+TheLegend875@users.noreply.github.com> Date: Sat, 22 Dec 2018 22:39:38 +0100 Subject: [PATCH 50/62] fixed display of username when not logged in --- core/admin/mailu/ui/templates/client.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/admin/mailu/ui/templates/client.html b/core/admin/mailu/ui/templates/client.html index 6adc68a2..81bee135 100644 --- a/core/admin/mailu/ui/templates/client.html +++ b/core/admin/mailu/ui/templates/client.html @@ -53,7 +53,7 @@ configure your email client {% trans %}Username{% endtrans %} -

{{ current_user or "******" }}
+
{{ current_user if current_user.is_authenticated else "******" }}
{% trans %}Password{% endtrans %} From e7c9b32e231e533b844a50260e49cb6735b63363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 30 Dec 2018 15:07:45 +0200 Subject: [PATCH 51/62] Restore VERSION_TAG template --- docs/_templates/page.html | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs/_templates/page.html diff --git a/docs/_templates/page.html b/docs/_templates/page.html new file mode 100644 index 00000000..97296793 --- /dev/null +++ b/docs/_templates/page.html @@ -0,0 +1,4 @@ +{%- extends "layout.html" %} +{% block body %} + {{ body|replace("VERSION_TAG", version) }} +{% endblock %} From d6ba39b6a9736b9c972781caf7ec6888856713cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 30 Dec 2018 16:49:37 +0200 Subject: [PATCH 52/62] Traefik docs improvements: - Removed code tages to increase readability - Some extra line-breaks for source readability - Fix link to new mailu/traefik-certdumper container - dhparams is no longer stored in /certs - Use a proper "note" box - Fix typo in docs/compose/traefik directory name - Include links to example config files - Fix toml lexer build warning --- .../{treafik => traefik}/docker-compose.yml | 4 +- .../compose/{treafik => traefik}/traefik.toml | 0 docs/reverse.rst | 49 ++++++++++++------- 3 files changed, 32 insertions(+), 21 deletions(-) rename docs/compose/{treafik => traefik}/docker-compose.yml (93%) rename docs/compose/{treafik => traefik}/traefik.toml (100%) diff --git a/docs/compose/treafik/docker-compose.yml b/docs/compose/traefik/docker-compose.yml similarity index 93% rename from docs/compose/treafik/docker-compose.yml rename to docs/compose/traefik/docker-compose.yml index 0dc8369f..607fcaf1 100644 --- a/docs/compose/treafik/docker-compose.yml +++ b/docs/compose/traefik/docker-compose.yml @@ -20,7 +20,7 @@ services: certdumper: restart: always - image: nebukadneza/traefik-certdumper:latest + image: mailu/traefik-certdumper:$VERSION environment: # Make sure this is the same as the main=-domain in traefik.toml # !!! Also don’t forget to add "TRAEFIK_DOMAIN=[...]" to your .env! @@ -41,7 +41,6 @@ services: - "traefik.frontend.rule=Host:$TRAEFIK_DOMAIN" - "traefik.docker.network=mailu_default" ports: - - "80" # Let’s not expose 80 or 443 on host, since that’s taken by traefik - "$BIND_ADDRESS4:110:110" - "$BIND_ADDRESS4:143:143" - "$BIND_ADDRESS4:993:993" @@ -57,7 +56,6 @@ services: - "$BIND_ADDRESS6:465:465" - "$BIND_ADDRESS6:587:587" volumes: - - "$ROOT/certs:/certs" # Mount both certs directory (for dhparams.pem) and your domains key - "$ROOT/overrides/nginx:/overrides" - /data/traefik/ssl/$TRAEFIK_DOMAIN.crt:/certs/cert.pem - /data/traefik/ssl/$TRAEFIK_DOMAIN.key:/certs/key.pem diff --git a/docs/compose/treafik/traefik.toml b/docs/compose/traefik/traefik.toml similarity index 100% rename from docs/compose/treafik/traefik.toml rename to docs/compose/traefik/traefik.toml diff --git a/docs/reverse.rst b/docs/reverse.rst index cd23aad1..5f64b8f3 100644 --- a/docs/reverse.rst +++ b/docs/reverse.rst @@ -115,21 +115,28 @@ Depending on how you access the front server, you might want to add a ``proxy_re This will stop redirects (301 and 302) sent by the Webmail, nginx front and admin interface from sending you to ``localhost``. -use ``traefik`` in another container as central system-reverse-proxy +Use Traefik in another container as central system-reverse-proxy -------------------------------------------------------------------- -``traefik`` is a popular reverse-proxy aimed at containerized systems. As such, many may wish to integrate ``Mailu`` into a system which already uses ``traefik`` as its sole ingress/reverse-proxy. +`Traefik`_ is a popular reverse-proxy aimed at containerized systems. +As such, many may wish to integrate Mailu into a system which already uses Traefik as its sole ingress/reverse-proxy. -As the ``mailu/front`` container uses ``nginx`` not only for ``HTTP`` forwarding, but also for the mail-protocols like ``SMTP``, ``IMAP``, etc, we need to keep this container around even when using another ``HTTP`` reverse-proxy. Furthermore, ``traefik`` is neither able to forward non-HTTP, nor can it easily forward HTTPS-to-HTTPS. This, however, means 3 things: +As the ``mailu/front`` container uses Nginx not only for ``HTTP`` forwarding, but also for the mail-protocols like ``SMTP``, ``IMAP``, etc, we need to keep this +container around even when using another ``HTTP`` reverse-proxy. Furthermore, Traefik is neither able to forward non-HTTP, nor can it easily forward HTTPS-to-HTTPS. +This, however, means 3 things: - ``mailu/front`` needs to listen internally on ``HTTP`` rather than ``HTTPS`` - ``mailu/front`` is not exposed to the outside world on ``HTTP`` - ``mailu/front`` still needs ``SSL`` certificates (here, we assume ``letsencrypt``) for a well-behaved mail service -This makes the setup with ``traefik`` a bit harder: ``traefik`` saves its certificates in a proprietary ``JSON`` file, which is not readable by the ``nginx`` in the ``front``-container. To solve this, your ``acme.json`` needs to be exposed to the host or a ``docker-volume``. It will then be read by a script in another container, which will dump the certificates as ``PEM`` files, making them readable for ``nginx``. The `front` container will make sure to reload `nginx` whenever these certificates change. +This makes the setup with Traefik a bit harder: Traefik saves its certificates in a proprietary *JSON* file, which is not readable by Nginx in the ``front``-container. +To solve this, your ``acme.json`` needs to be exposed to the host or a ``docker-volume``. It will then be read by a script in another container, +which will dump the certificates as ``PEM`` files, readable for Nginx. The ``front`` container will automatically reload Nginx whenever these certificates change. -To set this up, first set ``TLS_FLAVOR=mail`` in your ``.env``. This tells ``mailu/front`` not to try to request certificates using ``letsencrypt``, but to read provided certificates, and use them only for mail-protocols, not for ``HTTP``. -Next, in your ``docker-compose.yml``, comment out the ``port`` lines of the ``front`` section for port ``…:80`` and ``…:440``. Add the respective traefik labels for your domain/configuration, like +To set this up, first set ``TLS_FLAVOR=mail`` in your ``.env``. This tells ``mailu/front`` not to try to request certificates using ``letsencrypt``, +but to read provided certificates, and use them only for mail-protocols, not for ``HTTP``. +Next, in your ``docker-compose.yml``, comment out the ``port`` lines of the ``front`` section for port ``…:80`` and ``…:440``. +Add the respective Traefik labels for your domain/configuration, like .. code-block:: yaml @@ -138,12 +145,14 @@ Next, in your ``docker-compose.yml``, comment out the ``port`` lines of the ``fr - "traefik.port=80" - "traefik.frontend.rule=Host:$TRAEFIK_DOMAIN" -**Please don’t forget to add ``TRAEFIK_DOMAIN=[...]`` TO YOUR ``.env``** +.. note:: Please don’t forget to add ``TRAEFIK_DOMAIN=[...]`` TO YOUR ``.env`` -If your ``traefik`` is configured to automatically request certificates from ``letsencrypt``, then you’ll have a certificate for ``mail.your.doma.in`` now. However, ``mail.your.doma.in`` might only be the location where you want the ``Mailu`` web-interfaces to live — your mail should be sent/received from ``your.doma.in``, and this is the ``DOMAIN`` in your ``.env``? -To support that use-case, ``traefik`` can request ``SANs`` for your domain. Lets add something like +If your Traefik is configured to automatically request certificates from *letsencrypt*, then you’ll have a certificate for ``mail.your.doma.in`` now. However, +``mail.your.doma.in`` might only be the location where you want the Mailu web-interfaces to live — your mail should be sent/received from ``your.doma.in``, +and this is the ``DOMAIN`` in your ``.env``? +To support that use-case, Traefik can request ``SANs`` for your domain. Lets add something like -.. code-block:: toml +.. code-block:: guess [acme] [[acme.domains]] @@ -152,13 +161,14 @@ To support that use-case, ``traefik`` can request ``SANs`` for your domain. Lets to your ``traefik.toml``. You might need to clear your ``acme.json``, if a certificate for one of these domains already exists. -For the last part, you’re still a bit on your own. You need some solution which dumps the certificates in ``acme.json``, so you can include them in the ``mailu/front`` container. One such example is `traefik-certdumper `, which has been adapted for use in Mailu. You can add it to your ``docker-compose.yml`` like: +You will need some solution which dumps the certificates in ``acme.json``, so you can include them in the ``mailu/front`` container. +One such example is ``mailu/traefik-certdumper``, which has been adapted for use in Mailu. You can add it to your ``docker-compose.yml`` like: .. code-block:: yaml certdumper: restart: always - image: nebukadneza/traefik-certdumper:latest + image: mailu/traefik-certdumper:$VERSION environment: # Make sure this is the same as the main=-domain in traefik.toml # !!! Also don’t forget to add "TRAEFIK_DOMAIN=[...]" to your .env! @@ -169,23 +179,23 @@ For the last part, you’re still a bit on your own. You need some solution whic -assuming you have ``volume-mounted`` your ``acme.json`` put to ``/data/traefik`` on your host. The dumper will then write out ``/data/traefik/ssl/your.doma.in.crt`` and ``/data/traefik/ssl/your.doma.in.key`` whenever ``acme.json`` is updated. Yay! Now let’s mount this to our ``front`` container like: +Assuming you have ``volume-mounted`` your ``acme.json`` put to ``/data/traefik`` on your host. The dumper will then write out ``/data/traefik/ssl/your.doma.in.crt`` +and ``/data/traefik/ssl/your.doma.in.key`` whenever ``acme.json`` is updated. Yay! Now let’s mount this to our ``front`` container like: .. code-block:: yaml volumes: - - "$ROOT/certs:/certs" # Mount both certs directory (for dhparams.pem) and your domains key - "$ROOT/overrides/nginx:/overrides" - /data/traefik/ssl/$TRAEFIK_DOMAIN.crt:/certs/cert.pem - /data/traefik/ssl/$TRAEFIK_DOMAIN.key:/certs/key.pem - -Note that we still keep the ``$ROOT/certs`` directory-mount there, where ``dhparams.pem`` is going to be placed. +.. _`Traefik`: https://traefik.io/ Override Mailu configuration ---------------------------- -If you do not have the resources for running a separate reverse proxy, you could override Mailu reverse proxy configuration by using a Docker volume. Simply store your configuration file (Nginx format), in ``/mailu/nginx.conf`` for instance. +If you do not have the resources for running a separate reverse proxy, you could override Mailu reverse proxy configuration by using a Docker volume. +Simply store your configuration file (Nginx format), in ``/mailu/nginx.conf`` for instance. Then modify your ``docker-compose.yml`` file and change the ``front`` section to add a mount: @@ -202,7 +212,10 @@ Then modify your ``docker-compose.yml`` file and change the ``front`` section to - "$ROOT/certs:/certs" - "$ROOT/nginx.conf:/etc/nginx/nginx.conf" -You can use our default configuration file as a sane base for your configuration. +You can also download the example configuration files: + +- :download:`compose/traefik/docker-compose.yml` +- :download:`compose/traefik/traefik.toml` Disable completely Mailu reverse proxy -------------------------------------- From fd23e02aaa25d556403d05f2280a9b16f2a04fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 30 Dec 2018 16:55:18 +0200 Subject: [PATCH 53/62] Use alpine versioned and defin volumes --- optional/traefik-certdumper/Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/optional/traefik-certdumper/Dockerfile b/optional/traefik-certdumper/Dockerfile index c8a3aa3f..92e5e900 100644 --- a/optional/traefik-certdumper/Dockerfile +++ b/optional/traefik-certdumper/Dockerfile @@ -1,8 +1,11 @@ -FROM alpine +FROM alpine:3.8 RUN apk --no-cache add inotify-tools jq openssl util-linux bash docker # while not strictly documented, this script seems to always(?) support previous acme.json versions too RUN wget https://raw.githubusercontent.com/containous/traefik/master/contrib/scripts/dumpcerts.sh -O dumpcerts.sh +VOLUME ["/traefik"] +VOLUME ["/output"] + COPY run.sh / ENTRYPOINT ["/run.sh"] From 7c7b52d935fbfbd0e90d82c963fa4a70d906045e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 30 Dec 2018 17:06:52 +0200 Subject: [PATCH 54/62] Include certdumper in autobuild --- tests/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/build.yml b/tests/build.yml index 0d89c5b8..4f6e33de 100644 --- a/tests/build.yml +++ b/tests/build.yml @@ -30,6 +30,10 @@ services: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}radicale:${MAILU_VERSION:-local} build: ../optional/radicale + traefik-certdumper: + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}traefik-certdumper:${MAILU_VERSION:-local} + build: ../optional/traefik-certdumper + admin: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}admin:${MAILU_VERSION:-local} build: ../core/admin From a5b96553aac0919fda68b64ef2dab7d2f48a4767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 30 Dec 2018 18:47:12 +0200 Subject: [PATCH 55/62] Check for dumpcerts.sh return status code --- optional/traefik-certdumper/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optional/traefik-certdumper/run.sh b/optional/traefik-certdumper/run.sh index 2f73eaf7..78d20a84 100755 --- a/optional/traefik-certdumper/run.sh +++ b/optional/traefik-certdumper/run.sh @@ -2,7 +2,7 @@ function dump() { echo "$(date) Dumping certificates" - bash dumpcerts.sh /traefik/acme.json /tmp/work/ + bash dumpcerts.sh /traefik/acme.json /tmp/work/ || return for crt_file in $(ls /tmp/work/certs/*); do pem_file=$(echo $crt_file | sed 's/certs/pem/g' | sed 's/.crt/-public.pem/g') From e1902907ff8616bdb64158e82c512b55e9cdcf0d Mon Sep 17 00:00:00 2001 From: hoellen Date: Sun, 30 Dec 2018 18:08:51 +0100 Subject: [PATCH 56/62] Prepare changelog for 1.6 --- CHANGELOG.md | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2afc69cf..9ced5a79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,109 @@ Notable changes to this project are documented in the current file. For more details about individual changes, see the Git log. You should read this before upgrading Freposte.io as some changes will include useful notes. +v1.6.0 - unreleased +------------------- + +- Global: Architecture of the central container (#56, #108) +- Global: Serve documentation with docker (#601, #608) +- Global: Travis-CI automated test build (#602) +- Global: Abstract db access from Postfix and Dovecot (#612) +- Global: Refactor the admin architecture and configuration management (#670) +- Feature: Used quota in admin interface (#216) +- Feature: User Signup (#281, #340) +- Feature: Client setup page (#342) +- Feature: Administration setup page (#343) +- Feature: Visual notice whether the mx record points to mailu server (#356) +- Feature: Option for vacation start (#362) +- Feature: Enable enigma in Roundcube (#391) +- Feature: Allow more charcaters as a valid email address (#443) +- Feature: IDNA support (#446) +- Feature: Disable user account (#449) +- Feature: Use fuzzy hashes in rpamd (#456, #527) +- Feature: Enable “doveadm -A” command (#458) +- Feature: Remove the Service Status page (#463) +- Feature: Automated Releases (#487) +- Feature: Support for ARC (#495) +- Feature: Add posibilty to run webmail on root (#501) +- Feature: Upgrade docker-compose.yml to version 3 (#539) +- Feature: Documentation to deploy mailu on a docker swarm (#551) +- Feature: Add full-text search support (#552) +- Feature: Add optional Maildir-Compression (#553) +- Feature: Preserve rspamd history on container restart (#561) +- Feature: FAQ (#564, #677) +- Feature: Kubernetes support (#576) +- Feature: Option to bounce or reject email when recipient is unknown (#583, #626) +- Feature: implement healthchecks for all containers (#631) +- Feature: Option to send front logs to journald or syslog (#584, #661) +- Feature: Support bcrypt and PBKDF2 (#647, #667) +- Feature: enable http2 (#674) +- Feature: Unbound DNS as optional service (#681) +- Feature: Re-write test suite (#682) +- Feature: Docker image prefixes (#702) +- Feature: Add authentication method “login” for Outlook (#704) +- Feature: Allow extending nginx config with overrides (#713) +- Feature: Dynamic attachment size limit (#731) +- Feature: Certificate watcher for external certs to reload nginx (#732) +- Feature: Kubernetes +- Enhancement: Use pre-defined dhparam (#322) +- Enhancement: Disable ssl_session_tickets (#329) +- Enhancement: max attachment size in roundcube (#338) +- Enhancement: Use x-forwarded-proto with redirects (#347) +- Enhancement: Added adress verification before accepting mails for delivery (#353) +- Enhancement: Reverse proxy - Real ip header and mail-letsencrypt (#358) +- Enhancement: Parametrize hosts (#373) +- Enhancement: Expose ports in dockerfiles (#392) +- Enhancement: Added webmail-imap dependency in docker-compose (#403) +- Enhancement: Add environment variables to allow running outside of docker-compose (#429) +- Enhancement: Add original Delivered-To header to received messages (#433) +- Enhancement: Use HOST_ADMIN in "Forwarding authentication server" (#436, #437) +- Enhancement: Use POD_ADDRESS_RANGE for Dovecot (#448) +- Enhancement: Using configurable filenames for TLS certs (#468) +- Enhancement: Don't require BootstrapCDN (GDPR-compliance) (#477) +- Enhancement: Use dynamic client_max_body_size for webmail (#502) +- Enhancement: New logo design (#509) +- Enhancement: New manifests for Kubernetes (#544) +- Enhancement: Pin Alpine image (#548, #557) +- Enhancement: Use safer cipher in roundcube (#597) +- Enhancement: Improve sender checks (#633) +- Enhancement: Use PHP 7.2 for rainloop and roundcube (#606, #642) +- Enhancement: Multi-version documentation (#664) +- Enhancement: Contribution documentation (#700) +- Enhancement: Move Mailu Docker network to a fixed subnet (#727) +- Enhancement: Added regex validation for alias username (#764) +- Enhancement: Update documentation +- Upstream: Update Roundcube +- Upstream: Update Rainloop +- Bug: Rainloop fails with "domain not allowed" (#93) +- Bug: Announces fail (#309) +- Bug: Authentication issues with rspamd admin ui (#315) +- Bug: front hangup on restart (#341) +- Bug: Display the proper user quota when set to 0/infinity (#345) +- Bug: Domain details button "Regenerate keys" when no keys are generated yet (#346) +- Bug: Relayed Domains: access denied error (#351) +- Bug: Do not deny HTTP access upon TLS error when the flavor is mail (#352) +- Bug: php_zip extension missing in Roundcube webmail (#364) +- Bug: RoundCube webmail .htaccess assumes PHP 5 (#366) +- Bug: No quota shows "0 Bytes" in user list (#368) +- Bug: RELAYNETS not honored when login is different from sender (#369) +- Bug: Request Entity Too Large (#371) +- Bug: Pass the full host to the backend (#372) +- Bug: Can't send from an email account that has forwarding (#390) +- Bug: SSL protocol error roundcube/imap (#411, #414) +- Bug: Unable to send from alternative domains (#415) +- Bug: Webadmin redirect ignores host port (#419) +- Bug: Disable esld when signing with dkim (#435) +- Bug: DKIM missing when using identities (#462) +- Bug: Moving mails from Junk to Trash flags them as ham (#474) +- Bug: Cannot set the "keep emails" for fetched accounts (#479) +- Bug: CVE-2018-8740 (#482) +- Bug: Hide administration header in sidebar for normal users (#505) +- Bug: Return correct status codes from auth rate limiter failure (#513) +- Bug: Domain edit page shows "Create" button (#523) +- Bug: Hostname resolving in start.py should retry on failure [docker swarm] (#555) +- Bug: Error when trying to log in with an account without domain (#585) +- Bug: Fix rainloop permissions (#637) + v1.5.1 - 2017-11-21 ------------------- From a7853ff52811464e71b7cc72bafbfc91004ba88d Mon Sep 17 00:00:00 2001 From: hoellen Date: Sun, 30 Dec 2018 18:21:51 +0100 Subject: [PATCH 57/62] link issue to url --- CHANGELOG.md | 190 +++++++++++++++++++++++++-------------------------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ced5a79..f3bcce93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,105 +8,105 @@ upgrading Freposte.io as some changes will include useful notes. v1.6.0 - unreleased ------------------- -- Global: Architecture of the central container (#56, #108) -- Global: Serve documentation with docker (#601, #608) -- Global: Travis-CI automated test build (#602) -- Global: Abstract db access from Postfix and Dovecot (#612) -- Global: Refactor the admin architecture and configuration management (#670) -- Feature: Used quota in admin interface (#216) -- Feature: User Signup (#281, #340) -- Feature: Client setup page (#342) -- Feature: Administration setup page (#343) -- Feature: Visual notice whether the mx record points to mailu server (#356) -- Feature: Option for vacation start (#362) -- Feature: Enable enigma in Roundcube (#391) -- Feature: Allow more charcaters as a valid email address (#443) -- Feature: IDNA support (#446) -- Feature: Disable user account (#449) -- Feature: Use fuzzy hashes in rpamd (#456, #527) -- Feature: Enable “doveadm -A” command (#458) -- Feature: Remove the Service Status page (#463) -- Feature: Automated Releases (#487) -- Feature: Support for ARC (#495) -- Feature: Add posibilty to run webmail on root (#501) -- Feature: Upgrade docker-compose.yml to version 3 (#539) -- Feature: Documentation to deploy mailu on a docker swarm (#551) -- Feature: Add full-text search support (#552) -- Feature: Add optional Maildir-Compression (#553) -- Feature: Preserve rspamd history on container restart (#561) -- Feature: FAQ (#564, #677) -- Feature: Kubernetes support (#576) -- Feature: Option to bounce or reject email when recipient is unknown (#583, #626) -- Feature: implement healthchecks for all containers (#631) -- Feature: Option to send front logs to journald or syslog (#584, #661) -- Feature: Support bcrypt and PBKDF2 (#647, #667) -- Feature: enable http2 (#674) -- Feature: Unbound DNS as optional service (#681) -- Feature: Re-write test suite (#682) -- Feature: Docker image prefixes (#702) -- Feature: Add authentication method “login” for Outlook (#704) -- Feature: Allow extending nginx config with overrides (#713) -- Feature: Dynamic attachment size limit (#731) -- Feature: Certificate watcher for external certs to reload nginx (#732) +- Global: Architecture of the central container ([#56](https://github.com/Mailu/Mailu/issues/56), [#108](https://github.com/Mailu/Mailu/issues/108)) +- Global: Serve documentation with docker ([#601](https://github.com/Mailu/Mailu/issues/601), [#608](https://github.com/Mailu/Mailu/issues/608)) +- Global: Travis-CI automated test build ([#602](https://github.com/Mailu/Mailu/issues/602)) +- Global: Abstract db access from Postfix and Dovecot ([#612](https://github.com/Mailu/Mailu/issues/612)) +- Global: Refactor the admin architecture and configuration management ([#670](https://github.com/Mailu/Mailu/issues/670)) +- Feature: Used quota in admin interface ([#216](https://github.com/Mailu/Mailu/issues/216)) +- Feature: User Signup ([#281](https://github.com/Mailu/Mailu/issues/281), [#340](https://github.com/Mailu/Mailu/issues/340)) +- Feature: Client setup page ([#342](https://github.com/Mailu/Mailu/issues/342)) +- Feature: Administration setup page ([#343](https://github.com/Mailu/Mailu/issues/343)) +- Feature: Visual notice whether the mx record points to mailu server ([#356](https://github.com/Mailu/Mailu/issues/356)) +- Feature: Option for vacation start ([#362](https://github.com/Mailu/Mailu/issues/362)) +- Feature: Enable enigma in Roundcube ([#391](https://github.com/Mailu/Mailu/issues/391)) +- Feature: Allow more charcaters as a valid email address ([#443](https://github.com/Mailu/Mailu/issues/443)) +- Feature: IDNA support ([#446](https://github.com/Mailu/Mailu/issues/446)) +- Feature: Disable user account ([#449](https://github.com/Mailu/Mailu/issues/449)) +- Feature: Use fuzzy hashes in rpamd ([#456](https://github.com/Mailu/Mailu/issues/456), [#527](https://github.com/Mailu/Mailu/issues/527)) +- Feature: Enable “doveadm -A” command ([#458](https://github.com/Mailu/Mailu/issues/458)) +- Feature: Remove the Service Status page ([#463](https://github.com/Mailu/Mailu/issues/463)) +- Feature: Automated Releases ([#487](https://github.com/Mailu/Mailu/issues/487)) +- Feature: Support for ARC ([#495](https://github.com/Mailu/Mailu/issues/495)) +- Feature: Add posibilty to run webmail on root ([#501](https://github.com/Mailu/Mailu/issues/501)) +- Feature: Upgrade docker-compose.yml to version 3 ([#539](https://github.com/Mailu/Mailu/issues/539)) +- Feature: Documentation to deploy mailu on a docker swarm ([#551](https://github.com/Mailu/Mailu/issues/551)) +- Feature: Add full-text search support ([#552](https://github.com/Mailu/Mailu/issues/552)) +- Feature: Add optional Maildir-Compression ([#553](https://github.com/Mailu/Mailu/issues/553)) +- Feature: Preserve rspamd history on container restart ([#561](https://github.com/Mailu/Mailu/issues/561)) +- Feature: FAQ ([#564](https://github.com/Mailu/Mailu/issues/564), [#677](https://github.com/Mailu/Mailu/issues/677)) +- Feature: Kubernetes support ([#576](https://github.com/Mailu/Mailu/issues/576)) +- Feature: Option to bounce or reject email when recipient is unknown ([#583](https://github.com/Mailu/Mailu/issues/583), [#626](https://github.com/Mailu/Mailu/issues/626)) +- Feature: implement healthchecks for all containers ([#631](https://github.com/Mailu/Mailu/issues/631)) +- Feature: Option to send front logs to journald or syslog ([#584](https://github.com/Mailu/Mailu/issues/584), [#661](https://github.com/Mailu/Mailu/issues/661)) +- Feature: Support bcrypt and PBKDF2 ([#647](https://github.com/Mailu/Mailu/issues/647), [#667](https://github.com/Mailu/Mailu/issues/667)) +- Feature: enable http2 ([#674](https://github.com/Mailu/Mailu/issues/674)) +- Feature: Unbound DNS as optional service ([#681](https://github.com/Mailu/Mailu/issues/681)) +- Feature: Re-write test suite ([#682](https://github.com/Mailu/Mailu/issues/682)) +- Feature: Docker image prefixes ([#702](https://github.com/Mailu/Mailu/issues/702)) +- Feature: Add authentication method “login” for Outlook ([#704](https://github.com/Mailu/Mailu/issues/704)) +- Feature: Allow extending nginx config with overrides ([#713](https://github.com/Mailu/Mailu/issues/713)) +- Feature: Dynamic attachment size limit ([#731](https://github.com/Mailu/Mailu/issues/731)) +- Feature: Certificate watcher for external certs to reload nginx ([#732](https://github.com/Mailu/Mailu/issues/732)) - Feature: Kubernetes -- Enhancement: Use pre-defined dhparam (#322) -- Enhancement: Disable ssl_session_tickets (#329) -- Enhancement: max attachment size in roundcube (#338) -- Enhancement: Use x-forwarded-proto with redirects (#347) -- Enhancement: Added adress verification before accepting mails for delivery (#353) -- Enhancement: Reverse proxy - Real ip header and mail-letsencrypt (#358) -- Enhancement: Parametrize hosts (#373) -- Enhancement: Expose ports in dockerfiles (#392) -- Enhancement: Added webmail-imap dependency in docker-compose (#403) -- Enhancement: Add environment variables to allow running outside of docker-compose (#429) -- Enhancement: Add original Delivered-To header to received messages (#433) -- Enhancement: Use HOST_ADMIN in "Forwarding authentication server" (#436, #437) -- Enhancement: Use POD_ADDRESS_RANGE for Dovecot (#448) -- Enhancement: Using configurable filenames for TLS certs (#468) -- Enhancement: Don't require BootstrapCDN (GDPR-compliance) (#477) -- Enhancement: Use dynamic client_max_body_size for webmail (#502) -- Enhancement: New logo design (#509) -- Enhancement: New manifests for Kubernetes (#544) -- Enhancement: Pin Alpine image (#548, #557) -- Enhancement: Use safer cipher in roundcube (#597) -- Enhancement: Improve sender checks (#633) -- Enhancement: Use PHP 7.2 for rainloop and roundcube (#606, #642) -- Enhancement: Multi-version documentation (#664) -- Enhancement: Contribution documentation (#700) -- Enhancement: Move Mailu Docker network to a fixed subnet (#727) -- Enhancement: Added regex validation for alias username (#764) +- Enhancement: Use pre-defined dhparam ([#322](https://github.com/Mailu/Mailu/issues/322)) +- Enhancement: Disable ssl_session_tickets ([#329](https://github.com/Mailu/Mailu/issues/329)) +- Enhancement: max attachment size in roundcube ([#338](https://github.com/Mailu/Mailu/issues/338)) +- Enhancement: Use x-forwarded-proto with redirects ([#347](https://github.com/Mailu/Mailu/issues/347)) +- Enhancement: Added adress verification before accepting mails for delivery ([#353](https://github.com/Mailu/Mailu/issues/353)) +- Enhancement: Reverse proxy - Real ip header and mail-letsencrypt ([#358](https://github.com/Mailu/Mailu/issues/358)) +- Enhancement: Parametrize hosts ([#373](https://github.com/Mailu/Mailu/issues/373)) +- Enhancement: Expose ports in dockerfiles ([#392](https://github.com/Mailu/Mailu/issues/392)) +- Enhancement: Added webmail-imap dependency in docker-compose ([#403](https://github.com/Mailu/Mailu/issues/403)) +- Enhancement: Add environment variables to allow running outside of docker-compose ([#429](https://github.com/Mailu/Mailu/issues/429)) +- Enhancement: Add original Delivered-To header to received messages ([#433](https://github.com/Mailu/Mailu/issues/433)) +- Enhancement: Use HOST_ADMIN in "Forwarding authentication server" ([#436](https://github.com/Mailu/Mailu/issues/436), [#437](https://github.com/Mailu/Mailu/issues/437)) +- Enhancement: Use POD_ADDRESS_RANGE for Dovecot ([#448](https://github.com/Mailu/Mailu/issues/448)) +- Enhancement: Using configurable filenames for TLS certs ([#468](https://github.com/Mailu/Mailu/issues/468)) +- Enhancement: Don't require BootstrapCDN (GDPR-compliance) ([#477](https://github.com/Mailu/Mailu/issues/477)) +- Enhancement: Use dynamic client_max_body_size for webmail ([#502](https://github.com/Mailu/Mailu/issues/502)) +- Enhancement: New logo design ([#509](https://github.com/Mailu/Mailu/issues/509)) +- Enhancement: New manifests for Kubernetes ([#544](https://github.com/Mailu/Mailu/issues/544)) +- Enhancement: Pin Alpine image ([#548](https://github.com/Mailu/Mailu/issues/548), [#557](https://github.com/Mailu/Mailu/issues/557)) +- Enhancement: Use safer cipher in roundcube ([#597](https://github.com/Mailu/Mailu/issues/597)) +- Enhancement: Improve sender checks ([#633](https://github.com/Mailu/Mailu/issues/633)) +- Enhancement: Use PHP 7.2 for rainloop and roundcube ([#606](https://github.com/Mailu/Mailu/issues/606), [#642](https://github.com/Mailu/Mailu/issues/642)) +- Enhancement: Multi-version documentation ([#664](https://github.com/Mailu/Mailu/issues/664)) +- Enhancement: Contribution documentation ([#700](https://github.com/Mailu/Mailu/issues/700)) +- Enhancement: Move Mailu Docker network to a fixed subnet ([#727](https://github.com/Mailu/Mailu/issues/727)) +- Enhancement: Added regex validation for alias username ([#764](https://github.com/Mailu/Mailu/issues/764)) - Enhancement: Update documentation - Upstream: Update Roundcube - Upstream: Update Rainloop -- Bug: Rainloop fails with "domain not allowed" (#93) -- Bug: Announces fail (#309) -- Bug: Authentication issues with rspamd admin ui (#315) -- Bug: front hangup on restart (#341) -- Bug: Display the proper user quota when set to 0/infinity (#345) -- Bug: Domain details button "Regenerate keys" when no keys are generated yet (#346) -- Bug: Relayed Domains: access denied error (#351) -- Bug: Do not deny HTTP access upon TLS error when the flavor is mail (#352) -- Bug: php_zip extension missing in Roundcube webmail (#364) -- Bug: RoundCube webmail .htaccess assumes PHP 5 (#366) -- Bug: No quota shows "0 Bytes" in user list (#368) -- Bug: RELAYNETS not honored when login is different from sender (#369) -- Bug: Request Entity Too Large (#371) -- Bug: Pass the full host to the backend (#372) -- Bug: Can't send from an email account that has forwarding (#390) -- Bug: SSL protocol error roundcube/imap (#411, #414) -- Bug: Unable to send from alternative domains (#415) -- Bug: Webadmin redirect ignores host port (#419) -- Bug: Disable esld when signing with dkim (#435) -- Bug: DKIM missing when using identities (#462) -- Bug: Moving mails from Junk to Trash flags them as ham (#474) -- Bug: Cannot set the "keep emails" for fetched accounts (#479) -- Bug: CVE-2018-8740 (#482) -- Bug: Hide administration header in sidebar for normal users (#505) -- Bug: Return correct status codes from auth rate limiter failure (#513) -- Bug: Domain edit page shows "Create" button (#523) -- Bug: Hostname resolving in start.py should retry on failure [docker swarm] (#555) -- Bug: Error when trying to log in with an account without domain (#585) -- Bug: Fix rainloop permissions (#637) +- Bug: Rainloop fails with "domain not allowed" ([#93](https://github.com/Mailu/Mailu/issues/93)) +- Bug: Announces fail ([#309](https://github.com/Mailu/Mailu/issues/309)) +- Bug: Authentication issues with rspamd admin ui ([#315](https://github.com/Mailu/Mailu/issues/315)) +- Bug: front hangup on restart ([#341](https://github.com/Mailu/Mailu/issues/341)) +- Bug: Display the proper user quota when set to 0/infinity ([#345](https://github.com/Mailu/Mailu/issues/345)) +- Bug: Domain details button "Regenerate keys" when no keys are generated yet ([#346](https://github.com/Mailu/Mailu/issues/346)) +- Bug: Relayed Domains: access denied error ([#351](https://github.com/Mailu/Mailu/issues/351)) +- Bug: Do not deny HTTP access upon TLS error when the flavor is mail ([#352](https://github.com/Mailu/Mailu/issues/352)) +- Bug: php_zip extension missing in Roundcube webmail ([#364](https://github.com/Mailu/Mailu/issues/364)) +- Bug: RoundCube webmail .htaccess assumes PHP 5 ([#366](https://github.com/Mailu/Mailu/issues/366)) +- Bug: No quota shows "0 Bytes" in user list ([#368](https://github.com/Mailu/Mailu/issues/368)) +- Bug: RELAYNETS not honored when login is different from sender ([#369](https://github.com/Mailu/Mailu/issues/369)) +- Bug: Request Entity Too Large ([#371](https://github.com/Mailu/Mailu/issues/371)) +- Bug: Pass the full host to the backend ([#372](https://github.com/Mailu/Mailu/issues/372)) +- Bug: Can't send from an email account that has forwarding ([#390](https://github.com/Mailu/Mailu/issues/390)) +- Bug: SSL protocol error roundcube/imap ([#411](https://github.com/Mailu/Mailu/issues/411), [#414](https://github.com/Mailu/Mailu/issues/414)) +- Bug: Unable to send from alternative domains ([#415](https://github.com/Mailu/Mailu/issues/415)) +- Bug: Webadmin redirect ignores host port ([#419](https://github.com/Mailu/Mailu/issues/419)) +- Bug: Disable esld when signing with dkim ([#435](https://github.com/Mailu/Mailu/issues/435)) +- Bug: DKIM missing when using identities ([#462](https://github.com/Mailu/Mailu/issues/462)) +- Bug: Moving mails from Junk to Trash flags them as ham ([#474](https://github.com/Mailu/Mailu/issues/474)) +- Bug: Cannot set the "keep emails" for fetched accounts ([#479](https://github.com/Mailu/Mailu/issues/479)) +- Bug: CVE-2018-8740 ([#482](https://github.com/Mailu/Mailu/issues/482)) +- Bug: Hide administration header in sidebar for normal users ([#505](https://github.com/Mailu/Mailu/issues/505)) +- Bug: Return correct status codes from auth rate limiter failure ([#513](https://github.com/Mailu/Mailu/issues/513)) +- Bug: Domain edit page shows "Create" button ([#523](https://github.com/Mailu/Mailu/issues/523)) +- Bug: Hostname resolving in start.py should retry on failure [docker swarm] ([#555](https://github.com/Mailu/Mailu/issues/555)) +- Bug: Error when trying to log in with an account without domain ([#585](https://github.com/Mailu/Mailu/issues/585)) +- Bug: Fix rainloop permissions ([#637](https://github.com/Mailu/Mailu/issues/637)) v1.5.1 - 2017-11-21 ------------------- From aefb638eca56b8ba4bb8f2e4b16fb68a454a73eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 30 Dec 2018 21:08:29 +0200 Subject: [PATCH 58/62] Fix links to documentation --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4a7611f0..ff7939e5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ This project is open source, and your contributions are all welcome. There are mostly three different ways one can contribute to the project: 1. use Mailu, either on test or on production instances, and report meaningful bugs when you find some; -2. contribute code and/or configuration to the repository (see [the development guidelines](https://mailu.io/contributors/guide.html) for details); -3. contribute localization to your native language (see [the localization docs](https://mailu.io/contributors/localization.html) for details); +2. contribute code and/or configuration to the repository (see [the development guidelines](https://mailu.io/master/contributors/guide.html) for details); +3. contribute localization to your native language (see [the localization docs](https://mailu.io/master/contributors/localization.html) for details); Either way, keep in mind that the code you write or the translation you produce muts be licensed under the same conditions as the project itself. Additionally, all contributors are considered equal co-authors of the project. From 2dfed9dc908a2765c779cac495f7461b1fb12110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 30 Dec 2018 21:15:41 +0200 Subject: [PATCH 59/62] Add usrpro team to authors --- AUTHORS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS.md b/AUTHORS.md index f62c2e14..11aca2a4 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -22,3 +22,5 @@ Other contributors: - "SunMar" - Dutch translation - "Marty Hou" - Chinese Simple translation - [Thomas Sänger](https://github.com/HorayNarea) - German translation + - [Tim Mohlmann](https://github.com/muhlemmer) - [Contributions](https://github.com/Mailu/Mailu/commits?author=muhlemmer) + - [Ionut Filip](https://github.com/ionutfilip) - [Contributions](https://github.com/Mailu/Mailu/commits?author=ionutfilip) From 03ee3aa918a77d9f4136c14c8a61eb97ebc48910 Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Sun, 30 Dec 2018 21:46:02 +0100 Subject: [PATCH 60/62] Fix typo in contributor docs --- docs/contributors/environment.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributors/environment.rst b/docs/contributors/environment.rst index b539293b..263ef747 100644 --- a/docs/contributors/environment.rst +++ b/docs/contributors/environment.rst @@ -184,7 +184,7 @@ directory structure. If you do no posses the resources, but want to become an involved tester/reviewer. Please contact `muhlemmer on Matrix`_. -He can provide access to a testing server, if a thrust relation can be established. +He can provide access to a testing server, if a trust relation can be established. .. _`muhlemmer on Matrix`: https://matrix.to/#/@muhlemmer:matrix.org From aaa7ef5de3da26b8ee86f29e1f74025715e56be3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Mon, 31 Dec 2018 03:13:47 +0200 Subject: [PATCH 61/62] Update demo server docs --- docs/demo.rst | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/docs/demo.rst b/docs/demo.rst index e2f6c4b0..9415e670 100644 --- a/docs/demo.rst +++ b/docs/demo.rst @@ -5,21 +5,32 @@ The demo server is for demonstration and test purposes only. Please be respectful and keep the demo server functional for others to be able to try it out. -The server is reset every day at 3am, french time. If you find the server is -unusable, you can still ask for someone to reset it manually on our Matrix -chat channel. Please do not open tickets everytime the server is down. Please -do not open tickets if the server is quite slow: it *is* slow because the -machine is a cheap leased server. +If you find the server is unusable, you can ask for someone to reset it manually on our Matrix +chat channel. Please do not open tickets every time the server is down. +Please do not open tickets if the server is quite slow: it *is* slow because the +services have only limited resources available. -Keep in mind that the demo server is also used for some automated tests and runs -the latest unstable version. If you find actual bugs when using the demo -server, please report these! +Keep in mind that the demo server runs the latest unstable (master) version. +If you find actual bugs when using the demo server, please report these! + +Functionality +------------- + +- The server is reset every day at 3am, UTC. +- You can send mail from any client to the server. + However, the stmp server is made incapable of relaying the e-mail to the destination server. + As such, the mail will never arrive. This is to prevent abuse of the server. +- The server is capable of receiving mail for any configured domains. +- The server exposes IMAP, POP3 and SMTP as usual for connection with mail clients such as Thunderbird. +- The containers have limited (throttled) CPU, this means it can respond slow during heavy operations. +- The containers have limited memory available and will be killed when exceeded. + This is to prevent people from doing nasty things to the server as a whole. Connecting to the server ------------------------ * Server name : ``test.mailu.io`` - * IP address : ``51.15.169.20`` + * IP address : ``173.249.45.89`` * Webmail : https://test.mailu.io/webmail/ * Admin UI : https://test.mailu.io/admin/ * Admin login : ``admin@test.mailu.io`` From 16c47faf35e393925f3e3320b16a255dfe3f25d5 Mon Sep 17 00:00:00 2001 From: Daniel Huber Date: Mon, 31 Dec 2018 12:39:35 +0100 Subject: [PATCH 62/62] Fix default docker prefix value of traefik certdumper docker-compose logs a warning if a environment variable is not set and has no default value. This adds a default string as the default for traefik certdumper which was added in 7c7b52d9. --- tests/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/build.yml b/tests/build.yml index 3436d25a..e06327cd 100644 --- a/tests/build.yml +++ b/tests/build.yml @@ -31,7 +31,7 @@ services: build: ../optional/radicale traefik-certdumper: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}traefik-certdumper:${MAILU_VERSION:-local} + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}traefik-certdumper:${MAILU_VERSION:-local} build: ../optional/traefik-certdumper admin: