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