Since Exim (version 3) rereads its configuration on every delivery attempt, it is unadvisable to edit a live configuration file. If you're using Debian and 4.x, the config it uses isn't the one you edit (it gets generated on init-script-reload), so you're OK.
Lots of bounce messages to fake Email addresses from spam?
mailq | awk '/frozen/ { print $3 }' | xargs exim -Mrm
See EximMailFilter.
If you're running Exim 3, make sure to read the notes at the bottom of this entry.
First, in the router section of exim.conf, add a router for Cyrus (at the top) as follows:
local_user_cyrus: driver = accept check_local_user local_part_suffix = +* transport = local_delivery_cyrus
Note that the local_part_suffix part allows you to specify user+mailfolder@domain... and the command in the local_delivery_cyrus section takes care of delivering to the correct subfolder of inbox.
Next, in the transport section, add a transport to allow delivery via Cyrus:
local_delivery_cyrus: driver = pipe command = /usr/libexec/cyrus/deliver -m ${substr_1:$local_part_suffix} -- $local_part user = cyrus group = mail return_output log_output message_prefix = message_suffix =
Finally, you will need to modify your alias resolution to use LDAP. This is based on my LDAP configuration, which consists of an Organisational Unit (OU) of Aliases, each container having an attribute rfc822MailMember, containing the real mailbox. An example:
dn: cn=greg,ou=Aliases,dc=compel,dc=co,dc=nz rfc822MailMember: greig objectClass: nisMailAlias objectClass: top cn: greg
This fixes the fact that no one can deal with the fact that GreigMcGill has an "i" in his name! ;)
So... back to exim.conf... the alias router looks like the following:
system_aliases: driver = redirect allow_fail allow_defer data = ${lookup ldap {ldap://10.0.0.1/cn=$local_part,\ ou=Aliases,dc=compel,dc=co,dc=nz?rfc822MailMember?base}} file_transport = address_file pipe_transport = address_pipe
Now, this assumes that your system is like mine, where each user is a real account, and getpwnam() and the like will return usernames out of LDAP via PAM. If this is the case, the above configuration should be all you need. If you are running a "black box" MailServer, then some other kind soul may like to add the required configuration below.
If you have a different LDAP Schema to the one mentioned above, either because your system installed a different set of Schema for the equivalent entries, or you are running a custom Schema that handles multiple virtual domain hosting without unix accounts, then just modify your LDAP lookups appropriately. As a hint:
data = ${lookup ldap {ldap://127.0.0.1/cn=$local_part,\ ou=Aliases,o=$domain,dc=wlug,dc=org,dc=nz?mailAlias?base}}
If my system recieves mail to say daniel@wlug.org.nz, it will for the dn given as:
cn=daniel,ou=Aliases,o=wlug.org.nz,dc=wlug,dc=org,dc=nz
and return the mailAlias attribute.
Between Exim, SendMail, Postfix and Courier, Exim has been the easiest to set up with a custom LDAP Schema by far. SendMail supposedly supports it, but in practice doesn't. Postfix is SendMail with a pretty configuration file, and has worse support for custom LDAP Schemas IMO. Exim > *.
The above system will work with previous version of Exim, however the format might be slightly different (not confirmed this, I just base this off what I've done with Exim 3.3.5)
The main difference is in the query line in the Aliases director example above:
data = ${lookup ldap {ldap://10.0.0.1/cn=$local_part,\ ou=Aliases,dc=compel,dc=co,dc=nz?rfc822MailMember?base}}
I always used something that looked like:
query = "ldap://127.0.0.1/ou=Aliases,o=$domain,ou=Domains,BASEDN?mailAlias?sub?cn=$local_part"
but there are probably other ways of doing this too :)
The mighty Cuchulain's config:
Transport:
NOTE: this must be placed somewhere sensible in the transports list. ie, before any transports for procmail(1), userforward, or local_user delivery.)
local_delivery_cyrus: driver = pipe command = "/usr/sbin/cyrdeliver -m ${substr_1:${local_part_suffix}} -- ${local_part}" user = cyrus group = mail envelope_to_add = true return_output log_output prefix = suffix =
Director:
local_user_cyrus: driver = localuser transport = local_delivery_cyrus
Exim 4.x has native LMTP support, so you don't need to pipe the mail to cyrus's deliver program. Instead, you can do the following:
Note that the same rules about placing local_user_cyrus in a sensible place apply here as well!
Router:
local_user_cyrus: debug_print = "R: local_user_cyrus for $local_part@$domain" driver = accept local_part_suffix = +* local_part_suffix_optional transport = cyrus_ltcp
Transport:
cyrus_ltcp: debug_print = "T: cyrus_ltcp for $local_part@$domain" driver = smtp protocol = lmtp hosts = localhost allow_localhost
Another thing you can do with Exim and Cyrus-IMAP integration is described at Cyrus Imap page of Exim Wiki. It allows Cyrus to check the existence of mailboxes before replying to "RCPT TO:" or "MAIL FROM:". Exim does not have to send back bounces in reply to "dictionary recipient" spam.
It is best suited for integration with Cyrus-IMAP virtual domains.
See also LMTPNotes.
This is for version 3.35 (the version with Debian Woody).
The default is to deliver local mail to /var/spool/mail/$USERNAME in MBox format. In the local_delivery section of exim.conf, remove the line that says
file = /var/spool/mail/${local_part}
and add lines that say
create_directory = true directory = /home/${local_part}/Maildir/ directory_mode = 770 maildir_format
Easy peasy. :) But see the comment below about possible gotchas, as this is just the basic bit.
I have Exim filtering set up in a .forward file to drop all my Email into the right place.
However, I was getting lots of messages like this in my logs:
2003-04-21 19:38:04 196iGy-00005j-01 == /home/user/Maildir/.Mailing Lists.WLUG/ <user@localhost> D=userforward defer (-31): directory_transport unset in userforward driver
The problem? exim.conf was set up for MailDir support, but for some reason the config for the directory delivery agent wasn't linked to the forwarding section.
Ensure address_directory has Maildir uncommented, and then find the userforward section. Under file_transport = address_file, set
directory_transport = address_directory
and rerun the queue, forcing redelivery if necessary, with exim -qff.
This when used in conjunction with Cyrus IMAP can be caused by trying to deliver to a mailbox which has reached it's maximum quota limit. The exim_mainlog entry looks similar to the following:
2004-01-08 11:08:12 1AeLqW-0007k0-00 == gerwin@north.pub.tla T=local_delivery_cyrus defer (0): Child process of local_delivery_cyrus transport returned 75 (could mean temporary error) from command: /usr/lib/cyrus-imapd/deliver
(If you have multiple domains on the same machine, and users account names don't correspond to their Email addresses.)
In the top section of your exim.conf
domainlist local_domains = @ : \ @[] : \ localhost : \ partial-lsearch;/etc/exim/virtual.domains
and underneath the part where it says something like
real_local: driver = accept check_local_user local_part_prefix = real- transport = local_delivery
add a section
virtual: driver = redirect allow_defer allow_fail data = ${lookup{$local_part@$domain}lsearch*@{/etc/exim/virtual.users}} domains = partial-lsearch;/etc/exim/virtual.domains retry_use_local_part
now you will need file called virtual.domains that is simply a list of all the domains for which you accept mail, and a virtual.users file with a table of users in the format:
example.com example.net
#example.com regularuser@example.com : localuser forwardinguser@example.com : someuser@example.org *@example.com : catchalluser #example.net regularuser@example.net : localuser2 forwardinguser@example.net : someuser2@example.org *@example.net : catchall2
Check that your DNS and hosts(5) settings are correct, and that you can correctly resolve hosts on the server.
If this all works as desired but connections are still slow, it could be an IDENT timeout. Try either setting:
rfc1413_hosts = * rfc1413_query_timeout = 0s
or installing an IDENT server on the Exim machine.
prefix = test- is your friend
Section 8 of the exiscan-acl patch documentation explains how to do it if you've compiled SPF into Exim. Otherwise, you can do so so via the Mail::SPF::Query Perl module. Appending A.7 of Spam Filtering for Mail Exchangers shows both approaches.
http://www.meini.org/spf/ contains Debian Packages for the Mail::SPF::Query and Net::CIDR::Lite modules and for libspf. The packaged libspf version is pretty old though, you might consider installing from SourceCode. You'll also need Net::DNS, for which a Debian package can be found at http://www.proesdorf.de/debian/.
Alternatively you could use Evan's deb packages but the newer code of libspf2 and build some new libspf2 packages.
If you have Exim4 configured as a mail proxy in front of, say, MS Exchange, or another Active Directory based email server, you may find the following useful to either limit spam, or transition from a "catchall" domain setup. Note that these two configurations are mutually exclusive.
This first config fragment provides the ability to reject nonexistent email addresses at SMTP time.
This first stanza belongs in the main configuration, and simply defines the LDAP lookup macro. You will need to create the "MTA Auth" user in AD. Copy Guest and enable it. Don't forget to set the IP address of the AD server correctly.
Note that port 3268 is used. AD geeks will recognise this as the Global Catalog port, and means you are asking the AD Forest, rather than just a particular server. If you don't want this, or your server isn't a GC server, just use port 389.
ITP_LDAP_AD_MAIL_RCPT = \ user="CN=MTA\ Auth,CN=Users,DC=site,DC=example,DC=co,DC=nz" \ pass=gand4lf \ ldap://10.7.31.10:3268/DC=site,DC=example,DC=co,DC=nz\ ?mail?sub?\ (&\ (objectClass=*)\ (proxyAddresses=SMTP:${quote_ldap:${local_part}@${domain}})\ )
This belongs as the first router in the routers section. Change the domains to match ALL domains we accept mail for.
adsi_itp_check: driver = redirect domains = *example.co.nz allow_fail allow_defer forbid_file forbid_pipe redirect_router = spam_redirect data = ${lookup ldap {ITP_LDAP_AD_MAIL_RCPT}\ {${local_part}@${domain}}{:fail: User unknown}}
The second fragment provides a "catchall" function for a domain. If an email address is not defined within a site, mail will be accepted and routed to the provided address (catchall@example.co.nz in this case). Please do not use this except as a transitory measure, as catchalls are inherently bad IMHO.
First, the lookup macro, as before.
ITP_LDAP_AD_MAIL_RCPT = \ user="CN=MTA\ Auth,CN=Users,DC=site,DC=example,DC=co,DC=nz" \ pass=gand4lf \ ldap://10.7.31.10:3268/DC=site,DC=example,DC=co,DC=nz\ ?mail?sub?\ (&\ (objectClass=*)\ (proxyAddresses=SMTP:${quote_ldap:${local_part}@${domain}})\ )
Now the catchall router:
adsi_itp_catchall: driver = redirect domains = *example.co.nz redirect_router = spam_redirect condition = ${if eq{${lookup ldap {ITP_LDAP_AD_MAIL_RCPT}{${local_part}@${domain}}}}{} {yes}{no}} data = catchall@example.co.nz
As nice as this solution is, it doesn't (in the above example) cater for Public Folders which are mail enabled. Greig informs me that you can modify the LDAP bind to do this, however. One way to do this is below:
ldap_default_servers = <; server.test.lan:3268 LDAP_AD_MAIL_RCPT = \ user="CN=ldap_user,OU=Users,DC=test,DC=lan" \ pass=ilovegreig \ ldap:///DC=test,DC=lan\ ?mail?sub?\ (&\ (|\ (objectClass=user)\ (objectClass=publicFolder)\ (objectClass=group)\ )\ (proxyAddresses=SMTP:${quote_ldap:${local_part}@${domain}})\ )
One issue I found was that I wasn't able to query the whole forest using port 389. I needed to use port 3268 (GC). If you're having problems, there's a high chance you haven't got the DN correct. Use adsiedit to check (found in the Windows Support Tools). More information can be found at http://www.exim.org/eximwiki/MsExchangeAddressVerification.
root@firewall.tla:/etc # exim4 -bv -v junk@firewall.tla R: spam_redirect for firewall.tla R: system_aliases for junk@firewall.tla junk@firewall.tla -> /dev/null *** Error in setting up pipe, file, or autoreply: file_transport unset in system_aliases router
There is a macro defined for the file_transport router, but its unset by default. To allow this behaivour, add this macro to either your /etc/exim4/conf.d/main/02_exim4-config_options.rul, or a local macros filw, such as /etc/exim4/conf.d/main/000_local_macros:
# allow writing to files in system aliases (potentially bad!) SYSTEM_ALIASES_FILE_TRANSPORT = address_file
A better answer is changing the destination using the redirect router alias :blackhole:.
SMTPS is easy, since 4.43:
# wlug: listen on 25 (smtp), 465 (ssmtp for Outlook) daemon_smtp_port = 25:465 tls_on_connect_ports = 465
in your main section. Between 4.03 and 4.43, you can use the -tls-on-connect command line parameter.
587 is harder, because the rules are "either SMTP AUTH or SSL". An Exim SSL/TLS recipe was posted to the list, which suggests (updated, and with client certs removed - you really want to only use SMTP AUTH):
# wlug: listen on 25 (smtp), 465 (ssmtp for Outlook) and 587 (submission) daemon_smtp_port = 25:465:587 # uncomment to only allow auth if you're on by SSL # auth_advertise_hosts = ${if eq{$tls_cipher}{}{localhost}{*}} tls_advertise_hosts = * tls_certificate = /etc/exim4/server-cert.pem tls_privatekey = /etc/exim4/server-key.pem
..and in your RCPT ACL (near the top):
accept authenticated = * encrypted = * accept condition = ${if eq{$interface_port}{587}{1}{0}} endpass message = SMTP AUTH required for port 587 authenticated = *
I wanted to set up an SMTP server for testing that would accept all mail and send it to a single mailbox so that we didn't accidentally send mail to anyone.
This example uses Debian's split config.
Add a new router in /etc/exim4/conf.d/router. Because these files are processed in alphabetical order, add it at the top. 09_exim4-config-redirect_all is a good choice.
redirect_all: debug_print = "R: redirecting all mail" driver = redirect data = "user_to_send_to"
Test using the method listed below.
JohnMcPherson pointed out the following useful tips:
If you're using Debian's split configuration setup, you can generate a new configuration file to a temporary location with:
$ update-exim4.conf -o ~/exim4.test.config
Then you can test the routing of that config without touching your running server using
$ exim -C ~/exim4.test.config -bt user@host.com
If it's not working how you intended, then ramp up the debugging and get all the details
$ exim -d+all -C ~/exim4.test.config -bt user@host.com < /dev/null
Part of CategoryMailNotes
4 pages link to EximNotes: