rspamd errors maps.rspamd.com

Ubuntu 24.04 | Mailcow 2025-10 | Rspamd 3.13.2

In my mailcow logs I stumbled upon a lot of errors on downloading maps files from maps.rspamd.com, most of the time like:

map; http_map_error: error reading https://maps.rspamd.com/freemail/free.txt.zst(157.180.118.77:443): connection with http server terminated incorrectly: ssl connect error: syscall fail: Connection refused

or

map; http_map_error: error reading https://maps.rspamd.com/rspamd/surbl-whitelist.inc.zst(157.180.118.77:443): connection with http server terminated incorrectly: ssl connect error: syscall fail: Connection refused

or

map; http_map_finish: cannot load map https://maps.rspamd.com/rspamd/dkim_whitelist.inc.zst from maps.rspamd.com: HTTP error 404

Of course I checked connection, dns and firewall. No issues there:

root@mc:/# wget https://maps.rspamd.com/freemail/free.txt.zst

--2025-10-17 09:47:23--  https://maps.rspamd.com/freemail/free.txt.zst
Resolving maps.rspamd.com (maps.rspamd.com)... 157.180.118.77
Connecting to maps.rspamd.com (maps.rspamd.com)|157.180.118.77|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 17010 (17K) [application/octet-stream]
Saving to: ‘free.txt.zst’

free.txt.zst                                      100%[=============================================================================================================>]  16.61K  --.-KB/s    in 0.002s  

2025-10-17 09:47:23 (8.99 MB/s) - ‘free.txt.zst’ saved [17010/17010]

And to be 100% sure, I did the same from within the rspamd docker container:

root@mc:/# docker exec -it mailcowdockerized-rspamd-mailcow-1 bash
root@rspamd:/# wget https://maps.rspamd.com/freemail/free.txt.zst

--2025-10-17 09:50:06--  https://maps.rspamd.com/freemail/free.txt.zst
Resolving maps.rspamd.com (maps.rspamd.com)... 157.180.118.77
Connecting to maps.rspamd.com (maps.rspamd.com)|157.180.118.77|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 17010 (17K) [application/octet-stream]
Saving to: 'free.txt.zst'

free.txt.zst                                      100%[=============================================================================================================>]  16.61K  --.-KB/s    in 0.001s  

2025-10-17 09:50:06 (12.9 MB/s) - 'free.txt.zst' saved [17010/17010]

While the errors do not have anything to do with my network connection, I suppose they are caused by some kind of rate limiting on the server's side at rspamd.com. I'm still not 100% sure - and I've seen some guys suggesting OpenSSL compliancy but couldn't solve the issue with the adjustments described.

So my strategy is to setup a mirror server that downloads the maps files and to let mailcow/rspamd get the files from there.

Please have a look at private mirror server for clamav. I'm going to use the same server for rspamd.

1- install a webserver

Same as described. Let's assume the url of the mirror server is https://mirror.mydomain.net and the document root of the web server is /opt/www/spamd

2- create script

We create a script on the mirror server:

cd /opt
vi rspamd-maps.sh

// paste this (press i, cmd-v, Esc, :x)

!/bin/sh
wget -O /opt/www/rspamd/rspamd/redirectors.inc.zst 'https://maps.rspamd.com/rspamd/redirectors.inc.zst'
wget -O /opt/www/rspamd/freemail/disposable.txt.zst 'https://maps.rspamd.com/freemail/disposable.txt.zst'
wget -O /opt/www/rspamd/rspamd/spf_dkim_whitelist.inc.zst 'https://maps.rspamd.com/rspamd/spf_dkim_whitelist.inc.zst'
wget -O /opt/www/rspamd/rspamd/dmarc_whitelist_new.inc.zst 'https://maps.rspamd.com/rspamd/dmarc_whitelist_new.inc.zst'
wget -O /opt/www/rspamd/rspamd/phishing_whitelist.inc.zst 'https://maps.rspamd.com/rspamd/phishing_whitelist.inc.zst'
wget -O /opt/www/rspamd/rspamd/surbl-whitelist.inc.zst 'https://maps.rspamd.com/rspamd/surbl-whitelist.inc.zst'
wget -O /opt/www/rspamd/rspamd/disabled_rbls.inc.zst 'https://maps.rspamd.com/rspamd/disabled_rbls.inc.zst'
wget -O /opt/www/rspamd/rspamd/mid.inc.zst 'https://maps.rspamd.com/rspamd/mid.inc.zst'
wget -O /opt/www/rspamd/rspamd/mime_types.inc.zst 'https://maps.rspamd.com/rspamd/mime_types.inc.zst'
wget -O /opt/www/rspamd/freemail/free.txt.zst 'https://maps.rspamd.com/freemail/free.txt.zst'

