Filtering out spam with SpamAssassin

You already have a perfectly working mail server by now. But every serious email provider does something about the insane amount of spam. With this new solution this has become simpler and way more reliable.

We are not only using real-time blacklists any more

Previous versions of the ISPmail guide relied a lot on real-time blacklists (RBLs). A blacklist is basically a list of IP addresses that can be queried through DNS. If an IP address is found in that specific DNS zone then there has been suspicious activity like a lot of spam or attacks from that address. So you may consider rejecting connections from that address. There are a lot of RBLs freely available. Unfortunately many of them are automatically maintained which means that an IP address may accidentally be blacklisted. If such blacklisting occurs to mail relays of large ISPs you will make your users very unhappy because they lose a lot of email.

Does that mean we are not using RBLs any more? Not at all. We will even be considering multiple RBLs now. Just that it is not sufficient if an IP address is listed in one blacklist. And that we will never just reject connections but rather flag an email as spam and deliver it to a special folder called “Junk” in the user’s inbox automatically.

Big fat red blinking warning: this does not work for users fetching mail using the POP3 protocol. POP3 just reads the inbox but cannot access any other folders. So those users will inadvertently assume that emails got lost because they do not see the “Junk” folder. In fact I would not suggest offering POP3 at all but I can’t tell whether it’s still a commonly used protocol.

We will even be checking incoming email for way more criteria than just black lists. You will like it.

What about virus scanning?

The bad news? This setup does not scan incoming email for malware (aka viriuses) any more. This is a very personal decision that I hope doesn’t upset you too much. I personally do not use Windows for working so I’m hardly affected. But of course I am aware that some of my users probably run Windows. Many viruses come with pirated software or through browser exploits (like Adobe Flash). Nothing you mail server could deal with. If users are uneducated and still click on attachments with EXE files they will face viruses that are not detected by virus scanning software because they are too new, mutated or even crafted to attack that user. To cut it short: I completely consider virus scanners snake oil. But enough with the ranting. 🙂

What is SpamAssassin

Our new super hero against spam is the SpamAssassin you already installed. To quote the home page: “It uses a robust scoring framework and plug-ins to integrate a wide range of advanced heuristic and statistical analysis tests on email headers and body text including text analysis, Bayesian filtering, DNS blocklists, and collaborative filtering databases.

SpamAssassin is basically a Perl script that reads an email, runs it through its plugins and computes a score that tells you how likely an email is spam. Your installation comes with over 60 plugins that help determine the spam probability. Its detection rate is so incredibly good that my well-trained Thunderbird junk filter hardly finds any addition spam.

Let me show you the analysis of a typical spam mail I received today:

Content analysis details:   (32.0 points, 5.0 required)

 pts rule name              description
---- ---------------------- --------------------------------------------------
 1.3 RCVD_IN_RP_RNBL        RBL: Relay in RNBL,
                            https://senderscore.org/blacklistlookup/
                            [203.151.98.74 listed in bl.score.senderscore.com]
 3.3 RCVD_IN_MSPIKE_L5      RBL: Very bad reputation (-5)
                            [203.151.98.74 listed in bl.mailspike.net]
 1.3 RCVD_IN_BL_SPAMCOP_NET RBL: Received via a relay in bl.spamcop.net
               [Blocked - see <http://www.spamcop.net/bl.shtml?203.151.98.74>]
 0.8 RCVD_IN_SORBS_WEB      RBL: SORBS: sender is an abusable web server
                            [203.151.98.74 listed in dnsbl.sorbs.net]
 2.7 RCVD_IN_PSBL           RBL: Received via a relay in PSBL
                            [203.151.98.74 listed in psbl.surriel.com]
 3.5 BAYES_99               BODY: Bayes spam probability is 99 to 100%
                            [score: 1.0000]
 0.7 ONLINE_PHARMACY        BODY: Online Pharmacy
 1.4 TVD_VISIT_PHARMA       BODY: Body mentions online pharmacy
 0.0 DIET_1                 BODY: Lose Weight Spam
 0.0 TVD_RCVD_IP            Message was received from an IP address
 3.5 HELO_DYNAMIC_SPLIT_IP  Relay HELO'd using suspicious hostname (Split
                            IP)
 2.5 URIBL_DBL_SPAM         Contains a spam URL listed in the DBL blocklist
                            [URIs: 6url.ru]
 1.7 URIBL_BLACK            Contains an URL listed in the URIBL blacklist
                            [URIs: 6url.ru]
 0.4 RCVD_IN_XBL            RBL: Received via a relay in Spamhaus XBL
                            [203.151.98.74 listed in zen.spamhaus.org]
 1.6 URIBL_WS_SURBL         Contains an URL listed in the WS SURBL blocklist
                            [URIs: 6url.ru]
 1.2 URIBL_JP_SURBL         Contains an URL listed in the JP SURBL blocklist
                            [URIs: 6url.ru]
 1.4 RCVD_IN_BRBL_LASTEXT   RBL: No description available.
                            [203.151.98.74 listed in bb.barracudacentral.org]
 0.8 SPF_NEUTRAL            SPF: sender does not match SPF record (neutral)
 0.2 BAYES_999              BODY: Bayes spam probability is 99.9 to 100%
                            [score: 1.0000]
 0.7 MIME_HTML_ONLY         BODY: Message only has text/html MIME parts
 0.0 HTML_MESSAGE           BODY: HTML included in message
 0.0 RCVD_IN_MSPIKE_BL      Mailspike blacklisted
 2.0 DRUGS_ERECTILE         Refers to an erectile drug
 1.0 RDNS_DYNAMIC           Delivered to internal network by host with
                            dynamic-looking rDNS
 0.0 MSGID_FROM_MTA_HEADER  Message-Id was added by a relay
 0.0 T_FROM_12LTRDOM        From a 12-letter domain

The first column shows the score that each plugin added. The second column shows the name of the plugin’s check. And the third line gives a brief explanation what the plugin found. All these scored added together leads to a total score of 32. Usually emails with a score greater than 5 or 6 can safely be considered spam. So this is definitely spam.

Before we configure Postfix let us first fix…

Debian bug #739738

Unfortunately the SpamAssassin version shipped with Debian Jessie contains a nasty bug that keeps printing error messages to your mail.log file and probably even prevents proper spam scanning. To fix it edit the file /usr/share/perl5/Mail/SpamAssassin/Util.pm, jump to line 288 and replace

return if !defined $_[0];

by

return undef if !defined $_[0];

Enable spam scanning with SpamAssassin

We will run SpamAssassin as a daemon process all the time waiting for connections from Postfix. The connection between Postfix and SpamAssassin works over the milter protocol. Run:

postconf smtpd_milters=unix:/spamass/spamass.sock

SpamAssassin expects special variables (aka “macros”) so add them to Postfix by running:

postconf milter_connect_macros="i j {daemon_name} v {if_name} _"

