Goal: greylist e-mail using sendmail & milter-greylist

start date: 2009/02/11; revised.

In reading the notes below, note that the numbers in the code boxes are from linux's “history” command. If you want to use any of the commands on your own system, don't input the line numbers.

Let me say how grateful I am to all of the folks who have developed Fedora, milter-greylist, bash, and hundreds if not thousands of other tools that make my system tick. The frustrations I faced are not their fault. I'm just a beginner at system administration who is trying to learn from his mistakes. I made a lot of very educational mistakes in the last couple of days.

Comments and corrections most welcome.

milter-greylist sites

system information

What version of sendmail am I running?

  • rpm -qa | grep sendmail

What version of linux am I on?

  • uname -a
Linux 2.6.24-19-xen #1 SMP x86_64 x86_64 x86_64 GNU/Linux

kudos to UltraEdit ...

I currently use the 10th version of UltraEdit32. It lets me SFTP to the server, edit files, and keep a list of favorites. I don't know what I would do without it. It has proven so excellent that I'm going to upgrade to version 14 (!).

I know that there are lots of other editors that can provide FTP access. I'm at home with UE and owe the author(s) a tremendous debt of gratitude. At one time this afternoon, I had more than a dozen files open, some on my desktop and the others on the remote server. UltraEdit handled it all very gracefully.

... and to a Bible

It doesn't show in the notes, but I peeked in Fedora 9 and Red Hat Enterprise Linux Bible by Christopher Negus from time to time. Good stuff.

The easy way out: yum install milter-greylist

I love what yum does for me. What an amazing system! I asked and it delivered.

  • milter-greylist.x86_64 4.0-2.fc9 fedora
  • configuration file: /etc/mail/greylist.conf
  • milter-greylist -c # check configuration
  725  yum install milter-greylist
  727  chkconfig milter-greylist on
  729  make -C /etc/mail
  730  service sendmail stop
  731  service milter-greylist start
  732  service sendmail start

But it didn't work. I fussed around, got confused, and decided to start over.

  787  yum remove milter-greylist
  791  yum install milter-greylist

It still didn't work. I tried playing with permissions and ownership, following various suggestions on various sites.

  • smmsp stands for “sendmail mail submission program.” That is the user and group associated with sendmail.
  813  chmod 755 /var/run/milter-greylist
  816  chmod 700 /var/run/milter-greylist
  817  chown smmsp.smmsp  /var/run/milter-greylist
  818  chmod 755  /var/run/milter-greylist

Turns out that was kind of dumb. In the Fedora RPM, the default user for milter-greylist is grmilter. Go figure. OK, let's start all over again.

  839  yum reinstall milter-greylist

I thought I would check what version of milter-greylist I had.

  852  milter-greylist -v

That, too, was dumb. “-v” tells milter-greylist to go into verbose mode. It doesn't return the version number. Here is what I should have done, if I had known what I was doing.

  857  rpm -qa | grep milter-greylist
  858  rpm -qa | grep sendmail

Somehow or another, I had gotten three milter-greylist daemons loaded. One is enough.

  930  ps aux
  931  ps aux | grep milter
  932  kill 12489
  933  kill 12506
  934  kill 17790

How many milter-greylists did I have on the system?

  957  which milter-greylist

Just one. OK. Back to ground zero.

sock not found

It took, like, approximately forever, but I finally found out that yum on Fedora puts the sock in “/var/run/milter-greylist” instead of “/var/milter-greylist”. So I had to change /etc/mail/sendmail.mc and rebuild it.


I should have Read the F[riendly] Manual that yum installs along with the daemon. That line is where it belongs. That's what I get for looking elsewhere for the information I needed.

The command to make a new sendmail.cf from sendmail.mc is:

make -C /etc/mail

Then sendmail has to be restarted for the changes to take effect.

service sendmail restart

Ask milter-greylist to log activity

I uncommented these lines in greylist.conf:

stat "|logger -p local7.info" \
      "%T{%Y/%m/%d %T} %d [%i] %r -> %f %S (ACL %A) %Xc %Xe %Xm %Xh"

Two places to look for output (that I know of):

  • /var/log/messages
  • /var/log/maillog

The daemon was running and starting to talk to the logs. Wheeee! But the @#$%*&! daemon still couldn't read or write its dumpfile.

  897  cd /var/lib/milter-greylist/db/
  898  ls -l

Nothing happening to see here. Move along, move along!

So I tried adding smmsp to grmilter's group.

  914  usermod -G grmilter smmsp

No joy. Next theory: were there two greylist.conf files on the system? Was I editing the wrong one?

  920  locate greylist.conf
  924  updatedb
  925  locate greylist.db
  926  locate greylist.conf
  927  locate milter-greylist