3- make the script executable and test

cd /opt
chmod u+x rspamd-maps.sh
./rdpamd-maps.sh

If it went well the rspamd files have been downloaded to the webserver root directory, like this:

root@mirror:/opt/www/rspamd# ls -lR

.:
total 8
drwxr-xr-x 2 root root 4096 Oct 15 19:49 freemail
drwxr-xr-x 2 root root 4096 Oct 15 22:36 rspamd

./freemail:
total 28
-rw-r--r-- 1 root root  6360 Jul 14  2018 disposable.txt.zst
-rw-r--r-- 1 root root 17010 Jul 14  2018 free.txt.zst

./rspamd:
total 52
-rw-r--r-- 1 root root   64 Feb 27  2025 disabled_rbls.inc.zst
-rw-r--r-- 1 root root 4199 Sep 29  2018 dmarc_whitelist_new.inc.zst
-rw-r--r-- 1 root root  541 Jul 14  2018 mid.inc.zst
-rw-r--r-- 1 root root 9621 Jul 14  2018 mime_types.inc.zst
-rw-r--r-- 1 root root  136 Feb 25  2021 phishing_whitelist.inc.zst
-rw-r--r-- 1 root root 5215 Jul 14  2018 redirectors.inc.zst
-rw-r--r-- 1 root root 1227 Jul 14  2018 spf_dkim_whitelist.inc.zst
-rw-r--r-- 1 root root 4161 Jul 14  2018 surbl-whitelist.inc.zst

4- create a cron job

Now, it's time to set a cron job in order the let the machine download updates automatically.

crontab -e

// add this line (in vi: press i cmd-v Esc :x):

0 */11 * * * /bin/sh -c "/opt/rspamd-maps.sh >> /var/log/rspamd.log 2>&1"

This job is executed every 11 hours. I like prime numbers.

5- create rspamd config files

I use rspamd as part of mailcow where rspamd is running under docker. So I go from there.

Unfortunately there is no global setting for the hostname maps.rspamd.com. I found 7 config files with references to it. In order to override the default settings we are going to create new config files. Let's put them in a new dir /rspamd-conf. This is on my docker host of mailcow-rspamd:

cd /rspamd-conf
ls -l
-rw-r--r-- 1 root root   69 Oct 16 21:48 known_senders.conf
-rw-r--r-- 1 root root  235 Oct 16 21:48 mid.conf
-rw-r--r-- 1 root root  232 Oct 16 21:48 mime_types.conf
-rw-r--r-- 1 root root 7885 Oct 16 21:48 multimap.conf
-rw-r--r-- 1 root root  527 Oct 16 21:48 phishing.conf
-rw-r--r-- 1 root root  360 Oct 16 21:48 rbl.conf
-rw-r--r-- 1 root root 1760 Oct 17 08:27 whitelist.conf

Below are the contents of the files. Copy and paste them (vi , press i cmd-v Esc :x). And don't forget to set the right url for the mirror server.

known_senders.conf

domains = "https://mirror.mydomain.net/rspamd/freemail/free.txt.zst";

mid.conf

  source = {
    url = [
      "https://mirror.mydomain.net/rspamd/mid.inc.zst",
      "$LOCAL_CONFDIR/local.d/maps.d/mid.inc",
      "$LOCAL_CONFDIR/local.d/mid.inc",
      "fallback+file://${CONFDIR}/maps.d/mid.inc"
    ];
  }

mime_types.conf

  file = [
    "https://mirror.mydomain.net/rspamd/mime_types.inc.zst",
    "$LOCAL_CONFDIR/local.d/maps.d/mime_types.inc.local",
    "${DBDIR}/mime_types.inc.local",
    "fallback+file://${CONFDIR}/maps.d/mime_types.inc"
  ]

