diff --git a/README.md b/README.md index 17292b60..81e343a7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [documentation::badge]: https://img.shields.io/badge/DOCUMENTATION-GH%20PAGES-0078D4?style=for-the-badge&logo=git&logoColor=white [documentation::web]: https://docker-mailserver.github.io/docker-mailserver/edge/ -A fullstack but simple mail server (SMTP, IMAP, LDAP, Antispam, Antivirus, etc.). Only configuration files, no SQL database. Keep it simple and versioned. Easy to deploy and upgrade. [Documentation][documentation::web] via MkDocs. [Why this image was created](https://tvi.al/simple-mail-server-with-docker/). +A fullstack but simple mail-server (SMTP, IMAP, LDAP, Antispam, Antivirus, etc.). Only configuration files, no SQL database. Keep it simple and versioned. Easy to deploy and upgrade. [Documentation][documentation::web] via MkDocs. [Why this image was created](https://tvi.al/simple-mail-server-with-docker/). If you have issues, read the full `README` **and** the [documentation][documentation::web] **for your version** (default is `edge`) first **before opening an issue**. The issue tracker is for issues, not for personal support. @@ -36,7 +36,7 @@ If you have issues, read the full `README` **and** the [documentation][documenta - [Postscreen](http://www.postfix.org/POSTSCREEN_README.html) - [Postgrey](https://postgrey.schweikert.ch/) - [LetsEncrypt](https://letsencrypt.org/) and self-signed certificates -- [Setup script](https://docker-mailserver.github.io/docker-mailserver/edge/config/setup.sh) to easily configure and maintain your mailserver +- [Setup script](https://docker-mailserver.github.io/docker-mailserver/edge/config/setup.sh) to easily configure and maintain your mail-server - Basic [Sieve support](https://docker-mailserver.github.io/docker-mailserver/edge/config/advanced/mail-sieve) using dovecot - SASLauthd with LDAP auth - Persistent data and state @@ -78,7 +78,7 @@ All workflows are using the tagging convention listed below. It is subsequently Since Docker Mailserver `v10.2.0`, `setup.sh` functionality is included within the Docker image. The external convenience script is no longer required if you prefer using `docker exec setup ` instead. -**Note:** If you're using Docker or Docker Compose and are new to Docker Mailserver, it is recommended to use the script `setup.sh` for convenience. +**Note:** If you're using Docker or Docker Compose and are new to `docker-mailserver`, it is recommended to use the script `setup.sh` for convenience. ``` BASH DMS_GITHUB_URL='https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master' @@ -90,20 +90,20 @@ chmod a+x ./setup.sh ./setup.sh help ``` -If no `docker-mailserver` container is running, any `./setup.sh` command will check online for the `:latest` image tag (the current stable release), performing a `pull` if necessary followed by running the command in a temporary container. +If no `docker-mailserver` container is running, any `./setup.sh` command will check online for the `:latest` image tag (the current stable release), performing a `pull` if necessary followed by running the command in a temporary container. -#### `setup.sh` for Docker Mailserver version `v10.1.x` and below +#### `setup.sh` for `docker-mailserver` version `v10.1.x` and below -If you're using Docker Mailserver version `v10.1.x` or below, you will need to get `setup.sh` with a specific version. Substitute `` with the mail server version you're using: `wget https://raw.githubusercontent.com/docker-mailserver/docker-mailserver//setup.sh`. +If you're using `docker-mailserver` version `v10.1.x` or below, you will need to get `setup.sh` with a specific version. Substitute `` with the `docker-mailserver` release version you're using: `wget https://raw.githubusercontent.com/docker-mailserver/docker-mailserver//setup.sh`. ### Create a docker-compose environment 1. [Install the latest docker-compose](https://docs.docker.com/compose/install/) 2. Edit `docker-compose.yml` to your liking - - substitute `` and `` according to your domain - - if you want to use SELinux for the `./config/:/tmp/docker-mailserver/` mount, append `-z` or `-Z` -3. Configure the mailserver container to your liking by editing `mailserver.env` ([**Documentation**](https://docker-mailserver.github.io/docker-mailserver/edge/config/environment/)) - - this file supports [_only_ simple `VAR=VAL`](https://docs.docker.com/compose/env-file/) (**don't** quote your values) + - substitute `mail` (hostname) and `example.com` (domainname) according to your FQDN + - if you want to use SELinux for the `./docker-data/dms/config/:/tmp/docker-mailserver/` mount, append `-z` or `-Z` +3. Configure the mailserver container to your liking by editing `mailserver.env` ([**Documentation**](https://docker-mailserver.github.io/docker-mailserver/edge/config/environment/)), but keep in mind this `.env` file: + - [_only_ basic `VAR=VAL`](https://docs.docker.com/compose/env-file/) is supported (**do not** quote your values!) - variable substitution is **not** supported (e.g. :no_entry_sign: `OVERRIDE_HOSTNAME=$HOSTNAME.$DOMAINNAME` :no_entry_sign:) ### Get up and running @@ -137,9 +137,9 @@ When keys are generated, you can configure your DNS server by just pasting the c If you'd like to change, patch or alter files or behavior of `docker-mailserver`, you can use a script. See the [documentation](https://docker-mailserver.github.io/docker-mailserver/edge/config/advanced/override-defaults/user-patches/) for a detailed explanation. -#### Update `docker-mailserver` +#### Updating `docker-mailserver` -Make sure to read the [CHANGELOG](https://github.com/docker-mailserver/docker-mailserver/blob/master/CHANGELOG.md) before, to be prepared for possible breaking changes. +Make sure to read the [CHANGELOG](https://github.com/docker-mailserver/docker-mailserver/blob/master/CHANGELOG.md) before updating to new versions, to be prepared for possible breaking changes. ``` BASH docker-compose pull @@ -153,7 +153,7 @@ You're done! And don't forget to have a look at the remaining functions of the ` #### Supported Operating Systems -We are currently providing support for Linux. Windows is _not_ supported and is known to cause problems. Similarly, macOS is _not officially_ supported - but you may get it to work there. In the end, Linux should be your preferred operating system for this image, especially when using this mailserver in production. +We are currently providing support for Linux. Windows is _not_ supported and is known to cause problems. Similarly, macOS is _not officially_ supported - but you may get it to work there. In the end, Linux should be your preferred operating system for this image, especially when using this mail-server in production. #### Bare Domains @@ -195,20 +195,20 @@ version: '3.8' services: mailserver: image: docker.io/mailserver/docker-mailserver:latest + container_name: mailserver hostname: mail domainname: example.com - container_name: mailserver ports: - "25:25" - "143:143" - "587:587" - "993:993" volumes: - - ./data/maildata:/var/mail - - ./data/mailstate:/var/mail-state - - ./data/maillogs:/var/log/mail + - ./docker-data/dms/mail-data/:/var/mail/ + - ./docker-data/dms/mail-state/:/var/mail-state/ + - ./docker-data/dms/mail-logs/:/var/log/mail/ + - ./docker-data/dms/config/:/tmp/docker-mailserver/ - /etc/localtime:/etc/localtime:ro - - ./config/:/tmp/docker-mailserver/ environment: - ENABLE_SPAMASSASSIN=1 - SPAMASSASSIN_SPAM_TO_INBOX=1 @@ -232,20 +232,20 @@ version: '3.8' services: mailserver: image: docker.io/mailserver/docker-mailserver:latest + container_name: mailserver hostname: mail domainname: example.com - container_name: mailserver ports: - "25:25" - "143:143" - "587:587" - "993:993" volumes: - - ./data/maildata:/var/mail - - ./data/mailstate:/var/mail-state - - ./data/maillogs:/var/log/mail + - ./docker-data/dms/mail-data/:/var/mail/ + - ./docker-data/dms/mail-state/:/var/mail-state/ + - ./docker-data/dms/mail-logs/:/var/log/mail/ + - ./docker-data/dms/config/:/tmp/docker-mailserver/ - /etc/localtime:/etc/localtime:ro - - ./config/:/tmp/docker-mailserver/ environment: - ENABLE_SPAMASSASSIN=1 - SPAMASSASSIN_SPAM_TO_INBOX=1 diff --git a/docker-compose.yml b/docker-compose.yml index dfbab8a1..d5c6fb20 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,13 +3,13 @@ version: '3.8' services: mailserver: image: docker.io/mailserver/docker-mailserver:latest + container_name: mailserver hostname: mail domainname: example.com - container_name: mailserver env_file: mailserver.env - # To avoid conflicts with yaml base-60 float, DO NOT remove the quotation marks. - # More information about the mailserver ports: + # More information about the mail-server ports: # https://docker-mailserver.github.io/docker-mailserver/edge/config/security/understanding-the-ports/ + # To avoid conflicts with yaml base-60 float, DO NOT remove the quotation marks. ports: - "25:25" # SMTP (explicit TLS => STARTTLS) - "143:143" # IMAP4 (explicit TLS => STARTTLS) @@ -17,11 +17,11 @@ services: - "587:587" # ESMTP (explicit TLS => STARTTLS) - "993:993" # IMAP4 (implicit TLS) volumes: - - ./data/maildata:/var/mail - - ./data/mailstate:/var/mail-state - - ./data/maillogs:/var/log/mail - - /etc/localtime:/etc/localtime:ro - - ./config/:/tmp/docker-mailserver/ + - ./docker-data/dms/mail-data/:/var/mail/ + - ./docker-data/dms/mail-state/:/var/mail-state/ + - ./docker-data/dms/mail-logs/:/var/log/mail/ + - ./docker-data/dms/config/:/tmp/docker-mailserver/ + - /etc/localtime:/etc/localtime:ro/ restart: always stop_grace_period: 1m cap_add: diff --git a/docs/content/config/advanced/auth-ldap.md b/docs/content/config/advanced/auth-ldap.md index ae418fee..9a517d4b 100644 --- a/docs/content/config/advanced/auth-ldap.md +++ b/docs/content/config/advanced/auth-ldap.md @@ -4,7 +4,7 @@ title: 'Advanced | LDAP Authentication' ## Introduction -Getting started with ldap and this mailserver we need to take 3 parts in account: +Getting started with ldap and `docker-mailserver` we need to take 3 parts in account: - `postfix` for incoming & outgoing email - `dovecot` for accessing mailboxes @@ -15,6 +15,7 @@ Getting started with ldap and this mailserver we need to take 3 parts in account Have a look at [the ENV page][docs-environment] for information on the default values. ### `LDAP_QUERY_FILTER_*` + Those variables contain the LDAP lookup filters for postfix, using `%s` as the placeholder for the domain or email address in question. This means that... - ...for incoming email, the domain must return an entry for the `DOMAIN` filter (see [`virtual_alias_domains`](http://www.postfix.org/postconf.5.html#virtual_alias_domains)). @@ -48,6 +49,7 @@ Those variables contain the LDAP lookup filters for postfix, using `%s` as the p ``` ### `DOVECOT_*_FILTER` & `DOVECOT_*_ATTRS` + These variables specify the LDAP filters that dovecot uses to determine if a user can log in to their IMAP account, and which mailbox is responsible to receive email for a specific postfix user. This is split into the following two lookups, both using `%u` as the placeholder for the full login name ([see dovecot documentation for a full list of placeholders](https://doc.dovecot.org/configuration_manual/config_file/config_variables/)). Usually you only need to set `DOVECOT_USER_FILTER`, in which case it will be used for both filters. @@ -89,9 +91,11 @@ If your directory doesn't have the [postfix-book schema](https://github.com/vari The LDAP server configuration for dovecot will be taken mostly from postfix, other options can be found in [the environment section in the docs][docs-environment]. ### `DOVECOT_AUTH_BIND` + Set this to `yes` to enable authentication binds ([more details in the dovecot documentation](https://wiki.dovecot.org/AuthDatabase/LDAP/AuthBinds)). Currently, only DN lookup is supported without further changes to the configuration files, so this is only useful when you want to bind as a readonly user without the permission to read passwords. ### `SASLAUTHD_LDAP_FILTER` + This filter is used for `saslauthd`, which is called by postfix when someone is authenticating through SMTP (assuming that `SASLAUTHD_MECHANISMS=ldap` is being used). Note that you'll need to set up the LDAP server for saslauthd seperately from postfix. The filter variables are explained in detail [in the `LDAP_SASLAUTHD` file](https://github.com/winlibs/cyrus-sasl/blob/master/saslauthd/LDAP_SASLAUTHD#L121), but unfortunately, this method doesn't really support domains right now - that means that `%U` is the only token that makes sense in this variable. @@ -111,6 +115,7 @@ The filter variables are explained in detail [in the `LDAP_SASLAUTHD` file](http ``` ## Secure Connection with LDAPS or StartTLS + To enable LDAPS, all you need to do is to add the protocol to `LDAP_SERVER_HOST`, for example `ldaps://example.org:636`. To enable LDAP over StartTLS (on port 389), you need to set the following environment variables instead (the **protocol must not be `ldaps://`** in this case!): @@ -130,9 +135,9 @@ To enable LDAP over StartTLS (on port 389), you need to set the following enviro services: mailserver: image: docker.io/mailserver/docker-mailserver:latest + container_name: mailserver hostname: mail domainname: example.com - container_name: mailserver ports: - "25:25" @@ -141,11 +146,11 @@ To enable LDAP over StartTLS (on port 389), you need to set the following enviro - "993:993" volumes: - - ./data/maildata:/var/mail - - ./data/mailstate:/var/mail-state - - ./data/maillogs:/var/log/mail + - ./docker-data/dms/mail-data/:/var/mail/ + - ./docker-data/dms/mail-state/:/var/mail-state/ + - ./docker-data/dms/mail-logs/:/var/log/mail/ + - ./docker-data/dms/config/:/tmp/docker-mailserver/ - /etc/localtime:/etc/localtime:ro - - ./config/:/tmp/docker-mailserver/ environment: - ENABLE_SPAMASSASSIN=1 @@ -196,9 +201,9 @@ To enable LDAP over StartTLS (on port 389), you need to set the following enviro services: mailserver: image: docker.io/mailserver/docker-mailserver:latest + container_name: mailserver hostname: mail domainname: example.com - container_name: mailserver ports: - "25:25" @@ -207,9 +212,9 @@ To enable LDAP over StartTLS (on port 389), you need to set the following enviro - "993:993" volumes: - - maildata:/var/mail - - mailstate:/var/mail-state - - ./config/:/tmp/docker-mailserver/ + - ./docker-data/dms/mail-data/:/var/mail/ + - ./docker-data/dms/mail-state/:/var/mail-state/ + - ./docker-data/dms/config/:/tmp/docker-mailserver/ environment: # We are not using dovecot here @@ -250,12 +255,6 @@ To enable LDAP over StartTLS (on port 389), you need to set the following enviro cap_add: - NET_ADMIN - - volumes: - maildata: - driver: local - mailstate: - driver: local ``` [docs-environment]: ../environment.md diff --git a/docs/content/config/advanced/full-text-search.md b/docs/content/config/advanced/full-text-search.md index efcb4674..0eb587c5 100644 --- a/docs/content/config/advanced/full-text-search.md +++ b/docs/content/config/advanced/full-text-search.md @@ -6,7 +6,7 @@ title: 'Advanced | Full-Text Search' Full-text search allows all messages to be indexed, so that mail clients can quickly and efficiently search messages by their full text content. Dovecot supports a variety of community supported [FTS indexing backends](https://doc.dovecot.org/configuration_manual/fts/). -Docker-mailserver comes pre-installed with two plugins that can be enabled with a dovecot config file. +`docker-mailserver` comes pre-installed with two plugins that can be enabled with a dovecot config file. Please be aware that indexing consumes memory and takes up additional disk space. @@ -14,13 +14,13 @@ Please be aware that indexing consumes memory and takes up additional disk space The [dovecot-fts-xapian](https://github.com/grosjo/fts-xapian) plugin makes use of [Xapian](https://xapian.org/). Xapian enables embedding an FTS engine without the need for additional backends. -The indexes will be stored as a subfolder named `xapian-indexes` inside your `mail` folder. With the default settings, 10GB of email data may generate around 4GB of indexed data. +The indexes will be stored as a subfolder named `xapian-indexes` inside your local `mail-data` folder (_`/var/mail` internally_). With the default settings, 10GB of email data may generate around 4GB of indexed data. While indexing is memory intensive, you can configure the plugin to limit the amount of memory consumed by the index workers. With Xapian being small and fast, this plugin is a good choice for low memory environments (2GB) as compared to Solr. #### Setup -1. To configure fts-xapian as a dovecot plugin, create a `fts-xapian-plugin.conf` file and place the following in it: +1. To configure `fts-xapian` as a dovecot plugin, create a file at `docker-data/dms/config/dovecot/fts-xapian-plugin.conf` and place the following in it: ``` mail_plugins = $mail_plugins fts fts_xapian @@ -58,14 +58,13 @@ While indexing is memory intensive, you can configure the plugin to limit the am 2. Update `docker-compose.yml` to load the previously created dovecot plugin config file: ```yaml - version: '3.8' services: mailserver: image: docker.io/mailserver/docker-mailserver:latest + container_name: mailserver hostname: mail domainname: example.com - container_name: mailserver env_file: mailserver.env ports: - "25:25" # SMTP (explicit TLS => STARTTLS) @@ -74,12 +73,12 @@ While indexing is memory intensive, you can configure the plugin to limit the am - "587:587" # ESMTP (explicit TLS => STARTTLS) - "993:993" # IMAP4 (implicit TLS) volumes: - - ./data/mail:/var/mail - - ./data/state:/var/mail-state - - ./data/logs:/var/log/mail + - ./docker-data/dms/mail-data/:/var/mail/ + - ./docker-data/dms/mail-state/:/var/mail-state/ + - ./docker-data/dms/mail-logs/:/var/log/mail/ + - ./docker-data/dms/config/:/tmp/docker-mailserver/ + - ./docker-data/dms/config/dovecot/fts-xapian-plugin.conf:/etc/dovecot/conf.d/10-plugin.conf:ro - /etc/localtime:/etc/localtime:ro - - ./config/:/tmp/docker-mailserver/ - - ./fts-xapian-plugin.conf:/etc/dovecot/conf.d/10-plugin.conf:ro restart: always stop_grace_period: 1m cap_add: @@ -87,23 +86,23 @@ While indexing is memory intensive, you can configure the plugin to limit the am - SYS_PTRACE ``` - 3. Recreate containers: +3. Recreate containers: ``` - docker-compose down - docker-compose up -d + docker-compose down + docker-compose up -d ``` - 4. Initialize indexing on all users for all mail: +4. Initialize indexing on all users for all mail: ``` - docker-compose exec mailserver doveadm index -A -q \* + docker-compose exec mailserver doveadm index -A -q \* ``` - 5. Run the following command in a daily cron job: +5. Run the following command in a daily cron job: ``` - docker-compose exec mailserver doveadm fts optimize -A + docker-compose exec mailserver doveadm fts optimize -A ``` ### Solr @@ -122,7 +121,7 @@ However, Solr also requires a fair bit of RAM. While Solr is [highly tuneable](h solr: image: lmmdock/dovecot-solr:latest volumes: - - solr-dovecot:/opt/solr/server/solr/dovecot + - ./docker-data/dms/config/dovecot/solr-dovecot:/opt/solr/server/solr/dovecot restart: always mailserver: @@ -132,15 +131,11 @@ However, Solr also requires a fair bit of RAM. While Solr is [highly tuneable](h ... volumes: ... - - ./etc/dovecot/conf.d/10-plugin.conf:/etc/dovecot/conf.d/10-plugin.conf:ro + - ./docker-data/dms/config/dovecot/10-plugin.conf:/etc/dovecot/conf.d/10-plugin.conf:ro ... - - volumes: - solr-dovecot: - driver: local ``` -2. `etc/dovecot/conf.d/10-plugin.conf`: +2. `./docker-data/dms/config/dovecot/10-plugin.conf`: ```conf mail_plugins = $mail_plugins fts fts_solr diff --git a/docs/content/config/advanced/kubernetes.md b/docs/content/config/advanced/kubernetes.md index 44b2f6ca..e0d343fc 100644 --- a/docs/content/config/advanced/kubernetes.md +++ b/docs/content/config/advanced/kubernetes.md @@ -151,9 +151,9 @@ metadata: annotations: ignore-check.kube-linter.io/run-as-non-root: >- - The mailserver needs to run as root + 'mailserver' needs to run as root ignore-check.kube-linter.io/privileged-ports: >- - The mailserver needs privilegdes ports + 'mailserver' needs privilegdes ports ignore-check.kube-linter.io/no-read-only-root-fs: >- There are too many files written to make The root FS read-only @@ -173,10 +173,10 @@ spec: container.apparmor.security.beta.kubernetes.io/mailserver: runtime/default spec: - hostname: mailserver + hostname: mail containers: - name: mailserver - image: ghcr.io/docker-mailserver/docker-mailserver:latest + image: docker.io/docker-mailserver/docker-mailserver:latest imagePullPolicy: IfNotPresent securityContext: @@ -281,21 +281,21 @@ spec: ### Sensitive Data -By now, the mailserver starts, but does not really work for long (or at all), because we're lacking certificates. You will need to choose yourself, which approach you'd want to go with. The [TLS][docs-tls] section provides you with an overview. +By now, `docker-mailserver` starts, but does not really work for long (or at all), because we're lacking certificates. The [TLS docs page][docs-tls] provides guidance for various approaches. !!! attention "Sensitive Data" For storing OpenDKIM keys, TLS certificates or any sort of sensitive data, you should be using `Secret`s. You can mount secrets like `ConfigMap`s and use them the same way. -## Exposing your Mailserver to the Outside World +## Exposing your Mail-Server to the Outside World -The more difficult part with K8s is to expose a deployed mailserver to the outside world. K8s provides multiple ways for doing that; each has downsides and complexity. The major problem with exposing the mailserver to outside world in K8s is to [preserve the real client IP][k8s-service-source-ip]. The real client IP is required by the mailserver for performing IP-based SPF checks and spam checks. If you do not require SPF checks for incoming mails, you may disable them in your [Postfix configuration][docs-postfix] by dropping the line that states `check_policy_service unix:private/policyd-spf`. +The more difficult part with K8s is to expose a deployed `docker-mailserver` to the outside world. K8s provides multiple ways for doing that; each has downsides and complexity. The major problem with exposing `docker-mailserver` to outside world in K8s is to [preserve the real client IP][k8s-service-source-ip]. The real client IP is required by `docker-mailserver` for performing IP-based SPF checks and spam checks. If you do not require SPF checks for incoming mails, you may disable them in your [Postfix configuration][docs-postfix] by dropping the line that states: `check_policy_service unix:private/policyd-spf`. -The easiest approach was covered above, using `#!yaml externalTrafficPolicy: Local`, which disables the service proxy, but makes the service local as well (which does not scale). This approach only works when you are given the correct (that is, a public and routable) IP address by a load balancer (like MetalLB). In this sense, the approach above is similar to the next example below. We want to provide you with a few alternatives too. **But** we also want to communicate the idea of another simple method: you could use a load-balancer without an external IP and DNAT the network traffic to the mail server. After all, this does not interfere with SPF checks because it keeps the origin IP address. If no dedicated external IP address is available, you could try the latter approach, if one is available, use the former. +The easiest approach was covered above, using `#!yaml externalTrafficPolicy: Local`, which disables the service proxy, but makes the service local as well (which does not scale). This approach only works when you are given the correct (that is, a public and routable) IP address by a load balancer (like MetalLB). In this sense, the approach above is similar to the next example below. We want to provide you with a few alternatives too. **But** we also want to communicate the idea of another simple method: you could use a load-balancer without an external IP and DNAT the network traffic to the mail-server. After all, this does not interfere with SPF checks because it keeps the origin IP address. If no dedicated external IP address is available, you could try the latter approach, if one is available, use the former. ### External IPs Service -The simplest way is to expose the mailserver as a [Service][k8s-network-service] with [external IPs][k8s-network-external-ip]. This is very similar to the approach taken above. Here, an external IP is given to the service directly by you. With the approach above, you tell your load-balancer to do this. +The simplest way is to expose `docker-mailserver` as a [Service][k8s-network-service] with [external IPs][k8s-network-external-ip]. This is very similar to the approach taken above. Here, an external IP is given to the service directly by you. With the approach above, you tell your load-balancer to do this. ```yaml --- @@ -327,7 +327,7 @@ This approach ### Proxy port to Service -The [proxy pod][k8s-proxy-service] helps to avoid the necessity of specifying external IPs explicitly. This comes at the cost of complexity; you must deploy a proxy pod on each [Node][k8s-nodes] you want to expose mailserver on. +The [proxy pod][k8s-proxy-service] helps to avoid the necessity of specifying external IPs explicitly. This comes at the cost of complexity; you must deploy a proxy pod on each [Node][k8s-nodes] you want to expose `docker-mailserver` on. This approach @@ -335,7 +335,7 @@ This approach ### Bind to concrete Node and use host network -One way to preserve the real client IP is to use `hostPort` and `hostNetwork: true`. This comes at the cost of availability; you can talk to the mailserver from outside world only via IPs of [Node][k8s-nodes] where mailserver is deployed. +One way to preserve the real client IP is to use `hostPort` and `hostNetwork: true`. This comes at the cost of availability; you can reach `docker-mailserver` from the outside world only via IPs of [Node][k8s-nodes] where `docker-mailserver` is deployed. ```yaml --- @@ -367,12 +367,12 @@ metadata: With this approach, -- it is not possible to access mailserver via other cluster Nodes, only via the one mailserver deployed at. +- it is not possible to access `docker-mailserver` via other cluster Nodes, only via the Node `docker-mailserver` was deployed at. - every Port within the Container is exposed on the Host side. ### Proxy Port to Service via PROXY Protocol -This way is ideologically the same as [using a proxy pod](#proxy-port-to-service), but instead of a separate proxy pod, you configure your ingress to proxy TCP traffic to the mailserver pod using the PROXY protocol, which preserves the real client IP. +This way is ideologically the same as [using a proxy pod](#proxy-port-to-service), but instead of a separate proxy pod, you configure your ingress to proxy TCP traffic to the `docker-mailserver` pod using the PROXY protocol, which preserves the real client IP. #### Configure your Ingress @@ -448,7 +448,7 @@ Then, configure both [Postfix][docs-postfix] and [Dovecot][docs-dovecot] to expe With this approach, -- it is not possible to access the mailserver via cluster-DNS, as the PROXY protocol is required for incoming connections. +- it is not possible to access `docker-mailserver` via cluster-DNS, as the PROXY protocol is required for incoming connections. [kustomize]: https://kustomize.io/ [docs-tls]: ../security/ssl.md diff --git a/docs/content/config/advanced/mail-fetchmail.md b/docs/content/config/advanced/mail-fetchmail.md index 1621a1a5..eeb8c9f4 100644 --- a/docs/content/config/advanced/mail-fetchmail.md +++ b/docs/content/config/advanced/mail-fetchmail.md @@ -10,10 +10,10 @@ environment: - FETCHMAIL_POLL=300 ``` -Generate a file called `fetchmail.cf` and place it in the `config` folder. Your `docker-mailserver` folder should look like this example: +Generate a file called `fetchmail.cf` and place it in the `docker-data/dms/config/` folder. Your `docker-mailserver` folder should look like this example: ```txt -├── config +├── docker-data/dms/config │   ├── dovecot.cf │   ├── fetchmail.cf │   ├── postfix-accounts.cf @@ -28,13 +28,13 @@ A detailed description of the configuration options can be found in the [online ### IMAP Configuration -!!! example +!!! example ```fetchmailrc - poll 'imap.example.com' proto imap + poll 'imap.gmail.com' proto imap user 'username' pass 'secret' - is 'user1@domain.tld' + is 'user1@example.com' ssl ``` @@ -43,15 +43,16 @@ A detailed description of the configuration options can be found in the [online !!! example ```fetchmailrc - poll 'pop3.example.com' proto pop3 + poll 'pop3.gmail.com' proto pop3 user 'username' pass 'secret' - is 'user2@domain.tld' + is 'user2@example.com' ssl ``` !!! caution - Don’t forget the last line: eg: `is 'user1@domain.tld'`. After `is` you have to specify one email address from the configuration file `config/postfix-accounts.cf`. + + Don’t forget the last line! (_eg: `is 'user1@example.com'`_). After `is`, you have to specify an email address from the configuration file: `docker-data/dms/config/postfix-accounts.cf`. More details how to configure fetchmail can be found in the [fetchmail man page in the chapter “The run control file”][fetchmail-docs-run]. diff --git a/docs/content/config/advanced/mail-forwarding/relay-hosts.md b/docs/content/config/advanced/mail-forwarding/relay-hosts.md index fb3426bb..68104349 100644 --- a/docs/content/config/advanced/mail-forwarding/relay-hosts.md +++ b/docs/content/config/advanced/mail-forwarding/relay-hosts.md @@ -12,10 +12,10 @@ Depending on the domain of the sender, you may want to send via a different rela Basic configuration is done via environment variables: -* `RELAY_HOST`: _default host to relay mail through, empty will disable this feature_ -* `RELAY_PORT`: _port on default relay, defaults to port 25_ -* `RELAY_USER`: _username for the default relay_ -* `RELAY_PASSWORD`: _password for the default user_ +- `RELAY_HOST`: _default host to relay mail through, `empty` (aka '', or no ENV set) will disable this feature_ +- `RELAY_PORT`: _port on default relay, defaults to port 25_ +- `RELAY_USER`: _username for the default relay_ +- `RELAY_PASSWORD`: _password for the default user_ Setting these environment variables will cause mail for all sender domains to be routed via the specified host, authenticating with the user/password combination. @@ -26,7 +26,7 @@ Setting these environment variables will cause mail for all sender domains to be ### Sender-dependent Authentication -Sender dependent authentication is done in `config/postfix-sasl-password.cf`. You can create this file manually, or use: +Sender dependent authentication is done in `docker-data/dms/config/postfix-sasl-password.cf`. You can create this file manually, or use: ```sh setup.sh relay add-auth [] @@ -39,14 +39,14 @@ An example configuration file looks like this: @domain2.com relay_user_2:password_2 ``` -If there is no other configuration, this will cause Postfix to deliver email through the relay specified in `RELAY_HOST` env variable, authenticating as `relay_user_1` when sent from `domain1.com` and authenticating as `relay_user_2` when sending from domain2.com. +If there is no other configuration, this will cause Postfix to deliver email through the relay specified in `RELAY_HOST` env variable, authenticating as `relay_user_1` when sent from `domain1.com` and authenticating as `relay_user_2` when sending from `domain2.com`. !!! note To activate the configuration you must either restart the container, or you can also trigger an update by modifying a mail account. ### Sender-dependent Relay Host -Sender dependent relay hosts are configured in `config/postfix-relaymap.cf`. You can create this file manually, or use: +Sender dependent relay hosts are configured in `docker-data/dms/config/postfix-relaymap.cf`. You can create this file manually, or use: ```sh setup.sh relay add-domain [] @@ -59,14 +59,14 @@ An example configuration file looks like this: @domain2.com [relay2.org]:2525 ``` -Combined with the previous configuration in `config/postfix-sasl-password.cf`, this will cause Postfix to deliver mail sent from domain1.com via `relay1.org:587`, authenticating as `relay_user_1`, and mail sent from domain2.com via `relay2.org:2525` authenticating as `relay_user_2`. +Combined with the previous configuration in `docker-data/dms/config/postfix-sasl-password.cf`, this will cause Postfix to deliver mail sent from `domain1.com` via `relay1.org:587`, authenticating as `relay_user_1`, and mail sent from `domain2.com` via `relay2.org:2525` authenticating as `relay_user_2`. !!! note You still have to define `RELAY_HOST` to activate the feature ### Excluding Sender Domains -If you want mail sent from some domains to be delivered directly, you can exclude them from being delivered via the default relay by adding them to `config/postfix-relaymap.cf` with no destination. You can also do this via: +If you want mail sent from some domains to be delivered directly, you can exclude them from being delivered via the default relay by adding them to `docker-data/dms/config/postfix-relaymap.cf` with no destination. You can also do this via: ```sh setup.sh relay exclude-domain @@ -80,11 +80,10 @@ Extending the configuration file from above: @domain3.com ``` -This will cause email sent from domain3.com to be delivered directly. +This will cause email sent from `domain3.com` to be delivered directly. #### References -Thanks to the author of [this article][1] for the inspiration. This is also worth reading to understand a bit more about how to set up Mailgun to work with this. - -[1]: https://community.rackspace.com/products/f/email-products-forum/3897/how-to-setup-postfix-with-a-mailgun-smtp-relay-when-using-multiple-domains +Thanks to the author of [this article][guide-relayhost-mailgun] for the inspiration. This is also worth reading to understand a bit more about how to set up Mailgun to work with this. +[guide-relayhost-mailgun]: https://community.rackspace.com/products/f/email-products-forum/3897/how-to-setup-postfix-with-a-mailgun-smtp-relay-when-using-multiple-domains diff --git a/docs/content/config/advanced/mail-sieve.md b/docs/content/config/advanced/mail-sieve.md index f9a8f2fe..f93edb2b 100644 --- a/docs/content/config/advanced/mail-sieve.md +++ b/docs/content/config/advanced/mail-sieve.md @@ -9,13 +9,13 @@ There are global and user specific filters which are filtering the incoming emai - Global-before -> User specific -> Global-after -Global filters are applied to EVERY incoming mail for EVERY email address. -To specify a global Sieve filter provide a `config/before.dovecot.sieve` or a `config/after.dovecot.sieve` file with your filter rules. +Global filters are applied to EVERY incoming mail for EVERY email address. +To specify a global Sieve filter provide a `docker-data/dms/config/before.dovecot.sieve` or a `docker-data/dms/config/after.dovecot.sieve` file with your filter rules. If any filter in this filtering chain discards an incoming mail, the delivery process will stop as well and the mail will not reach any following filters(e.g. global-before stops an incoming spam mail: The mail will get discarded and a user-specific filter won't get applied.) -To specify a user-defined Sieve filter place a `.dovecot.sieve` file into a virtual user's mail folder e.g. `/var/mail/domain.com/user1/.dovecot.sieve`. If this file exists dovecot will apply the filtering rules. +To specify a user-defined Sieve filter place a `.dovecot.sieve` file into a virtual user's mail folder e.g. `/var/mail/example.com/user1/.dovecot.sieve`. If this file exists dovecot will apply the filtering rules. -It's even possible to install a user provided Sieve filter at startup during users setup: simply include a Sieve file in the `config` path for each user login that need a filter. The file name provided should be in the form `.dovecot.sieve`, so for example for `user1@domain.tld` you should provide a Sieve file named `config/user1@domain.tld.dovecot.sieve`. +It's even possible to install a user provided Sieve filter at startup during users setup: simply include a Sieve file in the `docker-data/dms/config/` path for each user login that needs a filter. The file name provided should be in the form `.dovecot.sieve`, so for example for `user1@example.com` you should provide a Sieve file named `docker-data/dms/config/user1@example.com.dovecot.sieve`. An example of a sieve filter that moves mails to a folder `INBOX/spam` depending on the sender address: @@ -36,12 +36,12 @@ An example of a sieve filter that moves mails to a folder `INBOX/spam` depending Another example of a sieve filter that forward mails to a different address: -!!! example +!!! example ```sieve require ["copy"]; - redirect :copy "user2@otherdomain.tld"; + redirect :copy "user2@not-example.com"; ``` Just forward all incoming emails and do not save them locally: @@ -49,10 +49,10 @@ Just forward all incoming emails and do not save them locally: !!! example ```sieve - redirect "user2@otherdomain.tld"; + redirect "user2@not-example.com"; ``` -You can also use external programs to filter or pipe (process) messages by adding executable scripts in `config/sieve-pipe` or `config/sieve-filter`. This can be used in lieu of a local alias file, for instance to forward an email to a webservice. These programs can then be referenced by filename, by all users. Note that the process running the scripts run as a privileged user. For further information see [Dovecot's wiki](https://wiki.dovecot.org/Pigeonhole/Sieve/Plugins/Pipe). +You can also use external programs to filter or pipe (process) messages by adding executable scripts in `docker-data/dms/config/sieve-pipe` or `docker-data/dms/config/sieve-filter`. This can be used in lieu of a local alias file, for instance to forward an email to a webservice. These programs can then be referenced by filename, by all users. Note that the process running the scripts run as a privileged user. For further information see [Dovecot's wiki](https://wiki.dovecot.org/Pigeonhole/Sieve/Plugins/Pipe). ```sieve require ["vnd.dovecot.pipe"]; @@ -75,7 +75,7 @@ The [Manage Sieve](https://doc.dovecot.org/admin_manual/pigeonhole_managesieve_s - ENABLE_MANAGESIEVE=1 ``` -All user defined sieve scripts that are managed by ManageSieve are stored in the user's home folder in `/var/mail/domain.com/user1/sieve`. Just one sieve script might be active for a user and is sym-linked to `/var/mail/domain.com/user1/.dovecot.sieve` automatically. +All user defined sieve scripts that are managed by ManageSieve are stored in the user's home folder in `/var/mail/example.com/user1/sieve`. Just one sieve script might be active for a user and is sym-linked to `/var/mail/example.com/user1/.dovecot.sieve` automatically. !!! note ManageSieve makes sure to not overwrite an existing `.dovecot.sieve` file. If a user activates a new sieve script the old one is backuped and moved to the `sieve` folder. diff --git a/docs/content/config/advanced/optional-config.md b/docs/content/config/advanced/optional-config.md index da65f11d..a9a64d5d 100644 --- a/docs/content/config/advanced/optional-config.md +++ b/docs/content/config/advanced/optional-config.md @@ -4,14 +4,14 @@ hide: - toc # Hide Table of Contents for this page --- -This is a list of all configuration files and directories which are optional or automatically generated in your `config` directory. +This is a list of all configuration files and directories which are optional or automatically generated in your `docker-data/dms/config/` directory. ## Directories - **sieve-filter:** directory for sieve filter scripts. (Docs: [Sieve][docs-sieve]) - **sieve-pipe:** directory for sieve pipe scripts. (Docs: [Sieve][docs-sieve]) - **opendkim:** DKIM directory. Auto-configurable via [`setup.sh config dkim`][docs-setupsh]. (Docs: [DKIM][docs-dkim]) -- **ssl:** SSL Certificate directory. (Docs: [SSL][docs-ssl]) +- **ssl:** SSL Certificate directory if `SSL_TYPE` is set to `self-signed` or `custom`. (Docs: [SSL][docs-ssl]) ## Files diff --git a/docs/content/config/advanced/override-defaults/dovecot.md b/docs/content/config/advanced/override-defaults/dovecot.md index 6247cf09..2c7557bd 100644 --- a/docs/content/config/advanced/override-defaults/dovecot.md +++ b/docs/content/config/advanced/override-defaults/dovecot.md @@ -4,13 +4,13 @@ title: 'Override the Default Configs | Dovecot' ## Add Configuration -The Dovecot default configuration can easily be extended providing a `config/dovecot.cf` file. +The Dovecot default configuration can easily be extended providing a `docker-data/dms/config/dovecot.cf` file. [Dovecot documentation](https://wiki.dovecot.org) remains the best place to find configuration options. Your `docker-mailserver` folder should look like this example: ```txt -├── config +├── docker-data/dms/config │ ├── dovecot.cf │ ├── postfix-accounts.cf │ └── postfix-virtual.cf @@ -26,20 +26,25 @@ mail_max_userip_connections = 100 Another important option is the `default_process_limit` (defaults to `100`). If high-security mode is enabled you'll need to make sure this count is higher than the maximum number of users that can be logged in simultaneously. -This limit is quickly reached if users connect to the mail server with multiple end devices. +This limit is quickly reached if users connect to the `docker-mailserver` with multiple end devices. ## Override Configuration For major configuration changes it’s best to override the dovecot configuration files. For each configuration file you want to override, add a list entry under the `volumes` key. -You will need to first obtain the configuration from the running container: `mkdir -p ./config/dovecot && docker cp mailserver:/etc/dovecot/conf.d/10-master.conf ./config/dovecot/10-master.conf` - ```yaml services: mailserver: volumes: - - maildata:/var/mail - - ./config/dovecot/10-master.conf:/etc/dovecot/conf.d/10-master.conf + - ./docker-data/dms/mail-data/:/var/mail/ + - ./docker-data/dms/config/dovecot/10-master.conf:/etc/dovecot/conf.d/10-master.conf +``` + +You will first need to obtain the configuration from the running container (_where `mailserver` is the container name_): + +```sh +mkdir -p ./docker-data/dms/config/dovecot +docker cp mailserver:/etc/dovecot/conf.d/10-master.conf ./docker-data/dms/config/dovecot/10-master.conf ``` ## Debugging @@ -50,9 +55,9 @@ To debug your dovecot configuration you can use: - Or: `docker exec -it mailserver doveconf | grep ` !!! note - [`setup.sh`][github-file-setupsh] is included in the `docker-mailserver` repository. Make sure to grap the one matching your image version. + [`setup.sh`][github-file-setupsh] is included in the `docker-mailserver` repository. Make sure to use the one matching your image version release. -The `config/dovecot.cf` is copied internally to `/etc/dovecot/local.conf`. To check this file run: +The file `docker-data/dms/config/dovecot.cf` is copied internally to `/etc/dovecot/local.conf`. To verify the file content, run: ```sh docker exec -it mailserver cat /etc/dovecot/local.conf diff --git a/docs/content/config/advanced/override-defaults/postfix.md b/docs/content/config/advanced/override-defaults/postfix.md index 93e772dc..963809db 100644 --- a/docs/content/config/advanced/override-defaults/postfix.md +++ b/docs/content/config/advanced/override-defaults/postfix.md @@ -2,7 +2,7 @@ title: 'Override the Default Configs | Postfix' --- -The Postfix default configuration can easily be extended by providing a `config/postfix-main.cf` in postfix format. +The Postfix default configuration can easily be extended by providing a `docker-data/dms/config/postfix-main.cf` in postfix format. This can also be used to add configuration that is not in our default configuration. For example, one common use of this file is for increasing the default maximum message size: @@ -20,7 +20,7 @@ That specific example is now supported and can be handled by setting `POSTFIX_ME Each line in the provided file will be loaded into postfix. -In the same way it is possible to add a custom `config/postfix-master.cf` file that will override the standard `master.cf`. Each line in the file will be passed to `postconf -P`. The expected format is `//`, for example: +In the same way it is possible to add a custom `docker-data/dms/config/postfix-master.cf` file that will override the standard `master.cf`. Each line in the file will be passed to `postconf -P`. The expected format is `//`, for example: ```cf submission/inet/smtpd_reject_unlisted_recipient=no diff --git a/docs/content/config/advanced/override-defaults/user-patches.md b/docs/content/config/advanced/override-defaults/user-patches.md index 966fab03..5f4767d8 100644 --- a/docs/content/config/advanced/override-defaults/user-patches.md +++ b/docs/content/config/advanced/override-defaults/user-patches.md @@ -4,20 +4,21 @@ title: 'Custom User Changes & Patches | Scripting' If you'd like to change, patch or alter files or behavior of `docker-mailserver`, you can use a script. -In case you cloned this repository, you can copy the file `user-patches.sh.dist` under `config/` with `#!sh cp config/user-patches.sh.dist config/user-patches.sh` in order to create the `user-patches.sh` script. In case you are managing your directory structure yourself, create a `config/` directory and the `user-patches.sh` file yourself. +In case you cloned this repository, you can copy the file [`user-patches.sh.dist` (_under `config/`_)][gh-file-userpatches] with `#!sh cp config/user-patches.sh.dist docker-data/dms/config/user-patches.sh` in order to create the `user-patches.sh` script. + +If you are managing your directory structure yourself, create a `docker-data/dms/config/` directory and add the `user-patches.sh` file yourself. ``` sh -# 1. Either create the config/ directory yourself -# or let docker-mailserver create it on initial -# startup -~/somewhere $ mkdir config && cd config +# 1. Either create the docker-data/dms/config/ directory yourself +# or let docker-mailserver create it on initial startup +/tmp $ mkdir -p docker-data/dms/config/ && cd docker-data/dms/config/ -# 2. Create the user-patches.sh and edit it -~/somewhere/config $ touch user-patches.sh -~/somewhere/config $ vi user-patches.sh +# 2. Create the user-patches.sh file and edit it +/tmp/docker-data/dms/config $ touch user-patches.sh +/tmp/docker-data/dms/config $ nano user-patches.sh ``` -The contents could look like this +The contents could look like this: ``` sh #! /bin/bash @@ -32,10 +33,11 @@ $admin_maps_by_ccat{+CC_UNCHECKED} = undef; 1; # ensure a defined return END -... ``` And you're done. The user patches script runs right before starting daemons. That means, all the other configuration is in place, so the script can make final adjustments. !!! note Many "patches" can already be done with the Docker Compose-/Stack-file. Adding hostnames to `/etc/hosts` is done with the `#!yaml extra_hosts:` section, `sysctl` commands can be managed with the `#!yaml sysctls:` section, etc. + +[gh-file-userpatches]: https://github.com/docker-mailserver/docker-mailserver/blob/master/config/user-patches.sh.dist diff --git a/docs/content/config/advanced/podman.md b/docs/content/config/advanced/podman.md index dd3ba6b6..febd286e 100644 --- a/docs/content/config/advanced/podman.md +++ b/docs/content/config/advanced/podman.md @@ -8,7 +8,7 @@ Podman is a daemonless container engine for developing, managing, and running OC !!! warning "About Support for Podman" - Please note that Podman **is not** officially supported as Docker Mailserver is built and verified on top of the Docker Engine. This content is entirely community-supported. If you find errors, please open an issue and provide a PR. + Please note that Podman **is not** officially supported as `docker-mailserver` is built and verified on top of the _Docker Engine_. This content is entirely community supported. If you find errors, please open an issue and provide a PR. !!! warning "About this Guide" @@ -61,7 +61,7 @@ Also notice that Podman's rootless mode is not about running as a non-root user !!! warning - In order to make rootless mailserver work we must modify some settings in the Linux system, it requires some basic linux server knowledge so don't follow this guide if you not sure what this guide is talking about. Podman rootfull mode and Docker are still good and security enough for normal daily usage. + In order to make rootless `docker-mailserver` work we must modify some settings in the Linux system, it requires some basic linux server knowledge so don't follow this guide if you not sure what this guide is talking about. Podman rootfull mode and Docker are still good and security enough for normal daily usage. First, enable `podman.socket` in systemd's userspace with a non-root user. diff --git a/docs/content/config/best-practices/autodiscover.md b/docs/content/config/best-practices/autodiscover.md index fef6b64b..e082ab77 100644 --- a/docs/content/config/best-practices/autodiscover.md +++ b/docs/content/config/best-practices/autodiscover.md @@ -4,7 +4,7 @@ hide: - toc # Hide Table of Contents for this page --- -Email auto-discovery means a client email is able to automagically find out about what ports and security options to use, based on the mail server URL. It can help simplify the tedious / confusing task of adding own's email account for non-tech savvy users. +Email auto-discovery means a client email is able to automagically find out about what ports and security options to use, based on the mail-server URI. It can help simplify the tedious / confusing task of adding own's email account for non-tech savvy users. Email clients will search for auto-discoverable settings and prefill almost everything when a user enters its email address :heart: diff --git a/docs/content/config/best-practices/dkim.md b/docs/content/config/best-practices/dkim.md index 87061ef3..bbf5fff9 100644 --- a/docs/content/config/best-practices/dkim.md +++ b/docs/content/config/best-practices/dkim.md @@ -15,22 +15,26 @@ To enable DKIM signature, **you must have created at least one email account**. ./setup.sh config dkim ``` -After generating DKIM keys, you should restart the mail server. DNS edits may take a few minutes to hours to propagate. The script assumes you're being in the directory where the `config/` directory is located. The default keysize when generating the signature is 4096 bits for now. If you need to change it (e.g. your DNS provider limits the size), then provide the size as the first parameter of the command: +After generating DKIM keys, you should restart `docker-mailserver`. DNS edits may take a few minutes to hours to propagate. + +The script should ideally be run with a volume for _config_ attached (eg: `./docker-data/dms/config/:/tmp/docker-mailserver/`), otherwise by default it will mount `./config/:/tmp/docker-mailserver/`. + +The default keysize when generating the signature is 4096 bits for now. If you need to change it (e.g. your DNS provider limits the size), then provide the size as the first parameter of the command: ```sh ./setup.sh config dkim keysize ``` -For LDAP systems that do not have any directly created user account you can run the following command (since `8.0.0`) to generate the signature by additionally providing the desired domain name (if you have multiple domains use the command multiple times or provide a comma-separated list of domains): +For LDAP systems that do not have any directly created user account you can run the following command (since `8.0.0`) to generate the signature by additionally providing the desired domain name (if you have multiple domains use the command multiple times or provide a comma-separated list of domains): ```sh -./setup.sh config dkim keysize domain [,] +./setup.sh config dkim keysize domain [,] ``` -Now the keys are generated, you can configure your DNS server with DKIM signature, simply by adding a TXT record. If you have direct access to your DNS zone file, then it's only a matter of pasting the content of `config/opendkim/keys/domain.tld/mail.txt` in your `domain.tld.hosts` zone. +Now the keys are generated, you can configure your DNS server with DKIM signature, simply by adding a TXT record. If you have direct access to your DNS zone file, then it's only a matter of pasting the content of `docker-data/dms/config/opendkim/keys/example.com/mail.txt` in your `example.com.hosts` zone. ```console -$ dig mail._domainkey.domain.tld TXT +$ dig mail._domainkey.example.com TXT --- ;; ANSWER SECTION mail._domainkey. 300 IN TXT "v=DKIM1; k=rsa; p=AZERTYUIOPQSDFGHJKLMWXCVBN/AZERTYUIOPQSDFGHJKLMWXCVBN/AZERTYUIOPQSDFGHJKLMWXCVBN/AZERTYUIOPQSDFGHJKLMWXCVBN/AZERTYUIOPQSDFGHJKLMWXCVBN/AZERTYUIOPQSDFGHJKLMWXCVBN/AZERTYUIOPQSDFGHJKLMWXCVBN/AZERTYUIOPQSDFGHJKLMWXCVBN" @@ -45,10 +49,10 @@ mail._domainkey. 300 IN TXT "v=DKIM1; k=rsa; p=AZERTYUIOPQSDFGHJKLMWX 5. Save. !!! note - Sometimes the key in `config/opendkim/keys/domain.tld/mail.txt` can be on multiple lines. If so then you need to concatenate the values in the TXT record: + Sometimes the key in `docker-data/dms/config/opendkim/keys/example.com/mail.txt` can be on multiple lines. If so then you need to concatenate the values in the TXT record: ```console -$ dig mail._domainkey.domain.tld TXT +$ dig mail._domainkey.example.com TXT --- ;; ANSWER SECTION mail._domainkey. 300 IN TXT "v=DKIM1; k=rsa; " @@ -72,7 +76,7 @@ SyslogSuccess yes Socket inet:12301@localhost PidFile /var/run/opendkim/opendkim.pid -ReportAddress postmaster@my-domain.com +ReportAddress postmaster@example.com SendReports yes Mode v @@ -80,7 +84,7 @@ Mode v ## Switch Off DKIM -Simply remove the DKIM key by recreating (not just relaunching) the mailserver container. +Simply remove the DKIM key by recreating (not just relaunching) the `docker-mailserver` container. ## Debugging @@ -88,9 +92,9 @@ Simply remove the DKIM key by recreating (not just relaunching) the mailserver c - You can debug your TXT records with the `dig` tool. ```console -$ dig TXT mail._domainkey.domain.tld +$ dig TXT mail._domainkey.example.com --- -; <<>> DiG 9.10.3-P4-Debian <<>> TXT mail._domainkey.domain.tld +; <<>> DiG 9.10.3-P4-Debian <<>> TXT mail._domainkey.example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39669 @@ -99,10 +103,10 @@ $ dig TXT mail._domainkey.domain.tld ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: -;mail._domainkey.domain.tld. IN TXT +;mail._domainkey.example.com. IN TXT ;; ANSWER SECTION: -mail._domainkey.domain.tld. 3600 IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxBSjG6RnWAdU3oOlqsdf2WC0FOUmU8uHVrzxPLW2R3yRBPGLrGO1++yy3tv6kMieWZwEBHVOdefM6uQOQsZ4brahu9lhG8sFLPX4MaKYN/NR6RK4gdjrZu+MYSdfk3THgSbNwIDAQAB" +mail._domainkey.example.com. 3600 IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxBSjG6RnWAdU3oOlqsdf2WC0FOUmU8uHVrzxPLW2R3yRBPGLrGO1++yy3tv6kMieWZwEBHVOdefM6uQOQsZ4brahu9lhG8sFLPX4MaKYN/NR6RK4gdjrZu+MYSdfk3THgSbNwIDAQAB" ;; Query time: 50 msec ;; SERVER: 127.0.1.1#53(127.0.1.1) @@ -114,6 +118,6 @@ mail._domainkey.domain.tld. 3600 IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBA !!! warning "Key sizes >=4096-bit" - Keys of 4096 bits could de denied by some mailservers. According to https://tools.ietf.org/html/rfc6376 keys are preferably between 512 and 2048 bits. See issue [#1854][github-issue-1854]. + Keys of 4096 bits could de denied by some mail-servers. According to https://tools.ietf.org/html/rfc6376 keys are preferably between 512 and 2048 bits. See issue [#1854][github-issue-1854]. [github-issue-1854]: https://github.com/docker-mailserver/docker-mailserver/issues/1854 diff --git a/docs/content/config/best-practices/dmarc.md b/docs/content/config/best-practices/dmarc.md index 5ba8f0b4..c87386f4 100644 --- a/docs/content/config/best-practices/dmarc.md +++ b/docs/content/config/best-practices/dmarc.md @@ -4,28 +4,33 @@ hide: - toc # Hide Table of Contents for this page --- -!!! note - DMARC Guide: https://github.com/internetstandards/toolbox-wiki/blob/master/DMARC-how-to.md +More information at [DMARC Guide][dmarc-howto]. ## Enabling DMARC -In `docker-mailserver`, DMARC is pre-configured out-of the box. The only thing you need to do in order to enable it, is to add new TXT entry to your DNS. +In `docker-mailserver`, DMARC is pre-configured out of the box. The only thing you need to do in order to enable it, is to add new `TXT` entry to your DNS. -In contrast with [DKIM][docs-dkim], DMARC DNS entry does not require any keys, but merely setting the [configuration values](https://github.com/internetstandards/toolbox-wiki/blob/master/DMARC-how-to.md#overview-of-dmarc-configuration-tags). You can either handcraft the entry by yourself or use one of available generators (like https://dmarcguide.globalcyberalliance.org/). +In contrast with [DKIM][docs-dkim], the DMARC DNS entry does not require any keys, but merely setting the [configuration values][dmarc-howto-configtags]. You can either handcraft the entry by yourself or use one of available generators (like [this one][dmarc-tool::gca]). + +Typically something like this should be good to start with (_don't forget to replace `@example.com` to your actual domain_): -Typically something like this should be good to start with (don't forget to replace `@domain.com` to your actual domain) ``` -_dmarc.domain.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc.report@domain.com; ruf=mailto:dmarc.report@domain.com; sp=none; ri=86400" +_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc.report@example.com; ruf=mailto:dmarc.report@example.com; sp=none; ri=86400" ``` -Or a bit more strict policies (mind `p=quarantine` and `sp=quarantine`): +Or a bit more strict policies (_mind `p=quarantine` and `sp=quarantine`_): + ``` -_dmarc IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc.report@domain.com; ruf=mailto:dmarc.report@domain.com; fo=0; adkim=r; aspf=r; pct=100; rf=afrf; ri=86400; sp=quarantine" +_dmarc IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc.report@example.com; ruf=mailto:dmarc.report@example.com; fo=0; adkim=r; aspf=r; pct=100; rf=afrf; ri=86400; sp=quarantine" ``` -DMARC status is not being displayed instantly in Gmail for instance. If you want to check it directly after DNS entries, you can use some services around the Internet such as https://dmarcguide.globalcyberalliance.org/ or https://ondmarc.redsift.com/. In other case, email clients will show "DMARC: PASS" in ~1 day or so. +DMARC status is not being displayed instantly in Gmail for instance. If you want to check it directly after DNS entries, you can use some services around the Internet such as from [Global Cyber Alliance][dmarc-tool::gca] or [RedSift][dmarc-tool::redsift]. In other cases, email clients will show "DMARC: PASS" in ~1 day or so. Reference: [#1511][github-issue-1511] [docs-dkim]: ./dkim.md [github-issue-1511]: https://github.com/docker-mailserver/docker-mailserver/issues/1511 +[dmarc-howto]: https://github.com/internetstandards/toolbox-wiki/blob/master/DMARC-how-to.md +[dmarc-howto::configtags]: https://github.com/internetstandards/toolbox-wiki/blob/master/DMARC-how-to.md#overview-of-dmarc-configuration-tags +[dmarc-tool::gca]: https://dmarcguide.globalcyberalliance.org +[dmarc-tool::redsift]: https://ondmarc.redsift.com diff --git a/docs/content/config/best-practices/spf.md b/docs/content/config/best-practices/spf.md index dce77304..308c3fe0 100644 --- a/docs/content/config/best-practices/spf.md +++ b/docs/content/config/best-practices/spf.md @@ -18,13 +18,14 @@ To add a SPF record in your DNS, insert the following line in your DNS zone: ```txt ; MX record must be declared for SPF to work -domain.com. IN MX 1 mail.domain.com. +example.com. IN MX 1 mail.example.com. ; SPF record -domain.com. IN TXT "v=spf1 mx ~all" +example.com. IN TXT "v=spf1 mx ~all" ``` -This enables the _Softfail_ mode for SPF. You could first add this SPF record with a very low TTL. +This enables the _Softfail_ mode for SPF. You could first add this SPF record with a very low TTL. + _SoftFail_ is a good setting for getting started and testing, as it lets all email through, with spams tagged as such in the mailbox. After verification, you _might_ want to change your SPF record to `v=spf1 mx -all` so as to enforce the _HardFail_ policy. See http://www.open-spf.org/SPF_Record_Syntax for more details about SPF policies. @@ -37,7 +38,7 @@ For whitelisting a IP Address from the SPF test, you can create a config file (s **Example:** -Create and edit a `policyd-spf.conf` file here `//config/postfix-policyd-spf.conf`: +Create and edit a `policyd-spf.conf` file at `docker-data/dms/config/postfix-policyd-spf.conf`: ```conf debugLevel = 1 @@ -47,12 +48,12 @@ skip_addresses = 127.0.0.0/8,::ffff:127.0.0.0/104,::1 # Preferably use IP-Addresses for whitelist lookups: Whitelist = 192.168.0.0/31,192.168.1.0/30 -# Domain_Whitelist = mx1.mybackupmx.com,mx2.mybackupmx.com +# Domain_Whitelist = mx1.not-example.com,mx2.not-example.com ``` Then add this line to `docker-compose.yml`: ```yaml volumes: - - ./config/postfix-policyd-spf.conf:/etc/postfix-policyd-spf-python/policyd-spf.conf + - ./docker-data/dms/config/postfix-policyd-spf.conf:/etc/postfix-policyd-spf-python/policyd-spf.conf ``` diff --git a/docs/content/config/environment.md b/docs/content/config/environment.md index de3b9959..7b380d65 100644 --- a/docs/content/config/environment.md +++ b/docs/content/config/environment.md @@ -10,8 +10,8 @@ title: Environment Variables ##### OVERRIDE_HOSTNAME -- empty => uses the `hostname` command to get the mail server's canonical hostname. -- => Specify a fully-qualified domainname to serve mail for. This is used for many of the config features so if you can't set your hostname (e.g. you're in a container platform that doesn't let you) specify it in this environment variable. It will take priority over your docker-compose.yml's `hostname:` and `domainname:` values. +- **empty** => uses the `hostname` command to get canonical hostname for `docker-mailserver` to use. +- => Specify a fully-qualified domainname to serve mail for. This is used for many of the config features so if you can't set your hostname (_eg: you're in a container platform that doesn't let you_) specify it via this environment variable. It will take priority over `docker run` options: `--hostname` and `--domainname`, or `docker-compose.yml` config equivalents: `hostname:` and `domainname:`. ##### DMS_DEBUG @@ -30,7 +30,6 @@ Here you can adjust the [log-level for Supervisor](http://supervisord.org/loggin The log-level will show everything in its class and above. - ##### ONE_DIR - 0 => state in default directories. @@ -100,15 +99,19 @@ FAIL2BAN_BLOCKTYPE=drop ##### SSL_TYPE -- **empty** => SSL disabled. -- letsencrypt => Enables Let's Encrypt certificates. -- custom => Enables custom certificates. -- manual => Let you manually specify locations of your SSL certificates for non-standard cases - - Requires: `SSL_CERT_PATH` and `SSL_KEY_PATH` ENV vars to be set to the location of the files within the container. - - Optional: `SSL_ALT_CERT_PATH` and `SSL_ALT_KEY_PATH` allow providing a 2nd certificate as a fallback for dual (aka hybrid) certificate support. Useful for ECDSA with an RSA fallback. Presently only `manual` mode supports this feature. -- self-signed => Enables self-signed certificates. +In the majority of cases, you want `letsencrypt` or `manual`. -Please read [the SSL page in the documentation](https://docker-mailserver.github.io/docker-mailserver/edge/config/security/ssl) for more information. +`self-signed` can be used for testing SSL until you provide a valid certificate, note that third-parties cannot trust `self-signed` certificates, do not use this type in production. `custom` is a temporary workaround that is not officially supported. + +- **empty** => SSL disabled. +- letsencrypt => Support for using certificates with _Let's Encrypt_ provisioners. (Docs: [_Let's Encrypt_ Setup][docs-tls-letsencrypt]) +- manual => Provide your own certificate via separate key and cert files. (Docs: [Bring Your Own Certificates][docs-tls-manual]) + - Requires: `SSL_CERT_PATH` and `SSL_KEY_PATH` ENV vars to be set to the location of the files within the container. + - Optional: `SSL_ALT_CERT_PATH` and `SSL_ALT_KEY_PATH` allow providing a 2nd certificate as a fallback for dual (aka hybrid) certificate support. Useful for ECDSA with an RSA fallback. _Presently only `manual` mode supports this feature_. +- custom => Provide your own certificate as a single file containing both the private key and full certificate chain. (Docs: `None`) +- self-signed => Provide your own self-signed certificate files. Expects a self-signed CA cert for verification. **Use only for local testing of your setup**. (Docs: [Self-Signed Certificates][docs-tls-selfsigned]) + +Please read [the SSL page in the documentation][docs-tls] for more information. ##### TLS_LEVEL @@ -125,7 +128,7 @@ Configures the handling of creating mails with forged sender addresses. ##### ENABLE_SRS -Enables the Sender Rewriting Scheme. SRS is needed if your mail server acts as forwarder. See [postsrsd](https://github.com/roehling/postsrsd/blob/master/README.md#sender-rewriting-scheme-crash-course) for further explanation. +Enables the Sender Rewriting Scheme. SRS is needed if `docker-mailserver` acts as forwarder. See [postsrsd](https://github.com/roehling/postsrsd/blob/master/README.md#sender-rewriting-scheme-crash-course) for further explanation. - **0** => Disabled - 1 => Enabled @@ -170,7 +173,7 @@ Set the mailbox size limit for all users. If set to zero, the size will be unlim - **1** => Dovecot quota is enabled - 0 => Dovecot quota is disabled -See [mailbox quota](https://docker-mailserver.github.io/docker-mailserver/edge/config/user-management/accounts/#notes). +See [mailbox quota][docs-accounts]. ##### POSTFIX\_MESSAGE\_SIZE\_LIMIT @@ -183,14 +186,9 @@ Set the message size limit for all users. If set to zero, the size will be unlim - **empty** => Managesieve service disabled - 1 => Enables Managesieve on port 4190 -##### OVERRIDE_HOSTNAME - -- **empty** => uses the `hostname` command to get the mail server's canonical hostname -- => Specify a fully-qualified domainname to serve mail for. This is used for many of the config features so if you can't set your hostname (e.g. you're in a container platform that doesn't let you) specify it in this environment variable. - ##### POSTMASTER_ADDRESS -- **empty** => postmaster@domain.com +- **empty** => postmaster@example.com - => Specify the postmaster address ##### ENABLE_UPDATE_CHECK @@ -306,8 +304,8 @@ Defines the interval in which the mail log is being rotated. - monthly => Rotate monthly. Note that only the log inside the container is affected. -The full log output is still available via `docker logs mail` (or your respective container name). -If you want to control logrotation for the docker generated logfile see: [Docker Logging Drivers](https://docs.docker.com/config/containers/logging/configure/). +The full log output is still available via `docker logs mailserver` (_or your respective container name_). +If you want to control logrotation for the docker generated logfile, see: [Docker Logging Drivers](https://docs.docker.com/config/containers/logging/configure/). Also note that by default the logs are lost when the container is recycled. To keep the logs, mount a volume. @@ -351,7 +349,13 @@ Note: this SpamAssassin setting needs `ENABLE_SPAMASSASSIN=1` - **6.31** => triggers spam evasive actions -Note: this SpamAssassin setting needs `ENABLE_SPAMASSASSIN=1`. By default, the mailserver is configured to quarantine spam emails. If emails are quarantined, they are compressed and stored in a location dependent on the ONE_DIR setting above. If `ONE_DIR=1` the location is /var/mail-state/lib-amavis/virusmails/. If `ONE_DIR=0` it is /var/lib/amavis/virusmails/. These paths are inside the docker container. To inhibit this behaviour and deliver spam emails, set this to a very high value e.g. 100.0. +!!! note "This SpamAssassin setting needs `ENABLE_SPAMASSASSIN=1`" + + By default, `docker-mailserver` is configured to quarantine spam emails. + + If emails are quarantined, they are compressed and stored in a location dependent on the `ONE_DIR` setting above. To inhibit this behaviour and deliver spam emails, set this to a very high value e.g. `100.0`. + + If `ONE_DIR=1` (default) the location is `/var/mail-state/lib-amavis/virusmails/`, or if `ONE_DIR=0`: `/var/lib/amavis/virusmails/`. These paths are inside the docker container. ##### SA_SPAM_SUBJECT @@ -410,9 +414,9 @@ Note: The defaults of your fetchmailrc file need to be at the top of the file. O ##### LDAP_SERVER_HOST -- **empty** => mail.domain.com -- => Specify the dns-name/ip-address where the ldap-server is listening, or an URI like `ldaps://mail.domain.com` -- NOTE: If you going to use the mailserver in combination with docker-compose you can set the service name here +- **empty** => mail.example.com +- => Specify the dns-name/ip-address where the ldap-server is listening, or an URI like `ldaps://mail.example.com` +- NOTE: If you going to use `docker-mailserver` in combination with `docker-compose.yml` you can set the service name here ##### LDAP_SEARCH_BASE @@ -682,7 +686,7 @@ you to replace both instead of just the envelope sender. ##### SRS_DOMAINNAME -- **empty** => Derived from OVERRIDE_HOSTNAME, DOMAINNAME, or the container's hostname +- **empty** => Derived from [`OVERRIDE_HOSTNAME`](#override_hostname), `$DOMAINNAME` (internal), or the container's hostname - Set this if auto-detection fails, isn't what you want, or you wish to have a separate container handle DSNs #### Default Relay Host @@ -717,3 +721,8 @@ you to replace both instead of just the envelope sender. - password for default relay user [docs-faq-onedir]: ../faq.md#what-is-the-mail-state-folder-for +[docs-tls]: ./config/security/ssl.md +[docs-tls-letsencrypt]: ./security/ssl.md#lets-encrypt-recommended +[docs-tls-manual]: ./security/ssl.md#bring-your-own-certificates +[docs-tls-selfsigned]: ./security/ssl.md#self-signed-certificates +[docs-accounts]: ./config/user-management/accounts.md#notes diff --git a/docs/content/config/security/fail2ban.md b/docs/content/config/security/fail2ban.md index 60f3feae..402024a9 100644 --- a/docs/content/config/security/fail2ban.md +++ b/docs/content/config/security/fail2ban.md @@ -8,13 +8,13 @@ Fail2Ban is installed automatically and bans IP addresses for 3 hours after 3 fa ## Configuration files -If you want to change this, you can easily edit [`config/fail2ban-jail.cf`][github-file-f2bjail]. +If you want to change this, you can easily edit our github example file: [`config/fail2ban-jail.cf`][github-file-f2bjail]. -You can do the same with the values from `fail2ban.conf`, e.g `dbpurgeage`. In that case you need to edit [`config/fail2ban-fail2ban.cf`][github-file-f2bconfig]. +You can do the same with the values from `fail2ban.conf`, e.g `dbpurgeage`. In that case you need to edit: [`config/fail2ban-fail2ban.cf`][github-file-f2bconfig]. -The configuration files need to be located at the root of the `/tmp/docker-mailserver/` volume bind. +The configuration files need to be located at the root of the `/tmp/docker-mailserver/` volume bind (usually `./docker-data/dms/config/:/tmp/docker-mailserver/`). -This following configuration files from `/tmp/docker-mailserver/` will be copied at boot time. +This following configuration files from `/tmp/docker-mailserver/` will be copied during container startup. - `fail2ban-jail.cf` -> `/etc/fail2ban/jail.d/user-jail.local` - `fail2ban-fail2ban.cf` -> `/etc/fail2ban/fail2ban.local` @@ -25,13 +25,13 @@ Example configuration volume bind: ```yaml volumes: - - ./config/:/tmp/docker-mailserver/ + - ./docker-data/dms/config/:/tmp/docker-mailserver/ ``` !!! attention - The mail container must be launched with the `NET_ADMIN` capability in order to be able to install the iptable rules that actually ban IP addresses. + `docker-mailserver` must be launched with the `NET_ADMIN` capability in order to be able to install the iptable rules that actually ban IP addresses. - Thus either include `--cap-add=NET_ADMIN` in the docker run commandline or the equivalent `docker-compose.yml`: + Thus either include `--cap-add=NET_ADMIN` in the `docker run` command, or the equivalent in `docker-compose.yml`: ```yaml cap_add: diff --git a/docs/content/config/security/ssl.md b/docs/content/config/security/ssl.md index ef2e5d67..bfa3175a 100644 --- a/docs/content/config/security/ssl.md +++ b/docs/content/config/security/ssl.md @@ -2,12 +2,12 @@ title: 'Security | TLS (aka SSL)' --- -There are multiple options to enable SSL: +There are multiple options to enable SSL (via [`SSL_TYPE`][docs-env::ssl-type]): - Using [letsencrypt](#lets-encrypt-recommended) (recommended) - Using [Caddy](#caddy) - Using [Traefik](#traefik) -- Using [self-signed certificates](#self-signed-certificates-testing-only) with the provided tool +- Using [self-signed certificates](#self-signed-certificates-testing-only) - Using [your own certificates](#custom-certificate-files) After installation, you can test your setup with: @@ -17,7 +17,7 @@ After installation, you can test your setup with: ## Let's Encrypt (Recommended) -To enable Let's Encrypt on your mail server, you have to: +To enable Let's Encrypt for `docker-mailserver`, you have to: - Get your certificate using [letsencrypt client](https://github.com/letsencrypt/letsencrypt) - Add an environment variable `SSL_TYPE` with value `letsencrypt` (see [`docker-compose.yml`][github-file-compose]) @@ -28,8 +28,8 @@ To enable Let's Encrypt on your mail server, you have to: services: mailserver: hostname: mail - domainname: myserver.tld - fqdn: mail.myserver.tld + domainname: example.com + fqdn: mail.example.com ``` You don't have anything else to do. Enjoy. @@ -43,7 +43,7 @@ You don't have anything else to do. Enjoy. cd /home/ubuntu/docker/letsencrypt ``` -2. Now get the certificate (modify `mail.myserver.tld`) and following the certbot instructions. +2. Now get the certificate (modify `mail.example.com`) and following the certbot instructions. 3. This will need access to port 80 from the internet, adjust your firewall if needed: @@ -52,7 +52,7 @@ You don't have anything else to do. Enjoy. -v $PWD/log/:/var/log/letsencrypt/ \ -v $PWD/etc/:/etc/letsencrypt/ \ -p 80:80 \ - certbot/certbot certonly --standalone -d mail.myserver.tld + certbot/certbot certonly --standalone -d mail.example.com ``` 4. You can now mount `/home/ubuntu/docker/letsencrypt/etc/` in `/etc/letsencrypt` of `docker-mailserver`. @@ -70,7 +70,7 @@ You don't have anything else to do. Enjoy. ### Example using Docker, `nginx-proxy` and `letsencrypt-nginx-proxy-companion` -If you are running a web server already, it is non-trivial to generate a Let's Encrypt certificate for your mail server using `certbot`, because port 80 is already occupied. In the following example, we show how `docker-mailserver` can be run alongside the docker containers `nginx-proxy` and `letsencrypt-nginx-proxy-companion`. +If you are running a web server already, it is non-trivial to generate a Let's Encrypt certificate for your `docker-mailserver` using `certbot`, because port 80 is already occupied. In the following example, we show how `docker-mailserver` can be run alongside the docker containers `nginx-proxy` and `letsencrypt-nginx-proxy-companion`. There are several ways to start `nginx-proxy` and `letsencrypt-nginx-proxy-companion`. Any method should be suitable here. @@ -103,32 +103,30 @@ docker run --detach \ Start the rest of your web server containers as usual. -Start another container for your `mail.myserver.tld`. This will generate a Let's Encrypt certificate for your domain, which can be used by `docker-mailserver`. It will also run a web server on port 80 at that address: +Start another container for your `mail.example.com`. This will generate a Let's Encrypt certificate for your domain, which can be used by `docker-mailserver`. It will also run a web server on port 80 at that address: ```sh docker run -d \ --name webmail \ - -e "VIRTUAL_HOST=mail.myserver.tld" \ - -e "LETSENCRYPT_HOST=mail.myserver.tld" \ - -e "LETSENCRYPT_EMAIL=foo@bar.com" \ + -e "VIRTUAL_HOST=mail.example.com" \ + -e "LETSENCRYPT_HOST=mail.example.com" \ + -e "LETSENCRYPT_EMAIL=admin@example.com" \ library/nginx ``` You may want to add `-e LETSENCRYPT_TEST=true` to the above while testing to avoid the Let's Encrypt certificate generation rate limits. -Finally, start the mailserver with the `docker-compose.yml`. Make sure your mount path to the letsencrypt certificates is correct. - -Inside your `/path/to/mailserver/docker-compose.yml` (for the mailserver from this repo) make sure volumes look like below example: +Make sure your mount path to the letsencrypt certificates is correct. Edit your `/path/to/mailserver/docker-compose.yml` for the `mailserver` service to have volumes added like the example below: ```yaml volumes: - - maildata:/var/mail - - mailstate:/var/mail-state - - ./config/:/tmp/docker-mailserver/ + - ./docker-data/dms/mail-data/:/var/mail/ + - ./docker-data/dms/mail-state/:/var/mail-state/ + - ./docker-data/dms/config/:/tmp/docker-mailserver/ - /server/letsencrypt/etc:/etc/letsencrypt/live ``` -Then: `/path/to/mailserver/docker-compose up -d mail` +Then from the `docker-compose.yml` directory, run: `docker-compose up -d mailserver`. ### Example using Docker, `nginx-proxy` and `letsencrypt-nginx-proxy-companion` with `docker-compose` @@ -186,7 +184,7 @@ The following `docker-compose.yml` is the basic setup you need for using `letsen name: nginx-proxy ``` -The second part of the setup is the actual mail container. So, in another folder, create another `docker-compose.yml` with the following content (Removed all ENV variables for this example): +The second part of the setup is the `docker-mailserver` container. So, in another folder, create another `docker-compose.yml` with the following content (Removed all ENV variables for this example): ???+ example "Example Code" @@ -195,9 +193,9 @@ The second part of the setup is the actual mail container. So, in another folder services: mailserver: image: docker.io/mailserver/docker-mailserver:latest + container_name: mailserver hostname: mail domainname: example.com - container_name: mailserver ports: - "25:25" - "143:143" @@ -205,10 +203,10 @@ The second part of the setup is the actual mail container. So, in another folder - "587:587" - "993:993" volumes: - - ./mail:/var/mail - - ./mail-state:/var/mail-state - - ./config/:/tmp/docker-mailserver/ - - /mnt/data/nginx/certs/:/etc/letsencrypt/live/:ro + - ./docker-data/dms/mail-data/:/var/mail/ + - ./docker-data/dms/mail-state/:/var/mail-state/ + - ./docker-data/dms/config/:/tmp/docker-mailserver/ + - ./docker-data/nginx-proxy/certs/:/etc/letsencrypt/live/:ro cap_add: - NET_ADMIN - SYS_PTRACE @@ -231,23 +229,25 @@ The second part of the setup is the actual mail container. So, in another folder name: nginx-proxy ``` -The mail container needs to have the letsencrypt certificate folder mounted as a volume. No further changes are needed. The second container is a dummy-sidecar we need, because the mail-container do not expose any web-ports. Set your ENV variables as you need. (`VIRTUAL_HOST` and `LETSENCRYPT_HOST` are mandandory, see documentation) +`docker-mailserver` needs to have the letsencrypt certificate folder mounted as a volume. No further changes are needed. The second container is a dummy-sidecar we need, because the mail-container do not expose any web-ports. Set your ENV variables as you need. (`VIRTUAL_HOST` and `LETSENCRYPT_HOST` are mandandory, see documentation) ### Example using the Let's Encrypt Certificates on a Synology NAS Version 6.2 and later of the Synology NAS DSM OS now come with an interface to generate and renew letencrypt certificates. Navigation into your DSM control panel and go to Security, then click on the tab Certificate to generate and manage letsencrypt certificates. -Amongst other things, you can use these to secure your mail server. DSM locates the generated certificates in a folder below `/usr/syno/etc/certificate/_archive/`. +Amongst other things, you can use these to secure your mail-server. DSM locates the generated certificates in a folder below `/usr/syno/etc/certificate/_archive/`. Navigate to that folder and note the 6 character random folder name of the certificate you'd like to use. Then, add the following to your `docker-compose.yml` declaration file: ```yaml +# Note: If you have an existing setup that was working pre docker-mailserver v10.2, +# '/tmp/dms/custom-certs' below has replaced the previous '/tmp/ssl' container path. volumes: - - /usr/syno/etc/certificate/_archive//:/tmp/ssl + - /usr/syno/etc/certificate/_archive//:/tmp/dms/custom-certs/ environment: - SSL_TYPE=manual - - SSL_CERT_PATH=/tmp/ssl/fullchain.pem - - SSL_KEY_PATH=/tmp/ssl/privkey.pem + - SSL_CERT_PATH=/tmp/dms/custom-certs/fullchain.pem + - SSL_KEY_PATH=/tmp/dms/custom-certs/privkey.pem ``` DSM-generated letsencrypt certificates get auto-renewed every three months. @@ -257,8 +257,8 @@ DSM-generated letsencrypt certificates get auto-renewed every three months. If you are using Caddy to renew your certificates, please note that only RSA certificates work. Read [#1440][github-issue-1440] for details. In short for Caddy v1 the `Caddyfile` should look something like: ```caddyfile -https://mail.domain.com { - tls yourcurrentemail@gmail.com { +https://mail.example.com { + tls admin@example.com { key_type rsa2048 } } @@ -272,7 +272,7 @@ For Caddy v2 you can specify the `key_type` in your server's global settings, wh admin localhost:2019 http_port 80 https_port 443 - default_sni mywebserver.com + default_sni example.com key_type rsa4096 } ``` @@ -295,7 +295,7 @@ If you are instead using a json config for Caddy v2, you can set it in your site "match": [ { "host": [ - "mail.domain.com", + "mail.example.com", ] } ], @@ -325,17 +325,17 @@ If you are instead using a json config for Caddy v2, you can set it in your site "policies": [ { "subjects": [ - "mail.domain.com", + "mail.example.com", ], "key_type": "rsa2048", "issuer": { - "email": "email@email.com", + "email": "admin@example.com", "module": "acme" } }, { "issuer": { - "email": "email@email.com", + "email": "admin@example.com", "module": "acme" } } @@ -350,8 +350,8 @@ The generated certificates can be mounted: ```yaml volumes: - - ${CADDY_DATA_DIR}/certificates/acme-v02.api.letsencrypt.org-directory/mail.domain.com/mail.domain.com.crt:/etc/letsencrypt/live/mail.domain.com/fullchain.pem - - ${CADDY_DATA_DIR}/certificates/acme-v02.api.letsencrypt.org-directory/mail.domain.com/mail.domain.com.key:/etc/letsencrypt/live/mail.domain.com/privkey.pem + - ${CADDY_DATA_DIR}/certificates/acme-v02.api.letsencrypt.org-directory/mail.example.com/mail.example.com.crt:/etc/letsencrypt/live/mail.example.com/fullchain.pem + - ${CADDY_DATA_DIR}/certificates/acme-v02.api.letsencrypt.org-directory/mail.example.com/mail.example.com.key:/etc/letsencrypt/live/mail.example.com/privkey.pem ``` EC certificates fail in the TLS handshake: @@ -367,7 +367,7 @@ No client certificate CA names sent [Traefik][traefik::github] is an open-source application proxy using the [ACME protocol][ietf::rfc::acme]. [Traefik][traefik::github] can request certificates for domains and subdomains, and it will take care of renewals, challenge negotiations, etc. We strongly recommend to use [Traefik][traefik::github]'s major version 2. -[Traefik][traefik::github]'s storage format is natively supported if the `acme.json` store is mounted into the container at `/etc/letsencrypt/acme.json`. The file is also monitored for changes and will trigger a reload of the mail services. Wild card certificates issued for `*.domain.tld` are supported. You will then want to use `#!bash SSL_DOMAIN=domain.tld`. Lookup of the certificate domain happens in the following order: +[Traefik][traefik::github]'s storage format is natively supported if the `acme.json` store is mounted into the container at `/etc/letsencrypt/acme.json`. The file is also monitored for changes and will trigger a reload of the mail services (Postfix and Dovecot). Wild card certificates issued for `*.example.com` are supported. You will then want to use `#!bash SSL_DOMAIN=example.com`. Lookup of the certificate domain happens in the following order: 1. `#!bash ${SSL_DOMAIN}` 2. `#!bash ${HOSTNAME}` @@ -378,24 +378,25 @@ This setup only comes with one caveat: The domain has to be configured on anothe ???+ example "Example Code" Here is an example setup for [`docker-compose`](https://docs.docker.com/compose/): - ``` YAML + ```yaml version: '3.8' services: mailserver: image: docker.io/mailserver/docker-mailserver:latest + container_name: mailserver hostname: mail domainname: example.com - container_name: mailserver volumes: - - /traefik/acme.json:/etc/letsencrypt/acme.json:ro + - ./docker-data/traefik/acme.json:/etc/letsencrypt/acme.json:ro environment: SSL_TYPE: letsencrypt - SSL_DOMAIN: mail.example.com" + SSL_DOMAIN: mail.example.com # for a wildcard certificate, use # SSL_DOMAIN: example.com - traefik: - image: docker.io/traefik:v2.5 + reverse-proxy: + image: docker.io/traefik:latest #v2.5 + container_name: docker-traefik ports: - "80:80" - "443:443" @@ -406,17 +407,17 @@ This setup only comes with one caveat: The domain has to be configured on anothe - --entrypoints.http.http.redirections.entryPoint.scheme=https - --entrypoints.https.address=:443 - --entrypoints.https.http.tls.certResolver=letsencrypt - - --certificatesresolvers.letsencrypt.acme.email=admin@domain.tld + - --certificatesresolvers.letsencrypt.acme.email=admin@example.com - --certificatesresolvers.letsencrypt.acme.storage=/acme.json - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http volumes: - - /traefik/acme.json:/acme.json + - ./docker-data/traefik/acme.json:/acme.json - /var/run/docker.sock:/var/run/docker.sock:ro whoami: image: docker.io/traefik/whoami:latest labels: - - "traefik.http.routers.whoami.rule=Host(`mail.domain.tld`)" + - "traefik.http.routers.whoami.rule=Host(`mail.example.com`)" ``` ## Self-Signed Certificates @@ -425,28 +426,23 @@ This setup only comes with one caveat: The domain has to be configured on anothe Use self-signed certificates only for testing purposes! -This feature requires you to provide the following files into your [`config/ssl/` directory][docs-optional-config] (internal location: `/tmp/docker-mailserver/ssl/`): +This feature requires you to provide the following files into your [`docker-data/dms/config/ssl/` directory][docs-optional-config] (_internal location: `/tmp/docker-mailserver/ssl/`_): -- `${HOSTNAME}-key.pem` -- `${HOSTNAME}-cert.pem` +- `-key.pem` +- `-cert.pem` - `demoCA/cacert.pem` -Where `${HOSTNAME}` is the mailserver [FQDN](https://en.wikipedia.org/wiki/Fully_qualified_domain_name) (`hostname`(_mail_) + `domainname`(_example.com_), eg: `mail.example.com`). +Where `` is the [FQDN](https://en.wikipedia.org/wiki/Fully_qualified_domain_name) assigned to `docker-mailserver` (_eg: `mail.example.com` (FQDN) => `mail` (hostname) + `example.com` (domainname)_) via `docker run` command or `docker-compose.yml` config. -To use the certificate: +Add `SSL_TYPE=self-signed` to your `docker-mailserver` environment variables. Postfix and Dovecot will be configured to use the provided certificate (_`.pem` files above_) during container startup. -- Add `SSL_TYPE=self-signed` to your container environment variables. -- If a matching certificate (files listed above) is found in `config/ssl`, it will be automatically setup in postfix and dovecot. You just have to place them in `config/ssl` folder. - -#### Generating a self-signed certificate +### Generating a self-signed certificate !!! note - Since v10, support in `setup.sh` for generating a self-signed SSL certificate internally was removed. - - It is now similar to `SSL_TYPE=manual` (_except `manual` does not support verification for a custom CA_), but does not require additional ENV vars for providing the location of cert files. + Since `docker-mailserver` v10, support in `setup.sh` for generating a _self-signed SSL certificate_ internally was removed. -One way to generate self-signed certificates is with [Smallstep's `step` CLI](https://smallstep.com/docs/step-cli). This is exactly what [`docker-mailserver` does for creating test certificates](https://github.com/docker-mailserver/docker-mailserver/tree/master/test/test-files/ssl/example.test). +One way to generate self-signed certificates is with [Smallstep's `step` CLI](https://smallstep.com/docs/step-cli). This is exactly what [`docker-mailserver` does for creating test certificates][github-file::tls-readme]. For example with the FQDN `mail.example.test`, you can generate the required files by running: @@ -475,42 +471,49 @@ step certificate create "Smallstep Leaf" mail.example.test-cert.pem mail.example --kty RSA --size 2048 ``` -If you'd rather not install the CLI tool locally to run the `step` commands above; you can save the script above to a file such as `generate-certs.sh` (_and make it executable `chmod +x generate-certs.sh`_) in a directory that you want the certs to be placed, then run that script with docker: +If you'd rather not install the CLI tool locally to run the `step` commands above; you can save the script above to a file such as `generate-certs.sh` (_and make it executable `chmod +x generate-certs.sh`_) in a directory that you want the certs to be placed (eg: `docker-data/dms/custom-certs/`), then use docker to run that script in a container: ```sh -# --user to keep ownership of the files to your user and group ID +# '--user' is to keep ownership of the files written to +# the local volume to use your systems User and Group ID values. docker run --rm -it \ --user "$(id -u):$(id -g)" \ - --volume "${PWD}:/tmp" \ - --workdir "/tmp" \ - --entrypoint "/tmp/generate-certs.sh" \ + --volume "${PWD}/docker-data/dms/custom-certs/:/tmp/step-ca/" \ + --workdir "/tmp/step-ca/" \ + --entrypoint "/tmp/step-ca/generate-certs.sh" \ smallstep/step-ca ``` -## Custom Certificate Files +## Bring Your Own Certificates You can also provide your own certificate files. Add these entries to your `docker-compose.yml`: ```yaml volumes: - - /etc/ssl:/tmp/ssl:ro + - ./docker-data/dms/custom-certs/:/tmp/dms/custom-certs/:ro environment: - SSL_TYPE=manual - - SSL_CERT_PATH=/tmp/ssl/cert/public.crt - - SSL_KEY_PATH=/tmp/ssl/private/private.key + # Values should match the file paths inside the container: + - SSL_CERT_PATH=/tmp/dms/custom-certs/public.crt + - SSL_KEY_PATH=/tmp/dms/custom-certs/private.key ``` -This will mount the path where your ssl certificates reside as read-only under `/tmp/ssl`. Then all you have to do is to specify the location of your private key and the certificate. +This will mount the path where your certificate files reside locally into the _read-only_ container folder: `/tmp/dms/custom-certs`. + +The local and internal paths may be whatever you prefer, so long as both `SSL_CERT_PATH` and `SSL_KEY_PATH` point to the correct internal file paths. The certificate files may also be named to your preference, but should be PEM encoded. + +`SSL_ALT_CERT_PATH` and `SSL_ALT_KEY_PATH` are additional ENV vars to support a 2nd certificate as a fallback. Commonly known as hybrid or dual certificate support. This is useful for using a modern ECDSA as your primary certificate, and RSA as your fallback for older connections. They work in the same manner as the non-`ALT` versions. !!! info - You may have to restart your mailserver once the certificates change. + + You may have to restart `docker-mailserver` once the certificates change. ## Testing a Certificate is Valid - From your host: ```sh - docker exec mail openssl s_client \ + docker exec mailserver openssl s_client \ -connect 0.0.0.0:25 \ -starttls smtp \ -CApath /etc/ssl/certs/ @@ -519,7 +522,7 @@ This will mount the path where your ssl certificates reside as read-only under ` - Or: ```sh - docker exec mail openssl s_client \ + docker exec mailserver openssl s_client \ -connect 0.0.0.0:143 \ -starttls imap \ -CApath /etc/ssl/certs/ @@ -530,7 +533,7 @@ And you should see the certificate chain, the server certificate and: `Verify re In addition, to verify certificate dates: ```sh -docker exec mail openssl s_client \ +docker exec mailserver openssl s_client \ -connect 0.0.0.0:25 \ -starttls smtp \ -CApath /etc/ssl/certs/ \ @@ -543,7 +546,7 @@ docker exec mail openssl s_client \ Not recommended for purposes other than testing. -Add this to `config/dovecot.cf`: +Add this to `docker-data/dms/config/dovecot.cf`: ```cf ssl = yes @@ -560,13 +563,23 @@ These options in conjunction mean: If you have another source for SSL/TLS certificates you can import them into the server via an external script. The external script can be found here: [external certificate import script][hanscees-renewcerts]. +!!! attention "Only compatible with `docker-mailserver` releases < `v10.2`" + + The script expects `/etc/postfix/ssl/cert` and `/etc/postfix/ssl/key` files to be configured paths for both Postfix and Dovecot to use. + + Since the `docker-mailserver` 10.2 release, certificate files have moved to `/etc/dms/tls/`, and the file name may differ depending on provisioning method. + + This third-party script also has `fullchain.pem` and `privkey.pem` as hard-coded, thus is incompatible with other filenames. + + Additionally it has never supported handling `ALT` fallback certificates (for supporting dual/hybrid, RSA + ECDSA). + The steps to follow are these: -1. Transport the new certificates to `./config/ssl` (`/tmp/ssl` in the container) +1. Transfer the new certificates to `./docker-data/dms/custom-certs/` (volume mounted to: `/tmp/ssl/`) 2. You should provide `fullchain.key` and `privkey.pem` -3. Place the script in `./config/` (or `/tmp/docker-mailserver/` inside the container) +3. Place the script in `./docker-data/dms/config/` (volume mounted to: `/tmp/docker-mailserver/`) 4. Make the script executable (`chmod +x tomav-renew-certs.sh`) -5. Run the script: `docker exec mail /tmp/docker-mailserver/tomav-renew-certs.sh` +5. Run the script: `docker exec mailserver /tmp/docker-mailserver/tomav-renew-certs.sh` If an error occurs the script will inform you. If not you will see both postfix and dovecot restart. @@ -574,23 +587,23 @@ After the certificates have been loaded you can check the certificate: ```sh openssl s_client \ - -servername mail.mydomain.net \ + -servername mail.example.com \ -connect 192.168.0.72:465 \ 2>/dev/null | openssl x509 # or openssl s_client \ - -servername mail.mydomain.net \ - -connect mail.mydomain.net:465 \ + -servername mail.example.com \ + -connect mail.example.com:465 \ 2>/dev/null | openssl x509 ``` Or you can check how long the new certificate is valid with commands like: ```sh -export SITE_URL="mail.mydomain.net" -export SITE_IP_URL="192.168.0.72" # can also be `mail.mydomain.net` +export SITE_URL="mail.example.com" +export SITE_IP_URL="192.168.0.72" # can also use `mail.example.com` export SITE_SSL_PORT="993" # imap port dovecot ##works: check if certificate will expire in two weeks @@ -603,7 +616,7 @@ certcheck_2weeks=`openssl s_client -connect ${SITE_IP_URL}:${SITE_SSL_PORT} \ -servername ${SITE_URL} 2> /dev/null | openssl x509 -noout -checkend 1209600` #################################### -#notes: output can be +#notes: output could be either: #Certificate will not expire #Certificate will expire #################### @@ -611,7 +624,7 @@ certcheck_2weeks=`openssl s_client -connect ${SITE_IP_URL}:${SITE_SSL_PORT} \ What does the script that imports the certificates do: -1. Check if there are new certs in the `/tmp/ssl` folder. +1. Check if there are new certs in the internal container folder: `/tmp/ssl`. 2. Check with the ssl cert fingerprint if they differ from the current certificates. 3. If so it will copy the certs to the right places. 4. And restart postfix and dovecot. @@ -619,14 +632,16 @@ What does the script that imports the certificates do: You can of course run the script by cron once a week or something. In that way you could automate cert renewal. If you do so it is probably wise to run an automated check on certificate expiry as well. Such a check could look something like this: ```sh +# This script is run inside docker-mailserver via 'docker exec ...', using the 'mail' command to send alerts. ## code below will alert if certificate expires in less than two weeks -## please adjust varables! -## make sure the mail -s command works! Test! +## please adjust varables! +## make sure the 'mail -s' command works! Test! -export SITE_URL="mail.mydomain.net" -export SITE_IP_URL="192.168.2.72" # can also be `mail.mydomain.net` +export SITE_URL="mail.example.com" +export SITE_IP_URL="192.168.2.72" # can also use `mail.example.com` export SITE_SSL_PORT="993" # imap port dovecot -export ALERT_EMAIL_ADDR="bill@gates321boom.com" +# Below can be from a different domain; like your personal email, not handled by this docker-mailserver: +export ALERT_EMAIL_ADDR="external-account@gmail.com" certcheck_2weeks=`openssl s_client -connect ${SITE_IP_URL}:${SITE_SSL_PORT} \ -servername ${SITE_URL} 2> /dev/null | openssl x509 -noout -checkend 1209600` @@ -640,7 +655,7 @@ certcheck_2weeks=`openssl s_client -connect ${SITE_IP_URL}:${SITE_SSL_PORT} \ #echo "certcheck 2 weeks gives $certcheck_2weeks" ##automated check you might run by cron or something -## does tls/ssl certificate expire within two weeks? +## does the certificate expire within two weeks? if [ "$certcheck_2weeks" = "Certificate will not expire" ]; then echo "all is well, certwatch 2 weeks says $certcheck_2weeks" @@ -658,9 +673,11 @@ By default `docker-mailserver` uses [`ffdhe4096`][ffdhe4096-src] from [IETF RFC Despite this, if you must use non-standard DH parameters or you would like to swap `ffdhe4096` for a different group (eg `ffdhe2048`); Add your own PEM encoded DH params file via a volume to `/tmp/docker-mailserver/dhparams.pem`. This will replace DH params for both Dovecot and Postfix services during container startup. +[docs-env::ssl-type]: ../environment.md#ssl_type [docs-optional-config]: ../advanced/optional-config.md [github-file-compose]: https://github.com/docker-mailserver/docker-mailserver/blob/master/docker-compose.yml +[github-file::tls-readme]: https://github.com/docker-mailserver/docker-mailserver/blob/3b8059f2daca80d967635e04d8d81e9abb755a4d/test/test-files/ssl/example.test/README.md [github-issue-1440]: https://github.com/docker-mailserver/docker-mailserver/issues/1440 [hanscees-renewcerts]: https://github.com/hanscees/dockerscripts/blob/master/scripts/tomav-renew-certs diff --git a/docs/content/config/security/understanding-the-ports.md b/docs/content/config/security/understanding-the-ports.md index 6e2b8bd5..f60c356e 100644 --- a/docs/content/config/security/understanding-the-ports.md +++ b/docs/content/config/security/understanding-the-ports.md @@ -82,7 +82,7 @@ Due to these security concerns, [RFC 8314 (Section 4.1)][rfc-8314-s41] encourage Communication is always encrypted, avoiding the above mentioned issues with Explicit TLS. -You may know of these ports as **SMTPS, POP3S, IMAPS**, which indicate the protocol in combination with a TLS connection. However, Explicit TLS ports provide the same benefit when `STARTTLS` is successfully negotiated; Implicit TLS better communicates the improved security to all three protocols (SMTP/POP3/IMAP over Implicit TLS). +You may know of these ports as **SMTPS, POP3S, IMAPS**, which indicate the protocol in combination with a TLS connection. However, Explicit TLS ports provide the same benefit when `STARTTLS` is successfully negotiated; Implicit TLS better communicates the improved security to all three protocols (SMTP/POP3/IMAP over Implicit TLS). Additionally, referring to port 465 as *SMTPS* would be incorrect, as it is a submissions port requiring authentication to proceed via *ESMTP*, whereas ESMTPS has a different meaning(STARTTLS supported). Port 25 may lack Implicit TLS, but can be configured to be more secure between trusted parties via MTA-STS, STARTTLS Policy List, DNSSEC and DANE. @@ -94,9 +94,9 @@ Additionally, referring to port 465 as *SMTPS* would be incorrect, as it is a su !!! todo A related section or page on ciphers used may be useful, although less important for users to be concerned about. -### TLS connections on mail servers, compared to web browsers +### TLS connections for a Mail-Server, compared to web browsers -Unlike with HTTP where a web browser client communicates directly with the server providing a website, a secure TLS connection as discussed below is not the equivalent safety that HTTPS provides when the transit of email (receiving or sending) is sent through third-parties, as the secure connection is only between two machines, any additional machines (MTAs) between the MUA and the MDA depends on them establishing secure connections between one another successfully. +Unlike with HTTP where a web browser client communicates directly with the server providing a website, a secure TLS connection as discussed below is not the equivalent safety that HTTPS provides when the transit of email (receiving or sending) is sent through third-parties, as the secure connection is only between two machines, any additional machines (MTAs) between the MUA and the MDA depends on them establishing secure connections between one another successfully. Other machines that facilitate a connection that generally aren't taken into account can exist between a client and server, such as those where your connection passes through your ISP provider are capable of compromising a cleartext connection through interception. diff --git a/docs/content/config/setup.sh.md b/docs/content/config/setup.sh.md index d457ccdd..5e71dd4c 100644 --- a/docs/content/config/setup.sh.md +++ b/docs/content/config/setup.sh.md @@ -4,7 +4,7 @@ hide: - toc --- -[`setup.sh`][github-file-setupsh] is an administration script that helps with the most common tasks, including initial configuration. It is intended to be used from the host machine, _not_ from within your running container. +[`setup.sh`][github-file-setupsh] is an administration script that helps with the most common tasks, including initial configuration. It is intended to be run from the host machine, _not_ from inside your running container. The latest version of the script is included in the `docker-mailserver` repository. You may retrieve it at any time by running this command in your console: @@ -13,9 +13,9 @@ wget https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/maste chmod a+x ./setup.sh ``` -!!! warning "`setup.sh` for Docker Mailserver version `v10.1.x` and below" +!!! warning "`setup.sh` for `docker-mailserver` version `v10.1.x` and below" - If you're using Docker Mailserver version `v10.1.x` or below, you will need to get `setup.sh` with a specific version. Substitute `` with the [tagged release version](https://github.com/docker-mailserver/docker-mailserver/tags) that you're using: + If you're using `docker-mailserver` version `v10.1.x` or below, you will need to get `setup.sh` with a specific version. Substitute `` with the [tagged release version](https://github.com/docker-mailserver/docker-mailserver/tags) that you're using: `wget https://raw.githubusercontent.com/docker-mailserver/docker-mailserver//setup.sh`. @@ -35,12 +35,12 @@ SYNOPSIS COMMAND := { email | alias | quota | config | relay | debug } SUBCOMMAND DESCRIPTION - This is the main administration script that you use for all interactions with your - mail server. Setup, configuration and much more is done with this script. + This is the main administration script that you use for all your interactions with + 'docker-mailserver'. Setup, configuration and much more is done with this script. Please note that the script executes most of the commands inside the container itself. - If the image was not found, this script will pull the :latest tag of - mailserver/docker-mailserver. This tag refers to the latest release, + If the image was not found, this script will pull the ':latest' tag of + 'mailserver/docker-mailserver'. This tag refers to the latest release, see the tagging convention in the README under https://github.com/docker-mailserver/docker-mailserver/blob/master/README.md @@ -81,30 +81,30 @@ DESCRIPTION ./setup.sh debug login EXAMPLES - ./setup.sh email add test@domain.tld - Add the email account test@domain.tld. You will be prompted + ./setup.sh email add test@example.com + Add the email account test@example.com. You will be prompted to input a password afterwards since no password was supplied. - ./setup.sh config dkim keysize 2048 domain 'whoami.com,whoareyou.org' + ./setup.sh config dkim keysize 2048 domain 'example.com,not-example.com' Creates keys of length 2048 but in an LDAP setup where domains are not known to Postfix by default, so you need to provide them yourself in a comma-separated list. ./setup.sh config dkim help - This will provide you with a detailed explanation on how to use the + This will provide you with a detailed explanation on how to use the config dkim command, showing what arguments can be passed and what they do. OPTIONS Config path, container or image adjustments -i IMAGE_NAME - Provides the name of the docker-mailserver image. The default value is - docker.io/mailserver/docker-mailserver:latest + Provides the name of the 'docker-mailserver' image. The default value is + 'docker.io/mailserver/docker-mailserver:latest' -c CONTAINER_NAME Provides the name of the running container. -p PATH - Provides the config folder path to the temporary container - (does not work if docker-mailserver container already exists). + Provides the config folder path to the temporary container + (does not work if a 'docker-mailserver' container already exists). SELinux -z diff --git a/docs/content/config/troubleshooting/debugging.md b/docs/content/config/troubleshooting/debugging.md index 71450aa8..5cffde2c 100644 --- a/docs/content/config/troubleshooting/debugging.md +++ b/docs/content/config/troubleshooting/debugging.md @@ -38,7 +38,7 @@ I spent HOURS trying to debug "Connection Refused" and "Connection closed by for ```sh sudo su -docker exec -ti mail bash +docker exec -it mailserver bash cd /var/log cat fail2ban.log | grep dovecot diff --git a/docs/content/config/user-management/accounts.md b/docs/content/config/user-management/accounts.md index 3bbda0ce..49ba3005 100644 --- a/docs/content/config/user-management/accounts.md +++ b/docs/content/config/user-management/accounts.md @@ -9,28 +9,30 @@ hide: Users (email accounts) are managed in `/tmp/docker-mailserver/postfix-accounts.cf`. **_The best way to manage accounts is to use the reliable [`setup.sh`][docs-setupsh] script_**. Or you may directly add the _full_ email address and its encrypted password, separated by a pipe: ```cf -user1@domain.tld|{SHA512-CRYPT}$6$2YpW1nYtPBs2yLYS$z.5PGH1OEzsHHNhl3gJrc3D.YMZkvKw/vp.r5WIiwya6z7P/CQ9GDEJDr2G2V0cAfjDFeAQPUoopsuWPXLk3u1 -user2@otherdomain.tld|{SHA512-CRYPT}$6$2YpW1nYtPBs2yLYS$z.5PGH1OEzsHHNhl3gJrc3D.YMZkvKw/vp.r5WIiwya6z7P/CQ9GDEJDr2G2V0cAfjDFeAQPUoopsuWPXLk3u1 +user1@example.com|{SHA512-CRYPT}$6$2YpW1nYtPBs2yLYS$z.5PGH1OEzsHHNhl3gJrc3D.YMZkvKw/vp.r5WIiwya6z7P/CQ9GDEJDr2G2V0cAfjDFeAQPUoopsuWPXLk3u1 +user2@not-example.com|{SHA512-CRYPT}$6$2YpW1nYtPBs2yLYS$z.5PGH1OEzsHHNhl3gJrc3D.YMZkvKw/vp.r5WIiwya6z7P/CQ9GDEJDr2G2V0cAfjDFeAQPUoopsuWPXLk3u1 ``` -In the example above, we've added 2 mail accounts for 2 different domains. Consequently, the mail server will automatically be configured for multi-domains. Therefore, to generate a new mail account data, directly from your docker host, you could for example run the following: +In the example above, we've added 2 mail accounts for 2 different domains. Consequently, the mail-server will automatically be configured for multi-domains. Therefore, to generate a new mail account data, directly from your docker host, you could for example run the following: ```sh docker run --rm \ - -e MAIL_USER=user1@domain.tld \ + -e MAIL_USER=user1@example.com \ -e MAIL_PASS=mypassword \ -it mailserver/docker-mailserver:latest \ - /bin/sh -c 'echo "$MAIL_USER|$(doveadm pw -s SHA512-CRYPT -u $MAIL_USER -p $MAIL_PASS)"' >> config/postfix-accounts.cf + /bin/sh -c 'echo "$MAIL_USER|$(doveadm pw -s SHA512-CRYPT -u $MAIL_USER -p $MAIL_PASS)"' >> docker-data/dms/config/postfix-accounts.cf ``` -You will then be asked for a password, and be given back the data for a new account entry, as text. To actually _add_ this new account, just copy all the output text in `config/postfix-accounts.cf` file of your running container. +You will then be asked for a password, and be given back the data for a new account entry, as text. To actually _add_ this new account, just copy all the output text in `docker-data/dms/config/postfix-accounts.cf` file of your running container. !!! note + `doveadm pw` command lets you choose between several encryption schemes for the password. Use `doveadm pw -l` to get a list of the currently supported encryption schemes. !!! note + Changes to the accounts list require a restart of the container, using `supervisord`. See [#552][github-issue-552]. --- diff --git a/docs/content/config/user-management/aliases.md b/docs/content/config/user-management/aliases.md index 2393eea2..f1769acb 100644 --- a/docs/content/config/user-management/aliases.md +++ b/docs/content/config/user-management/aliases.md @@ -9,19 +9,19 @@ You can use [`setup.sh`][docs-setupsh] instead of creating and editing files man * delivered to an existing account registered in `/tmp/docker-mailserver/postfix-accounts.cf` * redirected to one or more other email addresses -Alias and target are space separated. An example on a server with domain.tld as its domain: +Alias and target are space separated. An example on a server with example.com as its domain: ```cf # Alias delivered to an existing account -alias1@domain.tld user1@domain.tld +alias1@example.com user1@example.com # Alias forwarded to an external email address -alias2@domain.tld external@gmail.com +alias2@example.com external-account@gmail.com ``` ## Configuring RegExp Aliases -Additional regexp aliases can be configured by placing them into `config/postfix-regexp.cf`. The regexp aliases get evaluated after the virtual aliases (`/tmp/docker-mailserver/postfix-virtual.cf`). For example, the following `config/postfix-regexp.cf` causes all email to "test" users to be delivered to `qa@example.com`: +Additional regexp aliases can be configured by placing them into `docker-data/dms/config/postfix-regexp.cf`. The regexp aliases get evaluated after the virtual aliases (container path: `/tmp/docker-mailserver/postfix-virtual.cf`). For example, the following `docker-data/dms/config/postfix-regexp.cf` causes all email sent to "test" users to be delivered to `qa@example.com` instead: ```cf /^test[0-9][0-9]*@example.com/ qa@example.com @@ -29,10 +29,11 @@ Additional regexp aliases can be configured by placing them into `config/postfix ## Address Tags (Extension Delimiters) an Alternative to Aliases -Postfix supports so-called address tags, in the form of plus (+) tags - i.e. address+tag@example.com will end up at address@example.com. This is configured by default and the (configurable !) separator is set to `+`. For more info, see [How to use Address Tagging (`user+tag@example.com`) with Postfix](https://www.stevejenkins.com/blog/2011/03/how-to-use-address-tagging-usertagexample-com-with-postfix/) and the [official documentation](http://www.postfix.org/postconf.5.html#recipient_delimiter). +Postfix supports so-called address tags, in the form of plus (+) tags - i.e. `address+tag@example.com` will end up at `address@example.com`. This is configured by default and the (configurable !) separator is set to `+`. For more info, see [How to use Address Tagging (`user+tag@example.com`) with Postfix](https://www.stevejenkins.com/blog/2011/03/how-to-use-address-tagging-usertagexample-com-with-postfix/) and the [official documentation](http://www.postfix.org/postconf.5.html#recipient_delimiter). !!! note - If you do decide to change the configurable separator, you must add the same line to *both* `config/postfix-main.cf` and `config/dovecot.cf`, because Dovecot is acting as the delivery agent. For example, to switch to `-`, add: + + If you do decide to change the configurable separator, you must add the same line to *both* `docker-data/dms/config/postfix-main.cf` and `docker-data/dms/config/dovecot.cf`, because Dovecot is acting as the delivery agent. For example, to switch to `-`, add: ```cf recipient_delimiter = - diff --git a/docs/content/contributing/coding-style.md b/docs/content/contributing/coding-style.md index ee9234f8..bc13d177 100644 --- a/docs/content/contributing/coding-style.md +++ b/docs/content/contributing/coding-style.md @@ -107,7 +107,7 @@ function __log_err Comments should only describe non-obvious matters. Comments should start lowercase when they aren't sentences. Make the code **self-descriptive** by using meaningful names! Make comments not longer than approximately 80 columns, then wrap the line. -A positive example, which is taken from `start-mailserver.sh`, would be +A positive example, which is taken from `setup-stack.sh`, would be ```bash function _setup_postfix_aliases @@ -135,11 +135,11 @@ function _setup_postfix_aliases UNAME=$(echo "${FROM}" | cut -d @ -f1) DOMAIN=$(echo "${FROM}" | cut -d @ -f2) - # if they are equal it means the line looks like: "user1 other@domain.tld" + # if they are equal it means the line looks like: "user1 other@example.com" [[ "${UNAME}" != "${DOMAIN}" ]] && echo "${DOMAIN}" >> /tmp/vhost.tmp done < <(grep -v "^\s*$\|^\s*\#" /tmp/docker-mailserver/postfix-virtual.cf || true) else - _notify 'inf' "Warning 'config/postfix-virtual.cf' is not provided. No mail alias/forward created." + _notify 'inf' "Warning '/tmp/docker-mailserver/postfix-virtual.cf' is not provided. No mail alias/forward created." fi ... diff --git a/docs/content/contributing/documentation.md b/docs/content/contributing/documentation.md index 8640e0de..86bdb10f 100644 --- a/docs/content/contributing/documentation.md +++ b/docs/content/contributing/documentation.md @@ -47,7 +47,7 @@ Using the official image ([squidfunk/mkdocs-material](https://hub.docker.com/r/s !!! note "Note: be sure to be in the docs folder (`cd ./docs/`)" ```sh -docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material +docker run --rm -it -p 8000:8000 -v "${PWD}:/docs" squidfunk/mkdocs-material ``` Each change will be hot-reloaded onto the page you view, just edit, save and look at the result. diff --git a/docs/content/contributing/issues-and-pull-requests.md b/docs/content/contributing/issues-and-pull-requests.md index a874bf4b..5e716791 100644 --- a/docs/content/contributing/issues-and-pull-requests.md +++ b/docs/content/contributing/issues-and-pull-requests.md @@ -8,13 +8,13 @@ This project is Open Source. That means that you can contribute on enhancements, !!! attention - **Before opening an issue**, read the [`README`][github-file-readme] carefully, study the [documentation][docs], the Postfix/Dovecot documentation and your search engine you trust. The issue tracker is not meant to be used for unrelated questions! + **Before opening an issue**, read the [`README`][github-file-readme] carefully, study the [documentation][docs], the Postfix/Dovecot documentation and your search engine you trust. The issue tracker is not meant to be used for unrelated questions! -When opening an issue, please provide details use case to let the community reproduce your problem. Please start the mail server with env `DMS_DEBUG=1` and paste the output into the issue. +When opening an issue, please provide details use case to let the community reproduce your problem. Please start `docker-mailserver` with ENV `DMS_DEBUG=1` and paste the output into the issue. !!! attention - **Use the issue templates** to provide the necessary information. Issues which do not use these templates are not worked on and closed. + **Use the issue templates** to provide the necessary information. Issues which do not use these templates are not worked on and closed. By raising issues, I agree to these terms and I understand, that the rules set for the issue tracker will help both maintainers as well as everyone to find a solution. @@ -26,7 +26,7 @@ Maintainers take the time to improve on this project and help by solving issues !!! question "Motivation" - You want to add a feature? Feel free to start creating an issue explaining what you want to do and how you're thinking doing it. Other users may have the same need and collaboration may lead to better results. + You want to add a feature? Feel free to start creating an issue explaining what you want to do and how you're thinking doing it. Other users may have the same need and collaboration may lead to better results. The development workflow is the following: @@ -37,7 +37,7 @@ The development workflow is the following: 3. Add integration tests if necessary 4. [Prepare your environment and run linting and tests][docs-tests] 5. Document your improvements if necessary (e.g. if you introduced new environment variables, describe those in the [ENV documentation][docs-environment]) -6. [Commit][commit] and [sign your commit][gpg], push and create a pull-request to merge into `master`. Please **use the pull-request template** to provide a minimum of contextual information and make sure to meet the requirements of the checklist. +6. [Commit][commit] and [sign your commit][gpg], push and create a pull-request to merge into `master`. Please **use the pull-request template** to provide a minimum of contextual information and make sure to meet the requirements of the checklist. 1. Pull requests are automatically tested against the CI and will be reviewed when tests pass 2. When your changes are validated, your branch is merged 3. CI builds the new `:edge` image immediately and your changes will be includes in the next version release. diff --git a/docs/content/examples/tutorials/basic-installation.md b/docs/content/examples/tutorials/basic-installation.md index ebd39604..f0226221 100644 --- a/docs/content/examples/tutorials/basic-installation.md +++ b/docs/content/examples/tutorials/basic-installation.md @@ -2,18 +2,18 @@ title: 'Tutorials | Basic Installation' --- -## Building a Simple Mailserver +## Building a Simple Mail-Server !!! warning Adding the docker network's gateway to the list of trusted hosts, e.g. using the `network` or `connected-networks` option, can create an [**open relay**](https://en.wikipedia.org/wiki/Open_mail_relay), for instance [if IPv6 is enabled on the host machine but not in Docker][github-issue-1405-comment]. We are going to use this docker based mailserver: -- First create a directory for the mailserver and get the setup script: +- First create a directory for `docker-mailserver` to store data in, and get the `setup.sh` script: ```sh - mkdir -p /var/ds/mail.example.org - cd /var/ds/mail.example.org/ + mkdir -p /var/ds/mail.example.com + cd /var/ds/mail.example.com/ curl -o setup.sh \ https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master/setup.sh @@ -30,19 +30,19 @@ We are going to use this docker based mailserver: services: mailserver: image: docker.io/mailserver/docker-mailserver:latest + container_name: mailserver hostname: mail domainname: example.com - container_name: mailserver ports: - "25:25" - "587:587" - "465:465" volumes: - - ./data/maildata:/var/mail - - ./data/mailstate:/var/mail-state - - ./data/maillogs:/var/log/mail + - ./docker-data/dms/mail-data/:/var/mail/ + - ./docker-data/dms/mail-state/:/var/mail-state/ + - ./docker-data/dms/mail-logs/:/var/log/mail/ + - ./docker-data/dms/config/:/tmp/docker-mailserver/ - /etc/localtime:/etc/localtime:ro - - ./config/:/tmp/docker-mailserver/ - /var/ds/wsproxy/letsencrypt/:/etc/letsencrypt/ environment: - PERMIT_DOCKER=network @@ -65,7 +65,7 @@ We are going to use this docker based mailserver: - [Environment Variables][docs-environment] - [`mailserver.env` file][github-file-dotenv] - Make sure to set the proper `domainname` that you will use for the emails. We forward only SMTP ports (not POP3 and IMAP) because we are not interested in accessing the mailserver directly (from a client). We also use these settings: + Make sure to set the proper `domainname` that you will use for the emails. We forward only SMTP ports (not POP3 and IMAP) because we are not interested in accessing the mail-server directly (from a client). We also use these settings: - `PERMIT_DOCKER=network` because we want to send emails from other docker containers. - `SSL_TYPE=letsencrypt` because we will manage SSL certificates with letsencrypt. @@ -82,12 +82,12 @@ We are going to use this docker based mailserver: - Pull the docker image: `docker pull mailserver/docker-mailserver:latest` -- Now generate the DKIM keys with `./setup.sh config dkim` and copy the content of the file `config/opendkim/keys/domain.tld/mail.txt` on the domain zone configuration at the DNS server. I use [bind9](https://github.com/docker-scripts/bind9) for managing my domains, so I just paste it on `example.org.db`: +- Now generate the DKIM keys with `./setup.sh config dkim` and copy the content of the file `docker-data/dms/config/opendkim/keys/example.com/mail.txt` on the domain zone configuration at the DNS server. I use [bind9](https://github.com/docker-scripts/bind9) for managing my domains, so I just paste it on `example.com.db`: ```txt mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFACAQ8AMIIBCgKCAQEAaH5KuPYPSF3Ppkt466BDMAFGOA4mgqn4oPjZ5BbFlYA9l5jU3bgzRj3l6/Q1n5a9lQs5fNZ7A/HtY0aMvs3nGE4oi+LTejt1jblMhV/OfJyRCunQBIGp0s8G9kIUBzyKJpDayk2+KJSJt/lxL9Iiy0DE5hIv62ZPP6AaTdHBAsJosLFeAzuLFHQ6USyQRojefqFQtgYqWQ2JiZQ3" - "iqq3bD/BVlwKRp5gH6TEYEmx8EBJUuDxrJhkWRUk2VDl1fqhVBy8A9O7Ah+85nMrlOHIFsTaYo9o6+cDJ6t1i6G1gu+bZD0d3/3bqGLPBQV9LyEL1Rona5V7TJBGg099NQkTz1IwIDAQAB" ) ; ----- DKIM key mail for example.org + "iqq3bD/BVlwKRp5gH6TEYEmx8EBJUuDxrJhkWRUk2VDl1fqhVBy8A9O7Ah+85nMrlOHIFsTaYo9o6+cDJ6t1i6G1gu+bZD0d3/3bqGLPBQV9LyEL1Rona5V7TJBGg099NQkTz1IwIDAQAB" ) ; ----- DKIM key mail for example.com ``` - Add these configurations as well on the same file on the DNS server: @@ -95,8 +95,8 @@ We are going to use this docker based mailserver: ```txt mail IN A 10.11.12.13 - ; mailservers for example.org - 3600 IN MX 1 mail.example.org. + ; mail-server for example.com + 3600 IN MX 1 mail.example.com. ; Add SPF record IN TXT "v=spf1 mx ~all" @@ -108,55 +108,55 @@ We are going to use this docker based mailserver: ```sh cd /var/ds/wsproxy - ds domains-add mail mail.example.org - ds get-ssl-cert myemail@gmail.com mail.example.org --test - ds get-ssl-cert myemail@gmail.com mail.example.org + ds domains-add mail mail.example.com + ds get-ssl-cert external-account@gmail.com mail.example.com --test + ds get-ssl-cert external-account@gmail.com mail.example.com ``` - Now the certificates will be available on `/var/ds/wsproxy/letsencrypt/live/mail.example.org`. + Now the certificates will be available on `/var/ds/wsproxy/letsencrypt/live/mail.example.com`. -- Start the mailserver and check for any errors: +- Start `docker-mailserver` and check for any errors: ```sh apt install docker-compose - docker-compose up mail + docker-compose up mailserver ``` - Create email accounts and aliases with `SPOOF_PROTECTION=0`: ```sh - ./setup.sh email add admin@example.org passwd123 - ./setup.sh email add info@example.org passwd123 - ./setup.sh alias add admin@example.org myemail@gmail.com - ./setup.sh alias add info@example.org myemail@gmail.com + ./setup.sh email add admin@example.com passwd123 + ./setup.sh email add info@example.com passwd123 + ./setup.sh alias add admin@example.com external-account@gmail.com + ./setup.sh alias add info@example.com external-account@gmail.com ./setup.sh email list ./setup.sh alias list ``` - Aliases make sure that any email that comes to these accounts is forwarded to my real email address, so that I don't need to use POP3/IMAP in order to get these messages. Also no anti-spam and anti-virus software is needed, making the mailserver lighter. + Aliases make sure that any email that comes to these accounts is forwarded to my real email address, so that I don't need to use POP3/IMAP in order to get these messages. Also no anti-spam and anti-virus software is needed, making the mail-server lighter. - Or create email accounts and aliases with `SPOOF_PROTECTION=1`: ```sh - ./setup.sh email add admin.gmail@example.org passwd123 - ./setup.sh email add info.gmail@example.org passwd123 - ./setup.sh alias add admin@example.org admin.gmail@example.org - ./setup.sh alias add info@example.org info.gmail@example.org - ./setup.sh alias add admin.gmail@example.org myemail@gmail.com - ./setup.sh alias add info.gmail@example.org myemail@gmail.com + ./setup.sh email add admin.gmail@example.com passwd123 + ./setup.sh email add info.gmail@example.com passwd123 + ./setup.sh alias add admin@example.com admin.gmail@example.com + ./setup.sh alias add info@example.com info.gmail@example.com + ./setup.sh alias add admin.gmail@example.com external-account@gmail.com + ./setup.sh alias add info.gmail@example.com external-account@gmail.com ./setup.sh email list ./setup.sh alias list ``` - This extra step is required to avoid the `553 5.7.1 Sender address rejected: not owned by user` error (the account used for setting up Gmail is `admin.gmail@example.org` and `info.gmail@example.org` ) + This extra step is required to avoid the `553 5.7.1 Sender address rejected: not owned by user` error (the account used for setting up Gmail is `admin.gmail@example.com` and `info.gmail@example.com` ) -- Send some test emails to these addresses and make other tests. Then stop the container with `ctrl+c` and start it again as a daemon: `docker-compose up -d mail`. +- Send some test emails to these addresses and make other tests. Then stop the container with `ctrl+c` and start it again as a daemon: `docker-compose up -d mailserver`. - Now save on Moodle configuration the SMTP settings and test by trying to send some messages to other users: - - **SMTP hosts**: `mail.example.org:465` + - **SMTP hosts**: `mail.example.com:465` - **SMTP security**: `SSL` - - **SMTP username**: `info@example.org` + - **SMTP username**: `info@example.com` - **SMTP password**: `passwd123` [docs-environment]: ../../config/environment.md diff --git a/docs/content/examples/tutorials/blog-posts.md b/docs/content/examples/tutorials/blog-posts.md index 85ba4f44..dcbfae76 100644 --- a/docs/content/examples/tutorials/blog-posts.md +++ b/docs/content/examples/tutorials/blog-posts.md @@ -2,8 +2,8 @@ title: 'Tutorials | Blog Posts' --- -This site lists blog entries that write about the project. If you blogged about `docker-mailserver` as well feel free to add your site! +This site lists blog entries that write about the project. If you blogged about `docker-mailserver` let us know so we can add it here! -- [Installing docker-mailserver](https://lowtek.ca/roo/2021/installing-docker-mailserver/) by [@andrewlow](https://github.com/andrewlow) -- [Simple Mailserver with docker](https://tvi.al/simple-mail-server-with-docker/) by [@tomav](https://github.com/tomav) -- [Self hosted mail server](https://www.ifthenel.se/self-hosted-mail-server/) by [@matrixes](https://github.com/matrixes) +- [Installing docker-mailserver](https://lowtek.ca/roo/2021/installing-docker-mailserver/) by [@andrewlow](https://github.com/andrewlow) +- [Simple mail-server with docker](https://tvi.al/simple-mail-server-with-docker/) by [@tomav](https://github.com/tomav) +- [Self hosted mail-server](https://www.ifthenel.se/self-hosted-mail-server/) by [@matrixes](https://github.com/matrixes) diff --git a/docs/content/examples/tutorials/mailserver-behind-proxy.md b/docs/content/examples/tutorials/mailserver-behind-proxy.md index 62e53088..78606b5b 100644 --- a/docs/content/examples/tutorials/mailserver-behind-proxy.md +++ b/docs/content/examples/tutorials/mailserver-behind-proxy.md @@ -1,5 +1,5 @@ --- -title: 'Tutorials | Mailserver behind Proxy' +title: 'Tutorials | Mail-Server behind a Proxy' --- ## Using `docker-mailserver` behind a Proxy @@ -23,17 +23,17 @@ Luckily `dovecot` and `postfix` are both Proxy-Protocol ready softwares so it de The configuration depends on the used proxy system. I will provide the configuration examples of [traefik v2](https://traefik.io/) using IMAP and SMTP with implicit TLS. -Feel free to add your configuration if you archived the same goal using different proxy software below: +Feel free to add your configuration if you achieved the same goal using different proxy software below: ??? "Traefik v2" Truncated configuration of traefik itself: ```yaml - version: '3.7' + version: '3.8' services: reverse-proxy: - image: traefik:latest + image: docker.io/traefik:latest # v2.5 container_name: docker-traefik restart: always command: @@ -54,16 +54,16 @@ Feel free to add your configuration if you archived the same goal using differen [...] ``` - Truncated list of necessary labels on the mailserver container: + Truncated list of necessary labels on the `docker-mailserver` container: ```yaml version: '3.8' services: mailserver: image: docker.io/mailserver/docker-mailserver:latest + container_name: mailserver hostname: mail domainname: example.com - container_name: mailserver restart: always networks: - proxy @@ -98,20 +98,20 @@ Feel free to add your configuration if you archived the same goal using differen The following changes can be achieved completely by adding the content to the appropriate files by using the projects [function to overwrite config files][docs-optionalconfig]. -Changes for `postfix` can be applied by adding the following content to `config/postfix-main.cf`: +Changes for `postfix` can be applied by adding the following content to `docker-data/dms/config/postfix-main.cf`: ```cf postscreen_upstream_proxy_protocol = haproxy ``` -and to `config/postfix-master.cf`: +and to `docker-data/dms/config/postfix-master.cf`: ```cf submission/inet/smtpd_upstream_proxy_protocol=haproxy smtps/inet/smtpd_upstream_proxy_protocol=haproxy ``` -Changes for `dovecot` can be applied by adding the following content to `config/dovecot.cf`: +Changes for `dovecot` can be applied by adding the following content to `docker-data/dms/config/dovecot.cf`: ```cf haproxy_trusted_networks = , diff --git a/docs/content/examples/uses-cases/forward-only-mailserver-with-ldap-authentication.md b/docs/content/examples/uses-cases/forward-only-mailserver-with-ldap-authentication.md index 6360c6a6..c87ab6be 100644 --- a/docs/content/examples/uses-cases/forward-only-mailserver-with-ldap-authentication.md +++ b/docs/content/examples/uses-cases/forward-only-mailserver-with-ldap-authentication.md @@ -1,10 +1,10 @@ --- -title: 'Use Cases | Forward-Only Mailserver with LDAP' +title: 'Use Cases | Forward-Only Mail-Server with LDAP' --- -## Building a Forward-Only Mailserver +## Building a Forward-Only Mail-Server -A **forward-only** mailserver does not have any local mailboxes. Instead, it has only aliases that forward emails to external email accounts (for example to a Gmail account). You can also send email from the localhost (the computer where the mailserver is installed), using as sender any of the alias addresses. +A **forward-only** mail-server does not have any local mailboxes. Instead, it has only aliases that forward emails to external email accounts (for example to a Gmail account). You can also send email from the localhost (the computer where `docker-mailserver` is installed), using as sender any of the alias addresses. The important settings for this setup (on `mailserver.env`) are these: @@ -27,7 +27,7 @@ We can create aliases with `./setup.sh`, like this: ## Authenticating with LDAP -If you want to send emails from outside the mailserver you have to authenticate somehow (with a username and password). One way of doing it is described in [this discussion][github-issue-1247]. However if there are many user accounts, it is better to use authentication with LDAP. The settings for this on `mailserver.env` are: +If you want to send emails from outside the mail-server you have to authenticate somehow (with a username and password). One way of doing it is described in [this discussion][github-issue-1247]. However if there are many user accounts, it is better to use authentication with LDAP. The settings for this on `mailserver.env` are: ```env ENABLE_LDAP=1 @@ -47,7 +47,7 @@ SASLAUTHD_LDAP_SEARCH_BASE=ou=users,dc=example,dc=org SASLAUTHD_LDAP_FILTER=(&(uid=%U)(objectClass=inetOrgPerson)) ``` -My LDAP data structure is very basic, containing only the username, password, and the external email address where to forward emails for this user. An entry looks like this +My LDAP data structure is very basic, containing only the username, password, and the external email address where to forward emails for this user. An entry looks like this: ```properties add uid=username,ou=users,dc=example,dc=org @@ -56,10 +56,10 @@ objectClass: inetOrgPerson sn: username cn: username userPassword: {SSHA}abcdefghi123456789 -email: real-email-address@external-domain.com +email: external-account@gmail.com ``` -This structure is different from what is expected/assumed from the configuration scripts of the mailserver, so it doesn't work just by using the `LDAP_QUERY_FILTER_...` settings. Instead, I had to do [custom configuration][github-file-readme-patches]. I created the script `config/user-patches.sh`, with a content like this: +This structure is different from what is expected/assumed from the configuration scripts of `docker-mailserver`, so it doesn't work just by using the `LDAP_QUERY_FILTER_...` settings. Instead, I had to use a custom configuration ([via `user-patches.sh`][docs-userpatches]). I created the script `docker-data/dms/config/user-patches.sh`, with content like this: ```bash #!/bin/bash @@ -96,17 +96,17 @@ postfix reload You see that besides `query_filter`, I had to customize as well `result_attribute` and `result_format`. -!!! seealso "See also" +!!! note "See also" - For more details about using LDAP see: [LDAP managed mail server with Postfix and Dovecot for multiple domains](https://www.vennedey.net/resources/2-LDAP-managed-mail-server-with-Postfix-and-Dovecot-for-multiple-domains) + For more details about using LDAP see: [LDAP managed mail-server with Postfix and Dovecot for multiple domains](https://www.vennedey.net/resources/2-LDAP-managed-mail-server-with-Postfix-and-Dovecot-for-multiple-domains) !!! note - Another solution that serves as a forward-only mailserver is this: https://gitlab.com/docker-scripts/postfix + Another solution that serves as a forward-only mail-server is [this](https://gitlab.com/docker-scripts/postfix). !!! tip One user reports only having success if `ENABLE_LDAP=0` was set. -[github-file-readme-patches]: https://github.com/docker-mailserver/docker-mailserver/blob/master/README.md#custom-user-changes--patches +[docs-userpatches]: ./config/advanced/override-defaults/user-patches.md [github-issue-1247]: https://github.com/docker-mailserver/docker-mailserver/issues/1247 diff --git a/docs/content/examples/uses-cases/imap-folders.md b/docs/content/examples/uses-cases/imap-folders.md index ae6b7559..1923d6a1 100644 --- a/docs/content/examples/uses-cases/imap-folders.md +++ b/docs/content/examples/uses-cases/imap-folders.md @@ -16,12 +16,11 @@ See [`target/dovecot/15-mailboxes.conf`][gh-config-dovecot-mailboxes] for existi The `Archive` special IMAP folder may be useful to enable. To do so, make a copy of [`target/dovecot/15-mailboxes.conf`][gh-config-dovecot-mailboxes] and uncomment the `Archive` mailbox definition. Mail clients should understand that this folder is intended for archiving mail due to the [`\Archive` _"SPECIAL-USE"_ attribute][rfc-6154]. -With the provided [docker-compose.yml][gh-config-dockercompose] example, a volume bind mounts the host directory `config` to the container location `/tmp/docker-mailserver`. Config file overrides should instead be mounted to a different location as described in [Overriding Configuration for Dovecot][docs-config-overrides-dovecot]: +With the provided [docker-compose.yml][gh-config-dockercompose] example, a volume bind mounts the host directory `docker-data/dms/config/` to the container location `/tmp/docker-mailserver/`. Config file overrides should instead be mounted to a different location as described in [Overriding Configuration for Dovecot][docs-config-overrides-dovecot]: -```YAML +```yaml volumes: - ... - - ./config/dovecot/15-mailboxes.conf:/etc/dovecot/conf.d/15-mailboxes.conf:ro + - ./docker-data/dms/config/dovecot/15-mailboxes.conf:/etc/dovecot/conf.d/15-mailboxes.conf:ro ``` ## Caution diff --git a/docs/content/faq.md b/docs/content/faq.md index c211df3a..73b9b2c6 100644 --- a/docs/content/faq.md +++ b/docs/content/faq.md @@ -15,11 +15,11 @@ Mails are stored in `/var/mail/${domain}/${username}`. Since `v9.0.0` it is poss You should use a [data volume container](https://medium.com/@ramangupta/why-docker-data-containers-are-good-589b3c6c749e#.uxyrp7xpu) for `/var/mail` to persist data. Otherwise, your data may be lost. -### How to alter the running mailserver instance _without_ relaunching the container? +### How to alter the running `docker-mailserver` instance _without_ relaunching the container? -`docker-mailserver` aggregates multiple "sub-services", such as Postfix, Dovecot, Fail2ban, SpamAssassin, etc. In many cases, one may edit a sub-service's config and reload that very sub-service, without stopping and relaunching the whole mail server. +`docker-mailserver` aggregates multiple "sub-services", such as Postfix, Dovecot, Fail2ban, SpamAssassin, etc. In many cases, one may edit a sub-service's config and reload that very sub-service, without stopping and relaunching the whole mail-server. -In order to do so, you'll probably want to push your config updates to your server through a Docker volume, then restart the sub-service to apply your changes, using `supervisorctl`. For instance, after editing fail2ban's config: `supervisorctl restart fail2ban`. +In order to do so, you'll probably want to push your config updates to your server through a Docker volume (these docs use: `./docker-data/dms/config/:/tmp/docker-mailserver/`), then restart the sub-service to apply your changes, using `supervisorctl`. For instance, after editing fail2ban's config: `supervisorctl restart fail2ban`. See [supervisorctl's documentation](http://supervisord.org/running.html#running-supervisorctl). @@ -56,13 +56,13 @@ Please do not use `CRLF`. #### Bind mounts (default) -From the location of your `docker-compose.yml`, create a compressed archive of your `./config` and `./data` folders: +From the location of your `docker-compose.yml`, create a compressed archive of your `docker-data/dms/config/` and `docker-data/dms/mail-*` folders: ```bash -tar --gzip -cf "backup-$(date +%F).tar.gz" config data +tar --gzip -cf "backup-$(date +%F).tar.gz" ./docker-data/dms ``` -Then to restore `./config` and `./data` folders from your backup file: +Then to restore `docker-data/dms/config/` and `docker-data/dms/mail-*` folders from your backup file: ```bash tar --gzip -xf backup-date.tar.gz @@ -75,17 +75,17 @@ Assuming that you use `docker-compose` and data volumes, you can backup the conf ```sh # create backup docker run --rm -it \ - -v "$PWD/config":/tmp/docker-mailserver \ - -v /backup/mail:/backup \ + -v "${PWD}/docker-data/dms/config/:/tmp/docker-mailserver/" \ + -v "${PWD}/docker-data/dms-backups/:/backup/" \ --volumes-from mailserver \ alpine:latest \ tar czf "/backup/mail-$(date +%F).tar.gz" /var/mail /var/mail-state /var/logs/mail /tmp/docker-mailserver # delete backups older than 30 days -find /backup/mail -type f -mtime +30 -delete +find "${PWD}/docker-data/dms-backups/" -type f -mtime +30 -delete ``` -### What is the `mail-state` folder for? +### What about `docker-data/dms/mail-state` folder? (_`/var/mail-state` internally_) When you run `docker-mailserver` with the ENV var `ONE_DIR=1` (_default since v10.2_), this folder will store the data from internal services so that you can more easily persist state to disk (via `volumes`). @@ -95,19 +95,19 @@ Service data is [relocated to the `mail-state` folder][mail-state-folders] for s ### How can I configure my email client? -Login are full email address (`user@domain.com`). +Login is full email address (`@`). ```properties # imap -username: +username: password: -server: +server: imap port: 143 or 993 with ssl (recommended) imap path prefix: INBOX # smtp smtp port: 25 or 587 with ssl (recommended) -username: +username: password: ``` @@ -115,7 +115,7 @@ Please use `STARTTLS`. ### How can I manage my custom SpamAssassin rules? -Antispam rules are managed in `config/spamassassin-rules.cf`. +Antispam rules are managed in `docker-data/dms/config/spamassassin-rules.cf`. ### What are acceptable `SA_SPAM_SUBJECT` values? @@ -132,12 +132,12 @@ environment: Yes, but not without some configuration changes. Normally it is assumed that `docker-mailserver` runs on a host with a name, so the fully qualified host name might be `mail.example.com` with the domain `example.com`. The MX records point to `mail.example.com`. -To use a bare domain where the host name is `example.com` and the domain is also `example.com`, change `mydestination`: +To use a bare domain (_where the host name is `example.com` and the domain is also `example.com`_), change `mydestination`: - From: `mydestination = $myhostname, localhost.$mydomain, localhost` - To: `mydestination = localhost.$mydomain, localhost` -Add the latter line to `config/postfix-main.cf`. That should work. Without that change there will be warnings in the logs like: +Add the latter line to `docker-data/dms/config/postfix-main.cf`. That should work. Without that change there will be warnings in the logs like: ```log warning: do not list domain example.com in BOTH mydestination and virtual_mailbox_domains @@ -145,7 +145,7 @@ warning: do not list domain example.com in BOTH mydestination and virtual_mailbo Plus of course mail delivery fails. -### Why are SpamAssassin `x-headers` not inserted into my `sample.domain.com` subdomain emails? +### Why are SpamAssassin `x-headers` not inserted into my `subdomain.example.com` subdomain emails? In the default setup, amavis only applies SpamAssassin x-headers into domains matching the template listed in the config file (`05-domain_id` in the amavis defaults). @@ -161,10 +161,10 @@ Put received spams in `.Junk/` imap folder using `SPAMASSASSIN_SPAM_TO_INBOX=1` # # m h dom mon dow command # Everyday 2:00AM, learn spam from a specific user -0 2 * * * docker exec mail sa-learn --spam /var/mail/domain.com/username/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin +0 2 * * * docker exec mailserver sa-learn --spam /var/mail/example.com/username/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin ``` -If you run the server with `docker-compose`, you can leverage on docker configs and the mailserver's own cron. This is less problematic than the simple solution shown above, because it decouples the learning from the host on which the mailserver is running and avoids errors if the server is not running. +With `docker-compose` you can more easily use the internal instance of `cron` within `docker-mailserver`. This is less problematic than the simple solution shown above, because it decouples the learning from the host on which `docker-mailserver` is running, and avoids errors if the mail-server is not running. The following configuration works nicely: @@ -174,13 +174,13 @@ The following configuration works nicely: ```sh # in the docker-compose.yml root directory - mkdir cron - touch cron/sa-learn - chown root:root cron/sa-learn - chmod 0644 cron/sa-learn + mkdir -p ./docker-data/dms/cron + touch ./docker-data/dms/cron/sa-learn + chown root:root ./docker-data/dms/cron/sa-learn + chmod 0644 ./docker-data/dms/cron/sa-learn ``` - Edit the system cron file `nano cron/sa-learn`, and set an appropriate configuration: + Edit the system cron file `nano ./docker-data/dms/cron/sa-learn`, and set an appropriate configuration: ```conf # This assumes you're having `environment: ONE_DIR=1` in the env-mailserver, @@ -190,35 +190,35 @@ The following configuration works nicely: # # Everyday 2:00AM, learn spam from a specific user # spam: junk directory - 0 2 * * * root sa-learn --spam /var/mail/domain.com/username/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin + 0 2 * * * root sa-learn --spam /var/mail/example.com/username/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin # ham: archive directories - 15 2 * * * root sa-learn --ham /var/mail/domain.com/username/.Archive* --dbpath /var/mail-state/lib-amavis/.spamassassin + 15 2 * * * root sa-learn --ham /var/mail/example.com/username/.Archive* --dbpath /var/mail-state/lib-amavis/.spamassassin # ham: inbox subdirectories - 30 2 * * * root sa-learn --ham /var/mail/domain.com/username/cur* --dbpath /var/mail-state/lib-amavis/.spamassassin + 30 2 * * * root sa-learn --ham /var/mail/example.com/username/cur* --dbpath /var/mail-state/lib-amavis/.spamassassin # # Everyday 3:00AM, learn spam from all users of a domain # spam: junk directory - 0 3 * * * root sa-learn --spam /var/mail/otherdomain.com/*/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin + 0 3 * * * root sa-learn --spam /var/mail/not-example.com/*/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin # ham: archive directories - 15 3 * * * root sa-learn --ham /var/mail/otherdomain.com/*/.Archive* --dbpath /var/mail-state/lib-amavis/.spamassassin + 15 3 * * * root sa-learn --ham /var/mail/not-example.com/*/.Archive* --dbpath /var/mail-state/lib-amavis/.spamassassin # ham: inbox subdirectories - 30 3 * * * root sa-learn --ham /var/mail/otherdomain.com/*/cur* --dbpath /var/mail-state/lib-amavis/.spamassassin + 30 3 * * * root sa-learn --ham /var/mail/not-example.com/*/cur* --dbpath /var/mail-state/lib-amavis/.spamassassin ``` - Then with plain `docker-compose`: + Then with `docker-compose.yml`: ```yaml services: mailserver: image: docker.io/mailserver/docker-mailserver:latest volumes: - - ./cron/sa-learn:/etc/cron.d/sa-learn + - ./docker-data/dms/cron/sa-learn:/etc/cron.d/sa-learn ``` - Or with [docker swarm](https://docs.docker.com/engine/swarm/configs/): + Or with [Docker Swarm](https://docs.docker.com/engine/swarm/configs/): ```yaml - version: "3.3" + version: '3.8' services: mailserver: @@ -230,31 +230,31 @@ The following configuration works nicely: configs: my_sa_crontab: - file: ./cron/sa-learn + file: ./docker-data/dms/cron/sa-learn ``` With the default settings, SpamAssassin will require 200 mails trained for spam (for example with the method explained above) and 200 mails trained for ham (using the same command as above but using `--ham` and providing it with some ham mails). Until you provided these 200+200 mails, SpamAssassin will not take the learned mails into account. For further reference, see the [SpamAssassin Wiki](https://wiki.apache.org/spamassassin/BayesNotWorking). ### How can I configure a catch-all? -Considering you want to redirect all incoming e-mails for the domain `domain.tld` to `user1@domain.tld`, add the following line to `config/postfix-virtual.cf`: +Considering you want to redirect all incoming e-mails for the domain `example.com` to `user1@example.com`, add the following line to `docker-data/dms/config/postfix-virtual.cf`: ```cf -@domain.tld user1@domain.tld +@example.com user1@example.com ``` ### How can I delete all the emails for a specific user? -First of all, create a special alias named `devnull` by editing `config/postfix-aliases.cf`: +First of all, create a special alias named `devnull` by editing `docker-data/dms/config/postfix-aliases.cf`: ```cf devnull: /dev/null ``` -Considering you want to delete all the e-mails received for `baduser@domain.tld`, add the following line to `config/postfix-virtual.cf`: +Considering you want to delete all the e-mails received for `baduser@example.com`, add the following line to `docker-data/dms/config/postfix-virtual.cf`: ```cf -baduser@domain.tld devnull +baduser@example.com devnull ``` ### How do I have more control about what SPAMASSASIN is filtering? @@ -293,28 +293,28 @@ if header :contains "X-Spam-Flag" "YES" { } ``` -Create a dedicated mailbox for emails which are infected/bad header and everything amavis is blocking by default and put its address into `config/amavis.cf` +Create a dedicated mailbox for emails which are infected/bad header and everything amavis is blocking by default and put its address into `docker-data/dms/config/amavis.cf` ```cf -$clean_quarantine_to = "amavis\@domain.com"; -$virus_quarantine_to = "amavis\@domain.com"; -$banned_quarantine_to = "amavis\@domain.com"; -$bad_header_quarantine_to = "amavis\@domain.com"; -$spam_quarantine_to = "amavis\@domain.com"; +$clean_quarantine_to = "amavis\@example.com"; +$virus_quarantine_to = "amavis\@example.com"; +$banned_quarantine_to = "amavis\@example.com"; +$bad_header_quarantine_to = "amavis\@example.com"; +$spam_quarantine_to = "amavis\@example.com"; ``` ### What kind of SSL certificates can I use? -You can use the same certificates you use with another mail server. +You can use the same certificates you would use with another mail-server. -The only thing is that we provide a `self-signed` certificate tool and a `letsencrypt` certificate loader. +The only difference is that we provide a `self-signed` certificate tool and a `letsencrypt` certificate loader. -### I just moved from my old mail server, but "it doesn't work"? +### I just moved from my old Mail-Server, but "it doesn't work"? If this migration implies a DNS modification, be sure to wait for DNS propagation before opening an issue. Few examples of symptoms can be found [here][github-issue-95] or [here][github-issue-97]. -This could be related to a modification of your `MX` record, or the IP mapped to `mail.my-domain.tld`. Additionally, [validate your DNS configuration](https://intodns.com/). +This could be related to a modification of your `MX` record, or the IP mapped to `mail.example.com`. Additionally, [validate your DNS configuration](https://intodns.com/). If everything is OK regarding DNS, please provide [formatted logs](https://guides.github.com/features/mastering-markdown/) and config files. This will allow us to help you. @@ -365,7 +365,7 @@ mail amavis[1459]: (01459-01) (!!)AV: ALL VIRUS SCANNERS FAILED ### How to use when behind a Proxy -Add to `/etc/postfix/main.cf` : +[Using `user-patches.sh`][docs-userpatches], update the container file `/etc/postfix/main.cf` to include: ```cf proxy_interfaces = X.X.X.X (your public IP) @@ -373,21 +373,22 @@ proxy_interfaces = X.X.X.X (your public IP) ### What About Updates -You can of course use a own script or every now and then pull && stop && rm && start the images but there are tools available for this. -There is a section in the [Update and Cleanup][docs-maintenance] documentation page that explains how to use it the docker way. +You can use your own scripts, or every now and then `pull && stop && rm && start` the images but there are tools already available for this. + +There is a section in the [Update and Cleanup][docs-maintenance] documentation page that explains how to do it the docker way. ### How to adjust settings with the `user-patches.sh` script Suppose you want to change a number of settings that are not listed as variables or add things to the server that are not included? -This docker-container has a built-in way to do post-install processes. If you place a script called **user-patches.sh** in the config directory it will be run after all configuration files are set up, but before the postfix, amavis and other daemons are started. +`docker-mailserver` has a built-in way to do post-install processes. If you place a script called **`user-patches.sh`** in the config directory it will be run after all configuration files are set up, but before the postfix, amavis and other daemons are started. -The config file I am talking about is this volume in the yml file: `./config/:/tmp/docker-mailserver/` +It is common to use a local directory for config added to `docker-mailsever` via a volume mount in your `docker-compose.yml` (eg: `./docker-data/dms/config/:/tmp/docker-mailserver/`). -To place such a script you can just make it in the config dir, for instance like this: +Add or create the script file to your config directory: ```sh -cd ./config +cd ./docker-data/dms/config touch user-patches.sh chmod +x user-patches.sh ``` @@ -410,11 +411,13 @@ cat /tmp/docker-mailserver/user-patches.sh exit ``` -You can do a lot of things with such a script. You can find an example `user-patches.sh` script here: [example `user-patches.sh` script][hanscees-userpatches] +You can do a lot of things with such a script. You can find an example `user-patches.sh` script here: [example `user-patches.sh` script][hanscees-userpatches]. + +We also have a [very similar docs page][docs-userpatches] specifically about this feature! #### Special use-case - Patching the `supervisord` config -It seems worth noting, that the `user-patches.sh` gets executed trough supervisord. If you need to patch some supervisord config (e.g. `/etc/supervisor/conf.d/saslauth.conf`), the patching happens too late. +It seems worth noting, that the `user-patches.sh` gets executed through `supervisord`. If you need to patch some supervisord config (e.g. `/etc/supervisor/conf.d/saslauth.conf`), the patching happens too late. An easy workaround is to make the `user-patches.sh` reload the supervisord config after patching it: @@ -425,6 +428,7 @@ supervisorctl update ``` [docs-maintenance]: ./config/advanced/maintenance/update-and-cleanup.md +[docs-userpatches]: ./config/advanced/override-defaults/user-patches.md [github-issue-95]: https://github.com/docker-mailserver/docker-mailserver/issues/95 [github-issue-97]: https://github.com/docker-mailserver/docker-mailserver/issues/97 [github-issue-1247]: https://github.com/docker-mailserver/docker-mailserver/issues/1247 diff --git a/docs/content/index.md b/docs/content/index.md index e6ee43db..35c8a9fc 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -11,7 +11,7 @@ This documentation provides you with advanced configuration, detailed examples, ## Getting Started 1. The script [`setup.sh`][github-file-setupsh] is supplied with this project. It supports you in **configuring and administrating** your server. Information on how to get it and how to use it is available [on a dedicated page][docs-setupsh]. -2. Be aware that advanced tasks may still require tweaking environment variables, reading through documentation and sometimes inspecting your running container for debugging purposes. After all, a mail server is a complex arrangement of various programs. +2. Be aware that advanced tasks may still require tweaking environment variables, reading through documentation and sometimes inspecting your running container for debugging purposes. After all, a mail-server is a complex arrangement of various programs. 3. A list of all configuration options is documented on [the ENV page][docs-environment]. The [`README.md`][github-file-readme] is a good starting point to understand what this image is capable of. 4. A list of all optional and automatically created configuration files and directories is available [on the dedicated page][docs-optionalconfig]. @@ -19,7 +19,7 @@ This documentation provides you with advanced configuration, detailed examples, See the [FAQ][docs-faq] for some more tips! !!! important - If you'd like to change, patch or alter files or behavior of `docker-mailserver`, you can use a script. Just place it in the `config/` folder that is created on startup and call it `user-patches.sh`. If you'd like to see the full documentation and an example, visit the ['Modifications via Script' page][docs-userpatches]. + If you'd like to change, patch or alter files or behavior of `docker-mailserver`, you can use a script. Just place a script called `user-patches.sh` in your `./docker-data/dms/config/` folder volume and it will be run on container startup. See the ['Modifications via Script' page][docs-userpatches]for additional documentation and an example. ## Contributing diff --git a/docs/content/introduction.md b/docs/content/introduction.md index 14ea6fb8..17c9b593 100644 --- a/docs/content/introduction.md +++ b/docs/content/introduction.md @@ -1,29 +1,27 @@ --- -title: An Introduction to Mail Servers +title: An overview of Mail-Server infrastructure --- -# An Introduction to Mail Servers - -What is a mail server and how does it perform its duty? +What is a mail-server, and how does it perform its duty? Here's an introduction to the field that covers everything you need to know to get started with `docker-mailserver`. -## Anatomy of a Mail Server +## Anatomy of a Mail-Server -A mail server is only a part of a [client-server relationship][wikipedia-clientserver] aimed at exchanging information in the form of [emails][wikipedia-email]. Exchanging emails requires using specific means (programs and protocols). +A mail-server is only a part of a [client-server relationship][wikipedia-clientserver] aimed at exchanging information in the form of [emails][wikipedia-email]. Exchanging emails requires using specific means (programs and protocols). `docker-mailserver` provides you with the server portion, whereas the client can be anything from a terminal via text-based software (eg. [Mutt][software-mutt]) to a fully-fledged desktop application (eg. [Mozilla Thunderbird][software-thunderbird], [Microsoft Outlook][software-outlook]…), to a web interface, etc. -Unlike the client-side where usually a single program is used to perform retrieval and viewing of emails, the server-side is composed of many specialized components. The mail server is capable of accepting, forwarding, delivering, storing and overall exchanging messages, but each one of those tasks is actually handled by a specific piece of software. All of these "agents" must be integrated with one another for the exchange to take place. +Unlike the client-side where usually a single program is used to perform retrieval and viewing of emails, the server-side is composed of many specialized components. The mail-server is capable of accepting, forwarding, delivering, storing and overall exchanging messages, but each one of those tasks is actually handled by a specific piece of software. All of these "agents" must be integrated with one another for the exchange to take place. -`docker-mailserver` has made informed choices about those components and their (default) configuration. It offers a comprehensive platform to run a fully featured mail server in no time! +`docker-mailserver` has made informed choices about those components and their (default) configuration. It offers a comprehensive platform to run a fully featured mail-server in no time! ## Components The following components are required to create a [complete delivery chain][wikipedia-emailagent]: -- MUA: a [Mail User Agent][wikipedia-mua] is basically any client/program capable of sending emails to arbitrary mail servers; while also capable of fetching emails from mail servers for presenting them to the end users. -- MTA: a [Mail Transfer Agent][wikipedia-mta] is the so-called "mail server" as seen from the MUA's perspective. It's a piece of software dedicated to accepting submitted emails, then forwarding them-where exactly will depend on an email's final destination. If the receiving MTA is responsible for the hostname the email is sent to, then an MTA is to forward that email to an MDA (see below). Otherwise, it is to transfer (ie. forward, relay) to another MTA, "closer" to the email's final destination. +- MUA: a [Mail User Agent][wikipedia-mua] is basically any client/program capable of sending emails to a mail-server; while also capable of fetching emails from a mail-server for presenting them to the end users. +- MTA: a [Mail Transfer Agent][wikipedia-mta] is the so-called "mail-server" as seen from the MUA's perspective. It's a piece of software dedicated to accepting submitted emails, then forwarding them-where exactly will depend on an email's final destination. If the receiving MTA is responsible for the FQDN the email is sent to, then an MTA is to forward that email to an MDA (see below). Otherwise, it is to transfer (ie. forward, relay) to another MTA, "closer" to the email's final destination. - MDA: a [Mail Delivery Agent][wikipedia-mda] is responsible for accepting emails from an MTA and dropping them into their recipients' mailboxes, whichever the form. Here's a schematic view of mail delivery: @@ -64,7 +62,7 @@ Fetching an email: MUA <------------------------------ ┫ MDA ╯ ┃ One important thing to note is that MTA and MDA programs may actually handle _multiple_ tasks (which is the case with `docker-mailserver`'s Postfix and Dovecot). -For instance, Postfix is both an SMTP server (accepting emails) and a relaying MTA (transferring, ie. sending emails to other MTA/MDA); Dovecot is both an MDA (delivering emails in mailboxes) and an IMAP server (allowing MUAs to fetch emails from the *mail server*). On top of that, Postfix may rely on Dovecot's authentication capabilities. +For instance, Postfix is both an SMTP server (accepting emails) and a relaying MTA (transferring, ie. sending emails to other MTA/MDA); Dovecot is both an MDA (delivering emails in mailboxes) and an IMAP server (allowing MUAs to fetch emails from the *mail-server*). On top of that, Postfix may rely on Dovecot's authentication capabilities. The exact relationship between all the components and their respective (sometimes shared) responsibilities is beyond the scope of this document. Please explore this wiki & the web to get more insights about `docker-mailserver`'s toolchain. @@ -143,7 +141,7 @@ Me ---------------> ┤ ├ -----------------> ┊ The best practice as of 2020 when it comes to securing Outward Submission is to use _Implicit TLS connection via ESMTP on port 465_ (see [RFC 8314][rfc-8314]). Let's break it down. - Implicit TLS means the server _enforces_ the client into using an encrypted TCP connection, using [TLS][wikipedia-tls]. With this kind of connection, the MUA _has_ to establish a TLS-encrypted connection from the get go (TLS is implied, hence the name "Implicit"). Any client attempting to either submit email in cleartext (unencrypted, not secure), or requesting a cleartext connection to be upgraded to a TLS-encrypted one using `STARTTLS`, is to be denied. Implicit TLS is sometimes called Enforced TLS for that reason. -- [ESMTP][wikipedia-esmtp] is [SMTP][wikipedia-smtp] + extensions. It's the version of the SMTP protocol that most mail servers speak nowadays. For the purpose of this documentation, ESMTP and SMTP are synonymous. +- [ESMTP][wikipedia-esmtp] is [SMTP][wikipedia-smtp] + extensions. It's the version of the SMTP protocol that a mail-server commonly communicates with today. For the purpose of this documentation, ESMTP and SMTP are synonymous. - Port 465 is the reserved TCP port for Implicit TLS Submission (since 2018). There is actually a boisterous history to that ports usage, but let's keep it simple. !!! warning @@ -151,7 +149,7 @@ The best practice as of 2020 when it comes to securing Outward Submission is to Although a very satisfactory setup, Implicit TLS on port 465 is somewhat "cutting edge". There exists another well established mail Submission setup that must be supported as well, SMTP+STARTTLS on port 587. It uses Explicit TLS: the client starts with a cleartext connection, then the server informs a TLS-encrypted "upgraded" connection may be established, and the client _may_ eventually decide to establish it prior to the Submission. Basically it's an opportunistic, opt-in TLS upgrade of the connection between the client and the server, at the client's discretion, using a mechanism known as [STARTTLS][wikipedia-starttls] that both ends need to implement. -In many implementations, the mail server doesn't enforce TLS encryption, for backwards compatibility. Clients are thus free to deny the TLS-upgrade proposal (or [misled by a hacker](https://security.stackexchange.com/questions/168998/what-happens-if-starttls-dropped-in-smtp) about STARTTLS not being available), and the server accepts unencrypted (cleartext) mail exchange, which poses a confidentiality threat and, to some extent, spam issues. [RFC 8314 (section 3.3)][rfc-8314-s33] recommends for mail servers to support both Implicit and Explicit TLS for Submission, _and_ to enforce TLS-encryption on ports 587 (Explicit TLS) and 465 (Implicit TLS). That's exactly `docker-mailserver`'s default configuration: abiding by RFC 8314, it [enforces a strict (`encrypt`) STARTTLS policy](http://www.postfix.org/postconf.5.html#smtpd_tls_security_level), where a denied TLS upgrade terminates the connection thus (hopefully but at the client's discretion) preventing unencrypted (cleartext) Submission. +In many implementations, the mail-server doesn't enforce TLS encryption, for backwards compatibility. Clients are thus free to deny the TLS-upgrade proposal (or [misled by a hacker](https://security.stackexchange.com/questions/168998/what-happens-if-starttls-dropped-in-smtp) about STARTTLS not being available), and the server accepts unencrypted (cleartext) mail exchange, which poses a confidentiality threat and, to some extent, spam issues. [RFC 8314 (section 3.3)][rfc-8314-s33] recommends for a mail-server to support both Implicit and Explicit TLS for Submission, _and_ to enforce TLS-encryption on ports 587 (Explicit TLS) and 465 (Implicit TLS). That's exactly `docker-mailserver`'s default configuration: abiding by RFC 8314, it [enforces a strict (`encrypt`) STARTTLS policy](http://www.postfix.org/postconf.5.html#smtpd_tls_security_level), where a denied TLS upgrade terminates the connection thus (hopefully but at the client's discretion) preventing unencrypted (cleartext) Submission. - **`docker-mailserver`'s default configuration enables and _requires_ Explicit TLS (STARTTLS) on port 587 for Outward Submission.** - It does not enable Implicit TLS Outward Submission on port 465 by default. One may enable it through simple custom configuration, either as a replacement or (better!) supplementary mean of secure Submission. @@ -185,7 +183,7 @@ Me -- STARTTLS ---> ┤(587) My MTA │ ┊ Third-part ### Retrieval - IMAP -A MUA willing to fetch an email from a mail server will most likely communicate with its [IMAP][wikipedia-imap] server. As with SMTP described earlier, communication will take place in the form of data packets exchanged over a network that both the client and the server are connected to. The IMAP protocol makes the server capable of handling _Retrieval_. +A MUA willing to fetch an email from a mail-server will most likely communicate with its [IMAP][wikipedia-imap] server. As with SMTP described earlier, communication will take place in the form of data packets exchanged over a network that both the client and the server are connected to. The IMAP protocol makes the server capable of handling _Retrieval_. In the case of `docker-mailserver`, the IMAP server is Dovecot. The MUA (client) may vary, yet its Retrieval request is performed as [TCP][wikipedia-tcp] packets sent over the _public_ internet. This exchange of information may be secured in order to counter eavesdropping. @@ -205,7 +203,7 @@ The best practice as of 2020 would be [POP3S][wikipedia-pop3s] on port 995, rath ## How does `docker-mailserver` help with setting everything up? -As a _batteries included_ Docker image, `docker-mailserver` provides you with all the required components and a default configuration, to run a decent and secure mail server. +As a _batteries included_ Docker image, `docker-mailserver` provides you with all the required components and a default configuration, to run a decent and secure mail-server. One may then customize all aspects of its internal components. @@ -221,7 +219,7 @@ We believe `docker-mailserver`'s default configuration to be a good middle groun Eventually, it is up to _you_ deciding exactly what kind of transportation/encryption to use and/or enforce, and to customize your instance accordingly (with looser or stricter security). Be also aware that protocols and ports on your server can only go so far with security; third-party MTAs might relay your emails on insecure connections, man-in-the-middle attacks might still prove effective, etc. Advanced counter-measure such as DANE, MTA-STS and/or full body encryption (eg. PGP) should be considered as well for increased confidentiality, but ideally without compromising backwards compatibility so as to not block emails. -The [README][github-file-readme] is the best starting point in configuring and running your mail server. You may then explore this wiki to cover additional topics, including but not limited to, security. +The [README][github-file-readme] is the best starting point in configuring and running your mail-server. You may then explore this wiki to cover additional topics, including but not limited to, security. [docs-understandports]: ./config/security/understanding-the-ports.md [github-file-compose]: https://github.com/docker-mailserver/docker-mailserver/blob/master/docker-compose.yml diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 6fb2005c..c85ce93c 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -1,6 +1,6 @@ # Site specific: site_name: 'Docker Mailserver' -site_description: 'A fullstack but simple mail server (SMTP, IMAP, LDAP, Antispam, Antivirus, etc.) using Docker.' +site_description: 'A fullstack but simple mail-server (SMTP, IMAP, LDAP, Antispam, Antivirus, etc.) using Docker.' site_author: 'docker-mailserver (Github Organization)' copyright: '

