Content filter with script

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Content filter with script

Abi Askushi
Hi all,

I am trying to setup a simple script, which will be used to check the mail size and count the emails per user (the script does only mail size checks at the moment). I am currently checking the logic with a simple script and I have followed the http://www.postfix.org/FILTER_README.html, the advanced option to avoid loops. When putting script at pickup I had loops. 

I don't understand what I am doing wrong and I get from postfix:

postfix/qmgr[2389]: 8A792402D3: from=<[hidden email]>, size=269, nrcpt=1 (queue active)
Mar  6 10:55:25 ohub-dev postfix/smtp[9895]: 8A792402D3: lost connection with localhost[::1] while receiving the initial server greeting
Mar  6 10:55:25 ohub-dev postfix/smtp[9895]: 8A792402D3: to=<[hidden email]>, orig_to=<guest>, relay=localhost[127.0.0.1]:10025, delay=0.06, delays=0.04/0.01/0.01/0, dsn=4.4.2, status=deferred (lost connection with localhost[127.0.0.1] while receiving the initial server greeting)


The above email is sent with the command: echo "test" | mail -s "test" guest

I have postfix 2.9.6-2 and I have done the following:

/etc/postfix/main.cf:
content_filter = scan:localhost:10025
receive_override_options = no_address_mappings

/etc/postfix/master.cf
# Filter
scan    unix  -       -       n       -       10      smtp
        -o smtp_send_xforward_command=yes
        -o disable_mime_output_conversion=yes
        -o smtp_generic_maps=
#
localhost:10025 inet  n       n       n       -       10      spawn
        user=filter argv=/usr/bin/filter localhost 10026
#
localhost:10026 inet  n       -       n       -       10      smtpd
        -o content_filter=
        -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks,no_milters
        -o smtpd_helo_restrictions=
        -o smtpd_client_restrictions=
        -o smtpd_sender_restrictions=



The script I am using is working ok when invoked from sender access and defined at master.cf as:
filter    unix  -       n       n       -       10      pipe
        flags=Rq user=filter argv=/usr/bin/mail_filter.php ${sender} -- ${recipient} ${size}


I understand that now I am using spawn and seems to behave differently from pipe mechanism but I have not been able to understand what is required in the script so as to process email and then send it back to localhost:10026 for further delivery.

The script (further down) is using sendmail to return the mail back and the returned email as I understand is received from pickup. It seems also that with spawn I don't have the ${sender} -- ${recipient} ${size} macros available even when defined at options as below:

localhost:10025 inet  n       n       n       -       10      spawn
        user=filter argv=/usr/bin/filter ${sender} -- ${recipient} ${size} localhost 10026



I will greatly appreciate any help as I am stuck on how to proceed and did not manage to find any pointers.

Alex


Script:
#!/bin/bash
# Simple mail size filtering script

INSPECT_DIR=/var/spool/filter
SENDMAIL="/usr/sbin/sendmail -G -i -f " # NEVER NEVER NEVER use "-t" here.

# VIP Account username and message size limit:
VIP_USER="vip"
VIP_LIMIT=5000000 # bytes

# User Message size limit
USER_LIMIT=100000 # bytes

# Return message to sender
message='Quota exceeded'

# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_NOPERM=77
EX_UNAVAILABLE=69

# Find out the ammount of arguments passed
args=("$@")
length=$#

# Find out the sender
SENDER=${args[0]}

# Extract recipients
RECIPIENTS=${args[@]:2:$(($length - 3))}

# Extract message size (last argument)
MESSAGE_SIZE=${args[@]:(-1)}

# Clean up when done or when aborting.
trap "rm -f in.$$" 0 1 2 3 15

# Set time stamp
timestamp=`date +"%d-%m-%Y %H:%M"`

# Start processing.
cd $INSPECT_DIR || {
    echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; }
 
cat >in.$$ || {
    echo Cannot save mail to file; exit $EX_TEMPFAIL; }

# Check who is the sender and apply policy accordingly
USER=`/bin/echo $SENDER | awk -F "@" '{print$1}'`
echo "USER: " $USER >> /var/log/filter

case $USER in
    $VIP_USER) # Limit VIP account
        if [ $MESSAGE_SIZE -gt $VIP_LIMIT ]; then
            echo "${message}";
            echo "$timestamp: Message size exceeded from " $SENDER  >> /var/log/filter;
            exit $EX_NOPERM;
        else
            echo "Business Mail size OK" >> /var/log/filter;
            $SENDMAIL $SENDER $RECIPIENTS <in.$$
        fi
        ;;
    *) # Limit User Mails
        if [ $MESSAGE_SIZE -gt $USER_LIMIT ]; then
            echo "${message}";
            echo "$timestamp: Message size exceeded from " $SENDER  >> /var/log/filter;
            exit $EX_NOPERM;
        else
            echo "User Mail size OK" >> /var/log/filter;
            $SENDMAIL $SENDER $RECIPIENTS <in.$$
        fi
        ;;