miltimap.conf

  redirector {
    type = "url";
    filter = "tld";
    map = "https://mirror.mydomain.net/rspamd/redirectors.inc.zst";
    symbol = "REDIRECTOR_URL";
    description = "The presence of a redirector in the mail";
    score = 0.0;
    one_shot = true;
  }

  # Freemail Addresses
  freemail_envfrom {
    type = "from";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/free.txt.zst";
    symbol = "FREEMAIL_ENVFROM";
    description = "Envelope From is a Freemail address";
    score = 0.0;
  }

  freemail_envrcpt {
    type = "rcpt";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/free.txt.zst";
    symbol = "FREEMAIL_ENVRCPT";
    description = "Envelope Recipient is a Freemail address";
    score = 0.0;
    one_shot = true;
  }

  freemail_from {
    type = "header";
    header = "from";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/free.txt.zst";
    symbol = "FREEMAIL_FROM";
    description = "From is a Freemail address";
    score = 0.0;
  }

  freemail_to {
    type = "header";
    header = "To";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/free.txt.zst";
    symbol = "FREEMAIL_TO";
    description = "To is a Freemail address";
    score = 0.0;
    one_shot = true;
  }

  freemail_cc {
    type = "header";
    header = "Cc";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/free.txt.zst";
    symbol = "FREEMAIL_CC";
    description = "To is a Freemail address";
    score = 0.0;
    one_shot = true;
  }

  freemail_replyto {
    type = "header";
    header = "Reply-To";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/free.txt.zst";
    symbol = "FREEMAIL_REPLYTO";
    description = "Reply-To is a Freemail address";
    score = 0.0;
  }

  freemail_mdn {
    type = "header";
    header = "Disposition-Notification-To";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/free.txt.zst";
    symbol = "FREEMAIL_MDN";
    description = "Disposition-Notification-To is a Freemail address";
    score = 0.0;
  }

  # Disposable Addresses
  disposable_envfrom {
    type = "from";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/disposable.txt.zst";
    symbol = "DISPOSABLE_ENVFROM";
    description = "Envelope From is a Disposable e-mail address";
    score = 0.0;
  }

  disposable_envrcpt {
    type = "rcpt";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/disposable.txt.zst";
    symbol = "DISPOSABLE_ENVRCPT";
    description = "Envelope Recipient is a Disposable e-mail address";
    score = 0.0;
    one_shot = true;
  }

  disposable_from {
    type = "header";
    header = "from";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/disposable.txt.zst";
    symbol = "DISPOSABLE_FROM";
    description = "From a Disposable e-mail address";
    score = 0.0;
  }

  disposable_to {
    type = "header";
    header = "To";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/disposable.txt.zst";
    symbol = "DISPOSABLE_TO";
    description = "To a disposable e-mail address";
    score = 0.0;
    one_shot = true;
  }

  disposable_cc {
    type = "header";
    header = "Cc";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/disposable.txt.zst";
    symbol = "DISPOSABLE_CC";
    description = "To a disposable e-mail address";
    score = 0.0;
    one_shot = true;
  }

  disposable_replyto {
    type = "header";
    header = "Reply-To";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/disposable.txt.zst";
    symbol = "DISPOSABLE_REPLYTO";
    description = "Reply-To a disposable e-mail address";
    score = 0.0;
  }

  disposable_mdn {
    type = "header";
    header = "Disposition-Notification-To";
    filter = "email:domain";
    map = "https://mirror.mydomain.net/freemail/disposable.txt.zst";
    symbol = "DISPOSABLE_MDN";
    description = "Disposition-Notification-To is a disposable e-mail address";
    score = 0.5;
  }

phishing.com

exceptions = {
    REDIRECTOR_FALSE = [
      "https://mirror.mydomain.net/rspamd/redirectors.inc.zst",
      "$LOCAL_CONFDIR/local.d/maps.d/redirectors.inc",
      "$LOCAL_CONFDIR/local.d/redirectors.inc",
      "fallback+file://${CONFDIR}/maps.d/redirectors.inc"
    ];
    PHISHED_WHITELISTED = [
      "glob;https://mirror.mydomain.net/rspamd/phishing_whitelist.inc.zst",
      "glob;$LOCAL_CONFDIR/local.d/maps.d/phishing_whitelist.inc",
      "glob;$LOCAL_CONFDIR/local.d/phishing_whitelist.inc",
    ];
  };

