DEBOPS.NULLMAILER(5)

NAME
debops.nullmailer - Manage nullmailer SMTP server with Ansible

SYNOPSIS

debops service/nullmailer [--limit group,host,...] [--diff] [--check] [--tags tag1,tag2,...] [--skip-tags tag1,tag2,...] [<ansible-playbook options>] ...

DESCRIPTION

The nullmailer <http://untroubled.org/nullmailer/> package can be used to setup a forwarding SMTP relay. It does not provide support for local mail, but forwards all messages to one or more remote SMTP servers for processing.

The debops.nullmailer role installs and configures the nullmailer service, optionally with a network access from remote hosts on port 25.

The role can detect other Mail Transport Agents installed on the managed host, and if an MTA from a configurable list is found, the role will automatically disable itself to allow easy switch to different SMTP servers.

GETTING STARTED

  Correct DNS configuration is recommended

The debops.nullmailer role uses the ansible_fqdn and ansible_domain variables to create correct values for the nullmailer service. It's recommended that the hosts which use nullmailer have the proper DNS configuration, which means that they should be resolvable in the DNS by their Fully Qualified Domain Name (hostname + domain name). The FQDN doesn't need to be accessible from the Internet when the hosts are on a private network, but it's recommended to select a subdomain of your main DNS domain and configure the DNS servers to advertise it on your private subnets.

  No local mail by default

The nullmailer service does not provide support for local mail - all mail is forwarded to the configured SMTP servers for further processing. If you need more advanced SMTP configuration, you should check out the debops.postfix role which can configure the Postfix MTA. This also means that in a new environment, you should prepare at least 1 host as the central mail hub for your network, or use an already existing SMTP server for relaying mail messages.

The debops.nullmailer role is designed to allow automatic switch to a different SMTP server - if it detects a postfix package installed on a host, it will automatically disable configuration of the nullmailer service to not interfere with existing Postfix configuration.

All mail directed to the local recipients will be forwarded to the root UNIX account on the upstream SMTP mail relay - if it's Postfix, then this will be a local UNIX account. There you can deal with the e-mail messages as you see fit - forward them to a virtual root@<domain> account, or to other people, filter them, etc.

Local sender and recipient addresses without specified FQDN domain will have the host's FQDN set in their e-mail address "domain" part. This might be not desirable when you use multiple hosts behind a mail relay and send messages to external recipients. In that case, in the Postfix service on the mail relay you can configure domain masquerading <http://www.postfix.org/ADDRESS_REWRITING_README.html#masquerade> to mask the internal hostnames.

If you use the debops.postfix role to manage the mail relay, you can do that with the following configuration in the Ansible inventory:

postfix__maincf:
  - name: 'masquerade_domains'
    value: [ 'example.org' ]
  - name: 'local_header_rewrite_clients'
    value: [ 'permit_inet_interfaces, 'permit_mynetworks',
             'permit_sasl_authenticated' ]
  - name: 'masquerade_exceptions'
    value: [ 'MAILER-DAEMON', 'postmaster', 'root' ]

This will mask any.thing.example.org in the e-mail addresses of senders and recipients and will convert them to example.org. The exceptions will ensure that the mail from root account is not rewritten and points to the correct host.

  Default SMTP relay

The role detects the preferred upstream SMTP relay by using DNS SRV Records for the following service:

_smtp._tcp.{{ nullmailer__domain }} (default port 25)

At the moment, only a single SRV resource record is supported.

If the SRV record is not found, the role will fall back to using static domain names, based on the host domain (nullmailer__domain):

SMTP:  smtp.example.org:25

For details on how to configure DNS SRV records, see DNS SRV Records. Alternatively, you can override the SRV based detection by defining a relay host in the Ansible inventory:

# ansible/inventory/group_vars/all/nullmailer.yml
nullmailer__relayhost: '<FQDN address of mail server>'

See Overriding DNS SRV Queries for more details.

  LDAP integration

If the LDAP environment is configured on the host, the debops.nullmailer role will automatically use it to create an LDAP service account in the directory. The relayhost configuration will have SMTP authentication enabled with the nullmailer@<host.example.org> username, which can then be used by the relay server via SASL authentication to find the corresponding nullmailer account in the LDAP directory and authenticate the service.

See the debops.postldap Ansible role documentation for details about configuring Postfix mail relay with LDAP directory support.

  Example inventory

The debops.nullmailer role is included by default in the common DebOps playbook and you don't need to add a host to a custom inventory group to activate it.

  Example playbook

If you are using this role without DebOps, here's an example Ansible playbook that uses the debops.nullmailer role:

