As you may have gathered from my previous blogs, I like Postfix, one thing I love about it is how modular it is. This became especially evident today when I was asked to make sure that all emails go out with the appropiate disclaimer on it. This company has one MS Exchange mail server which services a hand full of different companies’ domains.
It transpires that adding the pretty signature via a pretty Outlook stationary item is not an option, with the mix of ActiveSync enbaled devices among staff (ie iPhone & HTC), people using Webmail at home signatures were not always getting applied neatly via Outlook. So we had to find a workaround to make sure the stationary gets attached.
My first thought was on the Exchange itself, I knew that it was possible to add stationary via the SMTP sink as per this Microsoft Article, but this didn’t strike me as being a particularly elegant solution on an already heavily utilised box, plus MSExchange.org indicated that it may increase the load on the server.
In the end we decided upon doing it at al MTA level on our existing Ubuntu Postfix MTA and then use alterMIME to add the necessary text. We found two excellent resources that helped a great deal an article by Falko and another on the Zimbra Wiki.
We present here a combination of the steps we took with the direction from the two posts above and this would not have been possible without those guys sharing for the greater community.
Via your Ubuntu shell install alterMIME
apt-get install altermime
Next we need to create a user for alterMIME and set it up with a directory.
useradd -r -c “Postfix Filters” -d /var/spool/filter filter
mkdir /var/spool/filter
chown filter:filter /var/spool/filter
chmod 750 /var/spool/filter
Next we will install the default script that does the work.
cp /usr/share/doc/altermime/examples/postfix_filter.sh /etc/postfix/disclaimer
As discussed in the above articles alterMime requires some tweeking if you don’t want it to apply a standard disclaimer to all inbound and outbound email. We start this by creating different lists who will use different disclaimers. We’ll worry about populating later on.
touch /etc/postfix/disclaimer_addresses_companya
touch /etc/postfix/disclaimer_addresses_companyb
touch /etc/postfix/disclaimer_addresses_companyc
touch /etc/postfix/disclaimer_addresses_companyd
While we’re at it, we may as well copy across the default disclaimers that alterMime gives us (we can change them later with our specifics).
cp /usr/share/doc/altermime/examples/disclaimer.txt /etc/postfix/disclaimer_companya.txt
cp /usr/share/doc/altermime/examples/disclaimer.txt /etc/postfix/disclaimer_companyb.txt
cp /usr/share/doc/altermime/examples/disclaimer.txt /etc/postfix/disclaimer_companyc.txt
cp /usr/share/doc/altermime/examples/disclaimer.txt /etc/postfix/disclaimer_companyd.txt
Next we want to edit the configuartion file to take notice of the different email domains.
Lets backup the config file since we’re going to mess with it and it’s always nice to have a good copy of it.
cp /etc/postfix/disclaimer /etc/postfix/disclaimer.orig
Lets open the default config.
nano /etc/postfix/disclaimer
Delete all that in there already and replace with the following, txt version here.
#!/bin/sh
# Localize these.
INSPECT_DIR=/var/spool/filter
SENDMAIL=/usr/sbin/sendmail# Define our company address lists
disclaimer_addresses_companya=/etc/postfix/disclaimer_addresses_companya
disclaimer_addresses_companyb=/etc/postfix/disclaimer_addresses_companyb
disclaimer_addresses_companyc=/etc/postfix/disclaimer_addresses_companyc
disclaimer_addresses_companyd=/etc/postfix/disclaimer_addresses_companyd# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_UNAVAILABLE=69# Clean up when done or when aborting.
trap “rm -f in.$$” 0 1 2 3 15# 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; }
# Obtain From address domain
from_address=`grep -m 1 “From:” in.$$ | cut -f 2 -d ‘@’ | cut -d “>” -f 1`# If the from address matches companya then apply the appropiate disclaimed
if [ `grep -wi ^${from_address}$ ${disclaimer_addresses_companya}` ]; then
/usr/bin/altermime –input=in.$$
–disclaimer-html=/etc/postfix/disclaimer_companya.txt ||
{ echo Message content rejected; exit $EX_UNAVAILABLE; }# If the from address matches companyb then apply the appropiate disclaimed
if [ `grep -wi ^${from_address}$ ${disclaimer_addresses_companyb}` ]; then
/usr/bin/altermime –input=in.$$
–disclaimer-html=/etc/postfix/disclaimer_companyb.txt ||
{ echo Message content rejected; exit $EX_UNAVAILABLE; }# If the from address matches companyc then apply the appropiate disclaimed
if [ `grep -wi ^${from_address}$ ${disclaimer_addresses_companyc}` ]; then
/usr/bin/altermime –input=in.$$
–disclaimer-html=/etc/postfix/disclaimer_companyc.txt ||
{ echo Message content rejected; exit $EX_UNAVAILABLE; }# If the from address matches companyd then apply the appropiate disclaimed
if [ `grep -wi ^${from_address}$ ${disclaimer_addresses_companyd}` ]; then
/usr/bin/altermime –input=in.$$
–disclaimer-html=/etc/postfix/disclaimer_companyd.txt ||
{ echo Message content rejected; exit $EX_UNAVAILABLE; }fi
# Send the email on as per the Postfix stack
$SENDMAIL “$@” <in.$$exit $?
Now we need to make the file executable.
chgrp filter /etc/postfix/disclaimer
chmod 750 /etc/postfix/disclaimer
Now lets go and tell Postfix to use the alterMIME filter. Make sure you backup the existing file incase you need to roll back:
cp /etc/postfix/master.cf /etc/postfix/mastercf.orig
Edit the master.cf file
nano /etc/postfix/master.cf
Right under the first not commented out section lets put the filter in there, so we add a line underneath:
#
# Postfix master process configuration file. For details on the format
# of the file, see the master(5) manual page (command: “man 5 master”).
#
# Do not forget to execute “postfix reload” after editing this file.
#
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (100)
# ==========================================================================
smtp inet n – – – – smtpd
-o content_filter=dfilt:
Scroll all the way to the bottom and add the following to tell Postfix what variables to pass to alterMIME. Add the following two lines on the bottom.
dfilt unix – n n – – pipe
flags=Rq user=filter argv=/etc/postfix/disclaimer -f ${sender} — ${recipient}
Save and exit.
No you can go and populate the email lists by typing a seperate email address on it’s own.
nano /etc/postfix/disclaimer_addresses_companya
Add in something like this appropiate to your installation.
companya.com
Feel free to edit your disclaimer:
nano /etc/postfix/disclaimer_companya.txt
You could have something like this in your standard email disclaimer which will be interpreted as HTML.
<br />
The information contained in this document is strictly private & confidential and may also be privileged. If you are NOT the person to whom this email is addressed, please notify the sender immediately by reply. You should not copy the document or any of the attachments which may be contained herein, or use it for any purpose or disclose its contents to any third party.<br />
<br />
Employees of Company A are expressly required not to make any defamatory statements and not to infringe or authorise any infringements of copyright, or any other legal right, by email communication. Any such communication is contrary to the company’s policy and outside the scope of the employment of the individual concerned. The company will not accept any liability in respect of such communication, and the employee will be personally liable for any damages or other liability which may arise from it.<br />
<br />
Company A does not accept responsibility for changes made to this message after it was originally sent.<br />
<br />
Company A is the trading name of Company Alpha Limited, registered office: Company A House, Big Road, Big City, registered in England & Wales under company no 1234567.<br />
Save and close the document and you’re done.
Now reload Postfix:
postfix reload
Give it a test and you should now be attaching the statutory legal requirements onto your email. You may want to edit your email lists and your individual disclaimers too for each company.
21 Comments
Don’t you mean master.cf instead of main.cf? Anyways. very nice tutorial
Hi Peter,
Thanks for the comments 🙂
Yes, you are right I meant the master.cf when updating the SMTP pipes. Have corrected the main post.
Thanks,
Gyp
Thank you! Nice tutorial! But you should careful about the quotation marks you are using: “ this is going to give you a syntax error.
# Obtain From address domain
from_address=`grep -m 1 “From:” in.$$ | cut -f 2 -d ‘@’ | cut -d “>” -f 1`
Thanks for the tip Daniel, glad it came in useful 🙂
In a postfix mysql environment, where accounts are stored in MYSQL, is it possible to have dynamic signatures on a per user basis?
What I am trying to accomplish is storing email signatures on a per user basis directly in MYSQL and then having altermime insert the signature based on the sender. Does altermime work with mysql?
I am using iRedMail’s postfix, dovecot, mysql setup.
Hi Frank,
Thanks for dropping by.
Wow, I can see that would make life quite a heck of a lot easier. To be truthful that would be overkill for the project I used and I didn’t do it that way.
A search doesn’t seem to show anyone using Altermime with a MySQL database, I’m not sure if thats because Altermime doesn’t support it or if no one has even needed to do it. Finding nothing could indicate that it isn’t functionality that it supports.
The options I think you’ve got (from my humble experience), could be:
1) List all your users individually.
2) Run a SQL script as a scheduled job to produce the mappings into a flat file which is then used my Altermime. This option could tick all the boxes for you.
I’d be very interested to learn how you get on with this, and if you want somewhere to post a “how to” feel free to get in touch and you can post it on here as a guest author 🙂
Gyp
Got it to work with Amavis
http://serverfault.com/questions/401900/amavis-atermime-dynamic-email-signatures-disclaimers/403664#403664
The only glitch right now is that on replies the number of signatures (disclaimers) keep growing. Trying to figure out a quick and dirty way to prevent that. Thinking about adding a custom header, and then looking for it …
Oh wow, great work well done. Thanks for letting me know, I will be using that 🙂
It all started with your post. If you come up with a way to prevent duplicate signatures on subsquent replies let me know. Right now if we have a long conversation by email it keeps appending a new signature per response. Ideally it would also read the message or headers and only add them on first reply. Having signatures on mail server versus client makes lots of sense if we can get past these tiny issues.
The old growing footer debate 🙂 Last time I had a conversation with some legal orientated people they thought it was better to attach the disclaimer on every email. I suppose you could check if some words already exist and not apply it if so.
Also noticing quite a few more modern email clients (ie Gmail and Outlook) don’t display the footer if it already exists.
Will happily let you know if I come up with a solution.
The more I play around with this the more I realize how broken email actually is. Imap / Pop are outdated and crappy protocols. They do not support features like push, (without activesync or other hacks), they do not allow for shared mailboxes properly, or even read notifications.
I am working on building a new hybrid email system. Just right now for toying around, and if it works in production then perhaps an open source project on github. Its essentially setup as Dbmail as a mail store, with postfix to send the emails. Nothing too sexy about that, but it will support legacy clients such as outlook and ipads. Where it gets interesting is storing email in a db, we can then use HTML5 to build a robust email client. This allows for push via websockets. Also having the emails go through sql lets us build triggers that update the status of the email for shared email box environments. Trying to couple this wish the signatures, but actually read and modify the mime message (single disclaimer/signature) and tracking pixel for read notifications (similar to what is done with email marketing like mailchimp / mailgun). Last, trying to expand the dbmail schema to support contacts, calendar, tasks, and calls. The plan is to again support legacy protocals such as activesync and DAV (carddav, caldav) and add support for html push via rest api. The plan is to build an email system that is so developer friendly it can be used as the foundation for any application. All web apps need to support email / contacts/ calls / tasks . Trying in all these groupware options in a single image that can be deployed on any *x box.
once I get the project going for our own internal use and get to where the foundation makes sense, Ill open it up on github as a public project.
Frank
Can you please email me the code for this script or please inform me in detail in relation to this script?
It’s as above 🙂
dude , all the if commands in the example lack their fi (besides the last one)
I lost some time figuring that out before my doh moment 8)
Hi Golenus,
Firstly thanks very much for taking the time to comment 🙂
I was going to check the actual setup, but I no longer have access to that cients server unfortunately, but I believe it’s still working, but I could be wrong. This post could be starting to show it’s age a bit now.
I can see your point entirely and my understanding of bash scripting it fairly basically functional at best. I suppose you could either close each if with the fi as you mention, or you could change all but the first if to an elif.
Since it’s a long weekend this weekend I will set it up in my test lab and see what I get 🙂 Thanks again Golemus, will have a look.
Gyp
Can we have an image in Disclaimer ?
I don’t see why not, since you can use HTML you can insert and image with the standard IMG tag, ie
<img src=”http://www.gypthecat.com/stationary/Gyp_Signature_Tune.jpg” alt=”Gyp the Cat dot Com Mascot”>
You’ll obviously need to upload an image to a site you can get access to.
I suppose the other way would be to encode your image with Base64 with a service such as http://www.base64-image.de/ and then paste it straight into your disclaimer through Postfix.
Hi Gyp,
I’ve followed these instructions to the letter but am not successful, i reckon it’s only a small bit remaining. Kindly help me solve this.
I’m running CentOS + Postfix + Amavisd + Altermime + Roundcube.
My issue is that if i make the changes to the master.cf file (according to steps above) then i get an error message “SMTP Error (-1): Connection to server failed”.
I’m testing this out but it seems that the domainnames are not grabbed from the domain files.
Without the IF statement altermime works fine, so what is wrong here ?
I was able to get the altermime option –disclaimer-text working direclty when I run the script /etc/postfix/disclaimer -f [email protected] — [email protected] < message.txt but I cannot get the html disclaimer version working –disclaimer-html. My goal is to attach an image to the disclaimer. Any help is much appreciate.
Hi Gyp,
I edited the working disclaimer.txt file but the text attached to the messages doesn’t change! Any clue about this? Thanks!