0

The setup

Linux, Debian Wheezy, serves as mail server for about 1000 users. Courier and Postfix installed in this box.

Info about the server

It is a postfix setup which drops the emails to the mailboxes under/home/vmail/$domain/$user - this part is working.

What I plan to do:

I would like to implement that when an email gets sent via the server a script (/home/vmail/mail_logger.sh) gets triggered so that I can log and take actions. Why? I would like to implement a slowdown/disable action on an account if such an account gets hacked and someone starts sending spam emails over the system.

Right now I am rotating the logfiles and extracting which user sent how many emails over a period of time and than lock down the account if they are sending more than x emails per hour (configurable). This log-rotate implementation is not nice, so I thought it might be good to have a hock which gets triggered every time an email gets sent via smtps (right now just smtps is allowed for users - no smtp).

I have found this manual and it gave me some ideas how to implement "hocks" for the different delivery methods (smtp, smtpd, pickup)

In main.cf I have added the following lines

hooksmtp   unix  -       n       n       -       -       pipe  flags=F user=vmail argv=/home/vmail/mail_logger.sh ${sender} ${size} ${recipient} smtp
hooksmtps  unix  -       n       n       -       -       pipe  flags=F user=vmail argv=/home/vmail/mail_logger.sh ${sender} ${size} ${recipient} smtps
hookpickup unix  -       n       n       -       -       pipe  flags=F user=vmail argv=/home/vmail/mail_logger.sh ${sender} ${size} ${recipient} pickup`

and altered the following lines also in main.cf

smtp       inet  n       -       -       -       -       smtpd -o content_filter=hooksmtp:dummy
smtps     inet  n       -       -       -       -       smtpd -o content_filter=hooksmtps:dummy  -o syslog_name=postfix/smtps  -o smtpd_tls_wrappermode=yes   -o smtpd_sasl_auth_enable=yes  -o smt
pickup    fifo  n       -       -       60      1       pickup -o content_filter=hookpickup:dummy

to call the hocks on the specific actions.

Right now the triggered script looks like this and I will improve it later .....

cat /home/vmail/mail_logger.sh
#!/bin/bash
echo $(date +%Y.%m.%d_%H:%M:%S) $@ >> /home/vmail/mail_logger.log

I have now the problem, that now all the email gets handled by the "hooks" (which is good) but do not get delivered to the original destination (which is bad).

I had a look at the postfix manual and figured out that I could implement that for all emails a bcc is sent to an local email than get processed, but I thought that there should be another method of handling this.

So the question is how to change these lines that the "hocks" gets notified and the mails still get processed like they were before without the need to do a BCC and than process that BCC.

Other ideas of handling the problem above are also welcome. But please note that I don't want to run the spam scanner on that box because spam scanning gets handled by 4 MX nodes in front of the server (running debian and sa-exim).

Update 1: My first findings following the comments are

I have followed the comments and made these changes

in main.cf I have added the following lines

local_transport = hookpickup
always_bcc = extract@localhost

in master.cf I made sure that the hookpickup is in place

hookpickup unix  -       n       n       -       -       pipe  flags=F user=vmail
    argv=/home/vmail/mail_logger.sh ${sender} ${size} ${recipient} pickup

I did some tests and figured out, that

  • If I send a mail via SMTP, a BCC gets sent to extract@localhost and the "hook" picks it up and the script processes the content. - GOOD
  • If I send a email locally to root, the "hook" picks it up and the script processed the content but the email does not reach its destination - BAD.

I need now to setup that the local_transport = hookpickup just gets "triggered" if the email comes from the mailbox extract@localhost

Update 2: My next findings following the answer are

I have followed the first answer and made these changes

transport_maps = hash:/etc/postfix/map_mytransport
always_bcc = extract@localhost
# removed: local_transport = hookpickup

The file /etc/postfix/map_mytransport has the content

extract@localhost hookpickup:

Every time that you alter the content of /etc/postfix/map_mytransport you have to run postmap /etc/postfix/map_mytransport which will generate the file /etc/postfix/map_mytransport.db which postfix actually uses.

Please make sure that you have transport_maps not defined before or you will overwrite it with this setting and you could cause unexpected behavior. I followed to 70% this manual setting up the server and have not had it set but I know that other people have.

In master.cf I altered the hookpickup and added more values for debugging

hookpickup unix  -       n       n       -       -       pipe  flags=F user=vmail
    argv=/home/vmail/mail_logger.sh client_address=${client_address} client_hostname=${client_hostname} client_port=${client_port} client_protocol=${client_protocol} domain=${domain} extension=${extension}mailbox=${mailbox} nexthop=${nexthop} original_recipient=${original_recipient} recipient=${recipient} sasl_method=${sasl_method}  sasl_sender=${sasl_sender} sasl_username=${sasl_username} sender=${sender} size=${size}

The full description of the parameters can be found here.

To get the solution working I added the user extract to the system and restarted postfix.

The script /home/vmail/mail_logger.sh is now getting in "real time" the info's that I need to lock down an account if it sends out to many emails (defined per an threshold configured in the database).

masegaloeh
  • 17,978
  • 9
  • 56
  • 104
MarcoK
  • 23
  • 3
  • `I could implement that for all emails a bcc is sent to an local email than get processed, but I thought that there should be another method of handling this` --> What's wrong with this method? Have you tried it? – masegaloeh Dec 17 '14 at 03:26
  • End clients could consider this as that I am coping their emails.... Additionally I would have to make sure that just emails to that specific local email (extract@localhost) gets forwarded to the hock and not every email (like root@localhost). If this is the only option that I have, I am happy to read your hints and I will put my final version online here... – MarcoK Dec 17 '14 at 03:36
  • One of BCC method has been asked in [this question](http://serverfault.com/a/593684/218590). It has downside tough, you can differentiate email between pickup, smtps, and smtp. And for `content_filter` method like above, you should resubmit again to postfix. See [this documentation page](http://www.postfix.org/FILTER_README.html#simple_filter) for sample script. – masegaloeh Dec 17 '14 at 03:44

1 Answers1

1

Instead of overriding local_transport with your hookpickup, you can setup transport_maps.

#main.cf
transport_maps = hash:/etc/postfix/mytransport

#/etc/postfix/mytransport
extract@localhost hookpickup:

In this mode, just email send out to extract@localhost will be delivered to hookpickup

masegaloeh
  • 17,978
  • 9
  • 56
  • 104