© Docker Mailserver Organization
This project is licensed under the MIT license.

' @@ -146,10 +146,10 @@ nav: - 'Examples': - 'Tutorials': - 'Basic Installation': examples/tutorials/basic-installation.md - - 'Mailserver behind Proxy': examples/tutorials/mailserver-behind-proxy.md + - 'Mail-Server behind a Proxy': examples/tutorials/mailserver-behind-proxy.md - 'Blog Posts': examples/tutorials/blog-posts.md - 'Use Cases': - - 'Forward-Only Mailserver with LDAP': examples/uses-cases/forward-only-mailserver-with-ldap-authentication.md + - 'Forward-Only Mail-Server with LDAP': examples/uses-cases/forward-only-mailserver-with-ldap-authentication.md - 'Customize IMAP Folders': examples/uses-cases/imap-folders.md - 'FAQ' : faq.md - 'Contributing': diff --git a/setup.sh b/setup.sh index 6184f6f8..7e8dec0f 100755 --- a/setup.sh +++ b/setup.sh @@ -48,15 +48,15 @@ function _show_local_usage printf "${ORANGE}OPTIONS${RESET} ${LBLUE}Config path, container or image adjustments${RESET} -i IMAGE_NAME - Provides the name of the docker-mailserver image. The default value is - ${WHITE}docker.io/mailserver/docker-mailserver:latest${RESET} + Provides the name of the 'docker-mailserver' image. The default value is + '${WHITE}docker.io/mailserver/docker-mailserver:latest${RESET}' -c CONTAINER_NAME Provides the name of the running container. -p PATH Provides the local path of the config folder to the temporary container instance. - Does not work if an existing docker-mailserver container is already running. + Does not work if an existing a 'docker-mailserver' container is already running. ${LBLUE}SELinux${RESET} -z @@ -210,7 +210,7 @@ function _main if test -t 0 then - USE_TTY="-ti" + USE_TTY="-it" else # GitHub Actions will fail (or really anything else # lacking an interactive tty) if we don't set a diff --git a/target/bin/setup b/target/bin/setup index 088ed579..851beaec 100644 --- a/target/bin/setup +++ b/target/bin/setup @@ -20,7 +20,7 @@ function _usage printf "${PURPLE}SETUP${RED}(${YELLOW}1${RED}) ${ORANGE}NAME${RESET} - ${SCRIPT:-${0}} - docker-mailserver administration & configuration script + ${SCRIPT:-${0}} - 'docker-mailserver' Administration & Configuration script ${ORANGE}SYNOPSIS${RESET} ./${SCRIPT:-${0}} [ OPTIONS${RED}...${RESET} ] COMMAND [ help ${RED}|${RESET} ARGUMENTS${RED}...${RESET} ] @@ -28,19 +28,19 @@ ${ORANGE}SYNOPSIS${RESET} COMMAND ${RED}:=${RESET} { email ${RED}|${RESET} alias ${RED}|${RESET} quota ${RED}|${RESET} config ${RED}|${RESET} relay ${RED}|${RESET} debug } SUBCOMMAND ${ORANGE}DESCRIPTION${RESET} - This is the main administration script that you use for all interactions with your - mail server. Setup, configuration and much more is done with this script. + This is the main administration script that you use for all your interactions with + 'docker-mailserver'. Setup, configuration and much more is done with this script. - Please note that this script executes most of its commands inside the running 'mailserver' - container itself. If it cannot find a running container, it will attempt to run one using - any available tags which include label=org.opencontainers.image.title=\"docker-mailserver\" + Please note that this script executes most of its commands inside the container itself. + If it cannot find a running 'docker-mailserver' container, it will attempt to run one using + any available tags which include 'label=org.opencontainers.image.title=\"docker-mailserver\"' and then run the necessary commands. If the tag for the container is not found, this script - will pull the ${WHITE}:latest${RESET} tag of ${WHITE}docker.io/mailserver/docker-mailserver${RESET}.This tag refers to the - latest release, see the tagging convention in the README under + will pull the '${WHITE}:latest${RESET}' tag of '${WHITE}docker.io/mailserver/docker-mailserver${RESET}'. + This tag refers to the latest release, see the tagging convention in the README under: ${BLUE}https://github.com/docker-mailserver/docker-mailserver/blob/master/README.md${RESET} You will be able to see detailed information about the script you're invoking and their - arguments by appending ${WHITE}help${RESET} after your command. Currently, this does not work with all scripts. + arguments by appending '${WHITE}help${RESET}' after your command. Currently, this does not work with all scripts. ${RED}[${ORANGE}SUB${RED}]${ORANGE}COMMANDS${RESET} ${LBLUE}COMMAND${RESET} email ${RED}:=${RESET} @@ -75,11 +75,11 @@ ${RED}[${ORANGE}SUB${RED}]${ORANGE}COMMANDS${RESET} ${0} debug ${CYAN}login${RESET} ${ORANGE}EXAMPLES${RESET} - ${WHITE}./setup.sh email add test@domain.tld${RESET} - Add the email account ${WHITE}test@domain.tld${RESET}. You will be prompted + ${WHITE}./setup.sh email add test@example.com${RESET} + Add the email account ${WHITE}test@example.com${RESET}. You will be prompted to input a password afterwards since no password was supplied. - ${WHITE}./setup.sh config dkim keysize 2048 domain 'whoami.com,whoareyou.org'${RESET} + ${WHITE}./setup.sh config dkim keysize 2048 domain 'example.com,not-example.com'${RESET} Creates keys of length 2048 but in an LDAP setup where domains are not known to Postfix by default, so you need to provide them yourself in a comma-separated list. diff --git a/target/scripts/startup/setup-stack.sh b/target/scripts/startup/setup-stack.sh index 8a1d1c04..ea99e7e2 100644 --- a/target/scripts/startup/setup-stack.sh +++ b/target/scripts/startup/setup-stack.sh @@ -293,7 +293,7 @@ function _setup_dovecot_quota if [[ ! -f /tmp/docker-mailserver/dovecot-quotas.cf ]] then - _notify 'inf' "'config/docker-mailserver/dovecot-quotas.cf' is not provided. Using default quotas." + _notify 'inf' "'/tmp/docker-mailserver/dovecot-quotas.cf' is not provided. Using default quotas." : >/tmp/docker-mailserver/dovecot-quotas.cf fi @@ -316,7 +316,7 @@ function _setup_dovecot_local_user sed -i 's|\r||g' /tmp/docker-mailserver/postfix-accounts.cf _notify 'inf' "Regenerating postfix user list" - echo "# WARNING: this file is auto-generated. Modify config/postfix-accounts.cf to edit user list." > /etc/postfix/vmailbox + echo "# WARNING: this file is auto-generated. Modify /tmp/docker-mailserver/postfix-accounts.cf to edit the user list." > /etc/postfix/vmailbox # checking that /tmp/docker-mailserver/postfix-accounts.cf ends with a newline # shellcheck disable=SC1003 @@ -366,7 +366,7 @@ function _setup_dovecot_local_user echo "${DOMAIN}" >> /tmp/vhost.tmp done < <(grep -v "^\s*$\|^\s*\#" /tmp/docker-mailserver/postfix-accounts.cf) else - _notify 'inf' "'config/docker-mailserver/postfix-accounts.cf' is not provided. No mail account created." + _notify 'inf' "'/tmp/docker-mailserver/postfix-accounts.cf' is not provided. No mail account created." fi if ! grep '@' /tmp/docker-mailserver/postfix-accounts.cf 2>/dev/null | grep -q '|' @@ -709,7 +709,7 @@ function _setup_postfix_aliases [[ ${UNAME} != "${DOMAIN}" ]] && echo "${DOMAIN}" >>/tmp/vhost.tmp done < <(grep -v "^\s*$\|^\s*\#" /tmp/docker-mailserver/postfix-virtual.cf || true) else - _notify 'inf' "Warning 'config/postfix-virtual.cf' is not provided. No mail alias/forward created." + _notify 'inf' "Warning '/tmp/docker-mailserver/postfix-virtual.cf' is not provided. No mail alias/forward created." fi if [[ -f /tmp/docker-mailserver/postfix-regexp.cf ]] @@ -730,7 +730,7 @@ function _setup_postfix_aliases then cat /tmp/docker-mailserver/postfix-aliases.cf >>/etc/aliases else - _notify 'inf' "'config/postfix-aliases.cf' is not provided and will be auto created." + _notify 'inf' "'/tmp/docker-mailserver/postfix-aliases.cf' is not provided, it will be auto created." : >/tmp/docker-mailserver/postfix-aliases.cf fi @@ -1264,7 +1264,7 @@ function _setup_postfix_override_configuration postconf -e "${LINE}" fi done < /tmp/docker-mailserver/postfix-main.cf - _notify 'inf' "Loaded 'config/postfix-main.cf'" + _notify 'inf' "Loaded '/tmp/docker-mailserver/postfix-main.cf'" else _notify 'inf' "No extra postfix settings loaded because optional '/tmp/docker-mailserver/postfix-main.cf' not provided." fi @@ -1278,7 +1278,7 @@ function _setup_postfix_override_configuration postconf -P "${LINE}" fi done < /tmp/docker-mailserver/postfix-master.cf - _notify 'inf' "Loaded 'config/postfix-master.cf'" + _notify 'inf' "Loaded '/tmp/docker-mailserver/postfix-master.cf'" else _notify 'inf' "No extra postfix settings loaded because optional '/tmp/docker-mailserver/postfix-master.cf' not provided." fi