diff --git a/docs/cli.md b/docs/cli.md new file mode 100644 index 00000000..cccebfb4 --- /dev/null +++ b/docs/cli.md @@ -0,0 +1,102 @@ +Mailu command line +================== + +Managing users and aliases can be done from CLI using commands: + +* alias +* alias_delete +* user +* user_import +* user_delete +* config_update + +alias +----- + +``` +docker-compose run --rm admin python manage.py alias foo example.net "mail1@example.com,mail2@example.com" +``` + +alias_delete +------------ + +``` +docker-compose run --rm admin python manage.py alias_delete foo@example.net +``` + +user +---- + +``` +docker-compose run --rm admin python manage.py user --hash_scheme='SHA512-CRYPT' myuser example.net 'password123' +``` + +user_import +----------- +primary difference with simple `user` command is that password is being imported as a hash - very useful when migrating users from other systems where only hash is known. + +``` +docker-compose run --rm admin python manage.py user --hash_scheme='SHA512-CRYPT' myuser example.net '$6$51ebe0cb9f1dab48effa2a0ad8660cb489b445936b9ffd812a0b8f46bca66dd549fea530ce' +``` + +user_delete +------------ + +``` +docker-compose run --rm admin python manage.py user_delete foo@example.net +``` + +config_update +------------- + +This command sole purpose is for importing users/aliases in bulk and synchronizing DB entries with external YAML template: + +``` +cat mail-config.yml | docker-compose run --rm admin python manage.py config_update --delete_objects +``` + +where mail-config.yml looks like: + +``` +--- + +users: + - localpart: foo + domain: example.com + password_hash: klkjhumnzxcjkajahsdqweqqwr + hash_scheme: MD5-CRYPT + +aliases: + - localpart: alias1 + domain: example.com + destination: "user1@example.com,user2@example.com" +``` + +without `--delete_object` option config_update will only add/update new values but will *not* remove any entries missing in provided YAML input. + +Users +----- + +following are additional parameters that could be defined for users: + +* comment +* quota_bytes +* global_admin +* enable_imap +* enable_pop +* forward_enabled +* forward_destination +* reply_enabled +* reply_subject +* reply_body +* displayed_name +* spam_enabled +* spam_threshold + +Alias +----- + +additional fields: + +* wildcard + diff --git a/docs/compose/requirements.md b/docs/compose/requirements.md new file mode 100644 index 00000000..bff38417 --- /dev/null +++ b/docs/compose/requirements.md @@ -0,0 +1,112 @@ +Docker compose requirements +=========================== + +Hardware considerations +----------------------- + +You should make sure that your hardware (virtual or physical) is compatible with +the latest Linux kernel. Also, you should have at least 2GB of total memory and +1GB of free memory when running Mailu. + +Pick a distribution +------------------- + +The mail server runs as a set of Docker containers. It is thus almost agnostic +of the underlying operating system as long as a fairly recent Linux kernel is +running and the Docker API (>= 1.11) is available. + +Because most of our tests run on Debian Jessie and Debian Stretch, we recommend +one of these for the base system. Mailu should however be able to run on +any of the [officially supported distributions](https://docs.docker.com/engine/installation/). + +For the purpose of this guide, all examples are based on Debian Stretch. The +differences with other system will hardly be noticeable however. + +Install the distribution +------------------------ + +First, install Debian Stretch from the *netinstall* CD image. When installing, +make sure that you either: + + - setup a root *ext4* partition, + - or setup a root *btrfs* partition, + - or leave enough unpartitionned space for a dedicated *ext4* or *btrfs* + partition. + +If you chose to create a dedicated partition, simply mount it to +``/var/lib/docker``. You could also create a separate partition (*ext4* is a +sane default) ans mount it to ``/mailu`` for storing e-mail data. + +Docker supports *AUFS* over *ext4* and *btrfs* as stable storage drivers. +Other filesystems are supported such as *OverlayFS*. If you know what you are +doing, you should go for it. + +Mailu uses Docker port forwarding from the host to make services +available to external users. First, your host should have a public IP address +configured (see ``/etc/network/interfaces``) or your router should +forward connections to its internal IP address. Due to spam problems and +reputation services, it +is highly recommended that you use a dedicated IP address for your mail server +and that you have a dedicated hostname with forward and reverse DNS entries +for this IP address. + +Also, your host must not listen on ports ``25``, ``80``, ``110``, ``143``, +``443``, ``465``, ``587``, ``993`` or ``995`` as these are used by Mailu +services. Therefore, you should disable or uninstall any program that is +listening on these ports (or have them listen on a different port). For +instance, on a default Debian install: + +``` +apt-get autoremove --purge exim4 exim4-base +``` + +Finally, Docker relies heavily on ``iptables`` for port forwardings. You +should use ``iptables-persistent`` (or any equivalent tool on other +systems) for managing persistent rules. If you were brave enough to switch to +``nftables``, you will have to rollback until official support is released +by Docker or setup your own rulesets. + +Install Docker +-------------- + +Mailu relies on some of the latest Docker features. Therefore, you should +install Docker from the official repositories instead of your distribution +ones. + +The Docker website is full of [detailed instructions](https://docs.docker.com/engine/installation/) +about setting up a proper Docker install. Default configuration should be +suited for Mailu. + +Additionally, you must install ``docker-compose`` by following the instructions +from the [Docker website](https://docs.docker.com/compose/). Compose is a +management tool for Docker, especially suited for multiple containers systems +like Mailu. + +Once everything is setup, you should be able to run the following commands +(exact version numbers do not matter): + +``` +$ 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 + +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 +``` + diff --git a/docs/compose/setup.md b/docs/compose/setup.md new file mode 100644 index 00000000..c5ff86ec --- /dev/null +++ b/docs/compose/setup.md @@ -0,0 +1,124 @@ +Docker Compose setup +==================== + +Prepare the environment +----------------------- + +Mailu will store all of its persistent data in a path of your choice +(``/mailu`` by default) simply create the directory and move there: + +``` +mkdir /mailu +cd /mailu +``` + +Download the initial configuration file +--------------------------------------- + +Docker Compose configuration is stored in a file named ``docker-compose.yml``. +Additionally, Mailu relies on an environment file for various settings. +Download the proper template files from the git repository. For `stable`: + +``` +wget -O docker-compose.yml https://raw.githubusercontent.com/Mailu/Mailu/stable/docker-compose.yml.dist +wget -O .env https://raw.githubusercontent.com/Mailu/Mailu/stable/.env.dist +``` + +For the latest version (replace with version number otherwise): + +``` +wget -O docker-compose.yml https://raw.githubusercontent.com/Mailu/Mailu/master/docker-compose.yml.dist +wget -O .env https://raw.githubusercontent.com/Mailu/Mailu/master/.env.dist +``` + +Then open the ``.env`` file to setup the mail server. Modify the ``ROOT`` setting +to match your setup directory if different from ``/mailu``. + +Mdify the ``VERSION`` configuration in the ``.env`` file to reflect the version you picked.. + +Set the common configuration values +----------------------------------- + +Open the ``.env`` file and set configuration settings after reading the configuration +documentation. Some settings are specific to the Docker Compose setup. + +Modify ``BIND_ADDRESS4`` to match the public IP address assigned to your server. +This address should be configured on one of the network interfaces of the server. +If the address is not configured directly (NAT) on any of the network interfaces or if +you would simply like the server to listen on all interfaces, use ``0.0.0.0``. + +Modify ``BIND_ADDRESS6`` to match the public IPv6 address assigned to your server. +The behavior is identical to ``BIND_ADDRESS4``. + +Set the `TLS_FLAVOR` to one of the following +values: +- `cert` is the default and requires certificates to be setup manually; +- `letsencrypt` will use the Letsencrypt! CA to generate automatic ceriticates; +- `notls` will disable TLS, this is not recommended except for testing. + +Enable optional features +------------------------ + +Some of Mailu features are not used by every user and are thus not enabled in a +default configuration. + +A Webmail is a Web interface exposing an email client. Mailu webmails are +bound to the internal IMAP and SMTP server for users to access their mailbox through +the Web. By exposing a complex application such as a Webmail, you should be aware of +the security implications such an increase of attack surface. The ``WEBMAIL`` +configuration option must be one of the following: + +- ``none`` is the default value, no Webmail service will be exposed; +- ``roundcube`` will run the popular Roundcube Webmail ; +- ``rainloop`` will run the popular Rainloop Webmail. + +The administration interface is not exposed on the public address by default, +you will need to set the ``EXPOSE_ADMIN`` variable accordingly: + +- ``yes`` will expose the admin interface in ``/admin``; +- ``no`` (or any other value) will disable this behaviour. + +A Webdav server exposes a Dav interface over HTTP so that clients can store +contacts or calendars using the mail account. This can be enabled using the `WEBDAV` +setting. The configuration option must be one of the following: + +- ``none`` is the default value, no webdav service will be exposed; +- ``radicale`` exposes the radicale Webdav service. + +An antivirus server helps fighting large scale virus spreading campaigns +that leverage e-mail for initial infection. This can be setup using the ``ANTIVIRUS`` +setting. The configuration option must be one of the following: + +- ``none`` disables antivirus checks; +- ``clamav`` is the default values, the popular ClamAV antivirus is enabled. + +Make sure that you have at least 1GB or memory for ClamAV to load its signature +database. + +Finish setting up TLS +--------------------- + +Mailu relies heavily on TLS and must have a key pair and a certificate +available, at least for the hostname configured in the ``.env`` file. + +If you set `TLS_FLAVOR` to `cert` or if then you must create a `certs` directory +in your root path and setup a key-certificate pair there: + - ``cert.pem`` contains the certificate, + - ``key.pem`` contains the key pair. + +Start Mailu +----------- + +You may now start Mailu. Move the to the Mailu directory and run: + +``` +docker-compose up -d +``` + +Finally, you must create the initial admin user account: + +``` +docker-compose run --rm admin python manage.py admin root example.net password +``` + +This will create a user named ``root@example.net`` with password ``password`` and administration privileges. Connect to the Web admin interface and change the password to a strong one. diff --git a/docs/conf.py b/docs/conf.py index ed122062..5c3dd1a1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -41,7 +41,7 @@ templates_path = ['_templates'] # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] -source_suffix = '.rst' +source_suffix = '.md' # The master toctree document. master_doc = 'index' @@ -84,7 +84,7 @@ todo_include_todos = False # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' +html_theme = 'sphinx_rtd_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 00000000..ba674540 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,72 @@ +Mailu configuration settings +============================ + +Common configuration +-------------------- + +The `SECRET_KEY` **must** be changed for every setup and set to a 16 bytes +randomly generated value. It is intended to secure authentication cookies +among other critical uses. + +The `DOMAIN` holds the main e-mail domain for the server. This email domain +is used for bounce emails, for generating the postmaster email and other +technical addresses. + +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 `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 `AUTH_RATELIMIT` holds a security setting for fighting attackers that +try to guess user passwords. The value is the limit of requests that a single +IP address can perform against IMAP, POP and SMTP authentication endpoints. + +Mail settings +------------- + +The `MESSAGE_SIZE_LIMIT` is the maximum size of a single email. It should not +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. + +The `RELAYHOST` is an optional address of a mail server relaying all outgoing +mail. + +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 +want to be blacklisted by external services, but not too long delays if you +want to receive your email in time. + +The `RECIPIENT_DELIMITED` is a character used to delimit localpart from a +custom address part. For instance, if set to `+`, users can use addresses +like `localpart+custom@domain.tld` to deliver mail to `localpart@domain.tld`. +This is useful to provide external parties with different email addresses and +later classify incoming mail based on the custom part. + +The `DMAR_RUA` and `DMARC_RUF` are DMARC protocol specific values. They hold +the localpart for DMARC rua and ruf email addresses. + +Web settings +------------ + +The `WEB_ADMIN` contains the path to the main admin interface, while +`WEB_WEBMAIL` contains the path to the Web email client. + +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. + +Advanced settings +----------------- + +The `PASSWORD_SCHEME` is the password encryption scheme. You should use the +default value, unless you are importing password from a separate system and +want to keep using the old password encryption scheme. + diff --git a/docs/dns.md b/docs/dns.md new file mode 100644 index 00000000..6109e6d8 --- /dev/null +++ b/docs/dns.md @@ -0,0 +1,48 @@ +Setting up your DNS +=================== + +E-mail has a decentralized architecture: pretty much every e-mail provider on the Internet has the ability to communicate with every other provider to deliver e-mails, much like post-office services from different cities or countries communicate to deliver standard mail. + +The analogy stops when it comes to discovery and responsibilities. In the e-mail model, there are most of the time two, maximum three actors in delivering a message: the emitter, an (optional) relay and the recipient server (some architectures are much more complex, but either they can be simplified for the purpose of this document or they are extremely rare). Forgetting about the relay, the emitter has to discover where the recipient server is located around the Internet, which is based on DNS. + +Setting up a DNS domain is (almost) mandatory to exchange e-mail on the Internet. Before you start using Mailu, you must have at least one domain setup to receive emails. + +The mail server hostname +------------------------ + +Your mail server will have a unique hostname. That hostname is a fully qualified domain name, that points to your server IP address. How you pick the hostname is up to you, it must of course belong to a domain name that you own or manage and could belong to a domain that your server will receive mail for. + +You should pick a meaningful hostname that you can give your users to access the Web interface and other email services. For instance, if your main mail domain is ``mydomain.com`` (the one you setup in ``DOMAIN`` in your configuration file), then you could use ``mail.mydomain.com`` as a mail server hostname. + +Set that name in the ``HOSTNAME`` configuration entry. Then depending on your domain provider, make sure that you have an address record (``A``) serving the public IP address of your server: + +``` +mail.mydomain.com. IN A a.b.c.d +``` + +Also, ``a.b.c.d`` should be set in your ``BIND_INTERFACE`` configuration unless your server is in a DMZ and you are using port forwards to expose the services. + +Finally, make sure that you have a proper TLS certificate for you mail server hostname and install it according to the instructions in the [[Setup Guide]]. + +MX entries +---------- + +Once your server is running and accessible at your mail server hostname, you can simply add new domains in the Web interface. + +For every domain that your mail server is responsible for, you must have a corresponding ``MX`` entry in the domain's DNS configuration. That entry is required for other mail servers to discover the hostname of the mail server responsible for receiving the messages, and then its IP address using the ``A`` record you setup earlier. + +To setup an ``MX`` record, exact actions will depend on your DNS provider and hoster, but assuming you are using a zone file, you should add for ``mydomain.com``: + +``` +mydomain.com. IN MX 10 mail.mydomain.com. +``` + +The number is the ``MX`` priority, which has little importance if you are running a single mail server but should be adjusted if you run a separate backup server. + +And for another domain, ``myotherdomain.com`` for example: + +``` +myotherdomain.com. IN MX 10 mail.mydomain.com. +``` + +Note that both point to the same mail server hostname, which is unique to your server. diff --git a/docs/general.md b/docs/general.md new file mode 100644 index 00000000..73088718 --- /dev/null +++ b/docs/general.md @@ -0,0 +1,46 @@ +General concepts +================ + +Philosophy +---------- + +The philosophy behind Mailu is very simple and based on applying the +following principles, with decreasing priority: + + 1. a proper mail server runs only free software + 2. a proper mail server is easy to setup and maintain + 3. a proper mail server offers proper security + 4. a proper mail server has a simple and beautiful user interface + +Mailu was designed and is kept up to date based on these. Among the most +structuring choices, the following were quite challenging: + + - Mailu is based on containers (plural) so that any part can be reused + in separate projects and that updating or swapping any component does + not require to alter others. + - Mailu offers mail and does not bring any bloat in the default setup. + Additional features are available but not required. + - Mailu has a central front container that routes all HTTP and mail + traffic. + - Mailu has a Web administration interface that exposes both a Web ui + and internal API. + - Mailu authors are all equal in regard to copyright, thus the license + will remain free unless all contributors agree otherwise. + +History +------- + +Mailu started in late 2014 and was named Freeposte, the Freeposte.io at +the time. Early Mailu versions were maintained by a french nonprofit +named TeDomum, the initial purpose being to re-design their free e-mail +hosting service as Docker containers and add some fresh UI to the mix +in order to replace old interfaces like PostfixAdmin. + +At the time, Post.io was one of the most interesting solutions out there +and was only lacking a free software licence (hence Mailu's initial +name). Later, around late 2015, Mailu became a public project including +contributions from third parties. + +Today, Mailu is running many mail instances, but remains a community +project, where everyone is welcome to take part. + diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..f388e05b --- /dev/null +++ b/docs/index.md @@ -0,0 +1,28 @@ +Mailu +===== + +Mailu is a simple yet full-featured mail server as a set of Docker images. +It is free software (both as in free beer and as in free speech), open to +suggestions and external contributions. The project aims at providing people +with an easily setup, easily maintained and full-featured mail server while +not shipping proprietary software nor unrelated features often found in +popular groupware. + +The documentation is written as part of the repository and evolves with it. +Make sure that you access the proper version of the documentation, based on +the version of Mailu that you are running. + + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + general + setup + configuration + compose/requirements + compose/setup + kubernetes/index + maintain + cli + dns diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 65d5ab88..00000000 --- a/docs/index.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. Mailu documentation master file, created by - sphinx-quickstart on Wed Nov 1 12:36:49 2017. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to Mailu's documentation! -================================= - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/kubernetes/README.md b/docs/kubernetes/index.md similarity index 86% rename from docs/kubernetes/README.md rename to docs/kubernetes/index.md index 810e31f7..3a2488f0 100644 --- a/docs/kubernetes/README.md +++ b/docs/kubernetes/index.md @@ -1,10 +1,13 @@ -# Installing Mailu with Kubernetes # +Kubernetes setup +================ -# Prerequisites # +Prepare the environment +----------------------- The resource configurations in this folder assume that you have [Kubernetes Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) set up for your cluster. If you are not using the [NGINX Ingress Controller for Kubernetes](https://github.com/kubernetes/ingress/tree/master/controllers/nginx), please ensure that the configuration specified in the file matches your set up. -# How to use # +Setup the Kubernetes service +---------------------------- Using the resource configurations is simple: diff --git a/docs/maintain.md b/docs/maintain.md new file mode 100644 index 00000000..18b51f97 --- /dev/null +++ b/docs/maintain.md @@ -0,0 +1,46 @@ +Maintain a Mailu server +======================= + +Upgrading the mail server +------------------------- + +First check upstream for changes in the ``docker-compose.yml`` or in the +``.env`` files. Also, check ``CHANGELOG.md`` for changes that you +might not want to include. + +Update your ``.env`` file to reflect the version that you wish to install (if +you are running ``stable`` or ``latest``, you may skip this and proceed), then +simply pull the latest images and recreate the containers : + +``` +docker-compose pull +docker-compose up -d +``` + +Monitoring the mail server +-------------------------- + +Logs are managed by Docker directly. You can easily read your logs using : + +``` +docker-compose logs +``` + +Docker is able to forward logs to multiple log engines. Read the following documentation or details: https://docs.docker.com/engine/admin/logging/overview/. + +Migrating an instance +--------------------- + +The SMTP protocol has an embedded retry mechanism and multiple MX that can serve a single domain, so that most migration process or maintenance process do not require any specific care. + +Mailu relys heavily on files for storing everything, which helps the migration process, that can be performed based on file synchronization. + +The suggested migration process consists in setting up a new backup server that drops incoming emails (Mailu not started), synchronizing both servers, stopping the main server and launching the backup server. Then, the backup server is switched as a main MX and the old server is deleted. + +1. Prepare your new server, copy your `docker-compose.yml`, `.env` and basic configuration files to the server, so that it is ready to start configuration Mailu, *do not start Mailu* +2. Setup your DNS so that the backup server is an additional, deprioritized MX for the domain; this can be complex if you serve many domains, in which case you can simply accept that some remote MX will retry for a couple minutes, skip this step +3. While your DNS TTL expires and your modification propagates, start *rsyncing* your Mailu directory (`data`, `dkim`, `mail`, etc.) to the new server, repeat until there are only a couple files synchronized +4. Stop Mailu on the old server and run a final `rsync` while no process is writing to the files +5. Start Mailu on the new server, and production should be back to normal +6. Set your new server as the main MX for your domains, if you did not set an additional MX, make sure you still change the `A` and `AAAA` record for your MX name. + diff --git a/docs/setup.md b/docs/setup.md new file mode 100644 index 00000000..658e3f5d --- /dev/null +++ b/docs/setup.md @@ -0,0 +1,68 @@ +Setup a new Mailu server +======================== + +Things to consider +------------------ + +Mailu is working, it has been powering hundreds of e-mail accounts +since around January 2016, and has delivered over a million emails. +It is still not massively tested however and +you should not run any critical mail server until you have properly tested +every feature. + +Also, the idea behind Mailu is based on the work by folks from Poste.io. +If free software is not the reason you chose Mailu or if you are seeking +long-term professional support, you should probably turn to them instead. + +Prepare the environment +----------------------- + +You are free to choose any operating system that runs Docker (>= 1.11), +then chose between various flavors including Docker Compose, Kubernetes +and Rancher. + +Compose is the most tested flavor and should be used by any unexperimented +user. Make sure you complete the requirements for the flavor you chose. + +You should also have at least a DNS hostname and a DNS name for receiving +emails. Some instructions are provided on the matter in the article +[Setup your DNS](dns). + +Pick a Mailu version +-------------------- + +Mailu is shipped in multiple versions. + +- ``stable`` is the default version and features a stable server, it gets bugfixes + and patches but features are included every month or so after a couple weeks of + testing. This is the default setting and should match most requirements. + +- ``1.0``, ``1.1``, and other version branches feature old versions of Mailu + they will not receive any more patches (except for the stable one) and you should + not remain forever on one of those branches; you could however setup the stable + branch by number to avoid introducing unexpected new feature until you read the + changelog properly. This is the most conservative option. + +- ``latest`` points at the latest build from the master + development branch. It will most likely contain many more bugs, also you should + never use it for a production server. You are more than welcome to run a testing + server however and report bugs. + +Perform the specific setup steps +-------------------------------- + +Specific setup steps are described per flavor (Compose, Kubernetes, etc.) +and you should follow the steps after completing the requirements. + +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 + warnings or errors +- Use an open relay checker like [MailRadar](http://www.mailradar.com/openrelay/) + to ensure you're not contributing to the spam problem on the internet. + All tests there should result in "Relay denied". +- If using DMARC, be sure to check the reports you get to verify that legitimate + email is getting through and forgeries are being properly blocked.