Wednesday, November 19, 2014

Customize outgoing SendGrid emails X-SMTPAPI header by Postfix

SendGrid’s SMTP API allows developers to specify custom handling instructions for e-mail. This is accomplished through a header, X-SMTPAPI, that is inserted into the message.

We can do it easily, for example in PHP:
 $email = new SendGrid\Email();  
     setSubject('Subject goes here')->  
     setText('Hello World!')->  
     addFilter("subscriptiontrack", "enable", 0)->  
     addFilter("clicktrack", "enable", 0)->  
     addFilter("opentrack", "enable", 0)->  
     setHtml('<strong>Hello World!</strong>');  

But for some reasons, Client would like to replay emails to SendGrid by local Postfix and using Drupal built-in mail function without custom code, we can use Postfix smtp_header_checks to add the X-SMTPAPI header for outgoing emails.

Below are steps to do that:

1. Setup Postfix and config it to send emails via SendGrid as here
(it's better to use hashed password file like smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd instead smtp_sasl_password_maps = static:yourSendGridUsername:yourSendGridPassword)

2. Add smtp_header_checks to /etc/postfix/
smtp_header_checks = regexp:/etc/postfix/smtp_header_checks

3. Create /etc/postfix/smtp_header_checks file with the content, like:
/^From:/ PREPEND X-SMTPAPI: "category":["www"],"filters":{"subscriptiontrack":{"settings":{"enable":0}},"clicktrack":{"settings":{"enable":0}},"opentrack":{"settings":{"enable":0}}}}

Hint: we can easily get the X-SMTPAPI content by print it out from above PHP code, like:
 $arr = $email->toWebFormat();  
 echo $arr['x-smtpapi'];  

4. Reload Postfix

Friday, November 7, 2014

Move Mail-in-a-box to another server

I was asked to move a Mail-in-a-box to another server last night. It's quite new for me although I've migrated Zimbra server several times. On their web site, there's just a very simple setup guide. So I searched in the forum and found a instruction from Josh. I don't have much experience with Mail-in-a-box so had to find out what are STORAGE_ROOT and STORAGE_USER variables in code. It turned out they are set:

Then learned how to decrypt files via openssl as instructed and how to restore them via duplicity. Had to look into the code to see how they are encrypted then how to decrypt..
But then found out I didn't need to decrypt those files when we can use normal files in the /home/user-data/backup/duplicity/ instead of decrypted files from /home/user-data/backup/encrypted/.

To summary, below are steps to move Mail-in-a-box to another server:
1. Setup a new Ubuntu 14.04 x64 and setup Mail-in-a-box as the setup guide.
Copy the /etc/postfix/ from the old server over the new server.
2. Stop the service mailinabox on the old server : sudo service mailinabox stop
3. Do backup manually: sudo /home/my_account/mailinabox/management/
(this is usually incremental backup since mailinabox is scheduled backup daily)
4. Then stop mailinabox again (because it's started by the backup tool) to make sure no new mails come in.
5. rsync entire /home/user-data/backup/duplicity/ to the new server in a folder.
rsync -avr -e ssh /home/user-data/backup/ my_account@new_server:backup/
6. Do restore on the new server:
- Stop the mailinabox service: sudo service mailinabox stop
- In case we restore from encrypted files, we decrypt them with commands:
mkdir  /home/my_account/backup/decrypted && cd /home/my_account/backup/encrypted
for FILE in *.enc; do  openssl enc -d -aes-256-cbc -a -in $FILE -out ../decrypted/${FILE%.*} -pass file:../secret_key.txt; done- Restore by duplicity:
sudo duplicity --no-encryption restore file:///home/my_account/backup/duplicity /home/user-data
sudo duplicity --no-encryption restore file:///home/my_account/backup/decrypted /home/user-data
- Re-configure/update: cd /home/my_account/mailinabox && sudo setup/

In case we don't switch immediately, we can start the service mailinabox on the old server again and just before transition, do from step #2 to the rest. It will be faster because we will just sync new incremental backup.

Note that Josh said on the other thread that we can sync /home/user-data directly but I didn't test that.