{"id":569,"date":"2026-07-31T20:10:10","date_gmt":"2026-07-31T19:10:10","guid":{"rendered":"https:\/\/blog.inplico.uk\/?p=569"},"modified":"2026-07-31T20:18:06","modified_gmt":"2026-07-31T19:18:06","slug":"rspamd","status":"publish","type":"post","link":"https:\/\/blog.inplico.uk\/?p=569","title":{"rendered":"Rspamd"},"content":{"rendered":"<br \/>\n<h1>1. Rspamd<\/h1>\n<div class=\"important-box\">\n            <span class=\"important-icon\">\u2605<\/span><\/p>\n<div>\n                <strong>IMPORTANT:<\/strong><br \/>\n                This is not written by AI. When we were testing this we used AI to try and configure it and it got it badly wrong. We have noted this to be a trend and are encountering more and more AI documentation that is just pure nonsense. We are<br \/>\n                now marking <strong>ALL<\/strong> our hand written documentation as not AI generated. This does not mean that it is guarantee to work as that is dependent on the version and your base configuration, it is simply an informative<br \/>\n                statement and like much of the hand crafted documentation on the internet, we can only guarantee that it works on our own equipment.\n            <\/div>\n<\/p><\/div>\n<p>\n            We are using Rspamd to replace spamassassin as it is written in C and easier to configure.\u00a0 These are the steps required to get it working.\n        <\/p>\n<div class=\"warning-box\">\n            <span class=\"warning-icon\">&#9888;<\/span><\/p>\n<div>\n                <strong>WARNING:<\/strong><br \/>\n                This documentation assumes that you have an operational email server.\n            <\/div>\n<\/p><\/div>\n<h2>1.2 Installation<\/h2>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code># apt-get install rspamd redis-server\r\n<\/code><\/pre>\n<\/p><\/div>\n<\/p><\/div>\n<h2>1.3 Configure<\/h2>\n<h3 id=\"configure-redis-server\">1.3.1 Configure redis-server<\/h3>\n<p>        <P>The conriguration file for redis server is <code>\/etc\/redis\/redis.conf<\/code> and is well documented however there are a couple of parameters you may need to change in order to get it working.<\/P><\/p>\n<p>The first one is <code>bind<\/code> which we configured on the internal interface in order to get it to run.<\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code>bind 192.168.0.254 #or whatever your local interface is<\/code><\/pre>\n<\/p><\/div>\n<\/p><\/div>\n<div class=\"note-box\">\n            <span class=\"note-icon\">\u2139<\/span><\/p>\n<div>\n                <strong>NOTE:<\/strong><br \/>\n                Most doucmentation implies that you should configure this to 127.0.0.1 however we could never get it to start and so we explicitly ran it on the internal interface.\n            <\/div>\n<\/p><\/div>\n<p>\n            Other than that we just turned protected mode off (this should not be a problem as neitehr redis nor its ports are open to the internet).\n        <\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code>protected-mode no<\/code><\/pre>\n<\/p><\/div>\n<\/p><\/div>\n<p>\n            That should be all there is to redis other than to enable and start the service.<\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code>systemctl enable redis-server\r\nsystemctl start redis-server<\/code><\/pre>\n<\/p><\/div>\n<\/p><\/div>\n<div class=\"note-box\">\n            <span class=\"note-icon\">\u2139<\/span><\/p>\n<div>\n                <strong>IMPORTANT:<\/strong><br \/>\n                If you run into issues then redis server has its own logging. The log is located at \/var\/log\/redis\/redis-server.log\n            <\/div>\n<\/p><\/div>\n<h3>1.3.2 Configure rspamd<\/h3>\n<p>rspamd itself has a handful of configuration files that it needs in order to operate correctly<\/p>\n<div class=\"important-box\">\n            <span class=\"important-icon\">\u2605<\/span><\/p>\n<div>\n                <strong>IMPORTANT:<\/strong><br \/>\n                All rspamd configuration files must be saved in <b>\/etc\/rspamd\/local.d\/<\/b> You should not edit existing rspamd configuration files in other locations.\n            <\/div>\n<\/p><\/div>\n<h4>1.3.2.1 redis.conf<\/h4>\n<p><code>\/etc\/rspamd\/local.d\/redis.conf<\/code> (not to be confused with the redis.conf file mentioned in <a href=#configure-redis-server>1.3.1 Configure redis-server<\/a>) is where we tell <code>rspamd<\/code> how to talk to<br \/>\n            <code>redis-server<\/code> and is a simple one liner referencing the ip and port declared in the <code>\/etc\/rspamd\/local.d\/redis.conf<\/code> file.\n        <\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code>servers = \"192.168.0.254:6379\"; #or whatever your server ip is\r\n<\/code><\/pre>\n<\/p><\/div>\n<\/p><\/div>\n<h4>1.3.2.2 actions.conf<\/h4>\n<p>A very basic actions configuration (taken from the rspamd documentation) is<\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code># Basic action thresholds\r\nreject = 15;        # Reject obvious spam\r\nadd_header = 6;     # Add spam headers\r\ngreylist = 4;       # Temporary delay suspicious mail\r\n<\/code><\/pre>\n<\/p><\/div>\n<\/p><\/div>\n<h4>1.3.2.3 worker-controller.inc<\/h4>\n<p>This file configures the web interface that gives you all of the statistics etc.<\/p>\n<p>Before you set it up you need to create a hashed password using the <code>rspamadm<\/code> utility<\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code>rspamadm pw<\/code><\/pre>\n<\/p><\/div>\n<\/p><\/div>\n<p>And follow the instructions to generate your password.<\/p>\n<p>Copy the long string generated as you will need this for the next steps.<\/p>\n<p>Now create a file called <b>worker-controller.inc<\/b> and add the following<\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code>password = \"your-long-password-string-saved-from-the-previous-step\";\r\n# Listen on the server's LAN IP\r\nbind_socket = \"192.168.0.254:11334\" #replace with your own local ip\r\n\r\n# Explicitly restrict web UI access to your desktop IP only\r\nsecure_ip = \"162.168.0.2\" #replace with the explicit ip of your desktop client\r\nallow_local = false\r\n<\/code><\/pre>\n<\/p><\/div>\n<\/p><\/div>\n<p>\n            In this file we tell rspamd that we are only allowing a single ip on our lan to access the interface\n        <\/p>\n<h4>1.3.2.4 milter_headers.conf<\/h4>\n<p>\n            Unlike spamassassin, rspamd does not attach the spam status headers by default unless it finds something that it considers to be spam however we prefer to have them in all instances as for a tiny bit of overhead it vastly simplifies<br \/>\n            debugging. In order to do this you need to create a <b>milter_headers.conf<\/b> file and add the following\n        <\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code># Define which standard header routines to run\r\nuse = [\"x-spamd-result\", \"x-spam-status\", \"x-spam-level\"];\r\n\r\n# Force headers to be added to clean\/ham messages, not just spam\r\nalways_add = true;\r\n\r\n# Optional: Also add them for local or authenticated senders if desired\r\nskip_local = false;\r\nskip_authenticated = false;\r\n<\/code><\/pre>\n<\/p><\/div>\n<\/p><\/div>\n<h4>1.3.2.5 worker-proxy.inc<\/h4>\n<p>\n            The final configuration file enables the milter for intergration with Postfix and simply contains the following\n        <\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code>milter = yes;\r\ntimeout = 120s;\r\nupstream \"local\" {\r\n  default = yes;\r\n  self_scan = yes;  # Scan messages directly\r\n}\r\n<\/code><\/pre>\n<\/p><\/div>\n<\/p><\/div>\n<h4>1.3.2.6 Final Steps<\/h4>\n<p>\nAll that remains now is to enable and start the rspamd daemon\n<\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code>systemctl enable rspamd\r\nsystemctl start rspamd<\/code><\/pre>\n<\/p><\/div>\n<\/div>\n<div class=\"note-box\">\n    <span class=\"note-icon\">\u2139<\/span><\/p>\n<div>\n        <strong>Note:<\/strong><br \/>\n        If you encouter issues rspamd also has its own log, located at <b>\/var\/log\/rspamd\/rspamd.log<\/b>\n    <\/div>\n<\/div>\n<p>\nYou should now be able to connect to your interface on the client that you set in your <b>worker-controller.inc<\/b> configuration file by navigating to\n<\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code>http:\/\/192.168.0.254:11334\/ #replace with your own ip<\/code><\/pre>\n<\/p><\/div>\n<\/div>\n<p>in a browser<\/p>\n<div class=\"warning-box\">\n    <span class=\"warning-icon\">&#9888;<\/span><\/p>\n<div>\n        <strong>WARNING:<\/strong><br \/>\n        The connection is not secure as it uses basic http.  Use it with caution or secure it behind a reverse proxy.  This is just for initial configuration and testing.\n    <\/div>\n<\/div>\n<h3>1.3.3 Configure Postfix<\/h3>\n<p>\nAll that is left to do is hook it into postfix.  If you have a previous spamassassin configuration then it will probably look like\n<\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code>smtpd_milters = unix:spamass\/spamass.sock inet:localhost:8891\r\n<\/code><\/pre>\n<\/p><\/div>\n<\/div>\n<p>\nTo switctch to rspamd simply remove <b>unix:spamass\/spamass.sock<\/b> and replace it with\n<\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code>inet:162.168.1.254:11332 #change to your server's local ip<\/code><\/pre>\n<\/p><\/div>\n<\/div>\n<div class=\"important-box\">\n    <span class=\"important-icon\">\u2605<\/span><\/p>\n<div>\n        <strong>IMPORTANT:<\/strong><br \/>\n        Make sure you only remove references to spamassassin, you may likely have a reference to open DKIM on the same line like the example above.\n    <\/div>\n<\/div>\n<p>Our configuration was<\/p>\n<div class=\"code-container\">\n<div class=\"code-container-sub\">\n<pre><code>smtpd_milters = inet:172.17.1.22:11332, inet:localhost:8891\r\nnon_smtpd_milters = inet:172.17.1.22:11332, inet:localhost:8891\r\nmilter_default_action = accept\r\nmilter_protocol = 6\r\n<\/code><\/pre>\n<\/p><\/div>\n<\/div>\n<p>And that should be it; restart postfix and test everything by looking in the headers and checking the logs<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. Rspamd \u2605 IMPORTANT: This is not written by AI. When we were testing this we used AI to try and configure it and it got it badly wrong. We have noted this to be a trend and are encountering more and more AI documentation that is just pure nonsense. We are now marking ALL [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-569","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\/569","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=569"}],"version-history":[{"count":1,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts\/569\/revisions"}],"predecessor-version":[{"id":577,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts\/569\/revisions\/577"}],"wp:attachment":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=569"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=569"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=569"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}