Saving Postfix Messages
Sometimes for testing purposes you need to save all messages going through Postfix active queue. There are a couple of ways of doing this.
The simplest method is to simply add the “always_bcc” option to the main.cf. This will cause Postfix to send a blind copy of every message to the pre-defined “catch-all” address. A more advanced take on this approach is to create a new domain specifically for BCC mail. The new domain will be defined using sender_bcc_maps and recipient_bcc_maps with regular expressions for more granular control over what is being BCC’d and where. For example, you can add this to main.cf:
sender_bcc_maps = regexp:/etc/postfix/bcc_sender_domains recipient_bcc_maps = regexp:/etc/postfix/bcc_recpipient_domains
Then you create bcc_sender_domains and bcc_recpipient_domains to BCC all incoming and outgoing mail to/from the same username on the BCC domain:
/^([^@]+)\@primarydomain\.com$/ $1@bccdomain.com
A different approach is to simply copy everything in /var/spool/postfix/active to an archive location in real time. There are several utilities that allow you to do this. The one I use is lsyncd. You will need lsyncd version 2.1.4 or newer. Check out this article on the basics of lsyncd installation and configuration. Here’s a more specific example of the /etc/lsyncd.conf specifically for the purpose of saving Postfix active queue:
settings { logfile = "/var/log/lsyncd/lsyncd.log", statusFile = "/var/log/lsyncd/lsyncd.status", nodaemon = false, maxDelays = 3, onStartup = true, onAttrib = true, onCreate = true, onDelete = false, onModify = true, onMove = true, delete = false, } sync { default.rsyncssh, delete = false, source = "/var/spool/postfix/active/", host = "remote_server", targetdir = "/target_home/active/", delay=3, rsync = { owner = true, perms = true, checksum = true, compress = false, acls = true, verbose = true, _extra = {"-Kx"}, } }
The “delete = false” option will ensure lsyncd will not remove anything from the target directory. However, as you may imagine, after a period of time you may end up with a huge number of files on the <target_server>. Here’s a simple script that will monitor the target directory and, as soon as the number of files reaches 5,000, the script will move them to a subfolder with the current Unix epoch time:
#!/bin/bash find /target_home/var/spool/postfix -maxdepth 1 -mindepth 1 -type d | sort -u | while read line do if [ `\ls "${line}" | wc -l` -gt 5000 ] then d=$(date +'%s') mkdir -p "${line}/${d}" find "${line}" -maxdepth 1 -mindepth 1 -type f -exec /bin/mv -f {} "${line}/${d}/" \; fi done
Just add that to a crontab to run, say, every half hour for a moderately busy mail server.