Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F120823998
cyrus-imap-murder-topologies.rst
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
9 KB
Referenced Files
None
Subscribers
None
cyrus-imap-murder-topologies.rst
View Options
..
_deployment_imap_cyrus-imap-murder:
============================
Cyrus IMAP Murder Topologies
============================
A Cyrus IMAP Murder is an aggregate of multiple Cyrus IMAP servers, providing
transparent access to mailboxes throughout the murder.
For the purpose of this documentation, the following terminology needs to be
outlined:
frontend
A Cyrus IMAP frontend is a functional component that receives connections
from clients, and proxies those to the backend on which the relevant mailbox
resides.
..
NOTE
::
Please note that a frontend proxies the connection on a per-mailbox
level (as needed). As such, the client connection is
*terminated*
at the
frontend, the frontend
*interprets*
the protocol, and decides what
backend to create a
*new*
connection to (if needed).
backend
A Cyrus IMAP backend is the functional component that actually holds and
maintains a mail spool containing mailboxes and messages.
mupdate
To aggregate various backends, compose a single authoritative list of
mailboxes available throughout the murder, and communicate these to the
frontends, a Cyrus IMAP murder requires a server to be the mupdate master.
.. The Cyrus IMAP Murder Use-Case
.. ==============================
..
.. .. todo::
..
.. Document what exactly a Cyrus IMAP Murder offers in terms of features.
..
.. Other Scaling Options with Cyrus IMAP
.. =====================================
..
.. .. todo::
..
.. Insert the NGINX proxy use case and put it in light of the murder use-case.
Discrete Murder
===============
A Cyrus IMAP Discrete Murder topology separates frontends from backends.
As illustrated in the next diagram, the Mail User Agent (MUA) connects to a
frontend, and is proxied to
*backend1*
for the user's own mailbox, or
*backend2*
for a shared mailbox that resides on that server.
..
graphviz
::
digraph murder_discrete {
"MUA" -> "frontend" [ label = "client connection" ];
"frontend" -> "INBOX" [ label = "proxied connection" ];
"frontend" -> "shared/memo" [ label = "proxied connection" ];
}
In such a deployment scenario, the daemon responsible for synchronizing changes
made to LDAP with IMAP, called
**kolabd**
, recognizes the topology of a murder
and assures the LDAP
``mailHost``
attribute is set to the correct value -- the
FQDN
[#]_
of the backend system the mailbox is hosted on.
..
seealso
::
*
:ref:
`deployment_discrete-cyrus-imapd-considerations`
.. Unified Murder
.. ==============
..
.. In a Unified Cyrus IMAP Murder, all systems perform both the frontend as well as
.. the backend function. This means a user may connect to any backend, and be
.. proxied to other backends as needed.
..
.. .. graphviz::
..
.. digraph murder_unified {
.. rankdir=LR;
.. "MUA" -> "john.doe@example.org" [ label = "client connection" ];
.. "john.doe@example.org" -> "john.doe@example.org" [ label = "INBOX is local" ];
.. "john.doe@example.org" -> "shared/memo" [ label = "proxied connection" ];
.. }
..
.. A large unified murder is often fronted by NGINX IMAP proxies, so that the user
.. is initially proxied to the backend that holds the user's INBOX.
..
.. .. todo:: Write more about fronting a murder with NGINX IMAP proxies.
..
.. Replicated Murder
.. =================
..
.. .. todo:: Include a topology diagram for a Cyrus IMAP replicated murder topology
..
_deployment_discrete-cyrus-imapd-considerations:
Deployment Considerations for a Discrete Cyrus IMAP Murder Topology
===================================================================
In a Cyrus IMAP Discrete Murder topology, inbound as well as outbound
[#]_
email
messages need to be routed to and from the IMAP backend server, that hosts the
mailbox to which the email is to be delivered.
Similarly, backends need to be configured such that they do not find themselves
authoritative for the entire domain -- as part of the recipients is hosted on
other backends -- and use the ''smart'' internal MTA to relay messages to.
..
graphviz
::
digraph murder_discrete {
subgraph cluster_backend1 {
label = "backend1";
"John";
}
subgraph cluster_backend2 {
label = "backend2";
"Jane";
}
"MTA (Internal)" -> "John", "Jane" [label="inbound"];
"John", "Jane" -> "MTA (Internal)" [label="outbound"];
"MTA (Internal)" -> "MTA (Internet)" [dir=both];
}
The
*MTA (Internal)*
can use a lookup table for local recipients (valid
recipient addresses in any of the
:term:
`mydestination`
or
:term:
`relay_domains`
domain name spaces), that routes (instead of delivers) the message through to
the correct backend (called a
*transport map*
), using the LDAP
``mailHost``
attribute value for entries.
To configure such transport map lookup table, adjust the contents of the
following snippet to suite your deployment and save it to
:file:
`/etc/postfix/ldap/transport_maps.cf`
-- this file could exist already,
likely with a
``result_attribute``
value of
``mail``
, and a
``result_format``
value of
``lmtp:unix:/var/lib/imap/socket/lmtp``
:
..
parsed-literal
::
server_host = ldap.example.org
server_port = 389
version = 3
search_base = dc=example,dc=org
scope = sub
domain = example.org
bind_dn = uid=kolab-service,ou=Special Users,dc=example,dc=org
bind_pw = Welcome2KolabSystems
query_filter = (&(mail=%s)(\|(objectclass=kolabinetorgperson)(objectclass=kolabsharedfolder)))
result_attribute = mailHost
result_format = smtp:[%s]:25
..
NOTE
::
By the time the
*MTA (Internal)*
queries the transport map, any secondary
email address should have already been translated to a final recipient
email address (primary email address), for which Kolab uses *virtual alias
maps* by default.
The
*MTA (Internal)*
now needs to be configured to use this transport map:
..
parsed-literal
::
# postconf -e transport_maps=ldap:/etc/postfix/ldap/transport_maps.cf
# service postfix reload
The
*MTA (Internal)*
will now attempt delivery for John to backend1, and for
Jane to backend2.
The backends' MTA now needs to be configured to consider part of
:term:
`mydestination`
local -- the local mailboxes -- and part of
:term:
`mydestination`
remote -- the mailboxes on the other backend(s). This
consists of three parts:
#.
Setting the
**local_recipient_maps**
, line-breaks for legibility:
..
parsed-literal
::
server_host = ldap.example.org
server_port = 389
version = 3
search_base = dc=example,dc=org
scope = sub
domain = example.org
bind_dn = uid=kolab-service,ou=Special Users,dc=example,dc=org
bind_pw = Welcome2KolabSystems
query_filter = (& \\
(\|(mail=%s)(alias=%s)) \\
(\|(objectclass=kolabinetorgperson)(\|(objectclass=kolabgroupofuniquenames)(objectclass=kolabgroupofurls))(\|(\|(objectclass=groupofuniquenames)(objectclass=groupofurls))(objectclass=kolabsharedfolder))(objectclass=kolabsharedfolder)) \\
(mailHost=<%= fqdn -%>) \\
)
result_attribute = mail
..
NOTE
::
The most important to take away from this is to make local recipient
maps for the backend only include those LDAP entries for which the
``mailHost``
attribute is the same value as the system's FQDN.
#.
Setting the
**transport_maps**
, in (for example)
:file:
`/etc/postfix/ldap/transport_maps.cf`
:
..
parsed-literal
::
server_host = ldap.example.org
server_port = 389
version = 3
search_base = dc=example,dc=org
scope = sub
domain = example.org
bind_dn = uid=kolab-service,ou=Special Users,dc=example,dc=org
bind_pw = Welcome2KolabSystems
query_filter = (&(\|(alias=%s)(mail=%s))(objectclass=kolabinetorgperson)(mailhost=<%= fqdn -%>))
result_attribute = mail
result_format = lmtp:unix:/var/lib/imap/socket/lmtp
..
NOTE
::
Here too the most important part is to only transfer over the local LMTP
socket, only those messages intended for recipients with mailboxes
locally hosted -- Those LDAP entries for which the
``mailHost``
attribute is the same value as the system's FQDN.
For delivery to shared folders, an additional lookup table for transport
maps is needed (save as
:file:
`/etc/postfix/transport`
):
..
parsed-literal
::
shared@example.org lmtp:unix:/var/lib/imap/socket/lmtp
Execute the following commands to activate:
..
parsed-literal
::
#
:command:
`postmap /etc/postfix/transport`
#
:command:
`postconf -e transport_maps=ldap:/etc/postfix/ldap/transport_maps.cf,hash:/etc/postfix/transport`
#
:command:
`service postfix reload`
#.
Setting the
**relayhost**
, and redirect all mailboxes for locally hosted
domains not hosted on the local server to the smart host(s):
..
parsed-literal
::
#
:command:
`postconf -e local_transport=relay:[smtp.example.org]:25`
#
:command:
`postconf -e relayhost=[smtp.example.org]`
#
:command:
`service postfix reload`
..
rubric
::
Footnotes
..
[#]
It is actually not the FQDN of the system the mailbox is hosted on, but the
value of the
``servername``
setting in
:manpage:
`imapd.conf(5)`
that is
used.
..
[#]
*Outbound*
messages in this context include vacation responses, forwards to
colleagues, and such (automated) message traffic.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 24, 10:15 AM (1 d, 21 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18716919
Default Alt Text
cyrus-imap-murder-topologies.rst (9 KB)
Attached To
Mode
rD docs
Attached
Detach File
Event Timeline