rbl.conf

  url_whitelist = [
    "https://mirror.mydomain.net/rspamd/surbl-whitelist.inc.zst",
    "$LOCAL_CONFDIR/local.d/maps.d/surbl-whitelist.inc.local",
    "${DBDIR}/surbl-whitelist.inc.local",
    "fallback+file://${CONFDIR}/maps.d/surbl-whitelist.inc"
  ];

  disabled_rbl_suffixes_map = "https://mirror.mydomain.net/rspamd/disabled_rbls.inc.zst";

whitelist.conf

    rules {
        WHITELIST_SPF {
            valid_spf = true;
            domains [
                "/etc/rspamd/local.d/maps.d/spf_whitelist.inc.local",
                "/var/lib/rspamd/spf_whitelist.inc.local",
                "fallback+file:///etc/rspamd/maps.d/spf_whitelist.inc",
            ]
            score = -1.0;
            inverse_symbol = "BLACKLIST_SPF";
        }
        WHITELIST_DKIM {
            valid_dkim = true;
            domains [
                "/etc/rspamd/local.d/maps.d/dkim_whitelist.inc.local",
                "/var/lib/rspamd/dkim_whitelist.inc.local",
                "fallback+file:///etc/rspamd/maps.d/dkim_whitelist.inc",
            ]
            score = -1.0;
            inverse_symbol = "BLACKLIST_DKIM";
        }
        WHITELIST_SPF_DKIM {
            valid_spf = true;
            valid_dkim = true;
            domains [
                "https://mirror.mydomain.net/rspamd/spf_dkim_whitelist.inc.zst",
                "/etc/rspamd/local.d/maps.d/spf_dkim_whitelist.inc.local",
                "/var/lib/rspamd/spf_dkim_whitelist.inc.local",
                "fallback+file:///etc/rspamd/maps.d/spf_dkim_whitelist.inc",
            ]
            score = -3.0;
            inverse_symbol = "BLACKLIST_SPF_DKIM";
        }
        WHITELIST_DMARC {
            valid_dmarc = true;
            domains [
                "https://mirror.mydomain.net/rspamd/dmarc_whitelist_new.inc.zst",
                "/etc/rspamd/local.d/maps.d/dmarc_whitelist.inc.local",
                "/var/lib/rspamd/dmarc_whitelist.inc.local",
                "fallback+file:///etc/rspamd/maps.d/dmarc_whitelist.inc",
            ]
            score = -7.0;
            inverse_symbol = "BLACKLIST_DMARC";
        }
    }

Now, let's move on to the override folder of rspamd, in case of mailcow/rspamd you'll probably find it here:

cd /opt/mailcow-dockerized/data/conf/rspamd/override.d/

It is important to backup the config files in this folder before we are adding the just created ones:

mkdir /rspamd-conf/override.d-orig
cp *.conf /rsdpamd-conf/override.d-orig

Now, copy the new config files:

cp /rspamd-conf/*.conf .

And set to right ownership e.g. file permissions (make them same as the existing files in this folder):

chown systemd-network:systemd-network *.conf

Important: I assume the files are new in this folder and therefore just added - if there are existing config files to be overwritten, check and merge the contents of the existing and new files.

6- restart rspamd

To activate the new config the docker container have to be restarted:

docker ps | grep rspamd
76ecb493f46b   ghcr.io/mailcow/rspamd:2.4 "/docker-entrypoint.…" 35 hours ago Up 3 hours mailcowdockerized-rspamd-mailcow-1

docker restart 76ecb493f46b
76ecb493f46b

If something goes wrong, just reverse:

cd /opt/mailcow-dockerized/data/conf/rspamd/override.d/
rm *.conf
cp /rspamd-conf/override.d-orig/* .

docker restart 76ecb493f46b

If it did start, let's check the config:

docker exec -it 76ecb493f46b bash
rspamadm configdump

Of course, you should notice the errors in de logs disappeared (in Mailcow: Admin login > System > Configuration > Access > RspamdUI > RspamdUI). And check the logs of the mirror server for any misconfiguration or typos (usually in /var/log/nginx).

7- upgrades

I don't expect any issues with future upgrades of mailcow/rspamd. However, by using override.d a number of parameters become kinda hardcoded: the code blocks in the new config files override i.e. overrule the default ones. So check and double check when upgrading, especially with major releases.

-jer


You'll only receive email when they publish something new.

More from jertaa
All posts