19 mars 2024

Tuto Messagerie, partie VI : Rspamd

Tutoriel révisé en décembre 2022 / Debian 11

Sixième partie de ma série d’articles sur la mise en place d’un serveur mail complet. Courage, on arrive au bout ! Nous allons installer et configurer le digne remplaçant du vénérable Spamassassin, j’ai nommé Rspamd.

I – Installation

Le paquet Rspamd disponible dans les dépôts de Debian n’étant plus maintenu, on va passer par les dépôts de Rspamd

# wget -O- https://rspamd.com/apt-stable/gpg.key | apt-key add -

La, si un message évoque un problème de certificats, c’est que le paquet ca-certificates n’est pas présent.

# echo "deb [arch=amd64] http://rspamd.com/apt-stable/ bullseye main" > /etc/apt/sources.list.d/rspamd.list
# apt update
# apt install rspamd

Pour fonctionner, Rspamd a besoin d’un serveur redis. Perso, j’ai une VM dédiée à cela, mais ici, on va l’installer sur le serveur mail.

# apt install redis-server

Nous verrons dans un article plus tard l’installation d’un serveur redis « général ».

 

II – Configuration

A – Assistant

Pour la configuration initiale, un assistant est disponible, ne nous en privons pas :

# rspamadm configwizard

Puis répondez :

Welcome to the configuration tool
We use /etc/rspamd/rspamd.conf configuration file, writing results to /etc/rspamd
Modules enabled: mime_types, mid, bayes_expiry, rbl, settings, hfilter, elastic, multimap, phishing, dkim_signing, spf, trie, emails, force_actions, forged_recipients, maillist, metadata_exporter, dmarc, whitelist, dkim, chartable, fuzzy_check, once_received, milter_headers, asn, arc, regexp
Modules disabled (explicitly): bimi, rspamd_update, spamtrap, p0f, external_relay, aws_s3, dcc, http_headers, mx_check
Modules disabled (unconfigured): reputation, dynamic_conf, clustering, metric_exporter, spamassassin, clickhouse, maps_stats, external_services, fuzzy_collect, ip_score, antivirus
Modules disabled (no Redis): url_redirector, ratelimit, neural, history_redis, greylist, replies
Modules disabled (experimental):
Modules disabled (failed):
Do you wish to continue?[Y/n]:Y
Setup WebUI and controller worker:
Controller password is not set, do you want to set one?[Y/n]:Y
Enter passphrase:xxxxxxx
Set encrypted password to: .........
Redis servers are not set:
The following modules will be enabled if you add Redis servers:
* url_redirector
* ratelimit
* neural
* history_redis
* greylist
* replies
Do you wish to set Redis servers?[Y/n]:Y
Input read only servers separated by `,` [default: localhost]: 10.100.6.100
Input write only servers separated by `,` [default: 10.100.6.100]:
Do you have any password set for your Redis?[y/N]:N
Do you have any specific database for your Redis?[y/N]: Y
Enter Redis database:5
Do you want to setup dkim signing feature?[y/N]:N (on le fera plus tard)
File: /etc/rspamd/local.d/worker-controller.inc, changes list:
password => ......

File: /etc/rspamd/local.d/redis.conf, changes list:
write_servers => 10.100.6.100
db => 5
read_servers => 10.100.6.100

Apply changes?[Y/n]:Y
Create file /etc/rspamd/local.d/worker-controller.inc
Create file /etc/rspamd/local.d/redis.conf
2 changes applied, the wizard is finished now
*** Please reload the Rspamd configuration ***

Et on termine en rechargeant :

# service rspamd reload

 

B – Quelques ajustements

Au niveau de la configuration, tout se passe dans /etc/rspamd/, cependant, modifier ces fichiers n’est pas une bonne idée car comme indiqué dedans, ils se retrouveraient écrasés en cas d’update. On va donc utiliser le répertoire /etc/rspamd/local.d pour y indiquer nos modifications.

1 – classifier-bayes.conf

Fichier à créer :

autolearn = true;
backend = "redis";
new_schema = true;
users_enabled = true;
expire = 8640000;
2 – worker-controller.inc

Fichier créé par l’assistant. Ici, on rajoute les deux lignes pour les sockets. Le socket sur le port 11334 sera pour l’interface Web (c’est pour cela qu’on le bind sur l’ip interne de la machine et non sur localhost). Le second socket servira pour l’apprentissage des spams.

