Skip to main content

Where to place an SMTP DATA time ACL

Comments

3 comments

  • 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.