---
- name: Manage nullmailer SMTP server
  collections: [ 'debops.debops', 'debops.roles01',
                 'debops.roles02', 'debops.roles03' ]
  hosts: [ 'debops_all_hosts', 'debops_service_nullmailer' ]
  become: True
  environment: '{{ inventory__environment | d({})
                   | combine(inventory__group_environment | d({}))
                   | combine(inventory__host_environment  | d({})) }}'
  pre_tasks:
    - name: Prepare nullmailer environment
      import_role:
        name: 'nullmailer'
        tasks_from: 'main_env'
      tags: [ 'role::nullmailer', 'role::ferm', 'role::tcpwrappers' ]
  roles:
    - role: python
      tags: [ 'role::python', 'skip::python', 'role::ldap' ]
      python__dependent_packages3:
        - '{{ ldap__python__dependent_packages3 }}'
      python__dependent_packages2:
        - '{{ ldap__python__dependent_packages2 }}'
    - role: ldap
      tags: [ 'role::ldap', 'skip::ldap' ]
      ldap__dependent_tasks:
        - '{{ nullmailer__ldap__dependent_tasks }}'
    - role: ferm
      tags: [ 'role::ferm', 'skip::ferm' ]
      ferm__dependent_rules:
        - '{{ nullmailer__ferm__dependent_rules }}'
    - role: tcpwrappers
      tags: [ 'role::tcpwrappers', 'skip::tcpwrappers' ]
      tcpwrappers__dependent_allow:
        - '{{ nullmailer__tcpwrappers__dependent_allow }}'
    - role: nullmailer
      tags: [ 'role::nullmailer', 'skip::nullmailer' ]

DEFAULT VARIABLE DETAILS

Some of debops.nullmailer default variables have more extensive configuration than simple strings or lists, here you can find documentation and examples for them.

  nullmailer__remotes

This list, as well as nullmailer__default_remotes, is used to configure where nullmailer should forward all mail messages. Each element of a list can be either a string that defines the exact line in the /etc/nullmailer/remotes configuration file, or a YAML dictionary with following parameters:

host
    Required. DNS hostname of the SMTP server to which all messages will be forwarded.

protocol
    Optional. Specify the daemon from /usr/lib/nullmailer/ which should be used to send the mail messages. Either smtp (default) or qmtp.

port
    Optional. Specify the port to connect. If not specified, 25 will be used as default.

starttls
    Optional, boolean. If not specified and nullmailer__starttls is enabled, each configured SMTP server will be asked to provide encrypted connection using STARTTLS command. If item.ssl or item.options parameters are specified, the STARTTLS support is not enabled by default.

ssl Optional, boolean. If enabled, new connections to this SMTP server will automatically be encrypted using SSL. This usually requires a different port for communication, typically 465.

insecure
    Optional, boolean. By default when encrypted connections are used, nullmailer checks the validity of the X.509 certificate provided by the server. If this parameter is enabled, the validity checks won't be performed.

x509cafile
    Optional. Specify absolute path to the X.509 Certificate Authority certificate which should be used to validate the certificate of a given SMTP server. If not specified, the system-wide CA database will be used.

x509certfile
    Optional. Specify absolute path to the X.509 certificate which should be presented to the remote SMTP server for authentication.

x509crlfile
    Optional. Specify absolute path to the CRL file which should be used to validate the certificate provided by the remote SMTP server.

x509fmtder
    Optional, boolean. If enabled, indicates that the specified certificates are in DER format (PEM otherwise).

auth or auth_login
    Optional, boolean. If enabled, indicates that the specified sever requires user authentication before accepting forwarded mail messages.

user
    Optional. Specify the username which should be used to login to the remote SMTP server.

pass or password
    Optional. Specify the password which should be used to login to the remote SMTP server.

options
    Optional. Custom list of options recognized by the nullmailer protocol modules. Check the usage information in the /usr/lib/nullmailer/* commands to see possible options, and examples below to see how they can be used.

  Examples

Configure a remote SMTP server without TLS encryption:

nullmailer__remotes:
  - host: 'mx.example.org'
    starttls: False

Configure a remote SMTP server with mail messages delivered via submission protocol:

nullmailer__remotes:
  - host: 'mail.example.org'
    port: '587'
    auth: True
    user: 'username'
    pass: 'password'

Configure GMail as remote SMTP server with options specified manually:

nullmailer__remotes:
  - host: 'smtp.gmail.com'
    options: [ '--starttls', '--port=587', '--auth-login',
               '--user=username', '--pass=password' ]

  nullmailer__configuration_files

This list, as well as nullmailer__private_configuration_files, manages configuration files used by the nullmailer service. Each entry in the list is a YAML dictionary with parameters:

dest
    Required. Absolute path to the configuration file.

content
    File contents which should be placed in the configuration file. If it results in an empty string, file will be empty. Not needed if item.src is specified.

src Absolute path to the source file located on the Ansible Controller. Not needed if item.content is specified.

state
    Optional. If not specified or present, the configuration file will be created. If absent, the configuration file will be removed.

owner
    Optional. Specify an user account which should be the owner of the configuration file. The user account must already exist.

group
    Optional. Specify what group the configuration file belongs to. The group must already exist.

mode
    Optional. Specify the file attributes which should be set for the configuration file.

    You can find the usage examples of these lists in the role defaults/main.yml file.

AUTHOR
Maciej Delmanowski

COPYRIGHT
2014-2022, Maciej Delmanowski, Nick Janetakis, Robin Schneider and others