Where to place an SMTP DATA time ACL
Can someone help me to understand where to place an ACL.
We have a client who have industrial controllers installed for their (former) client that send alert emails when a condition is met. The client no longer has a contract and want to reject the alert emails from those controllers; unfortunately they no longer have access to them.
The common denominator in each email is the subject line of the email, it uses a common string.
The emails are authenticated as a local user on the server, the mail is then relayed to a remote email address.
My understanding is this flow:
AUTH
↓
MAIL FROM
↓
RCPT TO
↓
DATA
↓
headers received
↓
Subject matches STRING_HERE?
↓
YES → reject
NO → accept/queue
I've tried placing the ACL here as we need the email headers to match the subject:
/usr/local/cpanel/etc/exim/acls/ACL_CHECK_MESSAGE_PRE_BLOCK/custom_begin_check_message_pre
I rebuild exim conf
Before deploying the deny rule I've been testing it with:
warn
condition = ${if match{$h_subject}{(?i)^COMMON_STRING_HERE (locationA|locationB|locationC|locationD)}}
log_message = STRING SUBJECT TEST MATCH: $h_subject
But the log line never appears in exim_mainlog and so assume never reaches the ACL.
At what stage should I place the ACL to achieve the desired outcome?
Thank you.
-
This is an interesting question. I think the best approach is to identify where the SMTP connection and message filtering are handled in the mail flow before applying the ACL. If the goal is to block messages based on a consistent subject string, checking the available mail-server filtering or ACL options should help ensure the rule is applied at the correct stage without affecting legitimate emails.
0 -
You are on the right track regarding the mail flow, but in Exim / cPanel, message headers like
$h_subject:are only available during the DATA / MIME phase after the message body and headers have been fully transmitted.
The ACL file you selected (custom_begin_check_message_pre) hooks intoacl_not_smtpor standard pre-message checks, which often do not run or behave as expected for authenticated SMTP relays depending on how cPanel structures itsacl_smtp_dataconfiguration.
To reliably check the$h_subject:for incoming/relayed SMTP traffic, try these steps:
1.Place the ACL in custom_begin_outgoing_smtp_check_message:cPanel Exim Hook.In cPanel's Exim Advanced Editor, place your ACL rule in:/usr/local/cpanel/etc/exim/acls/ACL_OUTGOING_SMTP_CHECK_MESSAGE/custom_begin_outgoing_smtp_check_message
(If the mail is coming from an external remote IP authenticated as a local user, use/usr/local/cpanel/etc/exim/acls/ACL_CHECK_MESSAGE/custom_begin_check_messageinstead).2.Update the Rule:Syntax Verification.Ensure your test condition explicitly checks standard headers using$h_subject::
eximdrop message = Message rejected due to policy. log_message = REJECTED MATCHED SUBJECT: $h_subject condition = ${if match{$h_subject}{(?i)^COMMON_STRING_HERE (locationA|locationB|locationC|locationD)}{yes}{no}}3.Rebuild and Restart Exim:Command Line.Run the following command in SSH to apply the custom include and restart Exim:/scripts/buildeximconf && /scripts/restartsrv_eximVerification: Send a test email matching the regex string via SMTP auth. Check/var/log/exim_mainlogusingtail -f /var/log/exim_mainlog | grep "REJECTED MATCHED SUBJECT"to verify that Exim catches and drops the message.1 -
I checked this on a current cPanel/Exim installation, and there is one important detail here.
On my server,
ACL_CHECK_MESSAGE_PRE_BLOCKis not part ofacl_not_smtp. In the generated/etc/exim.confit is directly insideacl_smtp_data:acl_smtp_data: #BEGIN ACL-CHECK-MESSAGE-PRE-BLOCK # BEGIN INSERT default_check_message_preThis also matches Exim's documented behavior:
acl_smtp_dataruns after the message itself has been received and is the appropriate stage for tests that require message headers such asSubject:.The other important point is what cPanel places near the beginning of
default_check_message_pre:accept hosts = : +loopback : +recent_authed_mail_ips : +backupmx_hosts accept authenticated = * hosts = *So for an authenticated SMTP submission, anything that needs to inspect and reject the message must run before that
accept authenticated = *, otherwise processing of the DATA ACL has already been accepted.For that reason, I would not move this to an outgoing SMTP ACL without first checking the generated configuration.
custom_begin_check_message_prelooks like the appropriate hook for this use case, provided that the custom rule is inserted beforedefault_check_message_pre.I would also use the explicit Exim header syntax
$h_subject:.For example:
deny authenticated = * condition = ${if match{$h_subject:}{(?i)^COMMON_STRING_HERE (locationA|locationB|locationC|locationD)}{yes}{no}} message = Message rejected due to local policy log_message = Rejected authenticated message matching subject: $h_subject:After saving/rebuilding the Exim configuration, I would verify the actual placement in
/etc/exim.confrather than assuming the cPanel hook ordering:grep -n -A60 -B5 'ACL-CHECK-MESSAGE-PRE-BLOCK' /etc/exim.confThe custom rule should appear before the default:
accept authenticated = *If it does, the Subject test is being performed at DATA time, before cPanel accepts the authenticated message.
1 -
Thank you, much appreciated, I now have it working with your help.
vi /usr/local/cpanel/etc/exim/acls/ACL_CHECK_MESSAGE_PRE_BLOCK/custom_begin_check_message_pre
deny
condition = ${if match{$h_subject:}{(?i)^STRING (LocationA|LocationB)}{yes}{no}}
log_message = STRING REJECTED MATCHED SUBJECT: $h_subject
message = Message rejected: COMPANY is prohibited from relaying mail through this server/usr/local/cpanel/scripts/buildeximconf
/scripts/restartsrv_exim
tail -f /var/log/exim_mainlog
1
Please sign in to leave a comment.
Comments
4 comments