password = trucavous
bind_socket = "ip.interne:11334";
bind_socket = "/var/run/rspamd/rspamd.sock mode=0666 owner=nobody";
3  – metrics.conf

Fichier à créer. Il permet d’indiquer vos valeurs pour les différentes actions.

actions {
add_header = 5;
greylist = 25;
reject = 50;
}

A vous de bien régler ces paramètres. Ici, le reject est volontairement haut, dans un but de test et pour pouvoir le baisser au fur et à mesure.

4 – milter_headers.conf

Ce fichier est à créer. Il indique d’ajouter des entêtes dans les mails. Grace à eux, vous pourrez voir directement dans votre logiciel ce qui a provoqué ou non le marquage en spam. Mettez simplement :

extended_spam_headers = true;

Et voila pour la configuration de Rspamd. Il existe d’autres modules, mais nous en parlerons dans un futur article ou nous approfondirons le sujet sur Rspamd.

 

III – Liaison avec Postfix

Pour dire à Postfix de passer le mail à Rspamd, c’est le protocole milter que l’on va utiliser en indiquant en bas de notre fichier /etc/postfix/main.cf :

milter_protocol = 6
milter_default_action = accept
smtpd_milters = inet:localhost:11332
non_smtpd_milters=inet:localhost:11332
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}

Le milter_default_action spécifie l’action par défaut au cas ou Rspamd ne serait pas disponible. On recharge :

# postfix reload
# service rspamd restart

 

IV – Apprentissage

Pour l’utilisation de Rspamd au quotidien, pas grand chose à faire. C’est automatique, même pour les mises à jour. Cependant, si vous avez déjà un corpus de spam et de ham à lui apprendre, ce n’est pas une mauvaise chose de commencer par la, le filtre bayésien ne fonctionnant pas à moins de 200 mails appris par catégorie. Pour se faire, j’ai toujours deux dossiers récents de spams et de hams que je garde sous le coude. Je les déplace dans ma bal dans deux répertoires. Puis pour le spam :

# rspamc -h /var/run/rspamd/rspamd.sock learn_spam /home/vmail/domaine1.fr/toto/mailbox/.Spamtolearn/

et pour le ham :

# rspamc -h /var/run/rspamd/rspamd.sock learn_ham /home/vmail/domaine1.fr/toto/mailbox/.Hamtolearn/

Pour regarder ensuite les statistiques et voir à combien on en est :

# rspamc -h /var/run/rspamd/rspamd.sock stat

Pour un bon apprentissage, il faut lui apprendre des spams certes, mais également des hams, c’est important.

 

V – Apprentissage par déplacement

Couplé avec Dovecot, Rspamd nous propose de pouvoir apprendre également en fonction des actions des utilisateurs. Si un mail est déplacé vers le répertoire spam, il sera appris comme tel et au contraire,  s’il est sorti du répertoire Spam vers autre chose que la corbeille, il sera appris comme Ham. Dans le fichier /etc/dovecot/conf.d/90-sieve-extprograms.conf, mettez cela :

plugin {
  sieve_plugins = sieve_imapsieve sieve_extprograms
  imapsieve_mailbox1_name = Junk
  imapsieve_mailbox1_causes = COPY
  imapsieve_mailbox1_before = file:/etc/dovecot/sieve/report-spam.sieve
  imapsieve_mailbox2_name = *
  imapsieve_mailbox2_from = Junk
  imapsieve_mailbox2_causes = COPY
  imapsieve_mailbox2_before = file:/etc/dovecot/sieve/report-ham.sieve
  sieve_pipe_bin_dir = /etc/dovecot/sieve
  sieve_global_extensions = +vnd.dovecot.pipe
}

On recharge Dovecot :

# dovecot reload

Quand un mail sera déplacé dans le répertoire Junk (Spam), le filtre report-spam.sieve sera appelé. Quand un mail sera déplacé depuis le répertoire Junk vers un autre répertoire (autre que la Corbeille, on fait le distingo dans le script plus bas), le filtre report-ham.sieve sera appelé. On va créer les filtre sieves. On créer un répertoire :

# mkdir /etc/dovecot/sieve/
# cd /etc/dovecot/sieve

Puis un fichier /etc/dovecot/sieve/report-spam.sieve :

require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];

