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.
-
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
3 comments