Modoboa 2.13.0 est disponible
13 novembre 2026 — Antoine Nguyen
Avant de mettre à jour
Python 3.11 ou plus récent
Python 3.10 n'est plus supporté : il est arrivé en fin de vie, et dnspython 2.9.0 ne le supporte plus (#4355). Modoboa requiert désormais Python 3.11 ou plus récent, et pip n'installera pas 2.13.0 sous Python 3.10. Mettez d'abord Python à jour et reconstruisez votre virtualenv.
Détection de l'adresse du client
Modoboa ne fait plus confiance par défaut à l'en-tête X-Forwarded-For, que les clients peuvent définir eux-mêmes, et ne dépend plus de django-xforwardedfor-middleware. Si vous mettez à jour avec l'installeur, vous n'avez rien à faire.
Sinon, cette étape est obligatoire : sans elle, votre instance ne démarrera pas dans un nouveau virtualenv. Dans settings.py, remplacez x_forwarded_for.middleware.XForwardedForMiddleware dans MIDDLEWARE par modoboa.lib.middleware.TrustedProxyMiddleware, et indiquez dans NUM_PROXIES (section REST_FRAMEWORK) le nombre de reverse proxies devant Modoboa : 0 avec uwsgi_pass, Apache mod_wsgi ou une connexion directe, 1 pour nginx proxy_pass devant gunicorn. python manage.py check signale les instances restant à mettre à jour (modoboa.core.W003). Lancez ensuite pip uninstall django-xforwardedfor-middleware.
Autres changements à connaître
- Désactiver un compte révoque désormais ses jetons OAuth2. Pour rejeter aussi les jetons d'un compte désactivé par un autre moyen, définissez OAUTH2_VALIDATOR_CLASS dans OAUTH2_PROVIDER (modoboa.core.W004)
- Les échecs de connexion sont limités, par adresse du client et par identifiant
- load_initial_data et modoboa-admin.py deploy génèrent désormais un mot de passe aléatoire pour l'administrateur initial au lieu de admin:password. Si votre instance utilise encore ce mot de passe par défaut, changez-le
Le guide de mise à jour donne tous les détails.
Journal d'audit
Le journal d'audit a été repensé pour répondre à une question simple : qui a fait quoi, et quand ? Les événements sont désormais structurés, plus faciles à lire, filtrer et exporter.
- Événements structurés avec un catalogue d'actions, et un signal d'audit que les plugins peuvent utiliser pour enregistrer leurs propres actions (#4384)
- Messages rédigés en anglais, niveaux de log pertinents et noms des objets (#4385)
- Davantage d'actions sont enregistrées, et le détail de chaque événement est affiché (#4386)
- Filtres et dates ISO (#4387), et export CSV (#4389)
- Les administrateurs de domaine ont leur propre journal d'audit (#4388)
- Les utilisateurs peuvent consulter l'historique de leurs connexions (#4390)
Webmail
- Étiquettes de messages (#4394)
- Une nouvelle préférence n'affiche que les dossiers abonnés (#4398)
- Correctifs : l'INBOX d'une boîte partagée s'ouvre depuis le niveau de son propriétaire (#4347), et un échec d'authentification OAUTHBEARER n'attend plus le timeout IMAP (#4357)
Administration
- Un bandeau configurable peut s'afficher en bas de chaque page (#4346)
- Les plugins peuvent verrouiller des champs d'un compte (#4348), y compris via l'API v1 (#4351)
- Les listes ont une barre d'outils responsive, et les identités peuvent être filtrées par domaine (#4376)
- La règle de réponse automatique garde sa position dans le script Sieve (#4409)
- Correctifs : vue de détail d'un compte vide quand aucun onglet de plugin n'est enregistré (#4352), chargement des traductions des plugins frontend (#4353), date des actualités sur sa propre ligne dans le widget du tableau de bord (#4377), et les rapports DMARC agrégés malformés sont ignorés au lieu de provoquer une erreur (#4411)
Durcissement de la sécurité
- Les jetons OAuth2 sont révoqués lors d'un changement de mot de passe (#4402)
- Les empreintes de mots de passe ne sont plus conservées dans l'historique des révisions (#4383)
- La réinitialisation du mot de passe des comptes ayant un mot de passe inutilisable est refusée (#4350)
- Le jeton d'accès brut est lu depuis l'en-tête Authorization (#4356), et le client Sieve rejette les identifiants manquants (#4401)
- Les dépendances frontend concernées par des avis de sécurité sont mises à jour : undici (#4354), glob et minimatch (#4396)
Paquets et dépendances
Chaque version est désormais livrée avec un fichier constraints.txt qui fixe chaque dépendance à la version testée avec elle (#4374). Utilisez-le quand vous installez ou reconstruisez un virtualenv : vous obtenez exactement l'ensemble que nous avons testé, sans mise à jour de dépendance qui apporterait ses propres migrations.
- django-oauth-toolkit est plafonné sous 3.5 (#4366), et rq, django-rq et redis à leur version majeure actuelle (#4373)
- Django 5.2.19 (#4404), dnspython 2.9.2 (#4355, #4403), django-phonenumber-field 9.0.0 (#4359), django-reversion 6.5.1 (#4363, #4399), ainsi que des mises à jour frontend (#4361, #4362, #4368, #4369, #4370, #4371, #4372, #4378, #4379, #4380, #4381, #4382, #4400)
- Traductions : le français et le japonais sont mis à jour (#4358, #4407, #4408, #4410)
- Développement : la documentation passe à une version plus récente de VitePress (#4405), des tests sont corrigés et isolés (#4349, #4391, #4395), et la politique de mise à jour des dépendances est resserrée (#4367)
Remerciements
Bienvenue à nos nouveaux contributeurs Christophe-Aubert et dylanpulver, et merci à kryskool pour la mise à jour de la documentation !
Mise à jour
Après les étapes propres à cette version décrites plus haut :
pip install -U modoboa==2.13.0 -c https://github.com/modoboa/modoboa/releases/download/2.13.0/constraints.txt
cd <modoboa_instance_dir>
python manage.py migrate
python manage.py collectstatic
python manage.py check --deploy
python manage.py load_initial_data
sudo systemctl restart uwsgi supervisor
Changelog complet : 2.12.0...2.13.0