Installing Milter-SPF with Sendmail
Here are step-by-step instructions for installing Milter-SPF
with Sendmail 8.13.1 on Solaris. You should also read the installation
instructions provided with Milter-SPF available here.
A multi-threaded Perl 5.8.0 or later is required for the
Sendmail::Milter Perl module. Since the version of Perl installed on my
system was not multi-threaded, I built a multi-threaded Perl from
source.
If your version of Perl is multi-threaded, it will have been compiled
with USE_ITHREADS:
# perl -V | grep "Compile-time
options:"
Compile-time options:
MULTIPLICITY USE_ITHREADS USE_LARGE_FILES PERL_IMPLICIT_CONTEXT
Step 1: Build and install a multi-threaded Perl
You may download Perl source here.
gzip -cd perl-5.8.5.tar.gz | tar xvf -
cd perl-5.8.5
sh Configure
During the Perl build process, I accepted the default choices for all
but two options. First, I chose to build a threading Perl:
Perl can be built to take
advantage of threads on some systems.
To do so, Configure can be run
with -Dusethreads.
Note that Perl built with
threading support runs slightly slower
and uses more memory than plain
Perl. The current implementation
is believed to be stable, but it
is fairly new, and so should be
treated with caution.
If this doesn't make any sense to
you, just accept the default 'n'.
Build a threading Perl? [n] y
Second, I chose to use the gcc compiler to build Perl:
Use which C compiler? [cc] gcc
make
Note: Since I already had a third-party Perl package installed from
Sunfreeware, I removed it prior to performing make install. Do not remove the
Perl package that is bundled with the Solaris operating system!
make install
Step 2: Install Milter-SPF prerequisites
I installed the following Perl modules as prerequisites for Milter-SPF:
Digest-HMAC
Digest-SHA1
Mail-SPF-Query
Mail-SRS
Net-CIDR
Net-CIDR-Lite
Net-DNS
Sendmail-Milter
Sys-Hostname-Long
URI
I recommend using the CPAN Perl module to install the above modules.
Note: before building Sendmail-Milter,
make sure that libmilter.a exists
in $SENDMAIL_SRC/obj*/libmilter.
If this file does not exist, build libmilter:
cd $SENDMAIL_SRC/libmilter
./Build
Otherwise, you may receive the following error when attempting
to start SPF-Milter:
ld.so.1:
/usr/local/bin/perl: fatal: relocation error: file
/usr/local/lib/perl5/site_perl/5.8.5/sun4-solaris-thread-multi/auto/Sendmail/Milter/Milter.so:
symbol smfi_setconn: referenced symbol not found
Step 3: Configure Sendmail to use
SPF-Milter
First,
check to see if Sendmail has been built with libmilter support. By
default, Sendmail 8.13.x versions and later are built with libmilter
support.
sendmail -d0.8 < /dev/null
Compiled with: DNSMAP
HESIOD HES_GETMAILHOST LDAPMAP LOG MAP_REGEX
MATCHGECOS MILTER MIME7TO8
MIME8TO7 NAMED_BIND NETINET NETINET6
NETUNIX NEWDB NIS PIPELINING SASLv2 SCANF STARTTLS TCPWRAPPERS
USERDB USE_LDAP_INIT
If you not see MILTER when
running this command, add the following two lines to $SENDMAIL_SOURCE/devtools/Site/site.config.m4:
APPENDDEF(`conf_libmilter_ENVDEF',
`-DMILTER')
APPENDDEF(`conf_sendmail_ENVDEF',
`-DMILTER')
and rebuild and reinstall
Sendmail:
cd
$SENDMAIL_SOURCE
./Build -c
./Build install
Once Sendmail has been built with libmilter support, add the following
three lines to the Sendmail macro configuration file $SENDMAIL_SOURCE/cf/cf/sendmail.mc:
define(`confMILTER_LOG_LEVEL',`9')dnl
define(`confMILTER_MACROS_HELO',
confMILTER_MACROS_HELO`, {verify}')dnl
INPUT_MAIL_FILTER(`spf-milter',
`S=local:/var/spf-milter/spf-milter.sock, F=T, T=C:4m;S:4m;R:8m;E:10m')
Note: I remove "F=T," in the INPUT_MAIL_FILTER
line so that Sendmail will continue processing the message if spf-milter is not available. I also
use a Milter.LogLevel of "0" to reduce the size of the mail logs; I
would only do this after verifying that the milter is working correctly.
From $SENDMAIL_SOURCE/libmilter/README:
The current flags (F=) are:
R
Reject connection if filter unavailable
T
Temporary fail connection if filter unavailable
If neither F=R nor F=T is
specified, the message is passed through sendmail
in case of filter errors as if
the failing filters were not present.
Build and install the
Sendmail configuration file /etc/mail/sendmail.cf:
cd $SENDMAIL_SOURCE/cf/cf
./Build install-cf
Step 4: Install and execute
Milter-SPF
In
this example, I installed sendmail-milter-spf-1.41.pl
into /usr/local/bin, and
executed the Milter-SPF Perl script as the daemon
user using an /etc/init.d/milter-spf
startup and shutdown script.
cp sendmail-milter-spf-1.41.pl
/usr/local/bin
Note: I made changes to sendmail-milter-spf-1.41.pl
to log all SPF results in $SPF_LOG_FILENAME
instead of just SPF failures (and those are only logged if Milter-SPF
is run in "tag-only" mode). Also, my multi-threaded Perl is located
in /usr/local/bin.
Changes in "unified diff" format:
diff -u sendmail-milter-spf-1.41.pl
sendmail-milter-spf-1.41.pl.bmh > sendmail-milter-spf-1.41.pl.patch
cat
sendmail-milter-spf-1.41.pl.patch
---
sendmail-milter-spf-1.41.pl 2004-06-30 10:18:57.000000000 -0500
+++
sendmail-milter-spf-1.41.pl.bmh 2004-11-16
14:57:47.242629789 -0600
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/local/bin/perl
#
# Sendmail Milter to
perform SPF lookups
#
@@ -368,6 +368,11 @@
" helo = ".$priv_data->{'helo'}.
" from = ".$priv_data->{'from'});
} else {
+
# Log SPF failure in $SPF_LOG_FILENAME in addition
+
# to rejecting message
+
write_log ("SPF \"fail\" from ip = ".$priv_data->{'ipaddr'}.
+
" helo = ".$priv_data->{'helo'}.
+
" from = ".$priv_data->{'from'});
$ctx -> setreply ('550', '5.7.1',
"$priv_data->{'spf_smtp_comment'}");
return SMFIS_REJECT;
}
@@ -567,6 +572,12 @@
" from = ".$priv_data->{'from'}.
" to = ".$priv_data->{'to'});
} else {
+
# Log SPF failure in $SPF_LOG_FILENAME in addition
+
# to rejecting message
+
write_log ("SPF \"fail\" from ip = ".$priv_data->{'ipaddr'}.
+
" helo = ".$priv_data->{'helo'}.
+
" from = ".$priv_data->{'from'}.
+
" to = ".$priv_data->{'to'});
$ctx -> setreply ('550', '5.7.1', "[RCPT TO:
<$priv_data->{'to'}>] $priv_data->{'spf_smtp_comment'}");
return SMFIS_REJECT;
}
@@ -590,6 +601,10 @@
#
prepend the new Received-SPF header.
if
($priv_data->{'spf_result'}) {
+
write_log ("SPF $priv_data->{'spf_result'} from ip =
".$priv_data->{'ipaddr'}.
+
" helo = ".$priv_data->{'helo'}.
+
" from = ".$priv_data->{'from'}.
+
" to = ".$priv_data->{'to'});
$ctx->addheader('Received-SPF', $priv_data->{'spf_result'} . ' ('
. $priv_data->{'spf_header_comment'} . ')');
}
To patch sendmail-milter-1.41.pl, execute patch < sendmail-milter-1.41.pl.patch
with the original sendmail-milter-1.41.pl
in the same directory.
I created the following /etc/init.d/milter-spf
Milter-SPF startup and shutdown script:
#!/bin/sh
PERL=/usr/local/bin/perl
MILTER_SPF=/usr/local/bin/sendmail-milter-spf-1.41.pl
case "$1" in
'start')
$PERL $MILTER_SPF daemon
;;
'stop')
$PERL $MILTER_SPF -k
;;
*)
echo "Usage: $0 { start | stop }"
exit 1
;;
esac
exit 0
chmod 744 /etc/init.d/milter-spf
chown root:sys /etc/init.d/milter-spf
ln -s /etc/init.d/milter-spf
/etc/rc2.d/S89milter-spf
ln -s /etc/init.d/milter-spf
/etc/rc1.d/K35milter-spf
Finally, start Milter-SPF and send Sendmail a SIGHUP to begin using it
with Sendmail.
/etc/init.d/milter-spf start
kill -HUP Sendmail_PID
Step 5: Test Milter-SPF
From a remote system (i.e. do not execute this from Milter-SPF-enabled
MTA), try the following test to confirm that Milter-SPF is properly
installed:
telnet your_MTA 25
EHLO your_hostname
MAIL FROM:
mengwong@vw.mailzone.com
You should see:
550 5.7.1
mengwong@vw.mailzone.com... Please see
http://spf.pobox.com/why.html?sender=mengwong@vw.mailzone.com&ip=your_IP&receiver=your_MTA
Back to brandonhutchinson.com.
Last modified: 11/16/2004