CCL Home Page Valid CSS! Valid XHTML 1.0 Transitional

Up Directory CCL sendmail, spamassassin and greylisting with relaydelay under Fedora 8 (F8)

sendmail, spamassassin and greylisting with relaydelay under Fedora 8 (F8)

UNDER CONSTRUCTION

This page uses Ajax (it saved me some time, since I did not have to retype all the examples in the HTML text you look at). If you want to look at the JavaScript that is running this thing, please click [ Here ] .

Before you read any of this, you need to read the disclaimer that is given at the end.

Prerequisites

Install wget as:
yum install wget
(though it will most likely tell you that you have it already).
Add livna repository to yum by typing:
rpm -ivh http://rpm.livna.org/livna-release-8.rpm
and check/make_sure that enabled=1 is changed to enabled=0 in the files:
/etc/yum.repos.d/livna.repo
/etc/yum.repos.d/livna-devel.repo
and
/etc/yum.repos.d/livna-testing.repo
Install pine (text based mail agent) from livna repo by typing:
yum --enablerepo=livna install pine
 
I also added dries repository to yum. In the directory /etc/yum.repos.d I created a file: dries.repo as:

cols=75;url=files/dries_repo8.txt

In this case the $releasever (release version) should be automatically replaced by yum with a 8 and the $basearch (base architecture) by the architecture (here i386, but if you are something else, say, x86_64, you better check the baseurl with your regular browser and check if they carry the 64-bit versions). You also need to retrieve a key for this archive:
wget http://dries.ulyssis.org/rpm/RPM-GPG-KEY.dries.txt
mv RPM-GPG-KEY.dries.txt /etc/pki/rpm-gpg/RPM-GPG-KEY-dries
The dries archive is great for various perl modules that you need. And if stuff is not available in the standard F8 archives, you just try:
yum --enablerepo=dries install whatever_you_want_there
 
I also installed freshrpms repository as:

cols=75;url=files/freshrpms_repo8.txt

that created a file: /etc/yum.repos.d/freshrpms.repo. I edited it and changed enabled=1 to enabled=0 so it is not used when I do my regular updates with
yum -y update
before I go to sleep. The problem is that the same packages are repeated at different sites with different versions and file locations and there is a potential for some packaging mismatch issues. So all my special repos have the enabled=0 and I use them when I need them. Moreover, I also installed the atrpms repo since some very useful packages are there. I just placed the file:

cols=75;url=files/atrpms_repo.txt

in /etc/yum.repos.d/atrpms.repo. This is a slow site so I also added mirrors.

Installing sendmail

This installation is for the host that serves as an MX host for a domain (i.e., that gets mail) and is also used as a gateway to send mail out. First, I used a convenience script bk for backing up the original configuration files:

url=files/bk.txt

and saved it as /usr/local/bin/bk and executabled it
chmod 755 usr/local/bin/bk
When you type
bk file
it just copies file(s) given as parameters to the file(s).YYMMDDHHMMSS. My advice: do it often, after each change, so you can backtrack. It saved me a lot of grief when I made some typos and then, luckily, identified them with:
diff myfile myfile.061213231221
after things stopped working. Now, check if you have all pieces of sendmail installed. Install them if something is missing as:
yum install 'sendmail*'
(yes, you need sendmail-devel and sendmail-doc is nice to have around.) If you do not know where the files went, you can always just ask. For example::
rpm -ql sendmail-doc
You should have the following stuff:

yum list all | grep sendmail
sendmail.i386                            8.14.2-1.fc8           installed
sendmail-cf.i386                         8.14.2-1.fc8           installed
sendmail-devel.i386                      8.14.2-1.fc8           installed
sendmail-doc.i386                        8.14.2-1.fc8           installed

or a higher version. Now, install some perl packages that will be needed later on. Do not worry... If you have them, yum will not install it again.

yum --enablerepo=dries --enablerepo=atrpms --enablerepo=freshrpms -y \
       install perl-Mail-SPF-Query.noarch \
       perl-Net-CIDR-Lite perl-Net-DNS perl-Razor-Agent 'pyzor*'

The virgin sendmail comes preconfigured in such a way that it will only receive mail from the local host/loopback address (127.0.0.1). I backed up original files:
cd /etc/mail
bk sendmail.mc sendmail.cf

