We host email and websites for numerous customers on a dedicated server running CentOS and configured through Virtualmin.

Email is handled through Postfix.

Over the weekend we noticed that a clients email account had been compromised and the server had been used to basically pump out spam. As a result our server was blacklisted, affecting every other account on the server. We believe that a desktop machine was infected with malware which allowed the spammers access to the SMTP login credentials to the account in question. From that point on it was open season.

My question is: is there anyway to put anything in place to automatically detect spam like activity of this nature?


  • 2
    You should pass your outgoing mail through spamassassin, as a matter of habit.. at the very least, you'll train your server to better recognize ham mail.
    – NickW
    Apr 22, 2013 at 13:38
  • 1
    I'd suggest throttling outgoing mail for accounts that don't have a need to send bulk e-mail, for starters.
    – ceejayoz
    Apr 22, 2013 at 13:39
  • I was under the impression (maybe wrongly) that spam assassin only processed incoming email, rather than outgoing?
    – WarpKid
    Apr 22, 2013 at 13:39
  • 1
    Spamassassin will scan whatever you tell it to.
    – NickW
    Apr 22, 2013 at 13:39
  • +1 Wow! I was going to post exactly the same question.
    – lepe
    Jul 26, 2013 at 2:17

4 Answers 4


As I posted above as a comment, I also had the same problem. After doing some research, I came up with this quick solution (still under testing -use it at your own risk-):

at your postfix main.cf file:

smtpd_relay_restrictions =

Be aware the "smtpd_relay_restrictions" are available from postfix 2.10, but you can apply them as well before 2.10, please check the Documentation.

In my case, I needed to perform 2 changes:

  1. move "permit_sasl_authenticated" down in my rules. Before, I was trusting to much in my authenticated users.
  2. add the rule: "reject_unknown_reverse_client_hostname", as most of the "authorized-spammers" where reporting "unknown" host (unfortunately, some of them contained hostname information). I also added a white list (using: check_client_access rule) from some of my customer's servers that are known to not being resolving their IP -> hostname.

So far, so good. Even better, as it is showing as "rejected" in the mail log, now I can ban those clients using my current fail2ban configuration.

As side note, you could perform an extensive checking (like perhaps rbl checking, before permitting your auth users to send mails). I haven't tried that though.

It would be nice to add spamassassin into the game and be able to flag and block those SPAM mails before delivering them. However as spamassassin was not playing really nice with Japanese messages (all my customers are Japanese), I don't feel like giving it so much power for now.

I hope it can help you.


If you use SASL/TLS to authenticate your users, you can set up different "paths" through your server. One path could be the classical port 25 incoming mail, which will run through amavisd-new, to be scanned for spam and viruses, and you could set up another path which has more permissive patterns, possibly with a higher spam threshold. You could also allow or disallow different types of email attachments.

You could even limit the sort of email, or more specifically, with what addresses your users can send as.

How you go about it depends on what sort of software you have in place at the moment.


My question is: is there anyway to put anything in place to automatically detect spam like activity of this nature?

For your use-case I would recommend to use postfwd. It has a flexible system of rules which can do smart filtering.


  • Complex combinations of smtp parameters in a single rule
  • Macros/ACLs/Groups for frequently used statements
  • Combined asynchronous dnsbl lookups with arbitrary actions depending on the results (e.g. allows dns whitelists or selective greylisting based on rbl lookup results)
  • Automatic deactivation of non-responding dnsbls
  • Rate limits for message count and size for any available item (user, client, sender, recipient, ...)
  • Scoring system for fine granular access control Date/time based rules
  • Conditional jumps to certain rules (like iptables -j)
  • Internal caching for requests and dns lookups
  • Runs as network daemon (no need to spawn processes)
  • Built in statistics for rule efficiency analysis

For e.g.

Do not allow more than 20MB or 1000 recipients per day for users alice and bob:

    action=size(sasl_username/20971520/86400/REJECT only 20mb per day for $$recipient)
    action=rcpt(sasl_username/100/86400/REJECT only 100 recipients per day for $$sasl_username)

Or you can configure different policies for different clients

# Class 1: high volume clients
# - per mail: max 30MB, max 200 concurrent recipients
id=CLASS100; client_address=table:/etc/postfwd/class1.cf; action=jump(CLASS101)

# Class 2: medium limited access
# - per mail: max 10MB, max 50 concurrent recipients
# - rate limit: 1000 recipients or 100MB per day
id=CLASS200; client_address=table:/etc/postfwd/class2.cf; action=jump(CLASS201)

# Class 3: very tight limits
# - per mail: max 4MB, max 10 concurrent recipients
# - rate limit: 100 recipients or 20MB per day
id=CLASS300; client_address=table:/etc/postfwd/class3.cf; action=jump(CLASS301)

# Does not fit anywhere? REJECT
id=DEFAULT; action=REJECT please contact postmaster@example.org

And so on. The only restriction - is your fantasy :)

  • How would you configure a rule that is valid for ALL mail accounts (not just alice and bob) so if a new account gets hijacked, it cannot send out more than 100 mails per hour?
    – rubo77
    Jul 1, 2020 at 2:24

Some time after I posted my previous answer, I came with this little trick which I think is more effective to handle stolen credentials (may not work for everyone):

1) Install fail2ban (if you don't have it already) to block failed login attempts from specific IP addresses.

2) Keep track (through an script) of the geo-location IPs connecting to your server. If you detect 2 different countries in less than 1 minute, lock the account and notify the user.

Locking the account will automatically block any clients trying to use that account.

This scenario have proven being effective in my case, as I don't expect my customers from being in 2 different countries in less than 1 minute (my servers are in Japan).

However if you have mail clients all over the world, I would suggest to increase the number of countries as mobile devices could potentially show such pattern if someone is at the border of two countries.

Also this technique implies you have a way to contact your customers directly (by phone or other way besides their compromised account).

This is specially good against malware which steals credentials, as I have experienced that in such cases, such malware seems to share those credentials among several infected clients (which are located all over the globe). However it won't be effective if the spam comes from a single client located in the same country as the original account owner resides.

The tracking script can be easily coded this way: tail -n0 -F the mail.log and pass each line into an parser script which will extract IP addresses and get their location using geoiplookup. Keep in a database (or file) with the account and last country/countries it was detected. If you are using UNIX accounts, the easier way to lock them is using: passwd ACCOUNT -l. Don't forget to send you an email so you know about the issue.

If you don't have scripting skills, or you don't want to start from zero, let me know and I will share my script.

  • pls could you share those scripts. Tnx
    – vsefer
    Jan 18, 2017 at 15:41

Not the answer you're looking for? Browse other questions tagged or ask your own question.