Delivery targets

This man page describes modules that can used with 'deliver_to' directive of SMTP endpoint module.

SQL module (target.imapsql)

SQL module described in maddy-storage(5) can also be used as a delivery target.

Queue module (target.queue)

Queue module buffers messages on disk and retries delivery multiple times to another target to ensure reliable delivery.

target.queue {
    target remote
    location ...
    max_parallelism 16
    max_tries 4
    bounce {
        destination example.org {
            deliver_to &local_mailboxes
        }
        default_destination {
            reject
        }
    }

    autogenerated_msg_domain example.org
    debug no
}

Arguments

First argument specifies directory to use for storage. Relative paths are relative to the StateDirectory.

Configuration directives

Syntax: target block_name
Default: not specified

REQUIRED.

Delivery target to use for final delivery.

Syntax: location directory
Default: StateDirectory/configuration_block_name

File system directory to use to store queued messages. Relative paths are relative to the StateDirectory.

Syntax: max_parallelism integer
Default: 16

Start up to integer goroutines for message processing. Basically, this option limits amount of messages tried to be delivered concurrently.

Syntax: max_tries integer
Default: 20

Attempt delivery up to integer times. Note that no more attempts will be done is permanent error occured during previous attempt.

Delay before the next attempt will be increased exponentally using the following formula: 15mins * 1.2 ^ (n - 1) where n is the attempt number. This gives you approximately the following sequence of delays: 18mins, 21mins, 25mins, 31mins, 37mins, 44mins, 53mins, 64mins, ...

Syntax: bounce { ... }
Default: not specified

This configuration contains pipeline configuration to be used for generated DSN (Delivery Status Notifiaction) messages.

If this is block is not present in configuration, DSNs will not be generated. Note, however, this is not what you want most of the time.

Syntax: autogenerated_msg_domain domain
Default: global directive value

Domain to use in sender address for DSNs. Should be specified too if 'bounce' block is specified.

Syntax: debug boolean
Default: no

Enable verbose logging.

Remote MX module (remote)

Module that implements message delivery to remote MTAs discovered via DNS MX records. You probably want to use it with queue module for reliability.

target.remote {
    hostname mx.example.org
    debug no
}

If a message check marks a message as 'quarantined', remote module will refuse to deliver it.

Configuration directives

Syntax: hostname domain
Default: global directive value

Hostname to use client greeting (EHLO/HELO command). Some servers require it to be FQDN, SPF-capable servers check whether it corresponds to the server IP address, so it is better to set it to a domain that resolves to the server IP.

Syntax: limits config block
Default: no limits

See 'limits' directive in maddy-smtp(5) for SMTP endpoint. It works the same except for address domains used for per-source/per-destination are as observed when message exits the server.

Syntax: local_ip IP address
Default: empty

Choose the local IP to bind for outbound SMTP connections.

Syntax: connect_timeout duration
Default: 5m

Timeout for TCP connection establishment.

RFC 5321 recommends 5 minutes for "initial greeting" that includes TCP handshake. maddy uses two separate timers - one for "dialing" (DNS A/AAAA lookup + TCP handshake) and another for "initial greeting". This directive configures the former. The latter is not configurable and is hardcoded to be 5 minutes.

Syntax: command_timeout duration
Default: 5m

Timeout for any SMTP command (EHLO, MAIL, RCPT, DATA, etc).

If STARTTLS is used this timeout also applies to TLS handshake.

RFC 5321 recommends 5 minutes for MAIL/RCPT and 3 minutes for DATA.

Syntax: submission_timeout duration
Default: 12m

Time to wait after the entire message is sent (after "final dot").

RFC 5321 recommends 10 minutes.

Syntax: debug boolean
Default: global directive value

Enable verbose logging.

Syntax: requiretls_override boolean
Default: true

Allow local security policy to be disabled using 'TLS-Required' header field in sent messages. Note that the field has no effect if transparent forwarding is used, message body should be processed before outbound delivery starts for it to take effect (e.g. message should be queued using 'queue' module).

Syntax: relaxed_requiretls boolean
Default: true

This option disables strict conformance with REQUIRETLS specification and allows forwarding of messages 'tagged' with REQUIRETLS to MXes that are not advertising REQUIRETLS support. It is meant to allow REQUIRETLS use without the need to have support from all servers. It is based on the assumption that server referenced by MX record is likely the final destination and therefore there is only need to secure communication towards it and not beyond.

Syntax: conn_reuse_limit integer
Default: 10

Amount of times the same SMTP connection can be used. Connections are never reused if the previous DATA command failed.

Syntax: conn_max_idle_count integer
Default: 10

Max. amount of idle connections per recipient domains to keep in cache.

Syntax: conn_max_idle_time integer
Default: 150 (2.5 min)

Amount of time the idle connection is still considered potentially usable.

Security policies

Syntax: mx_auth config block
Default: no policies

'remote' module implements a number of of schemes and protocols necessary to ensure security of message delivery. Most of these schemes are concerned with authentication of recipient server and TLS enforcement.

To enable mechanism, specify its name in the mx_auth directive block:

mx_auth {
    dane
    mtasts
}

Additional configuration is possible if supported by the mechanism by specifying additional options as a block for the corresponding mechanism. E.g.

mtasts {
    cache ram
}

If the mx_auth directive is not specified, no mechanisms are enabled. Note that, however, this makes outbound SMTP vulnerable to a numberous downgrade attacks and hence not recommended.

It is possible to share the same set of policies for multiple 'remote' module instances by defining it at the top-level using 'mx_auth' module and then referencing it using standard & syntax:

mx_auth outbound_policy {
    dane
    mtasts {
        cache ram
    }
}

# ... somewhere else ...

deliver_to remote {
    mx_auth &outbound_policy
}

# ... somewhere else ...

deliver_to remote {
    mx_auth &outbound_policy
    tls_client { ... }
}

Security policies: MTA-STS

Checks MTA-STS policy of the recipient domain. Provides proper authentication and TLS enforcement for delivery, but partially vulnerable to persistent active attacks.

Sets MX level to "mtasts" if the used MX matches MTA-STS policy even if it is not set to "enforce" mode.

mtasts {
    cache fs
    fs_dir StateDirectory/mtasts_cache
}

Syntax: cache fs|ram
Default: fs

Storage to use for MTA-STS cache. 'fs' is to use a filesystem directory, 'ram' to store the cache in memory.

It is recommended to use 'fs' since that will not discard the cache (and thus cause MTA-STS security to disappear) on server restart. However, using the RAM cache can make sense for high-load configurations with good uptime.

Syntax: fs_dir directory
Default: StateDirectory/mtasts_cache

Filesystem directory to use for policies caching if 'cache' is set to 'fs'.

Security policies: DNSSEC

Checks whether MX records are signed. Sets MX level to "dnssec" is they are.

maddy does not validate DNSSEC signatures on its own. Instead it reslies on the upstream resolver to do so by causing lookup to fail when verification fails and setting the AD flag for signed and verfified zones. As a safety measure, if the resolver is not 127.0.0.1 or ::1, the AD flag is ignored.

DNSSEC is currently not supported on Windows and other platforms that do not have the /etc/resolv.conf file in the standard format.

dnssec { }

Security policies: DANE

Checks TLSA records for the recipient MX. Provides downgrade-resistant TLS enforcement.

Sets TLS level to "authenticated" if a valid and matching TLSA record uses DANE-EE or DANE-TA usage type.

See above for notes on DNSSEC. DNSSEC support is required for DANE to work.

dane { }

Security policies: Local policy

Checks effective TLS and MX levels (as set by other policies) against local configuration.

local_policy {
    min_tls_level none
    min_mx_level none
}

Using 'local_policy off' is equivalent to setting both directives to 'none'.

Syntax: min_tls_level none|encrypted|authenticated
Default: none

Set the minimal TLS security level required for all outbound messages.

See Security levels page for details.

Syntax: min_mx_level: none|mtasts|dnssec
Default: none

Set the minimal MX security level required for all outbound messages.

See Security levels page for details.

SMTP transparent forwarding module (target.smtp)

Module that implements transparent forwarding of messages over SMTP.

Use in pipeline configuration:

deliver_to smtp tcp://127.0.0.1:5353
# or
deliver_to smtp tcp://127.0.0.1:5353 {
  # Other settings, see below.
}
target.smtp {
    debug no
    tls_client {
        ...
    }
    attempt_starttls yes
    require_tls no
    auth off
    targets tcp://127.0.0.1:2525
    connect_timeout 5m
    command_timeout 5m
    submission_timeout 12m
}

Endpoint addresses use format described in maddy-config(5).

Configuration directives

Syntax: debug boolean
Default: global directive value

Enable verbose logging.

Syntax: tls_client { ... }
Default: not specified

Advanced TLS client configuration options. See maddy-tls(5) for details.

Syntax: attempt_starttls boolean
Default: yes (no for target.lmtp)

Attempt to use STARTTLS if it is supported by the remote server. If TLS handshake fails, connection will be retried without STARTTLS unless 'require_tls' is also specified.

Syntax: require_tls boolean
Default: no

Refuse to pass messages over plain-text connections.

Syntax:
auth off
plain username password
forward
external
Default: off

Specify the way to authenticate to the remote server. Valid values:

Syntax: targets endpoints...
Default: not specified

REQUIRED.

List of remote server addresses to use. See Address definitions in maddy-config(5) for syntax to use. Basically, it is 'tcp://ADDRESS:PORT' for plain SMTP and 'tls://ADDRESS:PORT' for SMTPS (aka SMTP with Implicit TLS).

Multiple addresses can be specified, they will be tried in order until connection to one succeeds (including TLS handshake if TLS is required).

Syntax: connect_timeout duration
Default: 5m

Same as for target.remote.

Syntax: command_timeout duration
Default: 5m

Same as for target.remote.

Syntax: submission_timeout duration
Default: 12m

Same as for target.remote.

LMTP transparent forwarding module (target.lmtp)

The 'target.lmtp' module is similar to 'target.smtp' and supports all its options and syntax but speaks LMTP instead of SMTP.