To make sendmail listen to the requests from outside, you need to edit the file /etc/mail/sendmail.mc and comment out the line:
DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl
as
dnl DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl
or remove the restriction:
DAEMON_OPTIONS(`Port=smtp, Name=MTA')dnl
by commenting it as:
dnl DAEMON_OPTIONS(`Port=smtp, Name=MTA')dnl
(but it is usually commented out or absent from the stock sendmail.mc on F8). Then you need to convert the sendmail.mc file to the sendmail.cf by typing:
make -C /etc/mail
This should create a new sendmail.cf file. Now make sendmail start on boot-up:

cd /etc/rc.d/init.d
chkconfig --del sendmail
chkconfig --add sendmail
chkconfig --list sendmail
./sendmail restart

The sendmail should have the proper run levels set. Check line: # chkconfig: 2345 80 30 in the the /etc/rc.d/init.d/sendmail start-up script. If it does not have run levels 2345, edit it and put it there (though mine had, in the stock F8 distro). Do it before you run chkconfig above.
 
Before you can use your machine to send/receive mail you need to have appropriate DNS records for it in the DNS server that serves your machine. Let us assume that your machine is a mail gateway for the domain example.com and its particular name is mail.example.com (of course it can be the same as the address for the domain itself example.com which is a common practice.). Its Internet address is 192.168.23.34 (for those who know: it would be a very bad address for your mail gateway since it is not routable). You need the following things in your zone file for this domain (it is only an example!!!):

url=files/DNS.txt

You also need to ask your Internet Service Provider for setting your Reverse DNS mapping to your hostname. In the case above, you need to have the address 192.168.23.34 pointing to mail.example.com. Even if you are in charge of the DNS for your domain (i.e. of mapping from name to IP address), your Internet Service Provider is in charge of Reverse mapping, i.e., from IP address to name. While this is not critical, some spam filters will junk email coming from your machine if this is messed up. Also, if you plan to use commerce on this machine and therefore Digital Certificates (e.g., for SSL and credit cards) you have to have correct Reverse DNS Mapping, since Digital Certificates have to have it. It takes time, do it NOW!!!.
 
Now... I hope that you have some user account on this machine beside root. You really need it for testing. if you do not, create it. For example, to create an account for user jkl with user id (uid) 5000 (the same for group name and gid) do the following:

groupadd -g 5000 jkl
useradd -u 5000 -g jkl -c 'Jan Labanowski' -s /bin/bash jkl
passwd jkl

To test if your sendmail sends mail you need to have some email account somewhere, say it is jim@machine.where.you.get.mail.com and then create a test.txt message file like:

From: jkl@my.machine.being.setup.com
To: jim@machine.where.you.get.mail.com
Subject test

Testing: sending mail from joe@my.machine.being.setup.com to
      jim@machine.where.you.get.mail.com

Replace From: and To: addresses with a real thing, and send it as:
cat test.txt | /usr/lib/sendmail -v jim@machine.where.you.get.mail.com
If you can read the message on the target machine, it works. Note: some machines use greylisting and your message may be delayed for up to an hour. I will talk about greylisting later. Also, message may have ended up in a SPAM box, so check it too if you do not see it.
 
Now, it is time to see if your machine can receive mail. If you have a shell account on some other machine (and you have, or you would not do such things as playing with sendmail on LINUX) go there and try to send mail manually to your installation machine. You can try the following (assuming that your machine is called my.machine.being.setup.com and your user id there is jkl and that your shell account is at jkl@your.other.machine.com). You typed the stuff in bold:

telnet my.machine.being.setup.com 25
Trying 192.93.21.143...
Connected to my.machine.being.setup.com (192.93.21.143).
Escape character is '^]'.
220 my.machine.being.setup.com ESMTP Sendmail 8.13.6/8.13.6; Tue,
   18 Jul 2006 18:50:12 -0400
helo your.other.machine.com
250 Hello my.machine.being.setup.com [192.93.21.143], pleased to meet you
Mail From: <jkl@your.other.machine.com>
250 2.1.0 <jkl@your.other.machine.com>... Sender ok
Rcpt To: <jkl@my.machine.being.setup.com>
250 2.1.5 <jkl@my.machine.being.setup.com>... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
From: jkl@your.other.machine.com
To: jkl@my.machine.being.setup.com
Subject: Testing mail

Testing mail from jkl@your.other.machine.com
to jkl@my.machine.being.setup.com
.
250 2.0.0 k6IMoCGJ021853 Message accepted for delivery
quit

Few comments here... The stuff above is an example how the machines talk to each other when sending mail. It is called a SMTP (Simple Mail Transport Protocol) protocol. The machine that wants to send mail connects to the port 25 of the target machine and provides it with the information:

  • HELO -- it is not HELLO! (they wanted to abbreviate all keywords to four-letter words -- dirty little scoundrels). It provides the name of the machine that the mail is coming from. While it seems redundant for the TCP/IP connections (the other end always knows the IP address where the connection originated) it has its reasons (beyond the scope of this short write-up).
  • Mail From: -- the address of the sender. It is called the "envelope from" and in principle has nothing to do with the email address that you see in your message on the From: line. This is where the mail will be bounced under normal circumstances if the address is not available on the target machine. There are many tricks that people play with it, some legitimate, and some evil.
  • Rcpt To: -- the "envelope to" address of the recipient. Again, it does not need to have anything to do with the To: line of the actual message (and beside, you can put here only one address, while on the To: line in the message you can put plenty). There maybe several lines like this if the same message goes to several recipients on the target machine.
  • DATA -- this tells the target machine that the actual message will follow. What follows should be a complete message with header and body. The message is ended with the period. (again, I am scratching the surface -- yes, there is a solution for the case when you have a lonely period on the line in the message, it just puts two periods).
  • QUIT -- marks that you are finished with connection, though you could start another message if you have more then one to send to the target machine

Remember about the empty line between header and the message body and the period on a line by itself at the end of the test message body. Then, log in as user jkl and check if you got this mail in your mailbox on the my.machine.being.setup.com. You can either see if your message is in the file: /var/spool/mail/jkl (the jkl is the user name) or use pine that you installed from livna repo as described high above. If no go, restart the machine, and then see if your sendmail is actually running by doing:
ps -ef | grep sendmail | grep -v grep
If it does not, do:
/etc/rc.d/init.d/sendmail start
and check again if it is running. If it does, at least you did not mess up this one... But you messed up the chkconfig part. If it still does not run, I do not know what to tell you... It probably gave you some message when it failed to start. Maybe you did mess up the sendmail.mc file?
 
If sendmail is running, and you still cannot send mail to your machine from some remote host, try to send mail locally on your machine from a terminal window by repeating a procedure with telnet as above but replacing my.machine.being.setup.com with localhost (that is, the computer you are setting up). The fact that you cannot connect from the remote computer may be due to a firewall somewhere. Obviously, in some organizations they block the port 25 to make sure that infected computers from within the organization do not send spam out, and only allow the outgoing port 25 from approved, official gateways. They may also block the incoming port 25 for regular computers and leave it open only for the MX gateways for the organization. It is a scary world out there and everyone tries to built its own prison and watch the free people having fun on the streets (I hate the bastards...).
 
If you do not see the sendmail process running you are hosed, and I do not know what to tell you. And you should have listened to daddy... You probably messed up something and did not listen to me. Or your system installation is broken, and you better backup everything and shove your F8 Zod DVD up the DVD-ROM drive and hit Ctrl/Alt/Delete. You cannot progress without having this step working.

Installing spamassassin

Spamassassin comes with F8 so you should have it. Just in case do:
yum install spamassassin
It should tell you Nothing to do. However, the way it is installed by default is to use procmail to filters spam for individual users. I wanted to filter spam for all users and send all spam to some mailbox. It is a policy decision. Some people love their spam and you cannot take it from them or they will cry. If you do not want to do it, do not do it, but this is how I run things. Obviously, you can also have a simple script that will run through the pile of dunk in /var/spool/mail/spammail, extract To: or Cc: addresses and also check the first Received: line and pass the copy of spam to the users predefined spam folders in, say: /home/userid/mail/Spam or tweak the spamassassin configuration for some special users.
 
I followed the instructions from: http://www.eschew.net/geek/spamassassin.php when I first did it (it was years ago...). First, you need to create the user that will collect all the spam mail that was trying to reach your machine that was stopped by spamassassin:

groupadd -g 30001 spammail
useradd -g 30001 -u 30001 -c 'Spam Mail' -s /sbin/nologin spammail

I also created another special user that will receive all the mail that was sent to a wrong address on this machine (i.e., to a non-existing user or address for which there is no alias in the /etc/aliases file):

groupadd -g 30002 nosuchuser
useradd -g 30002 -u 30002 -c 'Wrong Address' -s /sbin/nologin nosuchuser

Do not set passwords on these accounts since they are not login accounts.
 
Then you need to install the spamass-milter. To cut to the chase, I will not tell you about milters, but they are just sendmail filters that can "plug" itself into sendmail and interact with the stages of the process of receiving/sending mail. The modern releases of sendmail provide an interface to hook up special callbacks from well written pieces of software that can interact with the sendmail process. Get it as:
yum install spamass-milter
Note that installing spamass-milter created a new user sa-milt and new group sa-milt (on my system, they had different ids: 102, 103, respectively, since the gid 102 was earlier booked by builder, whatever it is).
 
Then I edited /etc/sysconfig/spamass-milter file to add stuff:

  • the user that will be getting spam mail
  • the IP address of my machine so outgoing mail is not checked for spam (remember to put YOUR OWN ADDRESS).

My line with flags was:
EXTRA_FLAGS="-b spammail@my.example.com -i 192.168.23.34,127.0.0.1"
You can learn about spamass-milter option by:
man spamass-milter
To have spamass-milter work with sendmail I added the following line to the /etc/mail/sendmail.mc (after the line: FEATURE(use_ct_file)dnl):

cols=75;url=files/sendmail_mc_1.txt

I also commented out the line:
dnl FEATURE(`accept_unresolvable_domains')dnl
since spammers often use unassigned addresses to send spam. This rejects mail from hosts without a valid DNS entry. I added a line:
define(`LUSER_RELAY', `local:nosuchuser')dnl
after define(`confAUTH_OPTIONS', `A')dnl to redirect misaddressed mail to a user nosuchuser created earlier. The spammers often knowingly send spam or virus to an nonexistent id on your machine so it bounces to a From: address that they provided, and if you do not pay attention you are redistributing unknowingly their evil wares as bounces. By putting this line, your machine will not send ANY BOUNCES, even if it should (e.g., some poor soul out there misspelled the user name in the email address of one of your legitimate users). Again... It is up to you... If you do it then all mail sent to a non-existing address is collected in /var/spool/mail/nosuchuser mailbox and can be inspected and also used for extracting the IP addresses of spammers and blacklisting them.
 
I also added some options to confPRIVACY_FLAGS and my line was:

cols=75;url=files/sendmail_mc_2.txt

It is a single long line with only one space char!!! (I could use the dnl, but...). Now... Set also your local domain. The sendmail comes with the line:
LOCAL_DOMAIN(`localhost.localdomain')dnl
Change this to whatever your domain actually is, for example:
LOCAL_DOMAIN(`server.example.com')dnl
Then I ran:
make -C /etc/mail
I also edited the spamassassin config file /etc/mail/spamassassin/local.cf:

cols=75;url=files/local_cf.txt

Note that my report_safe is 0 -- i.e., I am not modifying the incoming spam. Then, tired but proud and excited I restarted the sendmail:
/etc/rc.d/init.d/sendmail restart
and also did:
sa-learn --sync
to set up Bayesian database for spamassassin. To check which plug-ins can be, or are installed in spamassassin I went through the /etc/mail/spamassassin/v310.pre file. If you plan to do the same, please uncomment those that you need, though it is not an easy decision sometimes. Some of them require open ports on the firewall and some options may be an overkill and will result in good messages being junked. I actually only uncommented the:
loadplugin Mail::SpamAssassin::Plugin::AntiVirus
To learn what is running inside spamassassin run:
spamassassin -D --lint > junk.s 2>&1
and examine the junk.s file. Or even better, have some real spam message (named hereafter as my.spam) and pipe it through the spamassassin (note, for this to work the spam message has to be intact with intact header lines and body):
spamassassin -t -D < my.spam > junk.s 2>&1
Examine file junk.s and see which modules need to be downloaded and which are installed. For example, if you see:
dbg: diag: module not installed: Net::Ident ('require' failed)
then the Net::Ident is missing. I was missing two: IP::Country::Fast and Net::Ident. You either get the missing perl modules or you should comment the lines in /etc/mail/spamassassin/v310.pre though it is not really required since it is a warning not an error. But commenting them will suppress these warning messages. If you want to get the modules, in most cases the perl modules are represented by the corresponding RPM modules as: perl-Something-Something... For example:
yum --enablerepo=dries install perl-Net-Ident perl-IP-Country
did the trick in my case. The naming of RPMs with perl modules is like perl itself: there's more than one way to do it (TMTOWTDI [tim toh' dee]) and try few times before you give up, or just google first.
 
In the /etc/mail/spamassassin/v310.pre I uncommented
loadplugin Mail::SpamAssassin::Plugin::AntiVirus
after checking with
man Mail::SpamAssassin::Plugin::AntiVirus
(it comes with spamassassin). Then I went to /etc/rc.d/init.d and activated spamass-milter and spamassassin

cd /etc/rc.d/init.d
emacs spamass-milter
  change:   # chkconfig: - 79 21  --> # chkconfig: 2345 79 21
chkconfig --del spamass-milter
chkconfig --add spamass-milter
chkconfig --list spamass-milter

emacs spamassassin
  change: # chkconfig: - 80 30 --> # chkconfig: 2345 80 30
chkconfig --del spamassassin
chkconfig --add spamassassin
chkconfig --list spamassassin

and then executed a scripts (I ran stop scripts just in case):

/etc/rc.d/init.d/spamass-milter stop
/etc/rc.d/init.d/spamassassin stop
/etc/rc.d/init.d/sendmail stop
/etc/rc.d/init.d/spamassassin start
/etc/rc.d/init.d/spamass-milter start
/etc/rc.d/init.d/sendmail start

The spamassassin was running and collecting spam in spammail mailbox. What a relief...

relaydelay installation

To learn what is greylisting read my previous write-up at: http://server.ccl.net/cca/software/UNIX/greylisting/README.shtml and references therein. However, do not use the install instructions from the above write-up since they are quite rusty. Follow the ones below. The relaydelay is a thing that does greylisting. The greylisting is just another very efficient way to combat spam. It does it this way that it asks the sender to resend the message later rather than accepting it on first try. Spammers do not run legitimate mail queues and they do not like greylisting very much. There are many other greylisting milters around, but I like perl even though it is slow and memory hog. Retrieved relaydelay 0.4 as:

cd /etc/mail
wget http://projects.puremagic.com/greylisting/releases/relaydelay-0.04.tgz
tar zxvf relaydelay-0.04.tgz

That created a directory /etc/mail/relaydelay-0.04. Before doing anything else, I made sure that I had mysql and friends installed:
yum install 'mysql*'
Then I made sure that mysql server starts on boot.

cd /etc/rc.d/init.d
./mysqld stop       # just in case
emacs mysqld
   changed: chkconfig: - 64 36  --> # chkconfig: 345 64 36
chkconfig --del mysqld
chkconfig --add mysqld
chkconfig --list mysqld
./mysqld start

I actually did some things that they tell you at startup:

cols=75;rows=15;url=files/mysqlstart.txt

Then I set the password for the root user for mysql (do this only when you use mysql for the first time)

mysql -u root
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('Not-Unix-Root-Pass!');
mysql> exit

where you should replace the the Not-Unix-Root-Pass! with your own creation. Please make sure that you remember the password to the root account of your mysql server. If you forgot, you can reset it. How? First stop mysqld
/etc/rc.d/init.d/mysql stop
Then create a file with a line:
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('Not-Unix-Root-Pass!');
and save it as, for example: /tmp/junk.sql. Then run:
mysqld_safe --init-file=/tmp/junk.sql &
The mysqld should have changed the password and exited. Before I did something with mysql/relaydelay, I checked/installed the required perl modules:

DBI
DBD::mysql
Net::Daemon
Sendmail::Milter

I just used yum:

yum --enablerepo=dries --enablerepo=atrpms install \
     perl-DBI perl-DBD-MySQL perl-Net-Daemon \
     perl-Sendmail-Milter

At that time, it told me that it cannot find perl-Sendmail-Milter. So I got it from somewhere else:
http://www.city-fan.org/ftp/contrib/yum-repo/fc8/ i386/repodata/repoview/perl-Sendmail-Milter-0-0.18-8.fc8.html. I just did:

cols=75;url=files/getrpm.txt

While you can get it from CPAN archives, I had some problems compiling it before under Fedora, so I was quite happy that there is an RPM on the site above.
Then I tried again

yum --enablerepo=dries --enablerepo=atrpms install \
     perl-DBI perl-DBD-MySQL perl-Net-Daemon

Now, the relaydelay itself. First, download the patch for relaydelay 0.4 and install it:
http://lists.puremagic.com/pipermail/greylist-users/2003-September/000261.html. If the site is down (happened to me), just ask me for the files by email -- I am not sure what are the conditions for redistributing this stuff, but hopefully, the help to a friendly spam-buster is OK for the authors. You can get the patch installed as:

cols=75;url=files/patch.txt

It patched files: relaydelay.conf, relaydelay.pl and created a new file relaydelay (a startup script). Now you need to do some touch-ups -- I chose to use as a db_user the spam and the example of the db_pass is MyHardPassword. You will use something else (at least for password), will you? Save original of mysql.sql:

cd /etc/mail/relaydelay-0.04
bk mysql.sql

Edit file mysql.sql and uncomment and change line 23 to be:

cols=75;url=files/mysqlpass.txt

PLEASE!!! use something else for the password than MyHardPassword. And make a note of it!!! The user/password will be later needed to save/retrieve data from the database. Note that database users are totally unrelated to the UNIX users in /etc/password -- they are separate users needed only when you access data within mysql database server.
 
Now, create the tables needed by relaydelay (make sure mysqld is running by doing the following (you will need mysql root password):

ps -ef | grep mysql
cd /etc/mail/relaydelay-0.04
mysql -u root -p < mysql.sql

You can now check if it worked. Log in as user spam with the appropriate password (here assumed: to be MyHardPassword).

mysql -u spam -p
mysql> use relaydelay;
mysql> show tables;
+----------------------+
| Tables_in_relaydelay |
+----------------------+
| dns_name             |
| relayreport          |
| relaytofrom          |
+----------------------+
3 rows in set (0.00 sec)
mysql> quit;

There are few other files that need information about the user spam and its password. edit db_maintenance.pl and replace user/password.

cd /etc/mail/relaydelay-0.04
emacs db_maintenance.pl

   replace:
my $database_user = 'db_user';
my $database_pass = 'db_pass';

   with lines:
my $database_user = 'spam';
my $database_pass = 'MyHardPassword';

The default values of parameters and their meaning are described in the relaydelay.pl script itself. Change/override the default values by editing relaydelay.conf. I did the following:

cd /etc/mail/relaydelay-0.04
emacs relaydelay.conf
    replace:
my $database_user = 'db_user';
my $database_pass = 'db_pass';

    with lines:
my $database_user = 'spam';
my $database_pass = 'MyHardPassword';

    changed from:
$delay_mail_secs = 58 * 60;  # 58 Minutes
    to
$delay_mail_secs = 29 * 60;  # 29 Minutes

    also changed from:
$pass_mail_when_db_unavail = 0;
    to
$pass_mail_when_db_unavail = 1;

    and from
$reverse_mail_tracking = 0;
    to
$reverse_mail_tracking = 1;

    likewise from:
$reverse_mail_life_secs = 4 * 24 * 3600;  # 4 Days
    to
$reverse_mail_life_secs = 10 * 24 * 3600;  # 10 Days

also edited relaydelay.pl itself:

cd /etc/mail/relaydelay-0.04
emacs relaydelay.pl

    from:
my $database_user = 'db_user';
my $database_pass = 'db_pass';
    to
my $database_user = 'spam';
my $database_pass = 'MyHardPassword';

    from
my $log_file = '';
    to
my $log_file = '/var/log/relaydelay.log';

Edit relaydelay boot-up script if needed:

cd /etc/mail/relaydelay-0.04
bk relaydelay
emacs relaydelay

(check if CONFIG is set to your /etc/mail/relaydelay.conf, i.e.,
CONFIG=/etc/mail/relaydelay.conf and if not, edit it. Also change the:
/usr/local/sbin/relaydelay.pl $CONFIG
to
/usr/sbin/relaydelay.pl $CONFIG
Copy files where they belong:

cd /etc/mail/relaydelay-0.04
cp db_maintenance.pl /usr/sbin
chmod 700 /usr/sbin/db_maintenance.pl
cp relaydelay.conf /etc/mail
cp relaydelay.pl /usr/sbin
chmod 700 /usr/sbin/relaydelay.pl
cp relaydelay /etc/rc.d/init.d
chmod 700 /etc/rc.d/init.d/relaydelay
cd /etc/rc.d/init.d
chkconfig --del relaydelay
chkconfig --add relaydelay
chkconfig --list relaydelay

Now... the relaydelay has to be plugged as a milter into sendmail.mc
cd /etc/mail
emacs sendmail.mc

and before the line:
INPUT_MAIL_FILTER(`spamassassin', ...
add:

cols=75;url=files/sendmail_mc_3.txt

and after line:
define(`confMILTER_MACROS_HELO',`s, {tls_version},...
add line:
define(`confINPUT_MAIL_FILTERS',`relaydelay,spamassassin')dnl
Then process sendmail.mc --> sendmail.cf as:
cd /etc/mail
make -C /etc/mail

Create script /usr/local/bin/restart_sendmail

cols=75;url=files/restart_sendmail.txt


chmod 755 /usr/local/bin/restart_sendmail
and run it
restart_sendmail
and then again
restart_sendmail
If you have all [ OK ]s then you are OK, if not, you need to go through the editing details and copying files again (yes, I did mess up myself a few times).
 
From my experience with the older spamass-milter, it sometimes dies. This newer version runs in a wrapper that is an infinite loop that cycles when spamass-milter process dies. However, I still use the script /usr/local/bin/restart_sendmail_if_dead.pl that the cron runs every hour. Create file /usr/local/bin/restart_sendmail_if_dead.pl:

cols=75;rows=20;url=files/restart_sendmail_if_dead_pl.txt

and make it executable
chmod 755 /usr/local/bin/restart_sendmail_if_dead.pl
and run it to check if you do not have any typos:
restart_sendmail_if_dead.pl
If you have your stuff running (your previous restart_sendmail script worked), it should not say a word...
 
I then added a line to /var/spool/cron/root by using crontab command. You will probably be asked to edit this file with a vi editor -- you have to know about i, ESC and :wq, if you do not, please do not even start but rather set your editor to what you know. For example, to use emacs for editing I set the env first as (if you like it, you can put it into /root/.bashrc or whatever ~/.bashrc, later on):

VISUAL=/usr/bin/emacs
export VISUAL
EDITOR=/usr/bin/emacs
export EDITOR

Then use the cron table editor:
crontab -e
and add:
25 * * * * /usr/local/bin/restart_sendmail_if_dead.pl
i.e., it will be run 25 minutes past each hour. You can also add a line at the top:
MAILTO=your@email.adr (of course with real email address), if you want email to go to your@email.adr rather than to the root account (unless of course, if you have a line
root: your@email.addr
in your /etc/aliases file).
 
You also need to add the /usr/sbin/db_maintenance.pl script to the crontab so it runs periodically. Add there a line:
24 2 * * 6 /usr/sbin/db_maintenance.pl
with a command, like before:
crontab -e
I also ran the /usr/sbin/db_maintenance.pl from my terminal window to see if it works. At the beginning there is nothing to do so you get something like:

cols=75;url=files/db_out.txt

The relaydelay.log file will grow fast, and you need to rotate it, that is, rename older versions periodically as depicted in this pseudo-code:

for n=n_max to 2 {
  mv relaydelay.log.n-1 relaydelay.log.n;
}
mv relaydelay.log relaydelay.log.1

There is a rotate service in Linux, and what you have to do, is to create the following file (relaydelay) in the /etc/logrotate.d directory. Create file /etc/logrotate.d/relaydelay:

cols=75;url=files/logrotate.txt

The cron will run this script once a week.
 
The relaydelay also allows for the whitelists and the blacklists. You need the IP addresses (or classes of addresses) of hosts that should be let through immediately without TEMPFAIL (the whitelisting) or be always rejected (the blacklisting). The IP addresses can be partial, i.e., you can specify a single address, or a group of IP addresses that start from the same bytes. The script is available from: http://lists.puremagic.com/pipermail/greylist-users/2003-November/000327.html or http://www.maynidea.com/sendmail/addlist.html. While the script is perfect, I changed this script a bit, since I like to mess up things that were done by other good people. Since I used patched relaydelay.conf I used my beloved emacs editor and added variables:
my $run_as_daemon;
my $log_file;

and then
chmod 755 addlist.pl
cp -p addlist.pl /usr/local/bin

Then I was trying to find IP addresses of the "trusted" mail gateways or the machines from where I forward mail. If you read the docs, greylisting does not make sense for certain situations. For example, you do not want to greylist machines where you have your own account and you forward mail from it. Since mail was already received by you (but on another machine) you will only bother this poor machine with TEMPFAILs but you will get the mail anyhow, since it will keep trying (mail is already batched in its queue).
 
So to find machines for whitelisting I did stiff like:
dig -t MX example.com
which gave me the Mail eXchange record for the domain example.com, for example the smtp.example.com. Then I was retrieving the Address record for the mail exchanger as:
dig -t A smtp.example.com
and extracting the IP address of the friendly gateway machine. However, MX gateways are the machines that RECEIVE mail, not necessarily the ones that SEND mail. They may be different (though for smaller shops they are the same for practical considerations).
 
I also looked at the first Received: line of my mail messages from friendly machines to get IP addresses of friendly gateways. This gives you the IP addresses of senders. There is a new protocol (actually not that new anymore) called: SPF -- Sender Policy Framework, (http://spf.pobox.com/execsumm.html) that provides the DNS entries that announce the outgoing SMTP servers. It is a special TXT record in the DNS, but it is still not widely adopted. So beside the stuff above, dig harder:
dig -t TXT example.com
and analyze the SPF/TXT records (they sometimes have quite a fancy structure, bordering on, IMHO, useless). So I put all these good guys IP addresses to the file whitelist_ip.txt together with those that came with the relaydelay. By the same token, I collected the addresses of bad guys into a blacklist_ip.txt together with those already there. Then I processed my lists with the script as:
addlist.pl -whitelist 9999-12-31 23:59:59 < whitelist_ip.txt
addlist.pl -blacklist 9999-12-31 23:59:59 < blacklist_ip.txt

Of course, you can also delete your entries from your whitelist:
addlist.pl -whitelist -delete < whitelisted_hosts_to_delete.txt
or the following for blacklist
addlist.pl -blacklist -delete < blacklisted_hosts_to_delete.txt
My whitelist_ip.txt was the original plus these addresses:

69.17.110           # speakeasy net from dig -t TXT speakeasy.net
69.17.116           #       -""-
69.17.117

192.74.137     # theworld.com from SPF record
69.38.144      #       -""-

and IP addresses of my own machines
 
As to blacklist, I used the original blacklist and did not really rely for filtering on it, since I am blacklisting hosts in a different manner, through the /etc/mail/access file. I have scripts (they are so ugly that they cannot be published at this time). I collect spam messages that sneak through my defenses in a special mailbox. Then I run it through a script that retrieves IP addresses of spammers from the first Received: header line of the messages (in fact, it is more complicated than that -- for a forwarded mail, the Received: lines for the forwarding gateways are skipped). I then append these IP addresses into the /etc/mail/access file as, say:


#@ 12.21.92.210 - [06.12.11]
12.21.92.210    REJECT

#@ pool-141-154-245-42.bos.east.verizon.net - [06.06.10]
141.154.245.42  REJECT

(note the date between [...]) and then convert the file to a binary database as:
makemap hash /etc/mail/access.db < /etc/mail/access
so sendmail can read it and use it. I also have scripts that:

  • renew the data in /etc/mail/access for the hosts that still try to send me mail by going through the /var/log/maillog
  • remove the addresses from /etc/mail/access after 6 months of inactivity.

and few others, but this is a topic for another write-up.
 
Now... I run a few domains on this machine. The sendmail would not accept mail to all of them but one (it would say "no relaying", as it is set up). It would only accept mail to the host name listed in /etc/sysconfig/network as HOSTNAME. To allow other names for this machine to be used, you need to put them in the /etc/mail/local-host-names file. For example, if your machine receives mail for several TLD variants of your domain, you would put:

example.com
example.org
example.net
mail.example.com
mail.example.org
mail.example.net

Sometimes you have a situation when your host has several names and you want all mail coming out of (i.e., outgoing mail) to be always coming from one of the names that the host has. The mail will still be coming to all addresses listed in the file /etc/mail/local-host-names but outgoing mail will have a specific host name on the From: line and in the envelope from. For example, mail addressed to:

jkl@example.com
jkl@example.org
jkl@example.net
jkl@mail.example.com
jkl@mail.example.org
jkl@mail.example.net

will still be deposited in the same system mailbox: /var/spool/mail/jkl on your machine), but if you want to make sure that all mail that user jkl sends out, comes with the address: jkl@example.org you need to do masquerading. Find the line:
dnl MASQUERADE_AS(`mydomain.com')dnl
in the /etc/mail/sendmail.mc and change it to
MASQUERADE_AS(`example.org')dnl
(pay attention to quotes -- sendmail uses different characters for opening and closing quote). Then run
make -C /etc/mail
Another possibility (which is often the case) is that you want certain users to send mail from different machine names. This is usually the case when you are running several virtual hosts on the machine (i.e., they all resolve to the same IP address but represent different organizations). For example, you have users bob, jkl and sam and you want that mail coming from them from this machine to the outside world is:
bob@example.org
jkl@example.net
sam@example.com
(of course in the real world it would be mycomany.com, myothercompany,com etc...). You create file: /etc/mail/genericstable and put there

bob  bob@example.org
jkl  jkl@example.net
sam  sam@example.com

You also need to create a file /etc/mail/genericsdomain and put there the domains that you will be using (they should be the same as in /etc/mail/local-host-names) and put there the domain names:
example.com
example.org
example.net
mail.example.com
mail.example.org
mail.example.net
Then make a hash of the /etc/mail/genericstable as: makemap hash /etc/mail/genericstable.db < /etc/mail/genericstable
Then you need to add this Zoo to the /etc/mail/sendmail.mc file (some are there, some you need to uncomment by removing dnl at the beginning of the line, and some must be added)

FEATURE(masquerade_envelope)dnl
FEATURE(genericstable, `hash -o /etc/mail/genericstable')dnl
GENERICS_DOMAIN_FILE(`/etc/mail/genericsdomain')dnl
FEATURE(always_add_domain)dnl

and rebuild the sendmail.cf (and the .db files by:
make -C /etc/mail
You can go further with it. If you want people to have aliases assigned to their email accounts, put the following in the /etc/aliases file:

root:		      jkl
admin:		      jkl
bob.smith:	      bob
jan.k.labanowski:     jkl
samuel.rosenberg:     sam

What it means: you want mail sent to root and admin to go to the local user jkl, mail that is sent to bob.smith@example.com to go to the local user bob, mail to jan.k.labanowski@example.com to go to the local user jkl, and mail to samuel.rosenberg@example.com to go to local user sam. Note that you can have a chain of aliases but each chain should end up as a local user (or a script or an include file, but it is outside the scope of this writing). Before this works, you need to convert the /etc/aliases file to a db format by running a command:
newaliases
Now, say, you want to configure sendmail in such a way that the outgoing mail has users' aliases on the From: line rather than their local user IDs. The /etc/mail/genericstable to the rescue!!! You could use something like this for it:

bob  bob.smith@example.org
jkl  jan.k.labanowski@example.net
sam  samuel.rosenberg@example.com

and remember to run:

makemap hash /etc/mail/genericstable.db < /etc/mail/genericstable
make -C /etc/mail
restart_sendmail

If you want to look at the example of /etc/mail/sendmail.mc file, here it is:

cols=75;rows=25;url=files/sendmail_mc_tot.txt

Disclaimer: if you were duped by me, I am sorry... Nothing that is written above has any informative value, and I could have been pulling your leg. If you believed any of this, it is all your fault, and you cannot sue me, since I told you. However, if you found some errors here, I will be grateful for telling me about them, and I will try to correct them and give you credit.
Jan Labanowski
Computational Chemistry List, Ltd.
Columbus, OH 43221-3334
email: jkl at ccl dot net


Modified: Wed Feb 20 03:21:16 2008 GMT
Page accessed 51767 times since Fri Jan 31 04:16:29 2003 GMT