esac
exit $?


Reply | Threaded
Open this post in threaded view
|

Re: Content filter with script

Abi Askushi
Hi all,

Just checking if anyone can provide any hints on the below.

Thanx,
Alex

On Tue, Mar 6, 2018 at 3:16 PM, Alex K <[hidden email]> wrote:
Hi all,

I am trying to setup a simple script, which will be used to check the mail size and count the emails per user (the script does only mail size checks at the moment). I am currently checking the logic with a simple script and I have followed the http://www.postfix.org/FILTER_README.html, the advanced option to avoid loops. When putting script at pickup I had loops. 

I don't understand what I am doing wrong and I get from postfix:

postfix/qmgr[2389]: 8A792402D3: from=<[hidden email]>, size=269, nrcpt=1 (queue active)
Mar  6 10:55:25 ohub-dev postfix/smtp[9895]: 8A792402D3: lost connection with localhost[::1] while receiving the initial server greeting
Mar  6 10:55:25 ohub-dev postfix/smtp[9895]: 8A792402D3: to=<[hidden email]>, orig_to=<guest>, relay=localhost[127.0.0.1]:10025, delay=0.06, delays=0.04/0.01/0.01/0, dsn=4.4.2, status=deferred (lost connection with localhost[127.0.0.1] while receiving the initial server greeting)


The above email is sent with the command: echo "test" | mail -s "test" guest

I have postfix 2.9.6-2 and I have done the following:

/etc/postfix/main.cf:
content_filter = scan:localhost:10025
receive_override_options = no_address_mappings

/etc/postfix/master.cf
# Filter
scan    unix  -       -       n       -       10      smtp
        -o smtp_send_xforward_command=yes
        -o disable_mime_output_conversion=yes
        -o smtp_generic_maps=
#
localhost:10025 inet  n       n       n       -       10      spawn
        user=filter argv=/usr/bin/filter localhost 10026
#
localhost:10026 inet  n       -       n       -       10      smtpd
        -o content_filter=
        -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks,no_milters
        -o smtpd_helo_restrictions=
        -o smtpd_client_restrictions=
        -o smtpd_sender_restrictions=



The script I am using is working ok when invoked from sender access and defined at master.cf as:
filter    unix  -       n       n       -       10      pipe
        flags=Rq user=filter argv=/usr/bin/mail_filter.php ${sender} -- ${recipient} ${size}


I understand that now I am using spawn and seems to behave differently from pipe mechanism but I have not been able to understand what is required in the script so as to process email and then send it back to localhost:10026 for further delivery.

The script (further down) is using sendmail to return the mail back and the returned email as I understand is received from pickup. It seems also that with spawn I don't have the ${sender} -- ${recipient} ${size} macros available even when defined at options as below:

localhost:10025 inet  n       n       n       -       10      spawn
        user=filter argv=/usr/bin/filter ${sender} -- ${recipient} ${size} localhost 10026



I will greatly appreciate any help as I am stuck on how to proceed and did not manage to find any pointers.

Alex


Script:
#!/bin/bash
# Simple mail size filtering script

INSPECT_DIR=/var/spool/filter
SENDMAIL="/usr/sbin/sendmail -G -i -f " # NEVER NEVER NEVER use "-t" here.

# VIP Account username and message size limit:
VIP_USER="vip"
VIP_LIMIT=5000000 # bytes

# User Message size limit
USER_LIMIT=100000 # bytes

# Return message to sender
message='Quota exceeded'

# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_NOPERM=77
EX_UNAVAILABLE=69

# Find out the ammount of arguments passed
args=("$@")
length=$#

# Find out the sender
SENDER=${args[0]}

# Extract recipients
RECIPIENTS=${args[@]:2:$(($length - 3))}

# Extract message size (last argument)
MESSAGE_SIZE=${args[@]:(-1)}

# Clean up when done or when aborting.
trap "rm -f in.$$" 0 1 2 3 15

# Set time stamp
timestamp=`date +"%d-%m-%Y %H:%M"`

# Start processing.
cd $INSPECT_DIR || {
    echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; }
 
cat >in.$$ || {
    echo Cannot save mail to file; exit $EX_TEMPFAIL; }