Nope. Even after I updated the database for locate, there was only one greylist.conf on the system.

Partial success

I could send test messages to the server and see from the logs that sendmail and milter-greylist were working together. Nice!

dumpfile problem

But I kept getting the error message:

cannot read dumpfile "/var/lib/milter-greylist/db/greylist.db"
starting with an empty greylist

Things that didn't work

After each of these changes, I would restart the daemon and get the same output in the logs.

service milter-greylist restart

Playing with ownership and permissions, etc.

Now I know that Fedora uses grmilter as the user, maybe I've got stuff mixed up from previous “fixes” I tried.

  981  chown grmilter.grmilter greylist.db

I created an empty file named greylist.db with UltraEdit, then changed permissions for it to be written by the owner and group.

  983  chmod 775 greylist.db

I made a folder to match some documentation for the daemon.

  988  cd /var
  989  mkdir milter-greylist
  990  chown grmilter.grmilter milter-greylist

Nope. The daemon still couldn't read or write its database.

By now I was having trouble seeing and typing straight.

  993  s;s
  994  ;s
  995  ls

I tried creating another empty file in the new folder and gave it to grmilter.

  996  chown grmilter.grmilter greylist.db
  997  chmod 775 greylist.db

It was all to no avail.

Time to go the manly route: configure, make, make install

I went to the home page for the daemon and got the latest stable version in a tar (milter-greylist-4.0.1). I unpacked it on my desktop so I could follow the README instructions. First up: get the things needed to build the package.

 1017  yum install flex
 1018  yum install bison
 1019  yum install libmilter
 1020  yum install sendmail-devel
 1021  yum update libGeoIP

I used ftp to upload the folder in the tarball to /usr/src/milter-greylist-4.0.1

 1026  cd /usr/src/milter-greylist-4.0.1
 1029  ./configure -help

Permission denied to the root user! #$%*#$! Nobody talks like that to the root and gets away with it!

 1031  chmod 755 configure
 1032  ./configure -help

