DBMail with Exim
DBMail is a Message Delivery Agent and receives messages from any of a Message Transfer Agent, Message Submission Agent or Message User Agent. These can be delivered directly using dbmail-deliver or using any of the protocols LMTP, IMAP or POP. Exim can deliver email using dbmail-lmtp or dbmail-deliver. This article, together with the example template shows how to integrate DBMail with Exim.
Exim and DBMail are natural partners and the following example, found at https://github.com/dbmail/dbmail/blob/main/contrib/exim-dbmail-configure, uses dbmail-deliver to deliver incoming email to a users inbox. If a user has sieve scripts then dbmail will use them to ensure the email is delivered in the right location.
Exim and DBMail are natural partners. This article can be used with the exim config template exim-dbmail-configure to use Exim as the SMTP Message Transfer Agent (MTA) to deliver and store emails in DBMail as the Message Delivery Agent (MDA) for retrieval by any IMAP client. Both Exim and DBMail speak SQL and LDAP and both are included in this article and the template.
General settings
Exim defines various things such as servers and queries at the beginning of the configuration file, then access control lists for incoming smtp email, routers for how email should be handled, transports for how email should be delivered, then authentication.
Although straightforward, there are many configuration choices for email and organisations so this readme and the exim-dbmail-configuration template can only be a guide. As with any critical infrastructure, testing is essential.
DBMail can use PostgreSQL, MySQL and Oracle. The template uses sql authentication with PostgreSQL so if you use MySQL or Oracle change quote_pgsql to quote_mysql or quote_oracle. Also lookups ${lookup pgsql{}} ${lookup mysql{}} ${lookup oracle{}}. For LDAP uncomment the various sections in the template and comment out sql applying any changes for your organisation.
PostgreSQL
hide pgsql_servers = host/database/user/password
MySQL
hide mysql_servers = host/database/user/password
Oracle
hide oracle_servers = oracle.plc.example//user/password
LDAP
ldap_default_servers = example.com::389
The LDAP lookup needs configuring for your organisation
ALIAS_LDAP_VIRT_USER = \
user="uid=lookup,dc=example,dc=com" \
pass="password" \
ldap:///ou=users,dc=example,dc=com?uid?sub?(mail=${quote_ldap:$local_part}@${quote_ldap:$domain})} \
{$value}fail
It's essential to know who is authorised to send mail and when receiving where those emails should go. DBMail uses either SQL or LDAP for authentication and those are available to Exim.
Macro definitions
Exim uses macros for SQL queries, this template doesn't use them for LDAP. The three SQL queries to identify acceptable emails, domains for outgoing email and user authentication are:
- ALIAS_VIRT_USER for identifying valid emails;
- ALIAS_VIRT_DOMAIN for identifying domains;
- ALIAS_SERVER_AUTH_LOGIN for authenticating users.
For ldap:
- ALIAS_LDAP_VIRT_USER for identifying valid emails;
- ALIAS_LDAP_SERVER_AUTH_LOGIN for authenticating users.
Domain lookup can be either the SQL lookup or as LDAP is less flexible, simply revert to one of the exim suggestions:
# Define local_domains
domainlist local_domains = my.first.domain : my.second.domain
# Use local_domains
domains = +local_domains
Incoming mail
When exim receives mail, it checks with various ACLs. If you're using DBMail's sql authenticator, then it can check against known aliases:
require message = relay not permitted
domains = ${lookup pgsql{ALIAS_VIRT_DOMAIN}}
Ldap is less flexible so either revert to exim suggestions or you may prefer a local_domains sql table.
The local router checks if it can receive mail for a user and forwards it to the transport dbmail_delivery. Simply swap the condition for sql/ldap.
localuser:
driver = accept
condition = ${lookup pgsql{ALIAS_VIRT_USER}}
#condition = hide ${lookup ldap{ALIAS_LDAP_VIRT_USER}}
transport = dbmail_delivery
cannot_route_message = Unknown user
Delivering email
The transport dbmail_delivery calls dbmail-deliver to deliver the email. You may need to change the user and path depending on your distribution.
dbmail_delivery:
driver = pipe
command = "/usr/local/sbin/dbmail-deliver -d ${local_part}\@$domain"
return_fail_output
user = mail
If you have large volumes of mail you may prefer to have them delivered via lmtp.
dbmail_delivery:
driver = smtp
protocol = lmtp
hosts = localhost
allow_localhost
return_path_add
Authentication
Exim can authenticate users who submit email for forwarding with the same sql or ldap credentials as DBMail.
dbmail_login:
driver = plaintext
public_name = LOGIN
server_prompts = Username:: : Password::
server_condition = ${lookup pgsql{ALIAS_SERVER_AUTH_LOGIN}}
server_set_id = uid=$auth1
dbmail_login:
driver = plaintext
public_name = LOGIN
server_prompts = Username:: : Password::
server_condition = ${if and {{ \
!eq{}{$auth1} }{ \
ldapauth{user="uid=${quote_ldap_dn:$auth1},dc=example,dc=com" \
pass=${quote:$auth2} \
ldap://example.com} }} }
server_set_id = uid=$auth1
The exim-dbmail-configure template is kindly sponsored by XML Team llp.