if environment :matches "imap.email" "*" {
set "email" "${1}";
}

pipe :copy "train-spam.sh" [ "${email}" ];

puis, /etc/dovecot/sieve/report-ham.sieve :

require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];

if environment :matches "imap.mailbox" "*" {
set "mailbox" "${1}";
}

if string "${mailbox}" "Trash" {
stop;
}

if environment :matches "imap.email" "*" {
set "email" "${1}";
}

pipe :copy "train-ham.sh" [ "${email}" ];

On les compile :

# sievec report-ham.sieve
# sievec report-spam.sieve

Puis on change l’user :

# chown vmail:vmail report-*

On va passer à la création de nos deux petits scripts : Tout d’abord /etc/dovecot/sieve/train-ham.sh :

#!/bin/sh
exec /usr/bin/rspamc -h /var/run/rspamd/rspamd.sock learn_ham

et /etc/dovecot/sieve/train-spam.sh :

#!/bin/sh
exec /usr/bin/rspamc -h /var/run/rspamd/rspamd.sock learn_spam

Et on leur donne les droits :

# chown vmail:vmail train-*
# chmod +x train-*

Afin d’éviter une erreur de droits d’écriture, on va éditer le fichier du service Dovecot /etc/systemd/system/multi-user.target.wants/dovecot.service et ajouter ce qu’il y a en gras :

[...]
[Service]
Type=notify
ExecStart=/usr/sbin/dovecot -F
ExecReload=/usr/bin/doveadm reload
ExecStop=/usr/bin/doveadm stop
PrivateTmp=true
NonBlocking=yes
ProtectSystem=full
ProtectHome=no
PrivateDevices=true
ReadWritePaths=/etc/dovecot/sieve/
[...]
Ca, c’est à cause de ProtectSystem.

 

Ensuite :

# cd /etc/dovecot
# chown vmail:vmail sieve
# systemctl daemon-reload
# dovecot reload

Et voila, vous pouvez vérifier en déplaçant un spam ou un ham et voir dans les fichiers de logs /var/log/rspamd/rspamd.log :

#9159(controller) <e6896a>; csession; rspamd_controller_check_password: allow unauthorized connection from a unix socket
#9159(controller) <e6896a>; csession; rspamd_message_parse: loaded message; id: <004801d4dc01$02b7a725$5d7532ac$@lourd.com>; queue-id: <undef>; size: 1732; checksum: <b32bcf8d811d92610d2808ce822930dc>
#9159(controller) <e6896a>; csession; rspamd_mime_text_part_utf8_convert: converted from IBM852 to UTF-8 inlen: 104, outlen: 104 (104 UTF16 chars)
#9159(controller) <e6896a>; csession; rspamd_controller_learn_fin_task: </var/run/rspamd/rspamd.sock> learned message as spam: 004801d4dc01$02b7a725$5d7532ac$@lourd.com

Voila une affaire qui roule.

 

VI – Signature DKIM

Si jusque la, vous utilisiez Opendkim, vous pouvez l’oublier: Rspamd peut se charger de cette tâche, autant s’éviter une pièce de plus dans notre puzzle.

A – Configuration

On va tout d’abord créer le répertoire qui va accueillir nos clés :

# mkdir /etc/rspamd/dkim

Créez un fichier /etc/rspamd/local.d/dkim_signing.conf et ajoutez :

path = "/etc/rspamd/dkim/dkim.$domain.key";
allow_username_mismatch = true;

B – Signature d’un domaine

Pour signer un nouveau domaine :

# rspamadm dkim_keygen -b 2048 -s dkim -d domaine1.fr -k /etc/rspamd/dkim/dkim.domaine1.fr.key | tee -a /etc/rspamd/dkim/dkim.domaine1.fr.pub
  • -b indique que l’on veut une clé de 2048 bits.
  • -s est le sélecteur.
  • -d indique le domaine.
  • -k pour dire ou l’on veut stocker la clé privée.
  • et pour terminer, on enregistre la clé publique, qui par défaut est simplement affichée, dans un fichier.

Gardez la clé publique sous le coude, on la rajoutera dans le DNS dans la partie VII. Pour info, il est tout a fait possible d’avoir des sélecteurs différents, soit en fonction des domaines, soit pour versionner, etc… Dans ce cas, il faudrait renseigner le fichier /etc/rspamd/local.d/dkim_signing.conf de la sorte :

path = "/etc/rspamd/dkim/$selector.$domain.key";
selector_map = "/etc/rspamd/dkim_selectors.map";

Et le fichier /etc/rspamd/dkim_selectors.map devra contenir :

domaine.fr selecteur
domaine2.fr autre_selecteur
[...]

Puis changeons les droits :

# chmod u=rw,g=r,o= /etc/rspamd/dkim/*
# chown _rspamd /etc/rspamd/dkim/*

On recharge :

# service rspamd reload

 

VII – Interface Web

Rspamd propose une interface Web. Avant de la tester, je pensais que c’était un gadget, mais après avoir vu la chose, force est de constater qu’elle est plutôt bien fichue et permet de voir l’historique des messages, ce qui a provoqué ou non leur tag, rejet… On peut aussi y modifier les valeurs de metrics, les symboles (ce qui sert à détecter un spam par rapport à un critère donné). Bref, très pratique, je vous conseille de vous en servir. C’est déjà en écoute sur le port 11334, mais on ne va pas faire le goret et ouvrir cela sur le routeur. Servez vous d’un reverse proxy (Nginx est juste parfait) et indiquez dans la configuration de votre serveur.

location /rspamd/ {
  proxy_pass http://ip.interne.mail:11334/;
  proxy_http_version 1.1;
}

Pour s’y connecter ensuite : https://www.domaine1.fr/rspamd (par exemple) et le mot de passe est celui qu’on a renseigné grâce à l’assistant.

 

VIII – Conclusion

Voila, Rspamd est installé et opérationnel. La configuration reste simple, mais comme déjà dit, il existe d’autres modules que l’on peut utiliser. Ce sera pour un autre article, hors de la série sur le serveur de messagerie. La configuration présentée ici est bien suffisante dans un premier temps. En attendant, si vous voulez en savoir plus, la documentation officielle est ici : https://rspamd.com/doc/   On va passer à la finalisation de notre architecture mail avec, dans la partie VII, la mise en place des enregistrements SPF, DKIM et DMARC dans notre DNS.