linux! It demands that everybody do things the right way. :o(

OK. Let's roll! Cook up the new daemon, get rid of the old one, and make things HAPPEN!

 1033  ./configure
 1034  make
 1035  yum remove milter-greylist
 1036  make install
 1037  chkconfig milter-greylist on
 1039  service milter-greylist start

no init file

We're not in Kansas anymore, Toto. Manly men and women know that it's their responsibility to put the start-up file in /etc/init.d on Fedora. Fortunately, rc-redhat.sh.in comes in the tarball. I copied it to /etc/init.d/milter-greylist and tried again. And changed ownership and permissions and tried again.

 1042  chown smmsp.smmsp milter-greylist
 1044  chmod 775 milter-greylist
 1045  service milter-greylist start

Splendid! I solved that problem! It is good to be root!

no user


runuser: user @USER@ does not exist

The #$%*! he doesn't! Let's bring him into existence then:

 1049  useradd smmsp
 1050  groupadd smmsp

Wrong. ssmsp exists and is doing just fine. And he's got a group of his own to boot. That was not the problem.

 1053  chown smmsp.smmsp /etc/mailgreylist.conf
 1055  service milter-greylist start
 1056  service milter-greylist start
 1057  service milter-greylist start
 1058  service milter-greylist start

I really didn't ask four times in a row to start the daemon. I'm not as dumb as I look. In between each of those command lines I read the error messages, then went off and tried different things. I think that's what I did. The error messages were a lot like this:

Starting Milter-Greylist: runuser: warning: cannot change 
directory to /var/spool/mqueue: Permission denied
-bash: /var/spool/mqueue/.bash_profile: Permission denied
-bash: @BINDIR@/milter-greylist: No such file or directory

@USER@ and @BINDIR@ problem

The rc-redhat.sh.in that I copied to /etc/init.d/milter-greylist had two troublesome lines it

daemon --user=$user @BINDIR@/milter-greylist $OPTIONS

I suppose the script is expecting these to be supplied as parameters or something. I don't know. I'll find out someday.* I got things working by hard-coding the two vars.

daemon --user=$user /usr/local/bin/milter-greylist $OPTIONS

The story is actually a little more complicated than that, but this narrative is already long enough. This is where I ended up. That's my story and I'm sticking to it!

* I should have taken rc-redhat.sh from the /usr/src/milter-greylist-4.0.1 folder on the remote website. Makefile replaces the @USER@ and @BINDDIR@ tags with “root” and “/usr/local/bin”

Everybody (else) knows you don't use the “.in” files!

But rc-redhat.sh has “user=root” rather than “user=smmsp”. That's bad.

"mail" worked better than "smmsp"

Somewhere along the line, I noticed that this dude “mail” owned some folders. Maybe adding “smmsp” to mail's group would help.

 1063  usermod -G mail smmsp
 1064  service milter-greylist start

Wait, wait, wait! Maybe I should be using “mail” as the user for the daemon's services? Maybe I should chown things to mail?

 1067  cd /usr/local/bin/
 1069  chown mail.mail milter-greylist

new sock problem

Unable to bind to port /var/milter-greylist/milter-greylist.sock: Address already in use
Unable to create listening socket on conn /var/milter-greylist/milter-greylist.sock

More chown left to do

 1082  chown -R mail.mail /var/milter-greylist/milter-greylist

Ahhhhhhhhhhhhh. That did it. sendmail on Fedora is set up to use “smmsp”. But “mail” owns the mail queue. I think my problem (caused by me, of course) was that I didn't get all my ducks in a row. I needed to get all the users and ownerships aligned. What doesn't work is mixing root, smmsp, grmilter, and mail.

 1090  service sendmail restart
 1092  service milter-greylist restart
 1094  service sendmail restart

syntax error in greylist.conf

Great progress. Got rid of those error messages and got different ones.

Starting Milter-Greylist: config error at line 10: syntax error

Line 10 in greylist.conf read dumpfile “/var/milter-greylist/greylist.db 755”. I got rid of the 755 and then was permitted to move on to … more and better error messages.

GeoIP support not compiled in

{insert expletives}

Why in heaven's name not? Let's make sure that I've got what GeoIP wants on the system.

 1095  yum update geoip
 1096  yum install geoip-devel

Did that fix it?

 1099  cd /usr/src/milter-greylist-4.0.1
 1100  ./configure
 1101  make
 1102  man make
 1103  make -B
 1104  make install
 1105  service milter-greylist restart

“make -B” forces a rebuild. I hoped that with geoip-devel on the system, it would get compiled in.

Now for the three hardest words for a manly man to say: I was wrong. Yup. Me, of all people! GeoIP wasn't compiled in because I hadn't asked for it to be compiled in.

 1106  ./configure --with-libGeoIP
 1107  make
 1108  make -B
 1109  make install
 1110  service milter-greylist restart
It was all my fault.  Mea culpa, mea culpa, mea maxima culpa.

Then I had to add a line to /etc/mail/grelist.conf:
# The geoipdb statement is used to specify the location of GeoIP database
geoipdb "/usr/share/GeoIP/GeoIP.dat"

Sweet! Got rid of that error message! But still not reading/writing dumpfile.

 1114  chown -R mail.mail /var/milter-greylist
 1115  service milter-greylist restart
 1116  service milter-greylist restart

sendmail complaints: World writable directory

Somewhere along in these perils of Pauline, sendmail was complaining about world writable directories (permissions set to xx7 or xx6, I guess). The question came up again today in the milter-greylist discussion group.

I found a magic bullet at O'Reilly net that wiped out those messages.

chmod go-w / /etc /etc/mail /usr /var /var/spool /var/spool/mqueue /private

BLAM! sendmail was happy.

But then only root can write to /var/spool/mqueue (or so it seems–I'm feeling a little woozy again).

sendmail.org says that they've tightened up security checking in order to defeat some exploits. That page explains how to use dontBlameSendmail to get rid of the warnings.

Did I say it is good to be root? It is when things JUST #$%*&+ WORK!

Decisions, decisions.

  • Run milter-greylist as root.
    • Security risk?
      • Put root in jail.
  • Make one directory world-writable.
    • Is that one too many? Will the bad guys find the unlocked door?
  • Find some other end-around.
    • Yeah, but what?
      • Here's how sendmail splits the difference:
# ps aux | grep sendmail
root   ... sendmail: accepting connections
smmsp  ... sendmail: Queue runner ... for /var/spool/clientmqueue

Here's how mqueue looks on my server:


I wonder whether it would be possible to chown smmsp.mail /var/spool/mqueue and sneak past the security checks? No time to test that theory this afternoon <sigh>. I have to go do some stuff that I know how to do. {time passes–stuff done}

I think this is how yum gets around the problem:

drwxrwx--- 2 smmsp  smmsp  ... clientmqueue

Oliver Fromme's fortune cookie said, “It's trivial to make fun of Microsoft products, but it takes a real man to make them work, and a God to make them do anything useful.” That has nothing to do with this conundrum, but it's too funny not to make a note of it for future reference. Anything that makes me laugh out loud on a day like today is a good thing.

Let's write this up for future reference

Maybe it will help other people.

 1117  rpm -qa | grep sendmail
 1118  uname -a
 1119  cd /root
 1120  history > history.txt

Three contrasting setups

from tarball, badly hacked

The working setup. Not very rational. Lots of scars left over from my misguided efforts to find out what would work. But it works. <html><center></html>

remote server (production)
/etc/mail/greylist.conf user=“mail”
/etc/init.d/milter-greylist user=“mail”
file owner.group mod


yum install milter-greylist

I decided to go back over the two approaches I took previously, using a linux PC in my room as the testbed. <html><center></html>

sandbox (Fedora 10): yum install
/etc/mail/greylist.conf user “grmilter”
/etc/init.d/milter-greylist no user specified
after installation
file owner.group mod
while running
file owner.group mod
/var/lib/milter-greylist/db/greylist.dbnot created


build from the tarball


sandbox (Fedora 10): build from tarball
/etc/mail/greylist.conf user “smmsp”
/etc/init.d/milter-greylist user-defined
after make install
file owner.group mod
while running
file owner.group mod
/var/milter-greylist/greylist.dbnot created

* I've been playing around with permissions for /var/spool/mqueue. I doubt that 755 is acceptable. It let the daemon run. I think it gives sendmail conniptions. See above.


  • Makefile doesn't pick a startup file for /etc/init.d/. I copied /usr/src/rc-redhat.sh to /etc/init.d/milter-greylist. I probably made it executable, too. I forget.
  • /usr/src/rc-redhat.sh sets user=“root”. But the /etc/mail/greylist.conf installed by Makefile sets user=“smmsp”. That seems like the more secure approach to take. The rest of stuff in rc-redhat.sh seems OK.

access denied to mqueue spool

  • Not terribly surprising. Before I changed the permissions, it was root.mail 700. Changing permissions to 777 lets smmsp access mqueue–but it gives sendmail conniptions because it's an world-writable (if I remember correctly).
  • Maybe the right approach is to chown smmsp.mail and leave the permission at 700. Root can do anything it wants in any folder, almost.

milter-greylist dead but subsys locked

  • I looked at the lock. It comes and goes as I stop and restart the service. It looks like all of the other locks in /var/lock/subsys. No problem.
-rw-r--r-- 1 root root ... /var/lock/subsys/milter-greylist
  • Maybe having root own /var/milter-greylist isn't such a good idea when trying to run the daemon as smmsp:


# chown smmsp.smmsp /var/milter-greylist
# service milter-greylist start
# service milter-greylist status
milter-greylist (pid 5016) is running...

Sandbox: installation from tarball

This is a fresh install to try to find out where I went wrong yesterday. It's on a non-production machine.

  1. Fedora 10
  2. Downloaded milter-greylist-4.0.1
  3. installed stuff necessary to build
  4. /.config, make, make install

No file is installed for /etc/init.d/milter greylist (the script that starts the demon with the command service milter-greylist start).

  • I copied /usr/src/rc-redhat.sh to /etc/init.d/milter-greylist.
  • chmod 775 /etc/init.d/milter-greylist
  • I changed user=“root” to user=“smmsp” to match /etc/mail/greylist.conf.
# service milter-greylist start
Starting Milter-Greylist: runuser: warning: cannot change directory to /var/spool/mqueue: Permission denied
-bash: /var/spool/mqueue/.bash_profile: Permission denied
config error at line 10: syntax error
  • “config error at line 10” is the trailing 755. Piece o' cake. BTDT.
  • This is where I met mail yesterday:
# ls -l /var/spool
drwx------ 2 root   mail   4096 2009-02-12 11:54 mqueue

Looks like only root can read mqueue (?). That would make it advantageous to run milter-greymail as root user–but, if I'm not mistaken, that's not considered good form these days.

  • smmsp and mail are both users on the system
  • /var/spool belongs to root.root, 777.
  • OK, today I'll try chmod 760 /var/spool/mqueue.
  • No go. I guess it's time to look at /var/spool/mqueue/.bash_profile. … It's empty. That's not the problem
  • chmod 777 /var/spool/mqueue.
  • That did it.



verifying milter-greylist

  • output to /var/log/messages
    • info about a transaction, with this appended: “Greylisting in action, please come back later”.
    • info about mail that passed the test, with this appended: “Delayed for 00:18:00 by milter-greylist-4.0.1”.
  • output to /var/log/maillog
    • on restart of milter-greymail:
Feb 11 20:49:27 ... milter-greylist: Final database dump: no change to dump
Feb 11 20:56:52 ... milter-greylist: greylist: mi_stop=1
Feb 11 20:56:52 ... milter-greylist: smfi_main() returned 0
  • same information about transactions (go away or delayed) with the addition of “Milter add: header: X-Greylist:” to the “Delayed for…” information.
blog/milter-greylist_and_fedora_9.txt · Last modified: 2023/08/12 19:17 by
Recent changes RSS feed Creative Commons License Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki