Skip to content
birdwes edited this page Oct 7, 2018 · 2 revisions

Cyrus Imap


The Cyrus Electronic Mail Project is continuing to build a highly scalable enterprise mail system designed for use in a small to large enterprise environments using standards based technologies. The Cyrus technologies will scale from independent use in small departments to a system centrally managed in a large enterprise.

The major item of interest to Exim users is the Cyrus Imap server, which can be integrated with an exim MTA.


Making Real Time LMTP Callouts to a Cyrus IMAP

Based on information provided by Andrzej Filip in "Real Time Cyrus and Exim Integration" and copied into here.

Original e-mail announcement to exim-users mailing list.

Cyrus Configuration

Make cyrus wait for unauthenticated lmtp connections over TCP on local interface. In cyrus.conf add:-

  lmtp          cmd="lmtpd -a" listen="" prefork=0

Without "-a" lmtp requires authentication for LMTP over TCP (Exim does not support callouts over UNIX sockets). If your /etc/services files does not define lmtp service (2003/tcp) then use listen=""

Exim Configuration

Define cyrus_domains domainlist to list all virtual domains handled by your cyrus.

domainlist cyrus_domains = : :

The best place is just before (or just after) "domainlist local_domains =" line.

Define cyrus_ltcp (cyrus local tcp) transport in transports section.

  driver = smtp
  protocol = lmtp
  hosts = localhost

(Note, be cautious about localhost if your server has IPv6, if LMTP is only listening on IP4, you MUST specify hosts = instead of localhost, unless you have set it up otherwise. On my new server localhost resolves to ::1).

It will deliver messages to lmtp port at localhost using lmtp protocol. If your /etc/services files does not define lmtp service (2003/tcp) then add the following line to the file

port = 2003

Insert cyrus_vdom router as first routers section

  driver = accept
  domains = +cyrus_domains
  transport = cyrus_ltcp

It will select cyrus_lmtp transport for all addresses in cyrus_domains domains.

Add checking validity of addresses in cyrus virtual domain in acl_check_rcpt section. I have added the lines just after "accept hosts = :" line [skipping tests for SMTP not over TCP/IP (local)].

# Reject "faked" envelope sender addresses in cyrus domains

deny sender_domains = +cyrus_domains
     message        = Sender unknown/invalid
     !verify        = sender/callout=defer_ok,5s

# Accept valid (and reject invalid) envelope recipient adresses in cyrus domains

accept domains      = +cyrus_domains
     message        = ${if match{$acl_verify_message}\
                      {\N(?m)^\d{3} (\d\.\d\.\d .{0,120})\Z\N} \
                      {IMAP said: $1}{Recipient unknown/invalid}}
     verify         = recipient/callout=random,5s

defer_ok makes exim accpet messages when cyrus in unavailable. 30s defines timeout for callout connection attempts. The strange looking message is supposed to provide Cyrus-IMAP's reply to failed "RCPT TO:" in Exim's reply to "RCPT TO:".


If you are getting the message (in exim4/mainlog)

Could not complete recipient verify callout

use hosts = instead of hosts = localhost in the transport. You might also have to adjust the hostname in the cyrus.conf accordingly. Try telnet lmtp to see if you can still connect to it.

Exim Wishlist for better Cyrus-IMAP integration

  • making Exim capable to do LMTP callouts via UNIX socket
  • making Exim support "socket map" protocol supported by Cyrus-IMAP (and sendmail).