You've already forked Mailu
mirror of
https://github.com/Mailu/Mailu.git
synced 2025-07-03 00:47:16 +02:00
Merge branch 'master' into delete-disable
This commit is contained in:
@ -125,12 +125,12 @@ The following steps have to be taken to configure an additional symbol (rule) th
|
||||
#This file is LIVE reloaded by rspamd. Any changes are EFFECTIVE IMMEDIATELY.
|
||||
dummy.com
|
||||
|
||||
3. Reload Rspamd by stopping the Rspamd container and starting the Rspamd container again. Example for docker-compose setup:
|
||||
3. Reload Rspamd by stopping the Rspamd container and starting the Rspamd container again. Example for docker compose setup:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose scale antispam=0
|
||||
docker-compose scale antispam=1
|
||||
docker compose scale antispam=0
|
||||
docker compose scale antispam=1
|
||||
|
||||
4. (Optional) Check if the custom symbol is loaded. To access the Rspamd webgui, log in the Mailu administration web interface with a user that is an administrator and go to Antispam. In Rspamd webgui go to tab Symbols. Change the group drop-down box to local_bl. The following additional rule will be listed.
|
||||
|
||||
@ -155,3 +155,31 @@ For more information on using the multimap filter see the official `multimap doc
|
||||
.. _`1438`: https://github.com/Mailu/Mailu/issues/1438
|
||||
.. _`1167`: https://github.com/Mailu/Mailu/issues/1167
|
||||
.. _`1566`: https://github.com/Mailu/Mailu/issues/1566
|
||||
|
||||
Can I change the list of authorized file attachments?
|
||||
-----------------------------------------------------
|
||||
|
||||
Mailu rejects emails with file attachements it deems to be "executable" or otherwise dangerous. If you would like to tweak the block list, you can do so using the following commands:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker compose exec antispam cat /etc/rspamd/local.d/forbidden_file_extension.map > overrides/rspamd/forbidden_file_extension.map
|
||||
docker compose restart antispam
|
||||
|
||||
Now the file `overrides/rspamd/forbidden_file_extension.map` can be edited, to make changes to the forbidden file extensions list.
|
||||
For the changes to take effect, rspamd must be restarted.
|
||||
|
||||
Mailu rejects emails with documents attached containing some macros. How can I fix it?
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
If configured to do so, Mailu uses a lightweight tool called `mraptor from oletools`_ to scan documents containing macros. By default only macros deemed potentially harmful are blocked, but there may be false positives. If you want to change the default behaviour, you may need to override the ``/etc/rspamd/local.d/composites.conf`` file in the antispam container. The following commands may be useful:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker compose exec antispam cat /etc/rspamd/local.d/composites.conf > overrides/rspamd/composites.conf
|
||||
docker compose restart antispam
|
||||
|
||||
Now the file `overrides/rspamd/composites.conf` can be edited, to override the mraptor configuration in rspamd.
|
||||
For the changes to take effect, rspamd must be restarted.
|
||||
|
||||
.. _`mraptor from oletools`: https://github.com/decalage2/oletools/wiki/mraptor
|
||||
|
33
docs/api.rst
Normal file
33
docs/api.rst
Normal file
@ -0,0 +1,33 @@
|
||||
Mailu RESTful API
|
||||
=================
|
||||
|
||||
Mailu offers a RESTful API for changing the Mailu configuration.
|
||||
Anything that can be configured via the Mailu web administration interface,
|
||||
can also be configured via the API.
|
||||
|
||||
The Mailu API can be configured via the setup utility (setup.mailu.io).
|
||||
It can also be manually configured via mailu.env:
|
||||
|
||||
* ``API`` - Expose the API interface (value: true, false)
|
||||
* ``WEB_API`` - Path to the API interface
|
||||
* ``API_TOKEN`` - API token for authentication
|
||||
|
||||
For more information refer to the detailed descriptions in the
|
||||
:ref:`configuration reference <advanced_settings>`.
|
||||
|
||||
|
||||
Swagger.json
|
||||
------------
|
||||
|
||||
The swagger.json file can be retrieved via: https://myserver/api/v1/swagger.json
|
||||
(WEB_API=/api)
|
||||
The swagger.json file can be consumed in programs such as Postman for generating all API calls.
|
||||
|
||||
|
||||
In-built SwaggerUI
|
||||
------------------
|
||||
The Mailu API comes with an in-built SwaggerUI. It is a web client that allows
|
||||
anyone to visualize and interact with the Mailu API.
|
||||
|
||||
Assuming ``/api`` is configured as value for ``WEB_API``, it
|
||||
is accessible via the URL: https://myserver/api/
|
32
docs/cli.rst
32
docs/cli.rst
@ -1,7 +1,7 @@
|
||||
Mailu command line
|
||||
==================
|
||||
|
||||
Managing users and aliases can be done from CLI using commands:
|
||||
Managing domains, users and aliases can be done from CLI using the commands:
|
||||
|
||||
* alias
|
||||
* alias-delete
|
||||
@ -19,7 +19,7 @@ alias
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose exec admin flask mailu alias foo example.net "mail1@example.com,mail2@example.com"
|
||||
docker compose exec admin flask mailu alias foo example.net "mail1@example.com,mail2@example.com"
|
||||
|
||||
|
||||
alias-delete
|
||||
@ -27,7 +27,7 @@ alias-delete
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose exec admin flask mailu alias-delete foo@example.net
|
||||
docker compose exec admin flask mailu alias-delete foo@example.net
|
||||
|
||||
|
||||
domain
|
||||
@ -35,7 +35,7 @@ domain
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose exec admin flask mailu domain example.net
|
||||
docker compose exec admin flask mailu domain example.net
|
||||
|
||||
|
||||
password
|
||||
@ -43,7 +43,7 @@ password
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose exec admin flask mailu password myuser example.net 'password123'
|
||||
docker compose exec admin flask mailu password myuser example.net 'password123'
|
||||
|
||||
|
||||
user
|
||||
@ -51,7 +51,7 @@ user
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose exec admin flask mailu user myuser example.net 'password123'
|
||||
docker compose exec admin flask mailu user myuser example.net 'password123'
|
||||
|
||||
|
||||
user-import
|
||||
@ -61,7 +61,7 @@ primary difference with simple `user` command is that password is being imported
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose run --rm admin flask mailu user-import myuser example.net '$6$51ebe0cb9f1dab48effa2a0ad8660cb489b445936b9ffd812a0b8f46bca66dd549fea530ce' 'SHA512-CRYPT'
|
||||
docker compose run --rm admin flask mailu user-import myuser example.net '$6$51ebe0cb9f1dab48effa2a0ad8660cb489b445936b9ffd812a0b8f46bca66dd549fea530ce' 'SHA512-CRYPT'
|
||||
|
||||
|
||||
user-delete
|
||||
@ -73,7 +73,7 @@ Add the flag `-r` to really delete the user after you have deleted user-data man
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose exec admin flask mailu user-delete foo@example.net
|
||||
docker compose exec admin flask mailu user-delete foo@example.net
|
||||
|
||||
|
||||
config-update
|
||||
@ -83,7 +83,7 @@ The sole purpose of this command is for importing users/aliases in bulk and sync
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cat mail-config.yml | docker-compose exec -T admin flask mailu config-update --delete-objects
|
||||
cat mail-config.yml | docker compose exec -T admin flask mailu config-update --delete-objects
|
||||
|
||||
where mail-config.yml looks like:
|
||||
|
||||
@ -137,7 +137,7 @@ The purpose of this command is to export the complete configuration in YAML or J
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ docker-compose exec admin flask mailu config-export --help
|
||||
$ docker compose exec -T admin flask mailu config-export --help
|
||||
|
||||
Usage: flask mailu config-export [OPTIONS] [FILTER]...
|
||||
|
||||
@ -162,11 +162,11 @@ Attributes explicitly specified in filters are automatically exported: there is
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ docker-compose exec admin flask mailu config-export --output mail-config.yml
|
||||
$ docker compose exec admin flask mailu config-export --output mail-config.yml
|
||||
|
||||
$ docker-compose exec admin flask mailu config-export domain.dns_mx domain.dns_spf
|
||||
$ docker compose exec -T admin flask mailu config-export domain.dns_mx domain.dns_spf
|
||||
|
||||
$ docker-compose exec admin flask mailu config-export user.spam_threshold
|
||||
$ docker compose exec -T admin flask mailu config-export user.email user.spam_threshold
|
||||
|
||||
config-import
|
||||
-------------
|
||||
@ -175,7 +175,7 @@ This command imports configuration data from an external YAML or JSON source.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ docker-compose exec admin flask mailu config-import --help
|
||||
$ docker compose exec -T admin flask mailu config-import --help
|
||||
|
||||
Usage: flask mailu config-import [OPTIONS] [FILENAME|-]
|
||||
|
||||
@ -190,11 +190,11 @@ This command imports configuration data from an external YAML or JSON source.
|
||||
-n, --dry-run Perform a trial run with no changes made.
|
||||
-?, -h, --help Show this message and exit.
|
||||
|
||||
The current version of docker-compose exec does not pass stdin correctly, so you have to user docker exec instead:
|
||||
To pass stdin correctly you have to use the `-T` option:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker exec -i $(docker-compose ps -q admin) flask mailu config-import -nv < mail-config.yml
|
||||
docker compose exec -T admin flask mailu config-import -nv < mail-config.yml
|
||||
|
||||
mail-config.yml contains the configuration and looks like this:
|
||||
|
||||
|
@ -138,7 +138,7 @@ WEBSITE=https://mailu.io
|
||||
# Log driver for front service. Possible values:
|
||||
# json-file (default)
|
||||
# journald (On systemd platforms, useful for Fail2Ban integration)
|
||||
# syslog (Non systemd platforms, Fail2Ban integration. Disables `docker-compose log` for front!)
|
||||
# syslog (Non systemd platforms, Fail2Ban integration. Disables `docker compose log` for front!)
|
||||
LOG_DRIVER=json-file
|
||||
|
||||
# Docker-compose project name, this will prepended to containers names.
|
||||
|
@ -91,7 +91,7 @@ The Docker website is full of `detailed instructions`_
|
||||
about setting up a proper Docker install. Default configuration should be
|
||||
suited for Mailu.
|
||||
|
||||
Additionally, you must install ``docker-compose`` by following the instructions
|
||||
Additionally, you must install ``docker compose`` v2 by following the instructions
|
||||
from the `Docker website`_ if you plan on using the Compose flavor. Compose is a
|
||||
management tool for Docker, especially suited for multiple containers systems
|
||||
like Mailu.
|
||||
@ -105,24 +105,34 @@ Once everything is setup, you should be able to run the following commands
|
||||
.. code-block:: bash
|
||||
|
||||
$ docker version
|
||||
Client:
|
||||
Version: 1.11.2
|
||||
API version: 1.23
|
||||
Go version: go1.6.2
|
||||
Git commit: b9f10c9
|
||||
Built: Sun Jun 5 23:17:55 2016
|
||||
OS/Arch: linux/amd64
|
||||
Client: Docker Engine - Community
|
||||
Version: 20.10.22
|
||||
API version: 1.41
|
||||
Go version: go1.18.9
|
||||
Git commit: 3a2c30b
|
||||
Built: Thu Dec 15 22:27:03 2022
|
||||
OS/Arch: linux/arm64
|
||||
Context: default
|
||||
Experimental: true
|
||||
|
||||
Server: Docker Engine - Community
|
||||
Engine:
|
||||
Version: 20.10.22
|
||||
API version: 1.41 (minimum version 1.12)
|
||||
Go version: go1.18.9
|
||||
Git commit: 42c8b31
|
||||
Built: Thu Dec 15 22:25:25 2022
|
||||
OS/Arch: linux/arm64
|
||||
Experimental: false
|
||||
containerd:
|
||||
Version: 1.6.14
|
||||
GitCommit: 9ba4b250366a5ddde94bb7c9d1def331423aa323
|
||||
runc:
|
||||
Version: 1.1.4
|
||||
GitCommit: v1.1.4-0-g5fd4c4d
|
||||
docker-init:
|
||||
Version: 0.19.0
|
||||
GitCommit: de40ad0
|
||||
|
||||
Server:
|
||||
Version: 1.11.1
|
||||
API version: 1.23
|
||||
Go version: go1.6.2
|
||||
Git commit: 5604cbe
|
||||
Built: Mon May 2 00:06:51 2016
|
||||
OS/Arch: linux/amd64
|
||||
|
||||
$ docker-compose version
|
||||
docker-compose version 1.7.1, build 6c29830
|
||||
docker-py version: 1.8.1
|
||||
CPython version: 3.5.1
|
||||
OpenSSL version: OpenSSL 1.0.2h 3 May 2016
|
||||
$ docker compose version
|
||||
Docker Compose version v2.14.1
|
||||
|
@ -95,7 +95,7 @@ You may now start Mailu. Move the to the Mailu directory and run:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose up -d
|
||||
docker compose up -d
|
||||
|
||||
Finally, you need an admin user account.
|
||||
|
||||
@ -106,7 +106,7 @@ Else, if you don't go with the automatic way, you need to manually create the ad
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose exec admin flask mailu admin me example.net 'password'
|
||||
docker compose exec admin flask mailu admin me example.net 'password'
|
||||
|
||||
This will create a user named ``me@example.net`` with password ``password`` and administration privileges.
|
||||
Connect to the Web admin interface and change the password to a strong one.
|
||||
|
@ -37,14 +37,15 @@ 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.
|
||||
|
||||
The ``WILDCARD_SENDERS`` setting is a comma delimited list of user email addresses
|
||||
The ``WILDCARD_SENDERS`` setting is a comma delimited list of user email addresses
|
||||
that are allowed to send emails from any existing address (spoofing the sender).
|
||||
|
||||
The ``AUTH_RATELIMIT_IP`` (default: 60/hour) holds a security setting for fighting
|
||||
attackers that waste server resources by trying to guess user passwords (typically
|
||||
using a password spraying attack). The value defines the limit of authentication
|
||||
attempts that will be processed on non-existing accounts for a specific IP subnet
|
||||
(as defined in ``AUTH_RATELIMIT_IP_V4_MASK`` and ``AUTH_RATELIMIT_IP_V6_MASK`` below).
|
||||
The ``AUTH_RATELIMIT_IP`` (default: 5/hour) holds a security setting for fighting
|
||||
attackers that attempt a password spraying attack. The value defines the limit of
|
||||
authentication attempts that will be processed on **distinct** non-existing
|
||||
accounts for a specific IP subnet as defined in
|
||||
``AUTH_RATELIMIT_IP_V4_MASK`` (default: /24) and
|
||||
``AUTH_RATELIMIT_IP_V6_MASK`` (default: /48).
|
||||
|
||||
The ``AUTH_RATELIMIT_USER`` (default: 100/day) holds a security setting for fighting
|
||||
attackers that attempt to guess a user's password (typically using a password
|
||||
@ -100,12 +101,19 @@ by setting ``INBOUND_TLS_ENFORCE`` to ``True``. Please note that this is forbidd
|
||||
internet facing hosts according to e.g. `RFC 3207`_ , because this prevents MTAs without STARTTLS
|
||||
support or e.g. mismatching TLS versions to deliver emails to Mailu.
|
||||
|
||||
The ``SCAN_MACROS`` (default: True) setting controls whether Mailu will endavour
|
||||
to reject emails containing documents with malicious macros. Under the hood, it uses
|
||||
`mraptor from oletools`_ to determine whether a macro is malicious or not.
|
||||
|
||||
.. _`mraptor from oletools`: https://github.com/decalage2/oletools/wiki/mraptor
|
||||
|
||||
.. _`RFC 3207`: https://tools.ietf.org/html/rfc3207
|
||||
|
||||
.. _fetchmail:
|
||||
|
||||
When ``FETCHMAIL_ENABLED`` is set to ``True``, the fetchmail functionality is enabled in the admin interface.
|
||||
The container itself still needs to be deployed manually. ``FETCHMAIL_ENABLED`` defaults to ``True``.
|
||||
When ``FETCHMAIL_ENABLED`` is set to ``True``, the fetchmail functionality is enabled and
|
||||
shown in the admin interface. The container itself still needs to be deployed manually.
|
||||
``FETCHMAIL_ENABLED`` defaults to ``True``.
|
||||
|
||||
The ``FETCHMAIL_DELAY`` is a delay (in seconds) for the fetchmail service to
|
||||
go and fetch new email if available. Do not use too short delays if you do not
|
||||
@ -134,13 +142,15 @@ Web settings
|
||||
|
||||
- ``WEB_WEBMAIL`` contains the path to the Web email client.
|
||||
|
||||
- ``WEB_API`` contains the path to the RESTful API.
|
||||
|
||||
- ``WEBROOT_REDIRECT`` redirects all non-found queries to the set path.
|
||||
An empty ``WEBROOT_REDIRECT`` value disables redirecting and enables
|
||||
An empty ``WEBROOT_REDIRECT`` value disables redirecting and enables
|
||||
classic behavior of a 404 result when not found.
|
||||
Alternatively, ``WEBROOT_REDIRECT`` can be set to ``none`` if you
|
||||
Alternatively, ``WEBROOT_REDIRECT`` can be set to ``none`` if you
|
||||
are using an Nginx override for ``location /``.
|
||||
|
||||
All three options need a leading slash (``/``) to work.
|
||||
All four options need a leading slash (``/``) to work.
|
||||
|
||||
.. note:: ``WEBROOT_REDIRECT`` has to point to a valid path on the webserver.
|
||||
This means it cannot point to any services which are not enabled.
|
||||
@ -150,11 +160,11 @@ Both ``SITENAME`` and ``WEBSITE`` are customization options for the panel menu
|
||||
in the admin interface, while ``SITENAME`` is a customization option for
|
||||
every Web interface.
|
||||
|
||||
- ``LOGO_BACKGROUND`` sets a custom background colour for the brand logo
|
||||
in the top left of the main admin interface.
|
||||
- ``LOGO_BACKGROUND`` sets a custom background colour for the brand logo
|
||||
in the topleft of the main admin interface.
|
||||
For a list of colour codes refer to this page of `w3schools`_.
|
||||
|
||||
- ``LOGO_URL`` sets a URL for a custom logo. This logo replaces the Mailu
|
||||
- ``LOGO_URL`` sets a URL for a custom logo. This logo replaces the Mailu
|
||||
logo in the topleft of the main admin interface.
|
||||
|
||||
.. _`w3schools`: https://www.w3schools.com/cssref/css_colors.asp
|
||||
@ -178,7 +188,7 @@ To have the account created automatically, you just need to define a few environ
|
||||
- ``ifmissing``: creates a new admin account when the admin account does not exist.
|
||||
- ``update``: creates a new admin account when it does not exist, or update the password of an existing admin account.
|
||||
|
||||
Note: It is recommended to set ``INITIAL_ADMIN_MODE`` to either ``update`` or ``ifmissing``. Leaving it with the
|
||||
Note: It is recommended to set ``INITIAL_ADMIN_MODE`` to either ``update`` or ``ifmissing``. Leaving it with the
|
||||
default value will cause an error when the system is restarted.
|
||||
|
||||
An example:
|
||||
@ -192,23 +202,27 @@ An example:
|
||||
|
||||
Depending on your particular deployment you most probably will want to change the default.
|
||||
|
||||
.. _advanced_cfg:
|
||||
.. _advanced_settings:
|
||||
|
||||
Advanced settings
|
||||
-----------------
|
||||
|
||||
The ``CREDENTIAL_ROUNDS`` (default: 12) setting is the number of rounds used by the
|
||||
password hashing scheme. The number of rounds can be reduced in case faster
|
||||
authentication is needed or increased when additional protection is desired.
|
||||
Keep in mind that this is a mitigation against offline attacks on password hashes,
|
||||
The ``API_TOKEN`` (default: None) configures the authentication token.
|
||||
This token must be passed as request header to the API as authentication token.
|
||||
This is a mandatory setting for using the RESTful API.
|
||||
|
||||
The ``CREDENTIAL_ROUNDS`` (default: 12) setting is the number of rounds used by the
|
||||
password hashing scheme. The number of rounds can be reduced in case faster
|
||||
authentication is needed or increased when additional protection is desired.
|
||||
Keep in mind that this is a mitigation against offline attacks on password hashes,
|
||||
aiming to prevent credential stuffing (due to password re-use) on other systems.
|
||||
|
||||
The ``SESSION_COOKIE_SECURE`` (default: True) setting controls the secure flag on
|
||||
the cookies of the administrative interface. It should only be turned off if you
|
||||
The ``SESSION_COOKIE_SECURE`` (default: True) setting controls the secure flag on
|
||||
the cookies of the administrative interface. It should only be turned off if you
|
||||
intend to access it over plain HTTP.
|
||||
|
||||
``SESSION_TIMEOUT`` (default: 3600) is the maximum amount of time in seconds between
|
||||
requests before a session is invalidated. ``PERMANENT_SESSION_LIFETIME`` (default: 108000)
|
||||
``SESSION_TIMEOUT`` (default: 3600) is the maximum amount of time in seconds between
|
||||
requests before a session is invalidated. ``PERMANENT_SESSION_LIFETIME`` (default: 108000)
|
||||
is the maximum amount of time in seconds a session can be kept alive for if it hasn't timed-out.
|
||||
|
||||
The ``LOG_LEVEL`` setting is used by the python start-up scripts as a logging threshold.
|
||||
@ -218,8 +232,8 @@ See the `python docs`_ for more information.
|
||||
|
||||
.. _`python docs`: https://docs.python.org/3.6/library/logging.html#logging-levels
|
||||
|
||||
The ``LETSENCRYPT_SHORTCHAIN`` (default: False) setting controls whether we send the
|
||||
ISRG Root X1 certificate in TLS handshakes. This is required for `android handsets older than 7.1.1`
|
||||
The ``LETSENCRYPT_SHORTCHAIN`` (default: False) setting controls whether we send the
|
||||
ISRG Root X1 certificate in TLS handshakes. This is required for `android handsets older than 7.1.1`
|
||||
but slows down the performance of modern devices.
|
||||
|
||||
.. _`android handsets older than 7.1.1`: https://community.letsencrypt.org/t/production-chain-changes/150739
|
||||
@ -228,11 +242,11 @@ The ``TLS_PERMISSIVE`` (default: true) setting controls whether ciphers and prot
|
||||
|
||||
.. _reverse_proxy_headers:
|
||||
|
||||
The ``REAL_IP_HEADER`` (default: unset) and ``REAL_IP_FROM`` (default: unset) settings
|
||||
controls whether HTTP headers such as ``X-Forwarded-For`` or ``X-Real-IP`` should be trusted.
|
||||
The former should be the name of the HTTP header to extract the client IP address from and the
|
||||
later a comma separated list of IP addresses designating which proxies to trust.
|
||||
If you are using Mailu behind a reverse proxy, you should set both. Setting the former without
|
||||
The ``REAL_IP_HEADER`` (default: unset) and ``REAL_IP_FROM`` (default: unset) settings
|
||||
controls whether HTTP headers such as ``X-Forwarded-For`` or ``X-Real-IP`` should be trusted.
|
||||
The former should be the name of the HTTP header to extract the client IP address from and the
|
||||
later a comma separated list of IP addresses designating which proxies to trust.
|
||||
If you are using Mailu behind a reverse proxy, you should set both. Setting the former without
|
||||
the later introduces a security vulnerability allowing a potential attacker to spoof his source address.
|
||||
|
||||
The ``TZ`` sets the timezone Mailu will use. The timezone naming convention usually uses a ``Region/City`` format. See `TZ database name`_ for a list of valid timezones This defaults to ``Etc/UTC``. Warning: if you are observing different timestamps in your log files you should change your hosts timezone to UTC instead of changing TZ to your local timezone. Using UTC allows easy log correlation with remote MTAs.
|
||||
@ -249,32 +263,22 @@ virus mails during SMTP dialogue, so the sender will receive a reject message.
|
||||
Infrastructure settings
|
||||
-----------------------
|
||||
|
||||
Various environment variables ``HOST_*`` can be used to run Mailu containers
|
||||
Various environment variables ``*_ADDRESS`` can be used to run Mailu containers
|
||||
separately from a supported orchestrator. It is used by the various components
|
||||
to find the location of the other containers it depends on. They can contain an
|
||||
optional port number. Those variables are:
|
||||
to find the location of the other containers it depends on. Those variables are:
|
||||
|
||||
- ``HOST_IMAP``: the container that is running the IMAP server (default: ``imap``, port 143)
|
||||
- ``HOST_LMTP``: the container that is running the LMTP server (default: ``imap:2525``)
|
||||
- ``HOST_HOSTIMAP``: the container that is running the IMAP server for the webmail (default: ``imap``, port 10143)
|
||||
- ``HOST_POP3``: the container that is running the POP3 server (default: ``imap``, port 110)
|
||||
- ``HOST_SMTP``: the container that is running the SMTP server (default: ``smtp``, port 25)
|
||||
- ``HOST_AUTHSMTP``: the container that is running the authenticated SMTP server for the webnmail (default: ``smtp``, port 10025)
|
||||
- ``HOST_ADMIN``: the container that is running the admin interface (default: ``admin``)
|
||||
- ``HOST_ANTISPAM_MILTER``: the container that is running the antispam milter service (default: ``antispam:11332``)
|
||||
- ``HOST_ANTISPAM_WEBUI``: the container that is running the antispam webui service (default: ``antispam:11334``)
|
||||
- ``HOST_ANTIVIRUS``: the container that is running the antivirus service (default: ``antivirus:3310``)
|
||||
- ``HOST_WEBMAIL``: the container that is running the webmail (default: ``webmail``)
|
||||
- ``HOST_WEBDAV``: the container that is running the webdav server (default: ``webdav:5232``)
|
||||
- ``HOST_REDIS``: the container that is running the redis daemon (default: ``redis``)
|
||||
- ``HOST_WEBMAIL``: the container that is running the webmail (default: ``webmail``)
|
||||
- ``ADMIN_ADDRESS``
|
||||
- ``ANTISPAM_ADDRESS``
|
||||
- ``ANTIVIRUS_ADDRESS``
|
||||
- ``FRONT_ADDRESS``
|
||||
- ``IMAP_ADDRESS``
|
||||
- ``REDIS_ADDRESS``
|
||||
- ``SMTP_ADDRESS``
|
||||
- ``WEBDAV_ADDRESS``
|
||||
- ``WEBMAIL_ADDRESS``
|
||||
|
||||
The startup scripts will resolve ``HOST_*`` to their IP addresses and store the result in ``*_ADDRESS`` for further use.
|
||||
|
||||
Alternatively, ``*_ADDRESS`` can directly be set. In this case, the values of ``*_ADDRESS`` is kept and not
|
||||
resolved. This can be used to rely on DNS based service discovery with changing services IP addresses.
|
||||
When using ``*_ADDRESS``, the hostnames must be full-qualified hostnames. Otherwise nginx will not be able to
|
||||
resolve the hostnames.
|
||||
These are used for DNS based service discovery with possibly changing services IP addresses.
|
||||
``*_ADDRESS`` values must be fully qualified domain names without port numbers.
|
||||
|
||||
.. _db_settings:
|
||||
|
||||
@ -352,15 +356,15 @@ Mail log settings
|
||||
|
||||
By default, all services log directly to stdout/stderr. Logs can be collected by any docker log processing solution.
|
||||
|
||||
Postfix writes the logs to a syslog server which logs to stdout. This is used to filter
|
||||
out messages from the healthcheck. In some situations, a separate mail log is required
|
||||
(e.g. for legal reasons). The syslog server can be configured to write log files to a volume.
|
||||
Postfix writes the logs to a syslog server which logs to stdout. This is used to filter
|
||||
out messages from the healthcheck. In some situations, a separate mail log is required
|
||||
(e.g. for legal reasons). The syslog server can be configured to write log files to a volume.
|
||||
It can be configured with the following option:
|
||||
|
||||
- ``POSTFIX_LOG_FILE``: The file to log the mail log to. When enabled, the syslog server will also log to stdout.
|
||||
|
||||
When ``POSTFIX_LOG_FILE`` is enabled, the logrotate program will automatically rotate the
|
||||
logs every week and keep 52 logs. To override the logrotate configuration, create the file logrotate.conf
|
||||
When ``POSTFIX_LOG_FILE`` is enabled, the logrotate program will automatically rotate the
|
||||
logs every week and keep 52 logs. To override the logrotate configuration, create the file logrotate.conf
|
||||
with the desired configuration in the :ref:`Postfix overrides folder<override-label>`.
|
||||
|
||||
|
||||
|
@ -153,25 +153,25 @@ After that you can run:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose up -d
|
||||
docker compose up -d
|
||||
|
||||
If you wish to run commands inside a container, simply run (example):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose exec admin ls -lah /
|
||||
docker compose exec admin ls -lah /
|
||||
|
||||
Or if you wish to start a shell for debugging:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose exec admin sh
|
||||
docker compose exec admin sh
|
||||
|
||||
Finally, if you need to install packages inside the containers for debugging:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose exec admin apk add --no-cache package-name
|
||||
docker compose exec admin apk add --no-cache package-name
|
||||
|
||||
Reviewing
|
||||
---------
|
||||
@ -215,8 +215,8 @@ For example, to test PR #500 against master, reviewers can use:
|
||||
|
||||
export DOCKER_ORG="mailuci"
|
||||
export MAILU_VERSION="pr-500"
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
|
||||
You can now test the PR. Play around. See if (external) mails work. Check for whatever functionality the PR is
|
||||
trying to fix. When happy, you can approve the PR. When running into failures, mark the review as
|
||||
|
@ -15,11 +15,11 @@ This means it is not possible to switch the database back-end used by roundcube
|
||||
|
||||
To switch to a different database back-end:
|
||||
|
||||
1. Run config-export to export the configuration. E.g. `docker-compose exec admin flask mailu config-export --secrets --output mail-config.yml`
|
||||
1. Run config-export to export the configuration. E.g. `docker compose exec admin flask mailu config-export --secrets --output mail-config.yml`
|
||||
2. Set up your new database server. Refer to the subsequent sections for tips for creating the database.
|
||||
3. Modify the database settings (DB_*) in mailu.env. Refer to the :ref:`configuration guide (link) <db_settings>` for the exact settings.
|
||||
4. Start your Mailu deployment.
|
||||
5. Run config-import to import the configuration. E.g. `docker exec -i $(docker-compose ps -q admin) flask mailu config-import -v < mail-config.yml`
|
||||
5. Run config-import to import the configuration. E.g. `docker exec -i $(docker compose ps -q admin) flask mailu config-import -v < mail-config.yml`
|
||||
|
||||
Mailu has now been switched to the new database back-end. The Mailu configuration has also been migrated.
|
||||
|
||||
@ -114,22 +114,22 @@ Prepare the environment. Mailu must not be in use. Only the database container.
|
||||
|
||||
1. Open a terminal.
|
||||
2. `cd /mailu`
|
||||
3. `docker-compose -p mailu down`
|
||||
4. `docker-compose -p mailu up -d database`
|
||||
3. `docker compose -p mailu down`
|
||||
4. `docker compose -p mailu up -d database`
|
||||
|
||||
Create the dump SQL file for recreating the database.
|
||||
|
||||
1. `docker-compose -p mailu exec database /bin/bash`
|
||||
1. `docker compose -p mailu exec database /bin/bash`
|
||||
2. `pg_dump -h database -p 5432 -U mailu > /backup/backup_db.sql`
|
||||
3. Enter the password. See the value of DB_PW in mailu.env.
|
||||
4. `exit`
|
||||
5. The dump is saved to /mailu/data/psql_backup/backup_db.sql.
|
||||
6. `docker-compose -p mailu down`
|
||||
6. `docker compose -p mailu down`
|
||||
|
||||
Prepare the new PostgreSQL deployment.
|
||||
|
||||
1. `mkdir -p /mailu/data/external_psql/pgdata`
|
||||
2. Create the file docker-compose-postgresql.yml with the following contents:
|
||||
2. Create the file docker compose-postgresql.yml with the following contents:
|
||||
|
||||
.. code-block:: docker
|
||||
|
||||
@ -147,12 +147,12 @@ Prepare the new PostgreSQL deployment.
|
||||
- "/mailu/data/psql_backup:/dump"
|
||||
|
||||
|
||||
3. `docker-compose -f docker-compose-postgresql.yml up -d`
|
||||
4. `docker-compose -f docker-compose-postgresql.yml exec database /bin/bash`
|
||||
3. `docker compose -f docker compose-postgresql.yml up -d`
|
||||
4. `docker compose -f docker compose-postgresql.yml exec database /bin/bash`
|
||||
5. `cat /dump/backup_db.sql | psql -h localhost -p 5432 -U mailu`
|
||||
6. `exit`
|
||||
7. `docker-compose -f docker-compose-postgresql.yml down`
|
||||
8. Remove the file docker-compose-postgresql.yml.
|
||||
7. `docker compose -f docker compose-postgresql.yml down`
|
||||
8. Remove the file docker compose-postgresql.yml.
|
||||
|
||||
The new PostgreSQL deployment has the dump loaded now. Now it is time to modify Mailu to use the official PostgreSQL docker image.
|
||||
|
||||
@ -199,7 +199,7 @@ to
|
||||
|
||||
Mailu is now configured to use the official PostgreSQL docker image. Bring your new deployment online
|
||||
|
||||
1. `docker-compose -p mailu up -d`
|
||||
1. `docker compose -p mailu up -d`
|
||||
|
||||
Optionally you can remove left-over files which were used by the old database:
|
||||
|
||||
|
@ -16,12 +16,13 @@ If you find actual bugs when using the demo server, please report these!
|
||||
Functionality
|
||||
-------------
|
||||
|
||||
- The server is reset every day at 3am, UTC.
|
||||
- The server is reset every day at 3am, 12pm, 8pm UTC.
|
||||
- You can send mail from any client to the server.
|
||||
However, the SMTP 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 RESTful API is enabled.
|
||||
- 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.
|
||||
@ -35,6 +36,8 @@ Connecting to the server
|
||||
* Admin UI : https://test.mailu.io/admin/
|
||||
* Admin login : ``admin@test.mailu.io``
|
||||
* Admin password : ``letmein``
|
||||
* RESTful API: https://test.mailu.io/api
|
||||
* API token: ``Bearer APITokenForMailu``
|
||||
|
||||
Adding domains
|
||||
--------------
|
||||
|
178
docs/faq.rst
178
docs/faq.rst
@ -145,51 +145,43 @@ Your mail service will be reachable for IMAP, POP3, SMTP and Webmail at the addr
|
||||
How to make IPv6 work?
|
||||
``````````````````````
|
||||
|
||||
Docker currently does not expose the IPv6 ports properly, as it does not interface with ``ip6tables``.
|
||||
Lets start with quoting everything that's wrong:
|
||||
Docker IPv6 interfacing with ``ip6tables``, which is required for proper IPv6 support, is currently considered experimental.
|
||||
|
||||
Unfortunately, initially Docker was not created with IPv6 in mind.
|
||||
It was added later and, while it has come a long way, is still not as usable as one would want.
|
||||
Much discussion is still going on as to how IPv6 should be used in a containerized world;
|
||||
See the various GitHub issues linked below:
|
||||
Although the supposed way to enable IPv6 would be to give each container a publicly routable address, docker's IPv6 support
|
||||
uses NAT to pass outside connections to the containers.
|
||||
|
||||
- Giving each container a publicly routable address means all ports (even unexposed / unpublished ports) are suddenly
|
||||
reachable by everyone, if no additional filtering is done
|
||||
(`docker/docker#21614 <https://github.com/docker/docker/issues/21614>`_)
|
||||
- By default, each container gets a random IPv6, making it impossible to do properly do DNS;
|
||||
the alternative is to assign a specific IPv6 address to each container,
|
||||
still an administrative hassle (`docker/docker#13481 <https://github.com/docker/docker/issues/13481>`_)
|
||||
- Published ports won't work on IPv6, unless you have the userland proxy enabled
|
||||
(which, for now, is enabled by default in Docker)
|
||||
- The userland proxy, however, seems to be on its way out
|
||||
(`docker/docker#14856 <https://github.com/docker/docker/issues/14856>`_) and has various issues, like:
|
||||
Currently we recommend to use `docker-ipv6nat` by `Robert Klarenbeek <https://github.com/robbertkl>` instead of docker's
|
||||
experimental support.
|
||||
|
||||
- It can use a lot of RAM (`docker/docker#11185 <https://github.com/docker/docker/issues/11185>`_)
|
||||
- Source IP addresses are rewritten, making it completely unusable for many purposes, e.g. mail servers
|
||||
(`docker/docker#17666 <https://github.com/docker/docker/issues/17666>`_),
|
||||
(`docker/libnetwork#1099 <https://github.com/docker/libnetwork/issues/1099>`_).
|
||||
Before enabling IPv6 you **MUST** disable the userland-proxy in your ``/etc/docker/daemon.json`` to not create an Open Relay!
|
||||
|
||||
-- `Robbert Klarenbeek <https://github.com/robbertkl>`_ (docker-ipv6nat author)
|
||||
.. code-block:: json
|
||||
|
||||
Okay, but I still want to use IPv6! Can I just use the installers IPv6 checkbox? **NO, YOU SHOULD NOT DO THAT!** Why you ask?
|
||||
Mailu has its own trusted IPv4 network, every container inside this network can use e.g. the SMTP container without further
|
||||
authentication. If you enabled IPv6 inside the setup assistant (and fixed the ports to also be exposed on IPv6) Docker will
|
||||
still rewrite any incoming IPv6 requests to an IPv4 address, *which is located inside the trusted network*. Therefore any
|
||||
incoming connection to the SMTP container will bypass the authentication stage by the front container regardless of your
|
||||
settings and causes an Open Relay. And you really don't want this!
|
||||
{
|
||||
"userland-proxy": false
|
||||
}
|
||||
|
||||
So, how to make it work? Well, by using `docker-ipv6nat`_! This nifty container will set up ``ip6tables``,
|
||||
just as Docker would do for IPv4. We know that NAT-ing is not advised in IPv6,
|
||||
however exposing all containers to public network neither. The choice is ultimately yous.
|
||||
You can enable `docker-ipv6nat` like this:
|
||||
|
||||
Mailu `setup utility`_ generates a safe IPv6 ULA subnet by default. So when you run the following command,
|
||||
Mailu will start to function on IPv6:
|
||||
docker run -d --name ipv6nat --privileged --network host --restart unless-stopped -v /var/run/docker.sock:/var/run/docker.sock:ro -v /lib/modules:/lib/modules:ro robbertkl/ipv6nat
|
||||
|
||||
.. code-block:: bash
|
||||
If you want to try docker's experimental IPv6 support, it can be enabled like this:
|
||||
|
||||
docker run -d --restart=always -v /var/run/docker.sock:/var/run/docker.sock:ro --privileged --net=host robbertkl/ipv6nat
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"userland-proxy": false,
|
||||
"ipv6": true,
|
||||
"experimental": true,
|
||||
"fixed-cidr-v6": "fd00:1234:abcd::/48",
|
||||
"ip6tables": true
|
||||
}
|
||||
|
||||
and enabling the IPv6 checkbox in the `setup utility`_.
|
||||
|
||||
This setup however is not officially supported, and might result in unforeseen issues.
|
||||
With bad misconfiguration you might even cause your instance to become an Open Relay, you have been warned!
|
||||
|
||||
.. _`docker-ipv6nat`: https://github.com/robbertkl/docker-ipv6nat
|
||||
.. _`setup utility`: https://setup.mailu.io
|
||||
|
||||
How does Mailu scale up?
|
||||
@ -449,8 +441,8 @@ down and up again. A container restart is not sufficient.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose down && \
|
||||
docker-compose up -d
|
||||
docker compose down && \
|
||||
docker compose up -d
|
||||
|
||||
*Issue reference:* `615`_.
|
||||
|
||||
@ -527,8 +519,8 @@ to check the logs.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose logs front | less -R
|
||||
docker-compose exec front less /var/log/letsencrypt/letsencrypt.log
|
||||
docker compose logs front | less -R
|
||||
docker compose exec front less /var/log/letsencrypt/letsencrypt.log
|
||||
|
||||
Common problems:
|
||||
|
||||
@ -586,20 +578,21 @@ down brute force attacks. The same applies to login attempts via the single sign
|
||||
|
||||
We *do* provide a possibility to export the logs from the ``front`` service and ``Admin`` service to the host.
|
||||
The ``front`` container logs failed logon attempts on SMTP, IMAP and POP3.
|
||||
The ``Admin``container logs failed logon attempt on the single sign on page.
|
||||
The ``Admin`` container logs failed logon attempt on the single sign on page.
|
||||
For this you need to set ``LOG_DRIVER=journald`` or ``syslog``, depending on the log
|
||||
manager of the host. You will need to setup the proper Regex in the Fail2Ban configuration.
|
||||
Below an example how to do so.
|
||||
|
||||
If you use a reverse proxy in front of Mailu, it is vital to set the environment variables REAL_IP_HEADER and REAL_IP_FROM.
|
||||
Without these environment variables, Mailu will not trust the remote client IP passed on by the reverse proxy and as a result your reverse proxy will be banned.
|
||||
See the :ref:`[configuration reference <reverse_proxy_headers>` for more information.
|
||||
|
||||
See the :ref:`configuration reference <reverse_proxy_headers>` for more information.
|
||||
|
||||
|
||||
Assuming you have a working Fail2Ban installation on the host running your Docker containers,
|
||||
follow these steps:
|
||||
|
||||
1. In the mailu docker-compose set the logging driver of the front container to journald; and set the tag to mailu-front
|
||||
1. In the mailu docker compose set the logging driver of the front container to journald; and set the tag to mailu-front
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@ -608,32 +601,57 @@ follow these steps:
|
||||
options:
|
||||
tag: mailu-front
|
||||
|
||||
2. Add the /etc/fail2ban/filter.d/bad-auth.conf
|
||||
2. Add the /etc/fail2ban/filter.d/bad-auth-bots.conf
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Fail2Ban configuration file
|
||||
[Definition]
|
||||
failregex = .* client login failed: .+ client:\ <HOST>
|
||||
failregex = ^\s?\S+ mailu\-front\[\d+\]: \S+ \S+ \[info\] \d+#\d+: \*\d+ client login failed: \"AUTH not supported\" while in http auth state, client: <HOST>, server:
|
||||
ignoreregex =
|
||||
journalmatch = CONTAINER_TAG=mailu-front
|
||||
|
||||
3. Add the /etc/fail2ban/jail.d/bad-auth.conf
|
||||
3. Add the /etc/fail2ban/jail.d/bad-auth-bots.conf
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[bad-auth]
|
||||
[bad-auth-bots]
|
||||
enabled = true
|
||||
backend = systemd
|
||||
filter = bad-auth
|
||||
filter = bad-auth-bots
|
||||
bantime = 604800
|
||||
findtime = 300
|
||||
maxretry = 10
|
||||
action = docker-action
|
||||
findtime = 600
|
||||
maxretry = 5
|
||||
action = docker-action-net
|
||||
|
||||
The above will block flagged IPs for a week, you can of course change it to you needs.
|
||||
The above will block flagged IPs for a week, you can of course change it to your needs.
|
||||
|
||||
4. In the mailu docker-compose set the logging driver of the Admin container to journald; and set the tag to mailu-admin
|
||||
4. Add the following to /etc/fail2ban/action.d/docker-action-net.conf
|
||||
|
||||
IMPORTANT: You have to install ipset on the host system, eg. `apt-get install ipset` on a Debian/Ubuntu system.
|
||||
|
||||
See ipset homepage for details on ipset, https://ipset.netfilter.org/.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[Definition]
|
||||
|
||||
actionstart = ipset --create f2b-bad-auth-bots nethash
|
||||
iptables -I DOCKER-USER -m set --match-set f2b-bad-auth-bots src -p tcp -m tcp --dport 25 -j DROP
|
||||
|
||||
actionstop = iptables -D DOCKER-USER -m set --match-set f2b-bad-auth-bots src -p tcp -m tcp --dport 25 -j DROP
|
||||
ipset --destroy f2b-bad-auth-bots
|
||||
|
||||
|
||||
actionban = ipset add -exist f2b-bad-auth-bots <ip>/24
|
||||
|
||||
actionunban = ipset del -exist f2b-bad-auth-bots <ip>/24
|
||||
|
||||
Using DOCKER-USER chain ensures that the blocked IPs are processed in the correct order with Docker. See more in: https://docs.docker.com/network/iptables/.
|
||||
|
||||
Please note that the provided example will block the subnet from sending any email to the Mailu instance.
|
||||
|
||||
5. In the mailu docker-compose set the logging driver of the Admin container to journald; and set the tag to mailu-admin
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@ -642,70 +660,38 @@ The above will block flagged IPs for a week, you can of course change it to you
|
||||
options:
|
||||
tag: mailu-admin
|
||||
|
||||
5. Add the /etc/fail2ban/filter.d/bad-auth-sso.conf
|
||||
6. Add the /etc/fail2ban/filter.d/bad-auth.conf
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Fail2Ban configuration file
|
||||
[Definition]
|
||||
failregex = .* Login failed for .+ from <HOST>.
|
||||
failregex = : Authentication attempt from <HOST> has been rate-limited\.$
|
||||
ignoreregex =
|
||||
journalmatch = CONTAINER_TAG=mailu-admin
|
||||
|
||||
6. Add the /etc/fail2ban/jail.d/bad-auth-sso.conf
|
||||
7. Add the /etc/fail2ban/jail.d/bad-auth.conf
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[bad-auth-sso]
|
||||
[bad-auth]
|
||||
enabled = true
|
||||
backend = systemd
|
||||
filter = bad-auth-sso
|
||||
filter = bad-auth
|
||||
bantime = 604800
|
||||
findtime = 300
|
||||
maxretry = 10
|
||||
findtime = 900
|
||||
maxretry = 15
|
||||
action = docker-action
|
||||
|
||||
The above will block flagged IPs for a week, you can of course change it to you needs.
|
||||
The above will block flagged IPs for a week, you can of course change it to your needs.
|
||||
|
||||
7. Add the /etc/fail2ban/action.d/docker-action.conf
|
||||
|
||||
Option 1: Use plain iptables
|
||||
8. Add the following to /etc/fail2ban/action.d/docker-action.conf
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[Definition]
|
||||
|
||||
actionstart = iptables -N f2b-bad-auth
|
||||
iptables -A f2b-bad-auth -j RETURN
|
||||
iptables -I DOCKER-USER -j f2b-bad-auth
|
||||
|
||||
actionstop = iptables -D DOCKER-USER -j f2b-bad-auth
|
||||
iptables -F f2b-bad-auth
|
||||
iptables -X f2b-bad-auth
|
||||
|
||||
actioncheck = iptables -n -L DOCKER-USER | grep -q 'f2b-bad-auth[ \t]'
|
||||
|
||||
actionban = iptables -I f2b-bad-auth 1 -s <ip> -j DROP
|
||||
|
||||
actionunban = iptables -D f2b-bad-auth -s <ip> -j DROP
|
||||
|
||||
Using DOCKER-USER chain ensures that the blocked IPs are processed in the correct order with Docker. See more in: https://docs.docker.com/network/iptables/
|
||||
|
||||
Option 2: Use ipset together with iptables
|
||||
IMPORTANT: You have to install ipset on the host system, eg. `apt-get install ipset` on a Debian/Ubuntu system.
|
||||
|
||||
See ipset homepage for details on ipset, https://ipset.netfilter.org/.
|
||||
|
||||
ipset and iptables provide one big advantage over just using iptables: This setup reduces the overall iptable rules.
|
||||
There is just one rule for the bad authentications and the IPs are within the ipset.
|
||||
Specially in larger setups with a high amount of brute force attacks this comes in handy.
|
||||
Using iptables with ipset might reduce the system load in such attacks significantly.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[Definition]
|
||||
|
||||
actionstart = actionstart = ipset --create f2b-bad-auth iphash
|
||||
actionstart = ipset --create f2b-bad-auth iphash
|
||||
iptables -I DOCKER-USER -m set --match-set f2b-bad-auth src -j DROP
|
||||
|
||||
actionstop = iptables -D DOCKER-USER -m set --match-set f2b-bad-auth src -j DROP
|
||||
@ -718,7 +704,7 @@ Using iptables with ipset might reduce the system load in such attacks significa
|
||||
|
||||
Using DOCKER-USER chain ensures that the blocked IPs are processed in the correct order with Docker. See more in: https://docs.docker.com/network/iptables/
|
||||
|
||||
1. Configure and restart the Fail2Ban service
|
||||
9. Configure and restart the Fail2Ban service
|
||||
|
||||
Make sure Fail2Ban is started after the Docker service by adding a partial override which appends this to the existing configuration.
|
||||
|
||||
@ -813,7 +799,7 @@ In many cases, Docker Compose will complain about the yaml syntax because it is
|
||||
Unless your distribution has proper up-to-date packages for Compose, we strongly advise that you install it either:
|
||||
|
||||
- from the Docker-CE repositories along with Docker CE itself,
|
||||
- from PyPI using `pip install docker-compose` or
|
||||
- from PyPI using `pip install docker compose` or
|
||||
- from Github by downloading it directly.
|
||||
|
||||
Detailed instructions can be found at https://docs.docker.com/compose/install/
|
||||
|
@ -28,7 +28,7 @@ Main features include:
|
||||
- **Web access**, multiple Webmails and administration interface
|
||||
- **User features**, aliases, auto-reply, auto-forward, fetched accounts
|
||||
- **Admin features**, global admins, announcements, per-domain delegation, quotas
|
||||
- **Security**, enforced TLS, DANE, MTA-STS, Letsencrypt!, outgoing DKIM, anti-virus scanner, Snuffleupagus
|
||||
- **Security**, enforced TLS, DANE, MTA-STS, Letsencrypt!, outgoing DKIM, anti-virus scanner, [Snuffleupagus](https://github.com/jvoisin/snuffleupagus/), block malicious attachments
|
||||
- **Antispam**, auto-learn, greylisting, DMARC and SPF, anti-spoofing
|
||||
- **Freedom**, all FOSS components, no tracker included
|
||||
|
||||
@ -70,6 +70,7 @@ the version of Mailu that you are running.
|
||||
webadministration
|
||||
antispam
|
||||
cli
|
||||
api
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
@ -14,9 +14,9 @@ simply pull the latest images and recreate the containers :
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose pull
|
||||
docker-compose down
|
||||
docker-compose up -d
|
||||
docker compose pull
|
||||
docker compose down
|
||||
docker compose up -d
|
||||
|
||||
Monitoring the mail server
|
||||
--------------------------
|
||||
@ -25,7 +25,7 @@ Logs are managed by Docker directly. You can easily read your logs using:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose logs
|
||||
docker compose logs
|
||||
|
||||
Docker is able to forward logs to multiple log engines. Read the following documentation for details: https://docs.docker.com/engine/admin/logging/overview/.
|
||||
|
||||
|
@ -382,9 +382,9 @@ For this upgrade it is necessary to bring the project down and up, due to networ
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose pull
|
||||
docker-compose down --remove-orphans
|
||||
docker-compose up -d
|
||||
docker compose pull
|
||||
docker compose down --remove-orphans
|
||||
docker compose up -d
|
||||
|
||||
After everything runs successfully, ``/mailu/certs/dhparam.pem`` is no longer needed and can be deleted.
|
||||
It's included in the Mailu distribution by default now. Also the old ``.env`` can be deleted.
|
||||
@ -441,8 +441,8 @@ were removed (e.g. rmilter):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker-compose pull
|
||||
docker-compose up -d --remove-orphans
|
||||
docker compose pull
|
||||
docker compose up -d --remove-orphans
|
||||
|
||||
If you experience problems when upgrading, feel free to post issues and contact
|
||||
us on our chat channel for emergency support.
|
||||
|
@ -1,5 +1,5 @@
|
||||
recommonmark
|
||||
Sphinx
|
||||
sphinx-autobuild
|
||||
sphinx-rtd-theme
|
||||
recommonmark==0.7.1
|
||||
Sphinx==5.2.0
|
||||
sphinx-autobuild==2021.3.14
|
||||
sphinx-rtd-theme==1.0.0
|
||||
docutils==0.16
|
||||
|
@ -1,17 +1,17 @@
|
||||
Using an external reverse proxy
|
||||
===============================
|
||||
|
||||
One of Mailu's use cases is as part of a larger services platform, where maybe
|
||||
One of Mailu's use cases is as part of a larger services platform, where maybe
|
||||
other Web services are available than just Mailu Webmail and Admin interfaces.
|
||||
|
||||
In such a configuration, one would usually run a frontend reverse proxy to serve all
|
||||
Web contents based on criteria like the requested hostname (virtual hosts)
|
||||
and/or the requested path.
|
||||
In such a configuration, one would usually run a frontend reverse proxy to serve all
|
||||
Web contents based on criteria like the requested hostname (virtual hosts)
|
||||
and/or the requested path.
|
||||
|
||||
The Mailu Admin Web frontend is disabled in the default setup for security reasons,
|
||||
it is however expected that most users will enable it at some point. Also, due
|
||||
to the Docker Compose configuration structure, it is impossible for us to facilitate
|
||||
disabling the Web frontend with a configuration variable. This guide was written to
|
||||
The Mailu Admin Web frontend is disabled in the default setup for security reasons,
|
||||
it is however expected that most users will enable it at some point. Also, due
|
||||
to the Docker Compose configuration structure, it is impossible for us to facilitate
|
||||
disabling the Web frontend with a configuration variable. This guide was written to
|
||||
help users setup such an architecture.
|
||||
|
||||
There are basically three options, from the most to the least recommended one:
|
||||
@ -22,13 +22,13 @@ There are basically three options, from the most to the least recommended one:
|
||||
|
||||
All options will require that you modify the ``docker-compose.yml`` and ``mailu.env`` file.
|
||||
|
||||
Mailu must also be configured with the information what header is used by the reverse proxy for passing the remote client IP.
|
||||
Mailu must also be configured with the information what header is used by the reverse proxy for passing the remote client IP.
|
||||
This is configured in the mailu.env file. See the :ref:`configuration reference <reverse_proxy_headers>` for more information.
|
||||
|
||||
Have Mailu Web frontend listen locally
|
||||
--------------------------------------
|
||||
|
||||
The simplest and safest option is to modify the port forwards for Mailu Web frontend and have your own frontend point there.
|
||||
The simplest and safest option is to modify the port forwards for Mailu Web frontend and have your own frontend point there.
|
||||
For instance, in the ``front`` section of Mailu ``docker-compose.yml``, use local ports 8080 and 8443 respectively for HTTP and HTTPS:
|
||||
|
||||
.. code-block:: yaml
|
||||
@ -45,7 +45,7 @@ For instance, in the ``front`` section of Mailu ``docker-compose.yml``, use loca
|
||||
volumes:
|
||||
- "$ROOT/certs:/certs"
|
||||
|
||||
Then on your own frontend, point to these local ports. In practice, you only need to point to the HTTPS port
|
||||
Then on your own frontend, point to these local ports. In practice, you only need to point to the HTTPS port
|
||||
(as the HTTP port simply redirects there). Here is an example Nginx configuration:
|
||||
|
||||
.. code-block:: nginx
|
||||
@ -68,19 +68,19 @@ Then on your own frontend, point to these local ports. In practice, you only nee
|
||||
#mailu.env file
|
||||
REAL_IP_HEADER=X-Real-IP
|
||||
REAL_IP_FROM=x.x.x.x,y.y.y.y.y
|
||||
#x.x.x.x,y.y.y.y.y is the static IP address your reverse proxy uses for connecting to Mailu.
|
||||
|
||||
Because the admin interface is served as ``/admin``, the Webmail as ``/webmail``, the single sign on page as ``/sso``, webdav as ``/webdav``, the client-autoconfiguration and the static files endpoint as ``/static``, you may also want to use a single virtual host and serve other applications (still Nginx):
|
||||
#x.x.x.x,y.y.y.y.y is the static IP address your reverse proxy uses for connecting to Mailu.
|
||||
|
||||
Because the admin interface is served as ``/admin``, the RESTful API as ``/api``, the Webmail as ``/webmail``, the single sign on page as ``/sso``, webdav as ``/webdav``, the client-autoconfiguration and the static files endpoint as ``/static``, you may also want to use a single virtual host and serve other applications (still Nginx):
|
||||
|
||||
.. code-block:: nginx
|
||||
|
||||
server {
|
||||
# [...] here goes your standard configuration
|
||||
|
||||
location ~* ^/(admin|sso|static|webdav|webmail|(apple\.)?mobileconfig|(\.well\-known/autoconfig/)?mail/|Autodiscover/Autodiscover) {
|
||||
location ~* ^/(admin|api|sso|static|webdav|webmail|(apple\.)?mobileconfig|(\.well\-known/autoconfig/)?mail/|Autodiscover/Autodiscover) {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_pass https://localhost:8443;
|
||||
proxy_pass https://localhost:8443;
|
||||
}
|
||||
|
||||
location /main_app {
|
||||
@ -103,13 +103,13 @@ Because the admin interface is served as ``/admin``, the Webmail as ``/webmail``
|
||||
.. note:: Please don’t add a ``/`` at the end of the location pattern or all your redirects will fail with 404 because the ``/`` would be missing, and you would have to add it manually to move on
|
||||
|
||||
.. code-block:: docker
|
||||
|
||||
|
||||
#mailu.env file
|
||||
REAL_IP_HEADER=X-Real-IP
|
||||
REAL_IP_FROM=x.x.x.x,y.y.y.y.y
|
||||
#x.x.x.x,y.y.y.y.y is the static IP address your reverse proxy uses for connecting to Mailu.
|
||||
#x.x.x.x,y.y.y.y.y is the static IP address your reverse proxy uses for connecting to Mailu.
|
||||
|
||||
Finally, you might want to serve the admin interface on a separate virtual host but not expose the admin container
|
||||
Finally, you might want to serve the admin interface on a separate virtual host but not expose the admin container
|
||||
directly (have your own HTTPS virtual hosts on top of Mailu, one public for the Webmail and one internal for administration for instance).
|
||||
|
||||
Here is an example configuration :
|
||||
@ -147,7 +147,7 @@ Here is an example configuration :
|
||||
#mailu.env file
|
||||
REAL_IP_HEADER=X-Real-IP
|
||||
REAL_IP_FROM=x.x.x.x,y.y.y.y.y
|
||||
#x.x.x.x,y.y.y.y.y is the static IP address your reverse proxy uses for connecting to Mailu.
|
||||
#x.x.x.x,y.y.y.y.y is the static IP address your reverse proxy uses for connecting to Mailu.
|
||||
|
||||
Depending on how you access the front server, you might want to add a ``proxy_redirect`` directive to your ``location`` blocks:
|
||||
|
||||
@ -166,8 +166,8 @@ Traefik as reverse proxy
|
||||
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.
|
||||
, 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:
|
||||
|
||||
@ -175,9 +175,9 @@ This, however, means 3 things:
|
||||
- ``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 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
|
||||
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``,
|
||||
@ -194,20 +194,20 @@ Add the respective Traefik labels for your domain/configuration, like
|
||||
|
||||
.. 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.example.com`` now. However, ``mail.your.example.com`` might only be the location where you want the Mailu web-interfaces
|
||||
If your Traefik is configured to automatically request certificates from *letsencrypt*, then you’ll have a certificate
|
||||
for ``mail.your.example.com`` now. However, ``mail.your.example.com`` might only be the location where you want the Mailu web-interfaces
|
||||
to live — your mail should be sent/received from ``your.example.com``, and this is the ``DOMAIN`` in your ``.env``?
|
||||
To support that use-case, Traefik can request ``SANs`` for your domain. The configuration for this will depend on your Traefik version.
|
||||
|
||||
Mailu must also be configured with the information what header is used by the reverse proxy for passing the remote
|
||||
Mailu must also be configured with the information what header is used by the reverse proxy for passing the remote
|
||||
client IP. This is configured in mailu.env:
|
||||
|
||||
.. code-block:: docker
|
||||
|
||||
|
||||
#mailu.env file
|
||||
REAL_IP_HEADER=X-Real-Ip
|
||||
REAL_IP_FROM=x.x.x.x,y.y.y.y.y
|
||||
#x.x.x.x,y.y.y.y.y is the static IP address your reverse proxy uses for connecting to Mailu.
|
||||
#x.x.x.x,y.y.y.y.y is the static IP address your reverse proxy uses for connecting to Mailu.
|
||||
|
||||
For more information see the :ref:`configuration reference <reverse_proxy_headers>` for more information.
|
||||
|
||||
@ -235,7 +235,7 @@ Add the appropriate labels for your domain(s) to the ``front`` container in ``do
|
||||
|
||||
Of course, be sure to define the Certificate Resolver ``foo`` in the static configuration as well.
|
||||
|
||||
Alternatively, you can define SANs in the Traefik static configuration using routers, or in the static configuration using entrypoints.
|
||||
Alternatively, you can define SANs in the Traefik static configuration using routers, or in the static configuration using entrypoints.
|
||||
Refer to the Traefik documentation for more details.
|
||||
|
||||
.. _`Traefik`: https://traefik.io/
|
||||
|
@ -67,7 +67,7 @@ Make sure that you test properly before going live!
|
||||
- Try to send an email to an external service
|
||||
- On the external service, verify that DKIM and SPF are listed as passing
|
||||
- Try to receive an email from an external service
|
||||
- Check the logs (``docker-compose logs -f servicenamehere``) to look for
|
||||
- Check the logs (``docker compose logs -f servicenamehere``) to look for
|
||||
warnings or errors
|
||||
- Use an open relay checker like `mxtoolbox`_
|
||||
to ensure you're not contributing to the spam problem on the internet.
|
||||
|
@ -162,6 +162,7 @@ You can add a fetched account by clicking on the `Add an account` button on the
|
||||
* Folders. A comma separated list of folders to fetch from the server. This is optional, by default only the INBOX will be pulled.
|
||||
|
||||
Click the submit button to apply settings. With the default polling interval, fetchmail will start polling the email account after ``FETCHMAIL_DELAY``.
|
||||
Make sure ``FETCHMAIL_ENABLED`` is set to ``true`` in ``mailu.env`` to enable fetching and showing fetchmail in the admin interface.
|
||||
|
||||
|
||||
Authentication tokens
|
||||
|
Reference in New Issue
Block a user