Nex edit the /etc/default/spamassassin file and set:

OPTIONS="--create-prefs --max-children 5 --helper-home-dir -x -u vmail"

CRON=1

The additional OPTIONS “-x -u vmail” tell SpamAssassin to look for its Bayes database in the home directory of the “vmail” user. To be exact it will be put into /var/vmail/.spamassassin. The Bayes database records words (aka “tokens”) from all seen emails and computes conditional probabilities that determine the likelihood that an email is spam.

CRON=1 enables the daily cron job in /etc/cron.daily/spamassassin that downloads a new set of spam detection rules every night.

To make the spamd process get started automatically run:

systemctl enable spamassassin

(Note: Debian Jessie uses the “systemd” to start and stop tasks. So setting ENABLED=1 does nothing. That’s a relic of times when Debian used sysvinit.)

We need to fix a permission issue. The SpamAssassin milter needs to access the same data as the spamd. So we need to add the the spamass-milter user to the debian-spamd group:

adduser spamass-milter debian-spamd

Restart SpamAssassin:

service spamassassin restart
service spamass-milter restart

Testing spam detection

SpamAssassin should be properly integrated now. To test it we can use a sample spam email that comes with SpamAssassin. It is also called GTUBE (Generic Test for Unsolicited Bulk Email). It contains a certain articial pattern that is recognized as spam by SpamAssassin. Do you know EICAR.COM to test virus scanners? This is the same thing for spam.

So let’s send that spam sample to John and see what happens. As “ip-address” please use the IP address of your ethernet interface. Run “ip addr” in your shell to find it out. Then:

swaks --to john@example.org --server ip-address --data /usr/share/doc/spamassassin/examples/sample-spam.txt

(We cannot use the simple “mail” command to test spam detection here because it would put the email directly into Postfix’s queue and bypass the milters.)

Check your /var/log/mail.log. It should read something like this:

Oct 22 02:02:53 ispmail-jessie postfix/smtpd[1718]: connect from localhost[::1]
Oct 22 02:02:53 ispmail-jessie postfix/smtpd[1718]: 8C356260F00: client=localhost[::1]
Oct 22 02:02:53 ispmail-jessie postfix/cleanup[1725]: 8C356260F00: message-id=<GTUBE1.1010101@example.net>
Oct 22 02:02:53 ispmail-jessie spamd[1607]: spamd: connection from localhost [::1]:48538 to port 783, fd 6
Oct 22 02:02:53 ispmail-jessie spamd[1607]: spamd: processing message <GTUBE1.1010101@example.net> for john:5000
Oct 22 02:02:53 ispmail-jessie spamd[1607]: spamd: identified spam (1001.5/5.0) for john:5000 in 0.1 seconds, 1128 bytes.
Oct 22 02:02:53 ispmail-jessie spamd[1607]: spamd: result: Y 1001 - ALL_TRUSTED,DATE_IN_PAST_96_XX,GTUBE,NO_DNS_FOR_FROM,T_HEADER_FROM_DIFFERENT_DOMAINS scantime=0.1,size=1128,user=john,uid=5000,required_score=5.0,rhost=localhost,raddr=::1,rport=48538,mid=<GTUBE1.1010101@example.net>,autolearn=no autolearn_force=no
Oct 22 02:02:53 ispmail-jessie postfix/qmgr[1715]: 8C356260F00: from=<root@ispmail-jessie.pmd.local>, size=3394, nrcpt=1 (queue active)
Oct 22 02:02:53 ispmail-jessie postfix/smtpd[1718]: disconnect from localhost[::1]
Oct 22 02:02:53 ispmail-jessie spamd[1606]: prefork: child states: II
Oct 22 02:02:53 ispmail-jessie dovecot: lda(john@example.org): msgid=<GTUBE1.1010101@example.net>: saved mail to INBOX
Oct 22 02:02:53 ispmail-jessie postfix/pipe[1728]: 8C356260F00: to=<john@example.org>, relay=dovecot, delay=0.31, delays=0.15/0.03/0/0.13, dsn=2.0.0, status=sent (delivered via dovecot service)
Oct 22 02:02:53 ispmail-jessie postfix/qmgr[1715]: 8C356260F00: removed

The interesting lines are those printed in bold letters. They come from the spamd. Apparently the email has scored 1001 points which is very much. The limit is 5 so the email is marked spam. If we would take a look at the delivered email saw these lines that have been added by SpamAssassin:

X-Spam-Flag: YES
X-Spam-Status: Yes, score=1001.5 required=5.0 tests=ALL_TRUSTED,
	DATE_IN_PAST_96_XX,GTUBE,NO_DNS_FOR_FROM,T_HEADER_FROM_DIFFERENT_DOMAINS
	autolearn=no autolearn_force=no version=3.4.0
X-Spam-Level: **************************************************
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
	ispmail-jessie.pmd.local

So far the email has only been flagged as spam. But it would still be delivered to John’s inbox. We need to do something about it.

Sending spam to the Junk folder

Fortunately Dovecot offers Sieve filters. John could log into Roundcube and configure a filter for himself that would save any emails to his “Junk” folder if the header line “X-Spam-Flag: YES” was found. This rule would be useful for all your users though so let’s find a general solution.

Dovecot lets us define global filters. Edit the file /etc/dovecot/conf.d/90-sieve.conf. Look for the “sieve_after” lines. They are commented out. So add a new line there:

sieve_after = /etc/dovecot/sieve-after

The “sieve after” filters are executed after the user’s filters. John can define his own filter rules. And after that Dovecot will run any filter rules it finds in files in /etc/dovecot/sieve-after. Create that directory:

mkdir /etc/dovecot/sieve-after

And create a new file /etc/dovecot/sieve-after/spam-to-folder.sieve reading:

require ["fileinto","mailbox"];

if header :contains "X-Spam-Flag" "YES" {
 fileinto :create "INBOX.Junk";
 stop;
}

The “require” lines include functionality to move emails into certain folders (fileinto) and to create folders if they don’t exist yet (mailbox). Then if SpamAssassin marked a header as spam it is moved into the INBOX.Junk folder which just appears as “Junk” to the user underneath their inbox.

Dovecot cannot deal with such human-readable files though. So we need to compile it:

sievec /etc/dovecot/sieve-after/spam-to-folder.sieve

That generated a machine-readable file /etc/dovecot/sieve-after/spam-to-folder.svbin.

Restart Dovecot:

service dovecot restart

And again send a test email to John:

swaks --to john@example.org --server localhost --data /usr/share/doc/spamassassin/examples/sample-spam.txt

Now when you look at John’s emails in Roundcube you will find the spam test mail in his Junk folder:

ispmail-jessie-roundcube-junkfolder

Now all your users will automatically get spam emails moved to their Junk folder. Nice – isn’t it?

