Troubleshooting Delivery Issues

Custom Exim ACL: The Ultimate Comprehensive Guide for Mastering

By the Domain India teamPublished 8 min read
Knowledge base article
Contents (8 sections)

Exim access control lists (ACLs) decide, at each stage of an SMTP conversation, whether your mail server accepts, rejects or delays a message. This guide explains how ACLs work, where to put custom rules on a plain server, cPanel & WHM and DirectAdmin, and gives tested patterns for common jobs. It is for administrators of their own VPS or dedicated server: on shared hosting you can't change the mail server's configuration.

Key takeaways

An ACL is a list of statements such as accept, deny and defer, each with conditions; Exim runs them top to bottom and stops at the first statement whose conditions all match. Hook your rules into the right stage: the RCPT ACL for sender, recipient and blocklist checks, the DATA or MIME ACL for content and attachments. On cPanel, add rules through WHM's Exim Configuration Manager, never by editing exim.conf. Always check the config with exim -bV and test with exim -bh before restarting Exim.

Shared hosting customers: this is not for you

On Domain India shared hosting, the mail server is managed for every account on the server, and you can't add Exim rules. Use the Email Filters and Spam Filters tools in cPanel, or the equivalent in your panel. If mail is being rejected or not sent, see I can receive mail but cannot send it or open a ticket.

1. How Exim ACLs work

Exim runs a named ACL at each stage of an incoming SMTP session. The main options that attach them are:

OptionRuns atTypical use
acl_smtp_connectClient connectsDrop known-bad IPs early
acl_smtp_heloHELO or EHLOReject forged or invalid HELO names
acl_smtp_mailMAIL FROMSender checks
acl_smtp_rcptEach RCPT TORelay control, recipient and sender checks, blocklists, rate limits
acl_smtp_dataAfter the message bodyHeader and content checks, spam scanning
acl_smtp_mimeEach MIME partAttachment name and type checks

Inside an ACL, each statement starts with a verb:

  • accept: stop and accept if all conditions match.
  • deny: stop and reject permanently (5xx) if all conditions match.
  • defer: stop and reject temporarily (4xx), so the sender retries.
  • require: if any condition fails, reject; otherwise continue.
  • warn: take no decision; used to log or add a header.
  • drop and discard: close the connection, or accept and silently throw the message away. Use discard with great care.

Conditions under a verb are ANDed together. An ACL that reaches its end without a match denies by default, so most ACLs finish with an explicit accept or deny.

2. Where custom rules go

Plain Exim
Edit the main configuration: /etc/exim/exim.conf on RHEL-family systems, or the exim4 configuration under /etc/exim4 on Debian and Ubuntu. Keep a copy first.
cPanel & WHM
Use WHM › Exim Configuration Manager › Advanced Editor. It has custom blocks for each ACL stage that survive updates; cPanel regenerates exim.conf, so direct edits are lost.
DirectAdmin
The stock exim.conf includes optional files such as /etc/exim.acl_check_recipient.pre.conf and /etc/exim.acl_check_message.pre.conf. Put custom rules there so updates keep them.

Whichever you use, back up first:

bash
cp -a /etc/exim.conf /root/exim.conf.$(date +%F)

3. Test before you restart

  1. Check the syntax.
    exim -bV prints the version and reports configuration errors. Nothing should be restarted until it is clean.
  2. Simulate a session.
    exim -bh 203.0.113.25 starts a fake SMTP session from that IP and prints every ACL decision. Type HELO, MAIL FROM and RCPT TO lines as a real client would.
  3. Check routing.
    exim -bt [email protected] shows how an address would be delivered.
  4. Restart.
    systemctl restart exim on RHEL-family systems (exim4 on Debian). Then watch the logs for a few minutes.

4. Common rules

The snippets below go into the RCPT ACL (or the matching custom block) above the final accept statements that allow local delivery and authenticated relaying. Adjust names and addresses to your own.

Block a sender domain:

text
deny    message = Mail from $sender_address_domain is not accepted
        senders = *@spamdomain.example : *@*.spamdomain.example

Reject clients whose reverse DNS doesn't check out (strict; some legitimate servers fail this, so start with warn and watch the log):

text
deny    message = Reverse DNS check failed for $sender_host_address
        !authenticated = *
        !verify = reverse_host_lookup

Use a DNS blocklist:

text
deny    message = $sender_host_address is listed at $dnslist_domain
        !authenticated = *
        dnslists = bl.spamcop.net

Some blocklists, including Spamhaus, refuse queries sent through large public resolvers and need a local resolver or a registered key. Read each list's usage terms before you rely on it.

