Postfix, relay MX
The goal here is to set up a spam and virus filtering relay MX, capable of acting as one of potentially many relays which show as the primary MX record for a domain. Ideally, the true destination MX will not show up in DNS at all - to prevent spammers from trying to target it directly. (Also ideally, that final destination MX will ONLY accept inbound mail from your relays, for hopefully obvious reasons.)
Contents |
necessary software
Build /usr/ports/mail/postfix, /usr/ports/mail/spamassassin, and /usr/ports/security/clamav from ports.
Once they're built, you'll need to enable them in /etc/rc.conf and start them:
# echo 'spamd_enable="YES"' >> /etc/rc.conf # echo 'clamav_freshclam_enable="YES"' >> /etc/rc.conf # echo 'clamav_clamd_enable="YES"' >> /etc/rc.conf # echo 'sendmail_enable="NONE"' >> /etc/rc.conf # echo 'postfix_enable="YES"' >> /etc/rc.conf # killall sendmail # /usr/local/etc/rc.d/postfix start # /usr/local/etc/rc.d/clamav-clamd start # /usr/local/etc/rc.d/clamav-freshclam start # /usr/local/etc/rc.d/sa-spamd start # /usr/local/etc/rc.d/postfix start
You'll also need Postprox, which is not in the ports tree. Get it from http://www.ivarch.com/programs/quickref/postprox.shtml - untar it, get into the directory the source code is in, and ./configure and make install without parameters. This will dump the binary in /usr/local/sbin and the manpages into the appropriate places.
/usr/local/etc/postfix/main.cf
You'll need to add this at the top:
permit_auth_destination = yes transport_maps = hash:/usr/local/etc/postfix/transport relay_domains = hash:/usr/local/etc/postfix/transport relay_recipient_maps = hash:/usr/local/etc/postfix/recipients unknown_relay_recipient_reject_code = 550 smtpd_proxy_filter=127.0.0.1:10025
Note that relay_recipient_maps is unnecessary if you aren't going to do recipient address verification during the SMTP conversation.
/usr/local/etc/postfix/master.cf
You'll need to append this at the bottom:
# SMTP Proxy. # 127.0.0.1:10025 inet n n n - 20 spawn user=filter argv=/usr/local/sbin/postprox -v -r -c /usr/local/bin/filter.sh 127.0.0.1:10026 # After-filter SMTP server. Receive mail from the content filter # on localhost port 10026. # 127.0.0.1:10026 inet n - n - - smtpd -o smtpd_authorized_xforward_hosts=127.0.0.0/8 -o smtpd_client_restrictions= -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o smtpd_data_restrictions= -o smtpd_junk_command_limit=100000 -o smtpd_soft_error_limit=10000 -o smtpd_error_sleep_time=0 -o smtpd_proxy_filter= -o mynetworks=127.0.0.0/8 -o receive_override_options=no_unknown_recipient_checks
Now you'll need a filter script:
/usr/local/bin/filter.sh
#!/bin/sh /usr/local/bin/clamdscan --disable-summary --stdout - < "$EMAIL" STATUS=$? [ -z "$STATUS" ] && STATUS=2 if [ $STATUS -eq 1 ]; then echo 550 Message contains a virus 1>&2 exit 1 fi if [ $STATUS -ne 0 ]; then echo 450 Unknown virus scanning error, please retry later 1>&2 exit 1 fi echo "X-Antivirus-Scanner: ClamAV (PASSED)" > "$OUTFILE" cat "$EMAIL" | /usr/local/bin/spamc -E --headers >> "$OUTFILE" STATUS=$? [ -z "$STATUS" ] && STATUS=2 [ $STATUS -eq 0 ] && exit 0 if [ $STATUS -eq 1 ]; then echo 550 This message appears to be spam, sorry 1>&2 exit 1 fi exit 2
/etc/postfix/transport
Now you'll need to set up the transport file. This is a list of each of your domains, with the destination to relay mail for that domain to, in the following format:
testing.test smtp:[192.168.0.15]:2525 moretests.test smtp:[192.168.0.16]
(Note that you can append a port number, if you don't want to use the standard port 25.)
Once you've got your transport file set up, you need to hash it for fast access by Postfix: postmap transport will do the trick. Do this each time you update the transport file.
/usr/local/etc/postfix/recipients
This is a list of all valid email addresses at your domains. In this example, the second domain listed accepts any address at its domain.
test@testing.test OK @moretests.test OK
As with transport, once you've got this file set up you need to hash it. postmap recipients will do the trick; do it again any time you change the file.
add the filter user
We need an unprivileged user to run the filter script.
pw useradd filter -s /sbin/nologin -d /home/filter mkdir /home/filter chown /home/filter
all done!
postfix reload and you should be good to go.