# Check who is the sender and apply policy accordingly
USER=`/bin/echo $SENDER | awk -F "@" '{print$1}'`
echo "USER: " $USER >> /var/log/filter

case $USER in
    $VIP_USER) # Limit VIP account
        if [ $MESSAGE_SIZE -gt $VIP_LIMIT ]; then
            echo "${message}";
            echo "$timestamp: Message size exceeded from " $SENDER  >> /var/log/filter;
            exit $EX_NOPERM;
        else
            echo "Business Mail size OK" >> /var/log/filter;
            $SENDMAIL $SENDER $RECIPIENTS <in.$$
        fi
        ;;
    *) # Limit User Mails
        if [ $MESSAGE_SIZE -gt $USER_LIMIT ]; then
            echo "${message}";
            echo "$timestamp: Message size exceeded from " $SENDER  >> /var/log/filter;
            exit $EX_NOPERM;
        else
            echo "User Mail size OK" >> /var/log/filter;
            $SENDMAIL $SENDER $RECIPIENTS <in.$$
        fi
        ;;
esac
exit $?



Reply | Threaded
Open this post in threaded view
|

Re: Content filter with script

Wietse Venema
Alex K:
> Hi all,
>
> Just checking if anyone can provide any hints on the below.

My advice: use postfwd to enforce size limits, instead of using a
filter. This advice is valid if email arrives via SMTP.

What is the problem with your code?

1) In your basic filter approach. the shell is not a safe program
to manipulate raw email addresses from the network. For example,
I'm not sure that your code will correctly handle an email address
that contains spaces.

2) The advanced filter approach uses SMTP to pass sender and recipient
information, as well as the message body. I suspect that your program
does not correctly implement the SMTP protocol.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Content filter with script

Abi Askushi


On Mar 8, 2018 00:39, "Wietse Venema" <[hidden email]> wrote:
Alex K:
> Hi all,
>
> Just checking if anyone can provide any hints on the below.

My advice: use postfwd to enforce size limits, instead of using a
filter. This advice is valid if email arrives via SMTP.

What is the problem with your code?

1) In your basic filter approach. the shell is not a safe program
to manipulate raw email addresses from the network. For example,
I'm not sure that your code will correctly handle an email address
that contains spaces.

2) The advanced filter approach uses SMTP to pass sender and recipient
information, as well as the message body. I suspect that your program
does not correctly implement the SMTP protocol.

        Wietse
Thank you Wietse.
It is clear. Indeed my script was used only as a filter at sender access and does not implement smtp.

Alex
Reply | Threaded
Open this post in threaded view
|

Re: Content filter with script

Karol Augustin
In reply to this post by Abi Askushi
On 2018-03-07 21:47, Alex K wrote:

> Hi all,
>
> Just checking if anyone can provide any hints on the below.
>
> Thanx, Alex
>
> On Tue, Mar 6, 2018 at 3:16 PM, Alex K <[hidden email]> wrote:
>
>> Hi all,
>>
>> I am trying to setup a simple script, which will be used to check the mail size and count the emails per user (the script does only mail size checks at the moment). I am currently checking the logic with a simple script and I have followed the http://www.postfix.org/FILTER_README.html, the advanced option to avoid loops. When putting script at pickup I had loops.

Check mtpolicyd, it has accounting plugin which might be what you are
looking for.

Karol


--
Karol Augustin
[hidden email]
http://karolaugustin.pl/
+353 85 775 5312
Reply | Threaded
Open this post in threaded view
|

Re: Content filter with script

Abi Askushi
Thank you Karol. I will check this.
I am interested to log the mails (count in/out), check the size then log these to a DB to show them in some GUI and using these values to apply some policies (allow or reject according to set limits)

Alex

On Thu, Mar 8, 2018 at 11:59 AM, Karol Augustin <[hidden email]> wrote:
On 2018-03-07 21:47, Alex K wrote:

> Hi all,
>
> Just checking if anyone can provide any hints on the below.
>
> Thanx, Alex
>
> On Tue, Mar 6, 2018 at 3:16 PM, Alex K <[hidden email]> wrote:
>
>> Hi all,
>>
>> I am trying to setup a simple script, which will be used to check the mail size and count the emails per user (the script does only mail size checks at the moment). I am currently checking the logic with a simple script and I have followed the http://www.postfix.org/FILTER_README.html, the advanced option to avoid loops. When putting script at pickup I had loops.

Check mtpolicyd, it has accounting plugin which might be what you are
looking for.

Karol


--
Karol Augustin
[hidden email]
http://karolaugustin.pl/
<a href="tel:%2B353%2085%20775%205312" value="+353857755312">+353 85 775 5312