Getting Mail Rate Limiting (milter-greylist) working

Short version:

To make “Mail Rate Limiting” work (it does not out of the box):

Add “noauth” and “nospf” (no quotes on either) on lines by themselves in:

/etc/milter-greylist/greylist.conf

(I did mine right at the top of that first block on non-commented text.)

And enable (or disabled and re-enable) “Rate limiting enabled” here:

Virtualmin -> Email Settings -> Mail Rate Limiting


Long version:

At least on my version of things setting this:

Virtualmin -> Email Settings -> Mail Rate Limiting

Does nothing on a nearly out-of-the-box install. I demonstrated a similar problem a last year and found a solution (which I left for myself in the forum) but was unsure then whether I had done anything else which might have resulted in that working (as I had tried some other things along the way), today with a newer install I have confirmed that that thread does not have (or no longer has) the complete answer:

https://forum.virtualmin.com/t/mail-rate-limiting-broken-out-of-the-box-ubuntu-24-04/129907/5

However, I believe that I have discovered the issue (or another issue) and how to correct it.

After following my instructions from the link above (which amount to putting “noauth” on a line by itself in the greylist.conf file) I was getting:

2025-08-06T18:30:21.477096+00:00 testsystem001 milter-greylist: smfi_getsymval failed for {I}
2025-08-06T18:30:21.477434+00:00 testsystem001 milter-greylist: (unknown id): Sender IP [the ip] and address <realuser@realdomain.com> are SPF-compliant, bypassing greylist

(and nothing else “milter-greylist” related when I sent a mail). This is because my domain is a real domain with SPF configured (of course) and milter-greylist seems to ignore all things SPFed by default. This does no good if the purpose is to rate-limit outgoing mail to combat spammers with guessed passwords (etc) so “nospf” in the config disables that.

My previous post addressed a problem that I was having then, with non-SPFed (test) domains:

2024-10-31T15:39:13.889351+00:00 xmail2 milter-greylist: User ronetest@newestisotest.com authenticated, bypassing greylisting

Indicating that milter-greylist also allows all mail from authenticated users by default (and ignores the rate limiting), also not useful for combating guessed-password disruption.

This is the equivalent of running the milter-greylist.service with -S and -A flags after them, and that is also an option/will do the same thing, in:

Webmin -> System -> Bootup and Shutdown

Click milter-greylist.service and add -S -A to the end of the ExecStart line as such:

ExecStart=/usr/sbin/milter-greylist -S -A

And click “Restart Now

Ron

SYSTEM INFORMATION
OS type and version Ubuntu 24.04.2
Virtualmin version 7.30.8
1 Like

I tried my own instructions again and the milter failed (this time for not being able to read the .sock file). It turned out that along the way I had broken postfix out of its chroot jail to make this work (and forgotten). Since that seems like a bad idea anywhere but on a test system here are some updated instructions which do not require it. (It sets the milter work from postfix’s chrooted path and sets the service to create the socket files with correct permissions each time it starts):

sudo nano /etc/milter-greylist/greylist.conf

Change this line (or comment it and put one below it):

socket "/var/run/milter-greylist/milter-greylist.sock" 

To this:

socket "/var/spool/postfix/var/run/milter-greylist/milter-greylist.sock" 

Then add (on lines by themselves*):

noauth 
nospf 

Save and exit

sudo systemctl edit milter-greylist

Paste these lines in their spot (and save and exit):

### Anything between here and the comment below will become the contents of the drop-in file 

[Service]
PermissionsStartOnly=true

ExecStartPre=/bin/mkdir -p /var/spool/postfix/var/run/milter-greylist
ExecStartPre=/bin/chown greylist:postfix /var/spool/postfix/var/run/milter-greylist
ExecStartPre=/bin/chmod 2750 /var/spool/postfix/var/run/milter-greylist

ExecStartPost=/bin/sh -c 'for i in $(seq 1 50); do [ -S /var/spool/postfix/var/run/milter-greylist/milter-greylist.sock ] && break; sleep 0.1; done; \
  [ -S /var/spool/postfix/var/run/milter-greylist/milter-greylist.sock ] && chgrp postfix /var/spool/postfix/var/run/milter-greylist/milter-greylist.sock && chmod 0660 /var/spool/postfix/var/run/milter-greylist/milter-greylist.sock || true'

### Edits below this comment will be discarded

sudo systemctl daemon-reload
sudo systemctl restart milter-greylist

(These are each one line to paste, doing my best with the forum formatting):

sudo postconf -e ‘smtpd_milters=inet:127.0.0.1:8891,local:/var/run/milter-greylist/milter-greylist.sock’

sudo postconf -e ‘non_smtpd_milters=inet:127.0.0.1:8891,local:/var/run/milter-greylist/milter-greylist.sock’

sudo systemctl reload postfix

*I think the noauth/nospf lines can go anywhere but mine are here:

# List of users that want greylisting
list "grey users" rcpt { \
        user1@example.com \
        user2@example.com \
        user3@example.com \
}
noauth
nospf
# Give this a try if you enabled DNSRBL

Ron

Postfix being chrooted or not isn’t a big deal. Historically, Wietse recommended against it, though I think the reasons for that recommendation are probably in the past. And, I think EL still ships without it being configured in a chroot by default. So, I wouldn’t call it a “bad idea”, but I do think one should stick with package-provided defaults whenever possible because it makes it harder to mess up in terms of backup and recovery, etc. It’s just better to stick with defaults whenever possible.

But, I guess we need to fix this on our end for newer Ubuntu/Debian versions that chroot postfix by default.

So, if I’m understanding it, the problem is that the milter-greylist service is configured for a non-chroot Postfix.

I don’t think I understand how nospf and noauth are related to the issue. I guess without them, only mail that doesn’t have valid SPF and isn’t from an authenticated sender will be rate limited? That feels like a problem, as we wouldn’t want to greylist authenticated users at all, even if you want to rate limit them. So, I wouldn’t want to make noauth the default even if we do make nospf the default.

Yes I think the gist of it is that Virtualmin ships with this (in “/etc/milter-greylist/greylist.conf”):

socket “/var/run/milter-greylist/milter-greylist.sock”

But since postfix ships chrooted, it considers “/var/spool/postfix/” to be “/” and so postfix prepends with that.

The outlined fix basically just tells the milter-greylist to work from the same place that postfix is looking (and creates that place).

I had thought that the other option was to break postfix out of chroot (I remember changing a y to an n at some point) but when I went to repeat my steps (and make an internal document on exactly how this would be set up) I ran into the milter problem (which I’d remembered solving) and followed the breadcrumbs I originally left here to no avail… ultimately ending with what I have now. I see now that my test version’s postfix is still chrooted and it also points to /var/spool/postfix in its milter-greylist.conf:

socket “/var/spool/postfix/var/run/milter-greylist/milter-greylist.sock” 666

However it does not have the milter-greylist service change, and the folder and files have permission/ownership differences which hindered (or appeared to hinder) me along the way to a working new install and for whatever reason I think are needed:

Test version:

ls -altr /var/spool/postfix/var/run/milter-greylist
total 8
drwxr-xr-x 4 root     root     4096 Aug  6 15:24 ..
srw-rw-rw- 1 greylist greylist    0 Aug  7 13:34 milter-greylist.sock
drwxrwxr-x 2 greylist greylist 4096 Aug  7 13:34 .

New version:

ls -altr /var/spool/postfix/var/run/milter-greylist
total 8
drwxr-xr-x 4 root     root    4096 Sep  5 12:02 ..
srw-rw---- 1 greylist postfix    0 Sep  9 12:46 milter-greylist.sock
drwxr-s--- 2 greylist postfix 4096 Sep  9 12:46 .

If I comment out the “noauth” (on either one) there is an additional milter-greylist log line when I send mail as an authenticated user:

2025-09-09T12:46:42.569514-07:00 fsivmail002 milter-greylist: User ron@rontest.com authenticated, bypassing greylisting

And it specifically does not blacklist either (when my quota is 1 per hour, it allows two in a row this way, but with “noauth” enabled it breaks as expected).

cat /etc/milter-greylist/greylist.conf | grep -vE ‘^#|^$|/(1[6-9]|2[0-4]|28|32)\b|Yahoo’

pidfile "/var/run/milter-greylist.pid"
socket "/var/spool/postfix/var/run/milter-greylist/milter-greylist.sock"
dumpfile "/var/lib/milter-greylist/greylist.db" 600
dumpfreq 10m
user "greylist"
quiet
list "my friends" addr {   \
}
list "broken mta" addr {   \
        64.124.204.39      \ # moveon.org (unique sender)
}
list "grey users" rcpt {  \
        user1@example.com \
        user2@example.com \
        user3@example.com \
}
noauth
nospf
racl continue from /.*/ addheader "X-Greylist: inspected by %V for IP:'%i' DOMAIN:'%d' HELO:'%h' FROM:'%f' RCPT:'%r'"
racl whitelist list "my network"
racl whitelist list "my friends"
racl whitelist list "broken mta"
racl greylist list "grey users" delay 30m autowhite 3d
ratelimit "domain_1757938947472856" rcpt 1 / 1d
racl blacklist from /.*@rontest.com/ ratelimit "domain_1757938947472856" msg "Message quota exceeded"
racl whitelist from /.*@rontest.com/
racl whitelist default

The main thing for me is that this does what I want and I can repeat it.

Ron

postfix chroot off && postfix reload
special command to turn off chroot for Debian & Debian based distros.

edit] iirc, milter-greylist is for greylisting, not rate limiting. can it do rate limiting too?