pavement

Postfix, relay MX

From FreeBSDwiki
Revision as of 07:55, 29 September 2009 by Jimbo (Talk | contribs)
Jump to: navigation, search

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.

Personal tools