Skip to main content

Where to place an SMTP DATA time ACL

Comments

4 comments

  • vztwo Naim

    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
  • Prashant kumar
     
    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 into acl_not_smtp or standard pre-message checks, which often do not run or behave as expected for authenticated SMTP relays depending on how cPanel structures its acl_smtp_data configuration.

    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_message instead).
    2.Update the Rule:Syntax Verification.
    Ensure your test condition explicitly checks standard headers using $h_subject::

    exim
     
    drop
      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_exim
    Verification: Send a test email matching the regex string via SMTP auth. Check /var/log/exim_mainlog using tail -f /var/log/exim_mainlog | grep "REJECTED MATCHED SUBJECT" to verify that Exim catches and drops the message.
     
    1
  • Zoltan Egri | 1b.hu

    I checked this on a current cPanel/Exim installation, and there is one important detail here.

    On my server, ACL_CHECK_MESSAGE_PRE_BLOCK is not part of acl_not_smtp. In the generated /etc/exim.conf it is directly inside acl_smtp_data:

    acl_smtp_data:
    
    #BEGIN ACL-CHECK-MESSAGE-PRE-BLOCK
    # BEGIN INSERT default_check_message_pre

    This also matches Exim's documented behavior: acl_smtp_data runs after the message itself has been received and is the appropriate stage for tests that require message headers such as Subject:.

    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_pre looks like the appropriate hook for this use case, provided that the custom rule is inserted before default_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.conf rather than assuming the cPanel hook ordering:

    grep -n -A60 -B5 'ACL-CHECK-MESSAGE-PRE-BLOCK' /etc/exim.conf

    The 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
  • bloatedstoat

    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.