Configure Journaling in SpamExperts/Postfix on Linux
There are two ways to configure journaling with Postfix:
- Using a local journaling address - Here you create a journaling address that is local to your main domain configured in SpamExperts e.g. your domain name is
demo-domain.invalid
, and you choose to usemailassurejournal@demo-domain.invalid
. See Set up Journaling Using a Local Journaling Address in Postfix on Linux - Using the global journaling address - Here you use the global journaling address that uses the SpamExperts domain e.g.
27d88847-3ec2-4f80-bc71-3b7c11b692dc-demo-domain.invalid@mx1.mtaroutes.com
. See Set up Journaling Using the Global Journaling Address in Postfix on Linux
Before you set up your journaling using either the global or a local journaling address you must first ensure Archiving is enabled in SpamExperts - see Enable Archiving on a Domain.
Set up Journaling Using a Local Journaling Address in Postfix on Linux
There are three steps to setting this up:
- Create a transport rule for each of the two journaling addresses - an SMTP transport rule to the journaling address generated in SpamExperts and pipe to an internal address on your mail system used to route mail to the journaling script - see Create a Transport Rule for Each of the Two Journaling Addresses
- Edit the Postfix primary config file and add an external pipe transport to the journaling script - see Edit the Postfix Primary Config File and Add an External Pipe Transport to the Journaling Script
- Create a script which will determine if the mail is internal and needs to be journaled - see Create a Script to Determine if the Mail is Internal and Should be Journaled
The following configuration has been tested on Ubuntu 14.04.5 LTS, other distributions may use different file locations.
Make sure your Postfix configuration files are stored in /etc/postfix/
.
Create a Transport Rule for Each of the Two Journaling Addresses
- Add the following lines to the postfix transport table e.g.
/etc/postfix/transport
replacing the placeholder values with appropriate values for your setup (do not include the angle brackets): - Run the following command as root to create the transport database:
- Ensure that the
transport_map
line in/etc/postfix/main.cf
is set to use the transport map database:
<ma-journal-address@demo-domain.invalid> smtp:<outbound SMTP server>:587
<internal-journal-address@demo-domain.invalid> external-pipe
postmap /etc/posfix/transport
transport_maps = hash:/etc/postfix/transport
Edit the Postfix Primary Config File and Add an External Pipe Transport to the Journaling Script
Add the following lines to /etc/postfix/master.cf
(the second line must be indented):
external-pipe unix - n n - - pipe
flags=DRhu user=dovecot:dovecot argv=/etc/postfix/journal.sh {-f $sender} {-j <external journal address>} {-d <yourdomain>}
The script must be run as a non-root user (dovecot in this example) and not as postfix. This is to avoid potential script injection hazards.
Create a Script to Determine if the Mail is Internal and Should be Journaled
The following script can be used as a basis for your own script. Customise it to suit your own environment.
Save it as etc/postfix/journal.sh
(if you save it elsewhere you must change master.cf
to reflect the change).
#!/bin/bash ################ # # Takes three parameters: -f <the from address> -j <journaling address> -d <the local domain> # ############### while getopts f:d:j: option do case "${option}" in f) FROM_ADDRESS=${OPTARG# };; j) JOURNAL_ADDRESS=${OPTARG# };; d) LOCAL_DOMAIN=${OPTARG# };; esac done TO_ADDRESS="unset" TO_DOMAIN= FROM_DOMAIN= #Create a temp file OUTFILE="$(mktemp)" #Cleanup on errors trap "rm -f $OUTFILE; exit 1" 0 1 2 3 13 15 # Exit, HUP, INT, QUIT, PIPE, TERM #Write the email to temp file and also read it to find the to and from addresses tee $OUTFILE | { while read -r LINE do if [[ "$TO_ADDRESS" == "unset" ]] ; then #Read this line and see if it is the To: line, if it is then strip out the email address THIS_LINE=`echo $LINE | grep -E "^(To:)" | grep -E -o "(\S)*@(\S)*" | sed 's/<//;s/>//'` If the address hasn't already been captured, store it into TO_ADDRESS if [[ $THIS_LINE ]] ; then TO_ADDRESS=$THIS_LINE break fi done #Strip the domain from the to and from email addresses TO_DOMAIN=$(echo $TO_ADDRESS | sed 's/.*@//') FROM_DOMAIN=$(echo $FROM_ADDRESS | sed 's/.*@//') #If the domains match then go ahead and send it to the journaling address if [[ "$TO_DOMAIN" == "$LOCAL_DOMAIN" && "$LOCAL_DOMAIN" == "$FROM_DOMAIN" ]]; then cat $OUTFILE | /usr/sbin/sendmail -f $FROM_ADDRESS -t $JOURNAL_ADDRESS fi } #Cleanup rm -f $OUTFILE trap 0 exit $exit_status
Ensure the script is executable by the user uid set in master.cf
Once you have completed all three steps, restart Postfix.
Set up Journaling Using the Global Journaling Address in Postfix on Linux
To set this up you need to:
- Find the SpamExperts Global Journaling Address
- Set up the Global Journaling Address in Postfix on Linux
Find the SpamExperts Global Journaling Address
You can find the global journal address at the Domain Level, in the Archive > Status page.
If the address ends with '@MX-record-hostname' please use @.
Set up the Global Journaling Address in Postfix on Linux
The following instructions assume that you are NOT already using Procmail. If you are already using Procmail, skip to step 3.
- Install Procmail using your distribution’s package management solution, e.g.:
- Ubuntu -
sudo apt install procmail
- Centos -
sudo yum install procmail
- Ubuntu -
- Edit
/etc/postfix/main.cf
and add the following line: - Edit
/etc/procmailrc
and add the following: - Restart Postfix – sudo postfix reload
mailbox_command = /usr/bin/procmail -a "$EXTENSION"
:0c: To:\W?.*@(?<domain>.*)(?=(?:From: ?.*@(\k<domain>))) !<yourglobaljournaling address> $DEFAULT
The setup described on this page have been confirmed working in our test environment but should be verified in your own configuration.