Rate-limit authenticated senders (limits a compromised mailbox):

text
deny    message = Sending rate exceeded, try again later
        authenticated = *
        ratelimit = 300 / 1h / per_rcpt / $authenticated_id

Let a trusted network through (place above the checks it should bypass):

text
accept  hosts = 198.51.100.0/24

5. Content and attachment rules

Content checks belong in later stages. In the MIME ACL, block risky attachment types:

text
acl_check_mime:
  deny    message = Blocked attachment type: $mime_filename
          condition = ${if match{${lc:$mime_filename}}{\N\.(exe|scr|bat|com|js|vbs)$\N}}
  accept

In the DATA ACL, you can add a spam score header when SpamAssassin (spamd) is running:

text
warn    spam = nobody:true
        add_header = X-Spam-Score: $spam_score

Set the maximum message size with the main option message_size_limit, not an ACL. Exim can scan only as much of the body as message_body_visible allows, so body-keyword rules are unreliable; a spam filter does this job better.

6. SPF, DKIM and DMARC

These checks need an Exim built with the matching support (exim -bV lists it). The syntax differs from ordinary conditions:

  • SPF uses the spf condition in the RCPT ACL, for example deny spf = fail with a message.
  • DKIM results are checked in acl_smtp_dkim using dkim_status.
  • DMARC needs the DMARC library and uses dmarc_status in the DATA ACL.

Old examples such as verify{spf} do not exist in Exim and will fail the config check. cPanel and DirectAdmin include their own SPF and DKIM handling, so use the panel's settings there rather than hand-written rules.

7. Troubleshooting

  • Config check fails: exim -bV names the line. Restore your backup if you can't fix it quickly.
  • Legitimate mail rejected: search the main and reject logs (/var/log/exim_mainlog and /var/log/exim_rejectlog on cPanel; /var/log/exim/mainlog and rejectlog on DirectAdmin) for the sender, then use exim -bh with the sender's IP to see which statement matched.
  • A rule never fires: an earlier accept matched first. Move the rule above it.
  • Everything is deferred: a DNS lookup or blocklist is timing out. Check the server's resolver.

For log searching, see Mastering mail log analysis.

8. Running this on Domain India

A Domain India VPS is self-managed with full root access, so you install and configure your own mail server and rules. VPS plans don't include cPanel; the VPS page lists the operating systems and panels offered. Prices on the card are live and exclude 18% GST.

VPS Starter
₹552.65/mo + GST
  • 1 vCPU
  • 2 GB DDR4 RAM
  • 64 GB NVMe SSD Storage
  • 2 TB Monthly Bandwidth
See plan details

If you'd rather not run a mail server at all, Business Email gives you managed mailboxes with DKIM signing, and works with any website host.

Business Email
₹60/mo + GST
  • Priced per mailbox - start with one
  • Email at your own domain ([email protected])
  • Add and remove mailboxes yourself
  • Webmail with calendar, contacts and tasks
See plan details
What is an Exim ACL?

An access control list is a set of statements that Exim runs at a stage of the SMTP session, such as RCPT or DATA. Each statement has a verb (accept, deny, defer, require, warn) and conditions. Exim stops at the first accept or deny whose conditions all match.

Can I add custom Exim rules on Domain India shared hosting?

No. The mail server on shared hosting is shared by every account, so its configuration is managed for you. Use the email filters and spam settings in your control panel, or open a ticket about a specific delivery problem.

Where do I add custom ACLs on cPanel?

In WHM, open Exim Configuration Manager and use the Advanced Editor's custom ACL blocks. cPanel rebuilds exim.conf, so direct edits to that file are lost.

How do I test an ACL without affecting live mail?

Run exim -bV to check the syntax, then exim -bh with a client IP address to simulate an SMTP session and see each ACL decision. Only restart Exim when both look right.

Why is my deny rule being ignored?

Exim stops at the first statement that matches. If an accept statement above your rule already matched, your rule never runs. Move it higher in the ACL.

How do I rate-limit outgoing mail per mailbox in Exim?

Add a deny statement with authenticated = * and a ratelimit condition keyed on $authenticated_id in the RCPT ACL, for example 300 recipients per hour.

Ready to set up your own mail server? Compare VPS plans, or look at Business Email if you'd rather have mailboxes managed for you. For a problem with mail on shared hosting, open a support ticket.

Run your own mail server on a VPS

Full root access on KVM virtualisation, so you control Exim, its rules and its logs.

See VPS plans

Ready when you are

Get Business Email from ₹60/mo + GST

See plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app
Custom Exim ACLs: A Practical Admin Guide