When a spammer uses his botnet of thousands of zombie PCs to spam at random nonexistent addresses @example.com, at a very high rate of speed, postfix exhausts our VPS provider's resource limits trying to deal with it. Specifically, it exhausts the number of non-TCP sockets, which is limited to 900 by the VPS. Am running postfix 2.3.3-2.1.el5_2 on CentOS 5 on a Virtuozzo linux VPS.
/var/log/maillog says:
Feb 23 06:26:22 postfix/smtpd[3938]: warning: connect #1 to subsystem private/proxymap: Cannot allocate memory
Feb 23 06:26:22 postfix/smtpd[3936]: fatal: socket: Cannot allocate memory
Feb 23 06:26:48 postfix/qmgr[17702]: fatal: socket: Cannot allocate memory
Firewalling would be kind of tough because of the thousands of IPs involved in the dictionary attack.
The VPS provider suggested tuning the following parameters, but did not give suggestions on what to set them to:
max_idle = 100s (default)
max_use = 100 (default)
I found another person having the same problem with postfix and spammer dictionary attacks:
http://forums.vpslink.com/linux/394-you-hitting-socket-resource-limits-2.html#post5241
He changed:
default_process_limit from 100 (default) to 10
... which solved the problem but introduced a performance penalty.
I am unsure exactly which parameter should be safely tuned here, even after skimming postfix.org/TUNING%5FREADME.html Can any postfix expert help?
Sadly, as Postfix follows the process driven model, high memory usage under load is one of it's side effect. You could try this
From /etc/postfix/master.cf
In the
maxproc
column, you can replace the-
with a smaller number to limit the number of concurrentsmtpd
processes, this should provide some gate on the amount of incoming mail.Another alternative would be to look at
fail2ban
which can be configured to parse/var/log/maillog
and raise iptables blocks for addresses that send a large amount of undeliverable mail.You might want to consider adding something similar to:
...to your
main.cf
file, which should cause postfix to dump some of the connections as soon as it figures out there isn't a user to deliver to. The magic is inreject_unlisted_recipient
, which will cause rejections for users that are not valid on your system when used withlocal_recipient_maps
. By doing so, it should take some pressure off by reducing the amount of processing going on, as each dropped connection frees up precious resources to deal with the next connection. Yes, the spammer will be able to determine what addresses are invalid, but better that the spammer wastes their time sending (and being rejected, wasting their bandwidth) than yours (fending off the attack).