18 réflexions sur « Tuto Messagerie, partie VI : Rspamd »

  1. Hello,

    J’ai 2 questions :

    1) Dans le worker-controller.inc, je n’ai pas compris pourquoi il ne fallait pas mettre localhost et remplacer par l’ip interne (d’ailleurs qu’appelles-tu ip interne ?). Me concernant, j’accès à mon interface comme ça.

    2) En parlant de l’interface web, tout fonctionne, sauf le graph qui est sensé apparaître en page d’accueil, le truc appelé Rspamd filter stats, pour moi il n’y a rien alors que je devrais y trouver des graphs (au moins un fromage). Dans la console Chrome, j’ai un https://rspamd.gl-amf.org/stat 403 (Unauthorized) à l’ouverture de la page et à l’ouverture, une nouvelle erreur : d3pie.min.js:9 Uncaught TypeError: d3.arc is not a function
    at Object.create (d3pie.min.js:9)
    at d3pie.min.js:9
    at d3pie.min.js:9.
    En fouillant un peu, je suis tombé sur cet incident, il semblerait que ça ne soit jamais résolu : https://github.com/rspamd/rspamd/issues/2085. Est-ce que tu as aussi ce problème ?

    En dehors de ça, le reste est fonctionnel (on devine d’ailleurs que cet outil est une petite merveille, quand je vois que l’on peut créer depuis ses propres filtres).

    1. Hello.
      1- Mon reverse Nginx est sur une autre machine. D’où le fait que je l’appelle par son IP interne 10.20.1.xxx)
      2 – Non, Ras chez moi.
      Avec un autre navigateur ? Quelle version de Rspamd ?

  2. Hello,

    Tous les navigateurs et Rspamd en 1.8.1 (de la Debian 10)

    Ma config nginx est la suivante :

    server {
    listen 443 ssl http2;
    server_name rspamd.site1.org;
    location / {
    root /usr/share/rspamd/www/;
    proxy_pass http://localhost:11334;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    }

    include ssl_configuration.conf;
    include restricted.conf;
    include resolver.conf;

    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection « 1; mode=block »;

    access_log /var/log/nginx/rspamd.site1.org.log;
    error_log /var/log/nginx/errors-rspamd.site1.org.log;
    }

    As-tu une idée ? Merci !

  3. Yes ! c’était ça le problème. Je n’avais pas vu qu’il y avait tant de différences entre les deux versions.
    Merci !

  4. Attention, il faut remplacer :
    puis, /etc/dovecot/sieve/report-spam.sieve :
    par
    puis, /etc/dovecot/sieve/report-ham.sieve :

  5. Je teste la partie V Apprentissage par déplacement…
    J’ai une erreur lors du lancement de la commande sievec report-ham.sieve
    report-ham: line 1: error: require command: unknown Sieve capability `vnd.dovecot.pipe’.
    report-ham: line 1: error: require command: unknown Sieve capability `imapsieve’.
    report-ham: line 15: error: unknown command ‘pipe’ (only reported once at first occurrence).

    Il doit manquer des plugins non ?
    Merci
    Fred

  6. Hello,

    Je ne sais pas si tu as les même problèmes, mais me concernant le passe en 2.0 me pose quelques soucis (non bloquants), j’ai notamment les erreurs suivantes :

    15/10/2019 à 10:32:13 main 15704 symcache jowob5 cannot register delayed dependency between LEAKED_PASSWORD_SCAM and BITCOIN_ADDR, LEAKED_PASSWORD_SCAM is missing
    15/10/2019 à 10:32:12 main 15704 cfg jowob5 signed maps are no longer supported for HTTP(s): sign+https://updates.rspamd.com/rspamd-2.ucl
    15/10/2019 à 10:32:12 main 15704 lua jowob5 invalid config for spamhaus_received: extra fields: \ »ignore_whitelists\ », RBL is DISABLED
    15/10/2019 à 10:32:12 main 15704 lua jowob5 invalid config for blocklistde_received: extra fields: \ »ignore_whitelists\ », RBL is DISABLED

    Comment je peux décoder ça et voir où ça coince ? pour chaque message d’erreur une recherche sur le web ne me rend pas grand chose (ça reste assez frais et je ne dois pas être le seul dans ce cas, je pense que ça va remonter).

    Je pense que pour la première, ça doit être une définition manquante dans le composites.conf, à rajouter sous local.d. Je vais tester.

    1. La même chose que ma réponse d’avant.
      Je n’ai pas encore creusé la nouvelle version.
      Ça va arriver vu que d’ici quelque temps, je vais upgrader les tutos pour Debian 10.

    2. Hello,

      Suite à la MAJ de mon tuto, en fait, les updates sont maintenant automatique, plus besoin de forcer ca (en gros).
      Et oui, la doc n’est pas clair, on est d’accord 😉

  7. Chez moi ca marche(tm)

    j’ai juste du activer le plugin imap_sieve dans mon dovecot, je suis sur une debian 10 « nue »
    dans mon fichier 20-imap.conf
    protocol imap {
    # Space separated list of plugins to load (default is global mail_plugins).
    mail_plugins = $mail_plugins imap_sieve

    }

    1. Hello.
      Je viens de vérifier, c’est bien dans l’article sur Dovecot.
      Mais heureux de savoir que ça marche !

  8. Hello,

    rspamd_update n’est plus activé par défaut depuis la 1.53. Je ne sais pas si quelqu’un l’utilisait, mais ça générait un message d’erreur.

    Qu’utilise-t-on à présent en lieu et place de rspamd_update ?

    1. Hello !
      Alors la, bonne question.
      Je ne me suis pas penché sur la question encore.
      Je regarde cela des que j’ai le temps et poste la solution 😉

    2. Hello,

      Suite à la MAJ de mon tuto, en fait, les updates sont maintenant automatique, plus besoin de forcer ca (en gros).
      Et oui, la doc n’est pas clair, on est d’accord 😉

  9. Petit problème avec RSpamD et son comportement.
    Je n’ai pas fais d’autres modifications que celles décrites dans ta doc, donc laissé la configuration par défaut sur tout le reste.

    Je me rend compte que la résolution du nom « rspamd.com » tombe régulièrement en panne car notre serveur DNS tombe en time-out dessus. Ça revient régulièrement mais retombe tout aussi régulièrement. En regardant les logs je me rend compte qu’il y a des centaines de demandes de résolution de ce nom depuis mon serveur … par jour ! 370 pour le 25/09 par exemple !

    Du coup je me demande si ce n’est pas tout simplement les services DNS de RSpamD qui nous black list, non ?

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *