1

Topic: How to route (transport) outgoing messages based on message size?

==== REQUIRED BASIC INFO OF YOUR IREDMAIL SERVER ====
- iRedMail version (check /etc/iredmail-release): latest 1.3
- Deployed with iRedMail Easy or the downloadable installer? downloadable
- Linux/BSD distribution name and version: Ubuntu 18
- Store mail accounts in which backend (LDAP/MySQL/PGSQL): MySQL
- Web server (Apache or Nginx): Nginx
- Manage mail accounts with iRedAdmin-Pro? no
- [IMPORTANT] Related original log or error message is required if you're experiencing an issue.
====

I know that I can choose different transport agents for different mail accounts (using the mailbox table in MySQL). However, how to deliver using local SMTP server for email messages larger than 10 MB and an external service (e.g. Google) for messages less than 10 MB?

Is there any message size based transport policies? How to edit them?

----

Spider Email Archiver: On-Premises, lightweight email archiving software developed by iRedMail team. Supports Amazon S3 compatible storage and custom branding.

2

Re: How to route (transport) outgoing messages based on message size?

No existing solution in iRedMail yet.
The easiest way to implement this is writing a plugin (in Python 3) for iRedAPD (the postfix policy server used by iRedMail) to handle it.

FYI: https://github.com/iredmail/iRedAPD/blo … PLUGINS.md

3

Re: How to route (transport) outgoing messages based on message size?

ZhangHuangbin wrote:

The easiest way to implement this is writing a plugin (in Python 3) for iRedAPD (the postfix policy server used by iRedMail) to handle it.

I have tried to get the size like this but it always returns 0:

from libs.logger import logger
from libs import SMTP_ACTIONS

def restriction(**kwargs):

    smtp_session_data = kwargs['smtp_session_data']
    size = smtp_session_data['size']

    if size:
        size = int(size)
    else:
        size = 0

    logger.info('smtp_session_data size: %s' % size)

    return SMTP_ACTIONS['default']

4

Re: How to route (transport) outgoing messages based on message size?

UPDATE

I have managed to do that, thank you @ZhangHuangbin for giving me the guidelines.

Like this (Python plugin):

from libs.logger import logger
from libs import SMTP_ACTIONS

SMTP_PROTOCOL_STATE = ['RCPT', 'END-OF-MESSAGE']

def restriction(**kwargs):

    smtp_session_data = kwargs['smtp_session_data']
    size = smtp_session_data['size']

    if size:
        size = int(size)
    else:
        size = 0

    logger.info('smtp_session_data size: %s' % size)

    if size >= 3000000:
        return 'FILTER smtp:'
    else:
        return SMTP_ACTIONS['default']

5

Re: How to route (transport) outgoing messages based on message size?

MW wrote:

SMTP_PROTOCOL_STATE = ['RCPT', 'END-OF-MESSAGE']

Only 'END-OF-MESSAGE' state has the message size.

6

Re: How to route (transport) outgoing messages based on message size?

Here is the partially working plugin:

from libs.logger import logger
from libs import SMTP_ACTIONS

SMTP_PROTOCOL_STATE = ['END-OF-MESSAGE']

def restriction(**kwargs):

    size = kwargs['smtp_session_data']['size']

    if size:
        size = int(size)
    else:
        size = 0

    logger.info('smtp_session_data size: %s' % size)

    if size < 10485760:
        return SMTP_ACTIONS['default']
    else:
        return 'FILTER smtp:'
        

If the message size is less than 10MB it is delivered by the relayhost defined in postfix main configuration file.

If it is larger than 10MB it is delivered by local mail server. But in this scenario there is a problem:

It sends successfully to mail accounts outside my server (e.g. to someone@gmail.com) but fails when sending to a mail account hosted on my server (e.g. from someone@my-first-domain.com to someone@my-second-domain.com), saying:

<someone@my-second-domain.com>: mail for my-second-domain.com loops back to myself.

Any idea what might be going on here?