Postfix Filter Outbound Email
In a previous article I wrote about using Sendmail to block outbound email and at the same time allow email to specific domains or specific email addresses.
As I explained Sendmail could handle blocking and selective relaying to domains effectively but could not easily handle adding specific email addresses to the mix. Below is a quick howto on setting up Postfix on Solaris 11 and configuring the blocking as required.
# svcadm disable svc:/network/smtp:sendmail # pkg install developer/gcc-45 # pkg install library/gnutls
** Note that the postfix-install script kicks off during gmake install. You will note I used /usr/local for install_root since I do not want to taint anything on the regular paths. However that does not work very well. I ended up having to move quite a few folders and files from /usr/local/usr/local to /usr/local. I will have to try this again and see if using / for install_root is acceptable for keeping things separate and not taint system paths.
# wget http://postfix.bbnx.net/postfix-release/official/postfix-2.10.2.tar.gz # gzip -d postfix-2.10.2.tar.gz # tar xf postfix-2.10.2.tar # pwd /usr/src/postfix-2.10.2 # gmake clean # gmake makefiles MAKE=gmake CCARGS='-DNO_NIS -DUSE_TLS -lssl -lcrypto' # gmake # gmake install ... /bin/sh postfix-install ... install_root: [/] /usr/local/ tempdir: [/usr/src/postfix-2.10.2] config_directory: [/etc/postfix] command_directory: [/usr/sbin] /usr/local/sbin daemon_directory: [/usr/libexec/postfix] /usr/local/libexec/postfix data_directory: [/var/lib/postfix] html_directory: [no] mail_owner: [postfix] mailq_path: [/usr/bin/mailq] /usr/local/bin/mailq manpage_directory: [/usr/local/man] newaliases_path: [/usr/bin/newaliases] /usr/local/bin/newaliases queue_directory: [/var/spool/postfix] readme_directory: [no] sendmail_path: [/usr/lib/sendmail] setgid_group: [postdrop] ...
Setup user, group and configure Postfix:
# groupadd postdrop # useradd -d /export/home/postfix -s /usr/bin/bash -m postfix 80 blocks # mkdir /etc/postfix # pwd /etc/postfix # grep -v ^# main.cf | grep ".$" queue_directory = /var/spool/postfix command_directory = /usr/local/sbin daemon_directory = /usr/local/libexec/postfix data_directory = /var/lib/postfix mail_owner = postfix unknown_local_recipient_reject_code = 550 mynetworks = 10.2.0.0/16, 127.0.0.0/8 debug_peer_level = 2 debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin ddd $daemon_directory/$process_name $process_id & sleep 5 sendmail_path = /usr/lib/sendmail newaliases_path = /usr/local/bin/newaliases mailq_path = /usr/local/bin/mailq setgid_group = postdrop html_directory = no manpage_directory = /usr/local/man sample_directory = /etc/postfix readme_directory = no inet_protocols = ipv4 header_checks = pcre:/etc/postfix/header_checks # tail -4 header_checks /^To: .*@domain1\.com/ FILTER smtp:mail.domain1.com /^To: .*@domain2\.com/ ACCEPT /^To: user@domain3\.com/ ACCEPT /^To: .*/ REJECT
*** ACCEPT is not really a defined ACTION but for me this works. I will have to look into this closer. Maybe action should be INFO.
*** Note that domain1 needed to relay to a specific internal host whereas domain2 is an example of direct forwarding to the Internet.
Fix the /usr/local/usr/local installation. Should do a re-install and fix this.
mv /usr/local/etc/postfix/* /etc/postfix/ mkdir /usr/local/sbin mkdir /usr/local/libexec/ mkdir /usr/local/libexec/postfix mkdir /var/spool/postfix mv /usr/local/usr/local/libexec/ /usr/local/ mv /usr/local/usr/local/libexec/postfix/postfix-script /usr/local/libexec/postfix/ mv /usr/local/usr/local/sbin/post* /usr/local/sbin/ mv /usr/local/usr/local/libexec/postfix/* /usr/local/libexec/postfix/ chgrp postdrop /usr/local/sbin/postqueue chgrp postdrop /usr/local/sbin/postdrop chmod +x /usr/local/sbin/postqueue chmod +x /usr/local/sbin/postdrop chmod +s /usr/local/sbin/postqueue chmod +s /usr/local/sbin/postdrop
Start and test:
# /usr/local/sbin/postfix start # tail -f /var/log/syslog
TODO: Redo and fix installation and add to Solaris SMF.
Update 12.30.13:
More testing showed that this solution does not work well with mailing lists ie multiple recipients in the To: field. After playing with a lot of different options I finally liked the idea of running multi-postfix. In short that entails a 1st instance accepting mail on port 25 and then split the message into multiple messages and feed it to the 2nd instance on 127.0.0.1:10026 or whatever addresses and ports you prefer. The trick is to use default_destination_recipient_limit = 1 option on the frontend instance. This seemed like an elegant solution, but for me my header checks were still not working like I want. After a lot of fiddling I decided to use a different approach. At some point I will document the two postfix instance solution since it might fit a lot of use cases.
The solution that I finally used was accepting mail on port 25 with python smtplib and then sanitizing the list before injecting back into sendmail on say127.0.0.1:10026. The article here: <>