94 thoughts on “Filtering out spam with SpamAssassin”

  1. A small concern.
    When testing the Jessie configuration, the movement of spam email to the auto created Junk folder works perfectly within Roundcube, but doesn’t reflect in Thunderbird as far as I can see. I don’t know about Outlook as I don’t use it at all.
    Even creating a Junk folder as a child of the Inbox in Thunderbird, failed to download the test spam email from the server. I guess that’s because an email client will only look at the Inbox.
    So my concern is, if a false positive was sent to the Junk folder in Roundcube, it could be the user using Thunderbird would never know it had arrived.
    Is this the normal behavior you’ve experienced in your testing, or have I got something wrong please? If it is, it may be better to not auto create those folders, so users still get all their email in whatever clients they are using. They will still have headers on the messages attached as a warning.

    1. Christoph Haas

      Can others verify that? I have tested it with Thunderbird on Xubuntu 14.04 and the Junk folder showed up. Especially with Thunderbird I had not expected any problems because it creates a “Junk” folder anyway for its built-in spam detection.

      I have checked though that the user is successfully subscribed to that folder regarding the IMAP protocol. So clients that obey that information should actually work.

      UPDATE: It may be that I accidentally define two Junk folders. One in 10-mail.conf named INBOX.Junk and one in 15-mailboxes called “Junk”. I’m about to verify that. Could someone else try to comment out the “Junk” folder and just use “INBOX.Junk” in the meantime?

      1. Further information.

        It seems in Thunderbird, it works (as your original configuration) provided the account is set to IMAP. The issue I experienced seems to be something to do with using a POP account. Perhaps that throws some light on it?

        1. Christoph Haas

          Ah, that explains it. Yes, POP3 has no notion of folders. I already hesitated to leave POP3 on because I don’t know one person who uses it. Well, now I heard of you – so that makes 1. 🙂 At least I will add a note to this page explaining that caveat.

          1. I like to be unique 😉

            The problem is, I have no way of knowing whether my users (a local Linux Users Group) use IMAP or POP3. I offer both to them so they have a choice. Some are very traditional. Others want all the latest gizmo’s and are developing stuff that’s mind blowing.

            So if I’m understanding your (excellent) work correctly, those that choose to use POP3, could indeed (in the circumstances I outlined) loose email – or more correctly, it would be hidden from them, remaining on the server in the created Junk folder.

            I’ve noticed if I comment out the line that controls the movement of emails to the Junk folder, the two folders are still created in Thunderbird using an IMAP account or indeed Roundcube (as these were crated by Dovecot), but the spam email is delivered to the users inbox with it’s attached headers. So maybe that’s a compromise.

      2. For me Thunderbird automatically subscribed to “Junk” and a “INBOX.Junk” folder was created after I received spam… I left the separator rule untouched earlier – if I understand correctly “/” is my separator then, right?

        I changed the sieve rule to

        fileinto :create “Junk”;

        That works for me.

        1. Christoph Haas

          If you start from scratch without any emails from a previous installation you can choose any seperator. But if you are about to migrate old maildirs then you need to use “.” so that Dovecot finds the emails. Or you would have to manually convert the directories and files of your /var/vmail directory.

        2. This changed sieve rule was correct for me too!
          i Think there is a configuration vault in the config 15-mailboxes.conf of dovecot config if you change it there in “INBOX.Junk” there you have it, if you let it like “Junk” then you will get only that you can manually put a “INBOX.Junk” folder from your thunderbird and you will recive the “hidden” spam, i just testet so you have to know your config of creation of folders in your 15-mailboxes.conf in the “setting up dovecot” section!

          greets

          Thhunder

  2. Hello,

    Thank you for all the great work that you are doing.
    I have one problem thought:

    When sending the test spam email with swaks, sometimes it works but mostly I get the error:

    spamass-milter[1704]: Thrown error: fork error: Cannot allocate memory

    Do you have any idea, what might have gone wrong ?

  3. Hello,

    I have followed the tutorial 2 times now, and I never get spamd part to work.
    When I send to email with swaks all the bolted lines never appear

    Nov 4 11:46:13 server postfix/smtpd[1290]: connect from localhost.localdomain[127.0.0.1]
    Nov 4 11:46:13 server postfix/smtpd[1290]: 6788B20DF2: client=localhost.localdomain[127.0.0.1]
    Nov 4 11:46:13 server postfix/cleanup[1299]: 6788B20DF2: message-id=
    Nov 4 11:46:13 server postfix/qmgr[1217]: 6788B20DF2: from=, size=1049, nrcpt=1 (queue active)
    Nov 4 11:46:13 server postfix/smtpd[1290]: disconnect from localhost.localdomain[127.0.0.1]
    Nov 4 11:46:13 server dovecot: lda(john@example.org): msgid=: saved mail to INBOX
    Nov 4 11:46:13 server postfix/pipe[1302]: 6788B20DF2: to=, relay=dovecot, delay=0.09, delays=0.02/0.01/0/0.06, dsn=2.0.0, status=sent (delivered via dovecot service)
    Nov 4 11:46:13 server postfix/qmgr[1217]: 6788B20DF2: removed

    1. Christoph Haas

      Let’s see. What does “postconf smtpd_milters” tell you? Which processes do you see when you run “pgrep -a spam”? And does “lsof /var/spool/postfix/spamass/spamass.sock” show?

      1. Thanks for the quick reply

        root@server:/etc/dovecot/conf.d# postconf smtpd_milters
        smtpd_milters = unix:/spamass/spamass.sock

        root@server:/etc/dovecot/conf.d# postconf smtpd_milters
        smtpd_milters = unix:/spamass/spamass.sock
        root@server:/etc/dovecot/conf.d# pgrep -a spam
        17578 /usr/sbin/spamd -d –pidfile=/var/run/spamassassin.pid –create-prefs –max-children 5 –helper-home-dir -x -u vmail
        17579 spamd child
        17580 spamd child
        17606 /usr/sbin/spamass-milter -P /var/run/spamass/spamass.pid -f -p /var/spool/postfix/spamass/spamass.sock -u spamass-milter -i 127.0.0.1

        root@server:/etc/dovecot/conf.d# lsof /var/spool/postfix/spamass/spamass.sock
        COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
        spamass-m 17606 spamass-milter 4u unix 0xffff88005f397780 0t0 37077 /var/spool/postfix/spamass/spamass.sock

        1. Christoph Haas

          Seems to be connected to the “localhost” destination. Strangely it works on one of my servers but not the other. In my experience milters are only used when the connection comes from a non-local IP address.

          So please try to send the email to your ethernet address. Run “ip a” to find out the IP address assigned to your eth… network interface. Then run swaks again but instead of “localhost” use that address.

          Please let us know if that does it.

  4. Miguel Lara

    First of all, thank tou for sharing all this, it’s an absolutely great tutorial. Everything’s been working fine for me, except that it looks like spamassassin is no adding the X-Spam-Flags to the header of the message and so, it is not filtering spam to the junk folder. Any clues of how can I enable this tagging?

    Thanks!

    1. Christoph Haas

      Hi Miguel. Thanks for the feedback. Regarding your issue: can you see that the “spamass-milter” process is run in your /var/log/mail.log?

  5. You implement the spam filter with the milter protocol. As I can see in the postfix documentation this is a before-queue filter. As I understand the postfix documentation after-queue filters have a better performance. So I will configure spamassassin with spampd. What do you mean about this approach?

    1. Christoph Haas

      An interesting idea. Where did you find that it increases performance? From my understanding it just shifts the spam analysis from before to after queueing the incoming email.

      I had a request from a reader recently asking if emails with at least a certain spam score could be rejected during the SMTP dialog. I didn’t yet research that but in that case it would require using a before-filter.

      And what do you mean by spampd?

      1. After-queue inspection allows you to use content filters of arbitrary complexity without causing timeouts while receiving mail, and without running out of memory resources under a peak load. Details of this approach are in the FILTER_README document. See http://www.postfix.org/CONTENT_INSPECTION_README.html.

        Spampd is in Debian: SMTP/LMTP-Proxy-Daemon based at SpamAssassin: apt-get install spampd. See http://wiki.apache.org/spamassassin/IntegratePostfixViaSpampd.

        1. Christoph Haas

          I see. Thanks for the explanation. Looking at the documentation it’s what is giving me nightmares. content_filter. Altering the master.cf. And getting several side-effects when using forwards and other filters. I totally agree with you that it’s the better solution regarding performance and blocking incoming emails. But I personally totally dislike their approach that reminds me so badly at the way that AMaViS is used with Postfix. I wonder if there is really no way to use after-queue milters. Why doesn’t Postfix implement that?

          1. Yes, you are right. Editing master.cf is terrible. But I have done it already, so I will try the approach with spampd.
            On the next system I will try your approach with the milter.

    2. Did you actually measure the performance? I am skeptical whether the performance increase is measurable in real life scenarios because throughput depends on so many factors.

  6. Thanks for this excellent tutorial ! All is working properly… except the dovecot sieve plugin : the spams are detected and spamd adds X-Spam-Flag: YES in the header, but the email is not moved into the Junk folder 🙁 Is there a way to activate sieve logs to have more information and verify that the dovecot plugin is really triggered ?

    I don’t know if it’s related to this problem but in the /var/log/mail.err I can see :

    Could not retrieve sendmail macro “i”!. Please add it to confMILTER_MACROS_ENVFROM for better spamassassin results

    1. Christoph Haas

      @Guillaume: Are you sure you ran “postconf milter_connect_macros=”i j {daemon_name} v {if_name} _”” as described on this page?

      Regarding sieve debugging – there used to be a debug log but I can’t find it either. Did you “sievec” the scripts? Are the scripts defined in the Dovecot config? Are the filenames correct?

      1. I finally found what I’ve missed… I had forgotten to configure /etc/dovecot/conf.d/20-lmtp.conf
        Now, of course, it works : spam are moved to Junk automatically.

        But the warning in /var/log/mail.err remains :
        spamass-milter: Could not retrieve sendmail macro “i”!. Please add it to confMILTER_MACROS_ENVFROM for better spamassassin results

  7. Yes I’m sure… here is my tail /etc/postfix/main.cf :

    virtual_transport = lmtp:unix:private/dovecot-lmtp

    smtpd_sasl_type = dovecot
    smtpd_sasl_path = private/auth
    smtpd_sasl_auth_enable = yes
    smtpd_milters = unix:/spamass/spamass.sock

    milter_connect_macros = i j {daemon_name} v {if_name} _

    The script’s folder is defined in the /etc/dovecot/conf.d/90-sieve.conf

    And the script’s name is : /etc/dovecot/sieve-after/spam-to-folder.sieve
    And there is a “compiled version” : /etc/dovecot/sieve-after/spam-to-folder.svbin

    I don’t see where I’m wrong… and I’m searching for hours now 🙁

  8. And what about the warning in mail.err ? Could not retrieve sendmail macro “i”!. Please add it to confMILTER_MACROS_ENVFROM for better spamassassin results ?

    Is it “normal” ? Do you encouter the same message ?

        1. I can confirm that: I have the same error message in mail.err.

          milter_connect_macros is set to “i j {daemon_name} v {if_name} _” as given above.

        1. me too. I have the same settings and the same error. Spam doesn’t get moved to the spam folder 🙁

    1. I have this exact same message. Spam will not move into the junk folder. I’ve triple checked all my settings and just have one question. In the Dovecot setup in my 10-mail.conf file I use the “separator = .” Also I made the additions of “mailbox INBOX.Junk { ” and “mailbox INBOX.Trash {” etc etc in my 15-mailboxes.conf file. However I noticed that there were other listings of “mailbox Junk” and “mailbox Trash” in the file 15-mailboxes.conf and they are not commented out. Could that be the reason that spam wont move into “Junk”?

  9. Has anyone managed to get the clamav-milter to work with Jessie?

    I’ve tried, but so far it’s failed to stop a test virus from the clamav libraries.

    It’s not broken anything, but it’s not stopped anything either.

    I know it’s not part of Christoph’s excellent tutorial, but if you’ve done it, I love to know how you configured it.

  10. If your swaks-command for testing the spamd throws the following error:

    === Trying xxx.xxx.xxx.xxx…
    *** Error connecting to xxx.xxx.xxx.xxx:
    *** IO::Socket::INET6: connect: Verbindungsaufbau abgelehnt

    Check if your external IP-address is present in /etc/postfix/main.cf in the attribute:
    inet_interfaces = 127.0.0.1, xxx.xxx.xxx.xxx
    and the setting
    inet_protocols = ipv4
    is present

    Costs me 1 hour, so I thought I save you the time.

  11. Hi Christoph,

    I love your Guide for setting up a professional mail-server. I used it since 5 years. Very great work.

    But now, I’ve a problem: When i tried to restart spamassassin, I get the error:
    ● spamassassin.service – Perl-based spam filter using text analysis
    Loaded: loaded (/lib/systemd/system/spamassassin.service; enabled)
    Active: failed (Result: exit-code) since So 2015-12-06 11:33:21 CET; 4min 50s ago
    Process: 25630 ExecStart=/usr/sbin/spamd -d –pidfile=/var/run/spamassassin.pid $OPTIONS (code=exited, status=2)
    Main PID: 10565 (code=exited, status=0/SUCCESS)

    Dez 06 11:33:21 mail spamd[25630]: BEGIN not safe after errors–compilation aborted at /usr/share/perl5/Mail/SpamAssassin/Util.pm line 1714.
    Dez 06 11:33:21 mail spamd[25630]: Compilation failed in require at /usr/share/perl5/Mail/SpamAssassin/Conf.pm line 85.
    Dez 06 11:33:21 mail spamd[25630]: BEGIN failed–compilation aborted at /usr/share/perl5/Mail/SpamAssassin/Conf.pm line 85.
    Dez 06 11:33:21 mail spamd[25630]: Compilation failed in require at /usr/share/perl5/Mail/SpamAssassin.pm line 71.
    Dez 06 11:33:21 mail spamd[25630]: BEGIN failed–compilation aborted at /usr/share/perl5/Mail/SpamAssassin.pm line 71.
    Dez 06 11:33:21 mail spamd[25630]: Compilation failed in require at /usr/sbin/spamd line 241.
    Dez 06 11:33:21 mail spamd[25630]: BEGIN failed–compilation aborted at /usr/sbin/spamd line 241.
    Dez 06 11:33:21 mail systemd[1]: spamassassin.service: control process exited, code=exited status=2
    Dez 06 11:33:21 mail systemd[1]: Failed to start Perl-based spam filter using text analysis.
    Dez 06 11:33:21 mail systemd[1]: Unit spamassassin.service entered failed state.

    I am not able to debug a perl script. So i need some ideas.

    THX

    1. Christoph Haas

      Hi Markus. Thanks for the nice words. Regarding your spamd problems… try running “spamd” from the shell as root. Perhaps it tells you wehre the actual problem lies. I suspect a configuration typo somewhere. Likely in your /etc/default/spamassassin file.

  12. IMHO the sieve file should have “imap4flags” in the require set and setflag “Junk”; before the fileinto command. That might just be my preference though.

  13. Jim Leonard

    The configuration in this article seems to prevent the use of user-specific spamassassin rules. On a system with local users, this would normally be handled by reading ~user/.spamassassin/user_prefs but it appears your config prevents this. Is there a way to address this?

    1. Christoph Haas

      @Jim: Just use Sieve filter rules. When you log into Roundcube you can set up filters that do most of which spamassassin does.

      1. Andreas Bogacki

        Your setup seems to be working with a single central spamassassin database. Since one users spam can be another users ham I would like to run spamassassin with user specific databases. Can you please advice how to do that without going back to an amavis setup?

  14. you don’t scan for viruses anymore, but what about filtering well-known bogus files before they entrer in the mail loop? less mail, less pain 🙂

    postconf mime_header_checks = regexp:/etc/postfix/mime_header_checks

    mime_header_checks:
    /name=[^>]*\.(bat|com|exe|dll|vbs)/ REJECT

    1. Keen Mouse

      This gives me an error and I’m too new to this to understand it. Can you point me in the right direction?

      postconf: warning: =: unknown parameter
      postconf: warning: regexp:/etc/postfix/mime_header_checks: unknown parameter
      mime_header_checks = $header_checks

      1. Christoph Haas

        Looks like a “postconf” command went wrong. Check your main.cf for unusual formatting.

  15. Spam detection doesn’t work for me in the test. Strangely the first time it worked, but not for subsequent tests. It works from the outside. But if I use swaks line in the test, the mail will be directly delivered to the inbox without spam checking. No entries in /var/log/mail.log

    I feel like this is the right behavior, since I don’t want outgoing mails to be checked anyways. But I still wanted to make this comment, if anyone is wondering why the test might fail.

    One reason for this could be that I currently use only one domain for the test. Which is also the virtual domain I set up. And the domain of the system itself (rdns advantage) . If I did this with example.org, it would probabely work fine.

  16. I like POP3, it’s faster than IMAP. And for a server with a small hard disk and many users, it’s a good idea.
    It’s work email so they don’t really need to access it from home.

  17. I simply just can not proceed here. See https://gist.github.com/burnersk/3778f85b45b633ce35a7

    There are two issues:

    * “/spamass/spamass.sock” does not exists
    * using existing “/var/spool/postfix/spamass/spamass.sock” causes “postfix/smtpd[]: warning: connect to Milter service unix:/var/spool/postfix/spamass/spamass.sock: No such file or directory”

    1. hello Burnesk,

      I am also having the same issue with socket.
      Did you find a solution to this? If so would you be kind enough to share it.
      Thank you in advance!!

      ~Sarju

  18. Hi Christoph,

    I’m following your well made tutorials since the Etch-version. Thank you for your fine work!

    Do you have an idea how to avoid external forwarding of junk mails?

    Situation: mails with score above 10 are rejected, mails with score between 3.5 and 10 are marked as spam and moved into the Junk-folder. That’s fine and must not change. Some virtual aliases forward messages to external servers. Not only the ham is forwared but also the spam with score >3.5. That’s a problem, as the external servers often reject those mails, which subsequently hang around in my deferred queue…

    Is there any chance to define: if an email is to be forwarded and the mail got a score # drop or reject the message?

    Bye, Dominik

  19. Running ispMail on Raspbian, RPI 1 B. I’m sooo happy. Incredible tutorial!
    Everything is going on except MailAssassin.
    I get on /var/log/mail.log:
    Feb 20 14:47:58 MailServer spamd[1688]: spamd: connection from ::1 [::1]:60049 to port 783, fd 6
    Feb 20 14:47:58 MailServer spamd[1688]: spamd: creating default_prefs: oscar/.spamassassin/user_prefs
    Feb 20 14:47:58 MailServer spamd[1688]: config: cannot create user preferences file oscar/.spamassassin/user_prefs: No such file or directory
    Feb 20 14:47:58 MailServer spamd[1688]: spamd: failed to create readable default_prefs: oscar/.spamassassin/user_prefs
    It seems it’s trying to open folders of a user called “oscar” as it was UNIX user and not a virtual user?

    And 2 or 3 lines later I get:
    Feb 20 14:48:01 MailServer spamd[1688]: plugin: eval failed: bayes: (in learn) locker: safe_lock: cannot create tmp lockfile oscar/.spamassassin/bayes.lock.MailServer.1688 for oscar/.spamassassin/bayes.lock: No such file or directory
    It seems to be the same trouble, right?

    Thank you very much,

  20. I have a trouble more people, as Guillaume and others, are having.
    Spamassassin seems to run, but I get on /var/log/mail.err:
    spamass-milter[461]: Could not retrieve sendmail macro “i”!. Please add it to confMILTER_MACROS_ENVFROM for better spamassassin results

    And yes, I’ve done: postconf milter_connect_macros=”i j {daemon_name} v {if_name} _”
    And checked it’s the last line on /etc/postfix/main.cf

  21. Do forwards set up in the virtual alias table get executed before mail is run through Spamassassin?

    I have a working system running on Jessie – thanks for the great instructions. But I have a few users that have setup their email accounts to forward all mail, all of the time, to Gmail. Obviously some of the email is spam, and because there is a forward, this email is sent to Gmail. But Google correctly identifies the incoming spam as spam and sends a bounce message back to my server saying an unusual amount of spam is originating from my IP address and that the IP has been rate limited.

    I was hoping that Spamassassin on my server would put the spam into the users INBOX.Junk folder via sieve and dovecot. But the instructions in this write-up are for ‘sieve-after’. So I read the docs and tried more or less the same sieve config, but this time creating a ‘sieve-before’ setup. But in testing with fake spam, the email still gets forwarded to Gmail.

    Is there a way to have Spamassassin check for spam, deal with the obvious spam emails, and then check the virtual_alias table for forwards? Would such be better accomplished with a Postfix header check? But then again, which comes first? The header check or the forwarding?

    Thanks, Kevin

  22. The best tutorial as I ever seen… thanks Christoph!!!

    Issue1:
    Apr 13 21:19:24 mx2-ct6 postfix/smtpd[31256]: connect from user-94-254-179-80.play-internet.pl[94.254.179.80]
    Apr 13 21:19:25 mx2-ct6 postfix/smtpd[31256]: warning: connect to Milter service unix:/spamass/spamass.sock: No such file or directory
    Apr 13 21:19:25 mx2-ct6 postfix/smtpd[31256]: NOQUEUE: milter-reject: CONNECT from user-94-254-179-80.play-internet.pl[94.254.179.80]: 451 4.7.1 Service unavailable – try again later; proto=SMTP
    Apr 13 21:19:25 mx2-ct6 postfix/smtpd[31256]: NOQUEUE: milter-reject: EHLO from user-94-254-179-80.play-internet.pl[94.254.179.80]: 451 4.7.1 Service unavailable – try again later; proto=SMTP helo=

    solution:
    change (/etc/postfix/main.cf):
    postconf smtpd_milters=unix:/spamass/spamass.sock
    to:
    postconf smtpd_milters=unix:spamass/spamass.sock

    Issue2:
    Apr 13 21:36:57 mx2-ct6 spamass-milter[31894]: Could not retrieve sendmail macro “i”!. Please add it to confMILTER_MACROS_ENVFROM for better spamassassin results

    solution:
    change (/etc/postfix/main.cf):
    postconf milter_connect_macros=”i j {daemon_name} v {if_name} _”
    to:
    postconf milter_connect_macros= i j {daemon_name} v {if_name} _

    Tested on Debian Jessie (Armbian)

    One more thing… very important when you need have access via TLS on 25 port:

    smtps inet n – n – – smtpd -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes

    Best regards,

  23. Ludovic BIARDEAU

    Hello,
    Thank you for this great tutorial.
    I seem to have the same error: “Could not retrieve sendmail macro “i”!. Please add it to confMILTER_MACROS_ENVFROM for better spamassassin results”.
    The swaks command does not generate junk:
    “spamd: clean message (2.4/5.0) for ludo:5000 in 0.4 seconds, 455 bytes.”
    So the reason why the mail does not go to junk seems to be that the score is under the limit (2.4/5.0 instead of 1001.5/5.0). The size is also different (455 bytes instead of 1128 bytes).
    Any idea about the source of this problem?
    Thank you,
    Best Regards

    1. Ludovic BIARDEAU

      My mistake… I made an error at the file path in the swaks command. The path did not exist, so the path itself was considered as mail content instead of the sample-spam.txt file content.
      This explained the low score…
      According to various forums, it seems that the log ‘Could not retrieve sendmail macro “i”’ can be ignored.

  24. First try
    —-
    swaks –to john@example.org –server localhost –data /usr/share/doc/spamassassin/examples/sample-spam.txt
    —– result
    etlekana@mail:/etc/apache2/sites-available$ swaks –to john@example.org –server localhost –data /usr/share/doc/spamassassin/examples/sample-spam.txt

    === Trying localhost:25…

    === Connected to localhost.

    EHLO mail.debian

    <- 250-mail.debian

    <- 250-PIPELINING

    <- 250-SIZE 10240000

    <- 250-VRFY

    <- 250-ETRN

    <- 250-STARTTLS

    <- 250-ENHANCEDSTATUSCODES

    <- 250-8BITMIME

    MAIL FROM:etlekana@mail.debian

    RCPT TO:john@example.org

    QUIT

    <- 221 2.0.0 Bye

    === Connection closed with remote host.

    etlekana@mail:/etc/apache2/sites-available$

    Second try
    ———–
    swaks –to john@example.org –server 192.168.56.102 –data /usr/share/doc/spamassassin/examples/sample-spam.txt
    ———– result
    etlekana@mail:/etc/apache2/sites-available$ swaks –to john@example.org –server 192.168.56.102 –data /usr/share/doc/spamassassin/examples/sample-spam.txt

    === Trying 192.168.56.102:25…

    === Connected to 192.168.56.102.

    EHLO mail.debian

    <- 250-mail.debian

    <- 250-PIPELINING

    <- 250-SIZE 10240000

    <- 250-VRFY

    <- 250-ETRN

    <- 250-STARTTLS

    <- 250-ENHANCEDSTATUSCODES

    <- 250-8BITMIME

    MAIL FROM:etlekana@mail.debian

    RCPT TO:john@example.org

    QUIT

    <- 221 2.0.0 Bye

    === Connection closed with remote host.

    etlekana@mail:/etc/apache2/sites-available$

    And a print out of my mail log.

    cat /var/log/mail.log

    Jul 26 06:16:20 mail postfix/smtpd[1188]: connect from localhost[::1]

    Jul 26 06:16:20 mail postfix/smtpd[1188]: NOQUEUE: reject: RCPT from localhost[::1]: 554 5.7.1 john@example.org: Recipient address rejected: Access denied; from=etlekana@mail.debian to=john@example.org proto=ESMTP helo=

    Jul 26 06:16:20 mail postfix/smtpd[1188]: disconnect from localhost[::1]

    Jul 26 06:17:35 mail postfix/smtpd[1188]: connect from unknown[192.168.56.102]

    Jul 26 06:17:35 mail postfix/smtpd[1188]: NOQUEUE: reject: RCPT from unknown[192.168.56.102]: 554 5.7.1 john@example.org: Recipient address rejected: Access denied; from=etlekana@mail.debian to=john@example.org proto=ESMTP helo=

    Jul 26 06:17:35 mail postfix/smtpd[1188]: disconnect from unknown[192.168.56.102]

    First test with SWAKS worked, the second failed. Hope any of you guys can see whats wrong.

    Kind Regards Thomas

  25. Tom Hutter

    It’s maybe worth mentioning that spamassassin has set bayes_min_spam_num=200 as default. Which means, that it can take some time before spam mails are recognized. If you want, you can decrease the number in /etc/spamassassin/local.cf.
    Also I recommend not to add “***SPAM***” to the mail subject (which most tutorials suggest), as IMAP mail is immutable. If you get false positives and move them back to INBOX, the ***SPAM*** tag in message stays, which is, well …. wrong.
    As you already filter mail by “X-Spam-Flag” “YES”, there is also no need for this 🙂

    cheers
    Tom

  26. Damian Walker

    Sadly the “Sending spam to the Junk folder” section doesn’t work for me. The message is identified by SpamAssassin and “X-Spam-Flag: YES” is added to the headers. But dovecot still leaves the spam message in my inbox. Could someone point me in the right direction so I can start looking for clues as to why this is?

  27. Davide Marchi

    running swaks I found a problem about “STARTTLS” as reported and none email was found on Junk folder:

    swaks --to john@example.org --server 91.205.175.213 --data /usr/share/doc/spamassassin/examples/sample-spam.txt
    === Trying 91.205.175.213:25...
    === Connected to 91.205.175.213.
    <- 220 server.sio4.org ESMTP Postfix (Debian/GNU) -> EHLO server.sio4.org
    <- 250-server.sio4.org <- 250-PIPELINING <- 250-SIZE 10240000 <- 250-VRFY <- 250-ETRN <- 250-STARTTLS <- 250-ENHANCEDSTATUSCODES <- 250-8BITMIME <- 250 DSN -> MAIL FROM:
    <** 530 5.7.0 Must issue a STARTTLS command first -> QUIT
    <- 221 2.0.0 Bye === Connection closed with remote host.

    Many many thanks!

  28. Just a minor remark: The sentence ” The SpamAssassin milter needs to access the same data as the spamd. So we need to add the debian-spamd group to the spamass-milter group:” is wrong, it is the USER spamass-milter that is added to the GROUP debian-spamd. The command is correct, but this is irritating if one e.g. tries to follow the tutorial inside an ansible script.

  29. Hi,
    successfully migrated my mailserver setup to a new machine. Thank you!
    Small issue left open: Emails are correctly detected and moved to INBOX.junk but do now show up in roundcube nor on other clients (mobile, thunderbird). What do I do? Thanks in advance!

  30. If your postfix in NOT chrooted, than one has to use

    postconf smtpd_milters=unix:spamass/spamass.sock

    instead of

    postconf smtpd_milters=unix:/spamass/spamass.sock

    (omitting first slash).

    Just my few cents to this wonderful tutorial.

  31. I can not find any occurrence of “spamd” in mail.log when receiving an e-mail. how can i debug the milter is working/configured correct?

    a)
    smtpd_milters =
    unix:/spamass/spamass.sock
    inet:127.0.0.1:8891
    milter_connect_macros = i j {daemon_name} v {if_name} _
    milter_default_action = tempfail
    policyd-spf_time_limit = 3600

    b)
    smtpd_milters =
    unix:spamass/spamass.sock
    inet:127.0.0.1:8891
    milter_connect_macros = i j {daemon_name} v {if_name} _
    milter_default_action = tempfail
    policyd-spf_time_limit = 3600

  32. Hello

    First of all thank you for this fantastic guide!

    I followed it on openSUSE Leap 42.2 and for the most part it works.

    What is not working however is to place spam mail into the spam folder (sieve).
    With openSUSE I get a permission error:

    =====================================
    Jan 12 10:07:24 vmi93*** dovecot[3452]: lmtp(8702): Connect from local
    Jan 12 10:07:24 vmi93*** dovecot[3452]: lmtp(ralf64@*****.tk): Error: xKdBHkxHd1j+IQAAAMb7Tw: sieve: file storage: Failed to open sieve sequence: stat(/etc/dovecot/sieve-after) failed: Permission denied (euid=777(vmail) egid=777(vmail) UNIX perms appear ok (ACL/MAC wrong?), dir owned by 0:0 mode=0755)
    Jan 12 10:07:24 vmi93220 dovecot[3452]: lmtp(ralf64@****.tk): xKdBHkxHd1j+IQAAAMb7Tw: sieve: msgid=: stored mail into mailbox ‘INBOX’
    Jan 12 10:07:24 vmi93220 dovecot[3452]: lmtp(8702): Disconnect from local: Successful quit
    ==================================
    So mail is delivered into the Inbox.

    I get the ***SPAM*** header – so it is correctly going through spamassassin.

    My spam-after-sieve file looks like this:

    =============
    require [“fileinto”,”mailbox”];

    if header :contains “X-Spam-Flag” “YES” {
    fileinto :create “INBOX/Junk”;
    stop;
    }
    =============
    I only changed the DOT into a SLASH because I used the SLASH in the mailbox setup

    If I configure a filter in Roundcube, that works fine.
    If I use thunderbird and use the option to handle SPAM flags from Spamassassin and place it into a folder – that works too.

    Does anyone have a idea where I have to look to make this work from the server side?

    Kind regards,
    Ralf

    1. I found the problem myself:

      It is a issue with AppArmor (SELinux).
      I have to disable this or create a custom rule

      Kind regards,
      Ralf

  33. Everything in this guide is working great, But I’m wondering if i can set a filter to just delete anything with a zip or exe file attached. Would this work? If not, can anyone educate me or point me toward where i can read about sieve filters to figure this out.

    require [“fileinto”,”mailbox”];

    if attachment :contains “.zip” “.exe” {
    fileinto :create “INBOX.Trash”;
    stop;
    }

  34. Regards Max Voß’s reply of 2015-11-28 https://workaround.org/ispmail/jessie/spamassassin/#comment-6470, thanks Max. I had exactly the same issue. After searching for “inet_interfaces” host:workaround.org/ispmail/jessie, I believe postconf inet_interfaces=all is missing from this great procedure. It could be inserted on https://workaround.org/ispmail/jessie/relaying-smtp-authentication in the section “The submission port” (although it is about interface rather than port).

  35. Hi, as the others everything is good but… spamass-milter.service cant start.
    I know it my fault as this is my first real linux project, but i cant find where.. this is what i get

    root@MAIL:/var/spool/postfix/spamass# journalctl -xn
    — Logs begin at Sun 2017-04-16 02:38:54 AEST, end at Sun 2017-04-16 03:36:47 AEST. —
    Apr 16 03:34:20 MAIL dovecot[996]: imap(test@elvardin.com.au): Disconnected: Logged out in
    Apr 16 03:35:20 MAIL dovecot[996]: imap-login: Login: user=, method=
    Apr 16 03:35:20 MAIL dovecot[996]: imap(test@elvardin.com.au): Disconnected: Logged out in
    Apr 16 03:36:20 MAIL dovecot[996]: imap-login: Login: user=, method=
    Apr 16 03:36:20 MAIL dovecot[996]: imap(test@elvardin.com.au): Disconnected: Logged out in
    Apr 16 03:36:47 MAIL systemd[1]: Starting LSB: milter for spamassassin…
    — Subject: Unit spamass-milter.service has begun with start-up
    — Defined-By: systemd
    — Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel

    — Unit spamass-milter.service has begun starting up.
    Apr 16 03:36:47 MAIL spamass-milter[3446]: Starting Sendmail milter plugin for SpamAssassi
    Apr 16 03:36:47 MAIL systemd[1]: spamass-milter.service: control process exited, code=exit
    Apr 16 03:36:47 MAIL systemd[1]: Failed to start LSB: milter for spamassassin.
    — Subject: Unit spamass-milter.service has failed
    — Defined-By: systemd
    — Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel

    — Unit spamass-milter.service has failed.

    — The result is failed.
    Apr 16 03:36:47 MAIL systemd[1]: Unit spamass-milter.service entered failed state.

    where do i go now..

  36. Md. Touhiduzzaman

    Hello Sir,
    I have using amavis as it was from last tutorial. But in the latest, you said to use spamassassin.
    What about my system? If I configure spamassassin, how will act amavis? Do I need to stop amavis then configure or both can run beside?
    Sorry if the answers have already given, I dont find any answer here.

    Waiting for your quick advice as my users are getting too much spam mails from last few weeks.

  37. The guide instructs us to use swaks with –server localhost after you do sievec, this is wrong and will result in the email bypassing the filter. For the benefit of other readers you must change ‘localhost’ to your external ip, as in the previous steps.

  38. I noticed that spamassasin is also checking outgoing mail for spam. Has anybody else seen something like this:

    May 31 13:48:17 mail spamd[1123]: spamd: connection from localhost [::1]:52888 to port 783, fd 6
    May 31 13:48:17 mail spamd[1123]: spamd: processing message for externer.empfaenger:5000
    May 31 13:48:18 mail spamd[1123]: spamd: clean message (-1.0/5.0) for externer.empfaenger:5000 in 0.4 seconds, 5105 bytes.
    May 31 13:48:18 mail spamd[1123]: spamd: result: . 0 – ALL_TRUSTED,HTML_MESSAGE scantime=0.4,size=5105,user=externer.empfaenger,uid=5000,required_score=5.0,rhost=localhost,raddr=::1,rport=52888,mid=,autolearn=ham autolearn_force=no
    May 31 13:48:18 mail opendkim[715]: BC81C9FAEF: DKIM-Signature field added (s=mail, d=meine.domain)
    May 31 13:48:18 mail spamd[635]: prefork: child states: II
    May 31 13:48:18 mail postfix/qmgr[19376]: BC81C9FAEF: from=, size=5024, nrcpt=1 (queue active)
    May 31 13:48:18 mail postfix/smtp[27798]: connect to smtpin.rzone.de[2a01:238:20a:202:50f0::1097]:25: Network is unreachable
    May 31 13:48:18 mail postfix/smtp[27798]: BC81C9FAEF: to=, relay=smtpin.rzone.de[81.169.145.97]:25, delay=1.1, delays=0.62/0.02/0.27/0.2, dsn=2.1.5, status=sent (250 2.1.5 OK mail delivered with id E04b4bt4VBmIjJ0)

    Any idea how to disable this?

  39. Hi Christoph!

    Great Tutorial. Just got one problem: with this setup, my outgoing eMails sent through the submission port by authenticated users are frequently flagged as spam by my local spamassassin, because they originate from a dynamic IP address that happens to be on some blacklist.

    Is there a way to configure postfix/spamassassin to only pass mails through spamassassin that came in through port 25 and leave mails that came through the submission port alone, without breaking other parts of the system? Thanks!

  40. The tutorial is great, but is missing configuration of Razor and Pyzor with SpamAssassin. Any chance you can add that? 🙂

    1. Christoph Haas

      Thanks for the suggestion. I am pretty sure it’s enabled by default. Please check your /etc/spamassassin/v310.pre. There should be a line like:

      loadplugin Mail::SpamAssassin::Plugin::Razor2

      1. The problem is that you have to manually install Pyzor and Razor (the binaries, that is, otherwise the plugins have no effect). Then you have to register Razor and create an identity file. With Pyzor, at least under Jessie and earlier, you have to run pyzor discover to fetch a list of servers. This seems to be obsolete with newer versions. All this has to happen with the correct user and group and you have to configure correct home dirs for both so that they can run correctly when triggered by SA.

  41. Philip Levine

    this is more code than I can understand. My experience is that I need to set a filter up in SA to send spam to my Thunderbird Junk folder. For some reason before the weekend the spam was just going in there but after the weekend the spam would stay in my inbox. It might have something to do with my using my laptop away from home. But with an IMAP account I don’t know why that would have made a difference.

  42. Keen Mouse

    Does this configuration allow for training SpamAssassin on false-positives and false-negatives? If so, how does that work? How would I go about configuring training on messages that are moved in or out of the Junk folder via IMAP?

  43. Hi,
    I’m also looking on how to train my bayesian. I don’t have it yet but I feel I’m quite close, I have it setup an hourly taks in cron:
    root sa-learn –no-sync –spam /var/vmail/myDomain/myUser/Maildir/.Spam/cur/ -C /var/vmail/.spamassassin/ -p /var/vmail/.spamassassin/ > /dev/null
    (and a second for ham mails)
    I think that the bayesian DB increases, but not for the correct user… Should I use the -u param? But with what name? vmail? My user? My user@myDomain?

    Again, I think I’m close enough, but not yet there 🙁

    Benjamin

    1. Christoph Haas

      I don’t have a ready solution for you. At some point I have just given up with AMaViS or SpamAssassin with per-user spam learning. But I have some good news nonetheless. I intend to have the new Debian Stretch tutorial ready by the end of October. And it will use a more capable spam handler that makes it relatively easy to handle per-user bayes databases. At the same time it’s easier to set up. 🙂

      1. Christoph,
        thanks for that quick answer (and the rest of your work for sure!)
        I’m really looking forward to your solution (SQL bayesian?), and I’ll keep on investigating on my cron, just for fun. I’ll come back to you if I get it to work before you 🙂
        (I have a catchall email, so I can easily get my hundreds of daily trainings spam)
        Benjamin

  44. Related to spamassassin setup within Ubuntu 14.04 I have find the following link relevant: https://askubuntu.com/questions/461684/i-cant-start-spamassassin-service. specifically there is a slight change again Christoph has taught us:

    I had the same problem. The answers here did not help me at all. I found that the problem went away, without disabling IPv6, by editing /etc/default/spamassassin and adding a user for spamd, as described here. The essential steps described in that page are:

    1) sudo apt-get install spamassassin spamc

    2) sudo adduser spamd –disabled-login

    3) Edit /etc/default/spamassassin to include the following:

    ENABLED=1
    SPAMD_HOME=”/home/spamd/”
    OPTIONS=”–create-prefs –max-children 5 –username spamd –helper-home-dir ${SPAMD_HOME} -s ${SPAMD_HOME}spamd.log”
    PIDFILE=”${SPAMD_HOME}spamd.pid”
    CRON=1

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to Top