{"id":141,"date":"2019-06-02T23:02:00","date_gmt":"2019-06-02T22:02:00","guid":{"rendered":"https:\/\/blog.inplico.uk\/?p=141"},"modified":"2022-11-02T12:33:30","modified_gmt":"2022-11-02T12:33:30","slug":"spamassassin","status":"publish","type":"post","link":"https:\/\/blog.inplico.uk\/?p=141","title":{"rendered":"Spamassassin"},"content":{"rendered":"<p><strong>Installation<\/strong><\/p>\n<p>First thing first:<strong> DON&#8217;T EVEN THINK ABOUT DOING THIS UNTIL YOU HAVE AN OPERATIONAL MAIL SERVER RUNNING DOVECOT, POSTFIX AND POSTFIXADMIN! You need to get it working on it&#8217;s own; If it has gone tits up already this won&#8217;t fix it.<\/strong><\/p>\n<p>Did I mention not to do this until you had a working server?\u00a0 Okay then, install spam assassin in the usual way:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">apt-get install spamassassin spamass-milter swaks<\/pre>\n<p>In most of this guide we edit the files manually, but here we can use postconf to add a couple of lines to the postfix configuration file <strong>cf<\/strong>. From the command line type<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">postconf smtpd_milters=unix:\/spamass\/spamass.sock \r\npostconf milter_connect_macros=\"i j {daemon_name} v {if_name} _\"<\/pre>\n<p>If you wish to do this manually, all that postconf does in this instance is append the 2 lines to the end of \/etc\/postfix\/main.cf to enable spamassassin.<\/p>\n<p>Next edit the <strong>\/etc\/default\/spamassassin<\/strong> file and set:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">OPTIONS=\"--create-prefs --max-children 5 --helper-home-dir -x -u mailer\" CRON=1<\/pre>\n<p>Be sure to make sure the \/home\/mailer directory exists, if not then create it and set the permissions correctly<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">mkdir \/home\/mailer\r\nchown -R mailer:mailer \/home\/mailer<\/pre>\n<p>The additional OPTIONS <em>\u201c-x -u mailer\u201d<\/em> tell SpamAssassin to look for its Bayes database in the home directory of the \u201cmailer\u201d user. To be exact it will be put into \/var\/mailer\/.spamassassin. The Bayes database records words (aka \u201ctokens\u201d) from all seen emails and computes\u00a0conditional probabilities that determine the likelihood that an email is spam.<\/p>\n<p>CRON=1 enables the daily cron job in \/etc\/cron.daily\/spamassassin that downloads a new set of spam detection rules every night.<\/p>\n<p>To make the spamd process get started automatically run:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">systemctl enable spamassassin<\/pre>\n<p>&nbsp;<\/p>\n<p>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 debian-spamd group to the spamass-milter group:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">adduser spamass-milter debian-spamd<\/pre>\n<p>Restart SpamAssassin:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">service spamassassin restart #service spamass-milter restart<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Testing spam detection<\/strong><\/p>\n<p>From the command line run<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">swaks --to user@fqdn.suffix --server xxx.xxx.xxx.xxx --data \/usr\/share\/doc\/spamassassin\/examples\/sample-spam.txt<\/pre>\n<p>You will need to set user@fqdn.suffix to a mailbox on the server and set <strong>&#8211;server<\/strong> to the ip address of your server<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Sending spam to the junk folder<\/strong><\/p>\n<p>Fortunately Dovecot offers Sieve filters. John could log into Roundcube and configure a filter for himself that would save any emails to his \u201cJunk\u201d folder if the header line \u201cX-Spam-Flag: YES\u201d was found. This rule would be useful for all your users though so let\u2019s find a general solution.<\/p>\n<p>Dovecot lets us define global filters. Edit the file <strong>\/etc\/dovecot\/conf.d\/90-sieve.conf<\/strong>. Look for the \u201csieve_after\u201d lines. They are commented out. So add a new line there:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">sieve_after = \/etc\/dovecot\/sieve-after<\/pre>\n<p>The \u201csieve after\u201d filters are executed after the user\u2019s 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:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">mkdir\u00a0\/etc\/dovecot\/sieve-after<\/pre>\n<p>And\u00a0create a new file \/etc\/dovecot\/sieve-after\/spam-to-folder.sieve reading:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">require [\"fileinto\",\"mailbox\"]; \r\nif header :contains \"X-Spam-Flag\" \"YES\" { \r\n    fileinto :create \"Junk\"; \r\n    stop; \r\n}<\/pre>\n<p>The \u201crequire\u201d lines include functionality to move emails into certain folders (fileinto) and to create folders if they don\u2019t exist yet (mailbox). Then if SpamAssassin marked a header as spam it is moved into the Junk folder which just appears as \u201cJunk\u201d to the user.<\/p>\n<p>Dovecot cannot deal with such human-readable files though. So we need to compile it:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">sievec \/etc\/dovecot\/sieve-after\/spam-to-folder.sieve<\/pre>\n<p>That generated a machine-readable file\u00a0\/etc\/dovecot\/sieve-after\/spam-to-folder.svbin. Restart Dovecot:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">service dovecot restart<\/pre>\n<p>And again send a test junk email using swaks. If all is well, the junk email will automatically have been put into Junk<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">swaks --to user@fqdn.suffix --server xxx.xxx.xxx.xxx --data \/usr\/share\/doc\/spamassassin\/examples\/sample-spam.txt<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Training spam assassin<\/strong><\/p>\n<p>First you need to get a load of junk that it has made its way into your inbox and mark it as junk and move it to your junk folder if this has not been done automatically.<\/p>\n<p>Once you have a good enough sample, from the command line on the server run<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">sa-learn --spam --dir \/mailstore\/fqdn.suffix\/user\/.Junk\/* -D<\/pre>\n<p>To update spam assassin simply run <strong>sa-update<\/strong> from the command line (although this should not be necessary as it runs as a cron job as long as you have set <strong>CRON=1<\/strong> in the spamassassin configuration file as described above.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Troubleshooting<\/strong><\/p>\n<p>Postfix is supposed to run chrooted, but I had an issue when setting up spamassassin where it could not find the socket using the chrooted path \/spamass\/spamass.sock.\u00a0 If this happens try and edit \/etc\/postfix\/main.cf and find the line<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">smtpd_milters=unix:\/spamass\/spamass.sock<\/pre>\n<p>And replace it with:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">smtpd_milters=unix:\/var\/spool\/postfix\/spamass\/spamass.sock<\/pre>\n<p>Hopefully if you restart postfix this will solve all your problems and realign your chakra.\u00a0 If not; you&#8217;re on your own!<\/p>\n<p><strong>UPDATE:<\/strong>\u00a0 A further restart and now it is using the chrooted path correctly so not sure what happened; left this note in just in case it happens again.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Installation First thing first: DON&#8217;T EVEN THINK ABOUT DOING THIS UNTIL YOU HAVE AN OPERATIONAL MAIL SERVER RUNNING DOVECOT, POSTFIX AND POSTFIXADMIN! You need to get it working on it&#8217;s own; If it has gone tits up already this won&#8217;t fix it. Did I mention not to do this until you had a working server?\u00a0 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-141","post","type-post","status-publish","format-standard","hentry","category-debian-server"],"_links":{"self":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts\/141","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=141"}],"version-history":[{"count":6,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts\/141\/revisions"}],"predecessor-version":[{"id":371,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts\/141\/revisions\/371"}],"wp:attachment":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=141"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=141"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=141"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}