Archives de catégorie : Zimbra

Bloquer les attaques par force brute sur Zimbra

Ce billet est un cut/paste d’un post sur le forum US.

Tout est basé sur l’utilisation de fail2ban, avec les bons fichiers de configuration…

Le jail.conf :

[zimbra-account]
 
enabled  = true
filter   = zimbra
action   = iptables-allports[name=Zimbra-account]
           sendmail[name=Zimbra-account, dest=it@enabletv.com]
logpath  = /opt/zimbra/log/mailbox.log
bantime  = -1
maxretry = 5
 
 
[zimbra-audit]
 
enabled  = true
filter   = zimbra
action   = iptables-allports[name=Zimbra-audit]
           sendmail[name=Zimbra-audit, dest=it@enabletv.com]
logpath  = /opt/zimbra/log/audit.log
bantime  = -1
maxretry = 5
 
[zimbra-recipient]
 
enabled  = true
filter   = zimbra
action   = iptables-allports[name=Zimbra-recipient]
           sendmail[name=Zimbra-recipient, dest=it@enabletv.com]
logpath  = /var/log/maillog
findtime = 604800
bantime  = 172800
maxretry = 5
 
[postfix]
 
enabled  = true
filter   = postfix
action   = iptables-multiport[name=Postfix, port=smtp, protocol=tcp]
           sendmail-buffered[name=Postfix, dest=it@enabletv.com]
logpath  = /var/log/maillog
bantime  = 172800
maxretry = 5

Le filtre (/etc/fail2ban/filter.d/zimbra.conf) :

# Fail2Ban configuration file
#
# Author: 
#
# $Revision: 1 $
#
 
[Definition]
 
# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values:  TEXT
#
failregex = \[ip=<HOST>;\] account - authentication failed for .* \(no such account\)$
            \[ip=<HOST>;\] security - cmd=Auth; .* error=authentication failed for .*, invalid password;$
            ;oip=<HOST>;.* security - cmd=Auth; .* protocol=soap; error=authentication failed for .* invalid password;$
            \[oip=<HOST>;.* SoapEngine - handler exception: authentication failed for .*, account not found$
            WARN .*;ip=<HOST>;ua=ZimbraWebClient .* security - cmd=AdminAuth; .* error=authentication failed for .*;$
            NOQUEUE: reject: RCPT from .*\[<HOST>\]: 550 5.1.1 .*: Recipient address rejected:
 
# .*\[ip=<HOST>;\] .* - authentication failed for .* \(invalid password\)
# 
# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =

Bien entendu, il faut configurer le reste de fail2ban comme vous le souhaitez (durée du ban, etc) et ne pas oublier que vous pouvez bloquer un vrai utilisateur qui se trompe de mot de passe…

Si c’est le cas, il faut regarder quelle règle dans le firewall correspond à cet utilisateur :

[root@mail fail2ban]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
fail2ban-Zimbra-audit  tcp  --  anywhere             anywhere  
 
Chain fail2ban-Zimbra-audit (1 references)
target     prot opt source                 destination         
DROP       all  --  bad.spammer.com    anywhere            
DROP       all  --  legitimate.user.com   anywhere

Et le libérer :

iptables -D fail2ban-Zimbra-audit 2
Laisser un commentaire

Too many connections, slow down.

Orange a décidé qu’il faut parler lentement à ses MX (ça date un peu maintenant)…

Sinon les mails sont « bloqués » (le relai est bloqué en fait) avec une erreur :

status=deferred (delivery temporarily suspended: host smtp-in.orange.fr[80.12.242.148] refused to talk to me: 421 mwinf5c29 ME Trop de connexions, veuillez verifier votre configuration. Too many connections, slow down. OFR004_104 [104]

Voilà les éléments qui permettent d’adapter son postfix à Orange (compilation d’éléments trouvés sur le net et qui semblent fonctionner pour nous)…

Dans /etc/postfix/transport, on ajoute un transport spécifique pour Orange/Wanadoo.

wanadoo.com slow:
wanadoo.fr slow:
orange.com slow:
orange.fr slow:

Dans /etc/postfix/master.cf, on crée la règle correspondante.

#
# Slow - special pour Orange/Wanadoo
#
slow    unix    -       -       n       -       5       smtp
   -o syslog_name=postfix-slow
   -o smtp_destination_concurrency_limit=3
   -o slow_destination_rate_delay=1

Dans /etc/postfix/main.cf, on ajoute les variables (la première ligne est peut-être déjà déclarée dans votre main.cf).

transport_maps = hash:/etc/postfix/transport
slow_destination_recipient_limit = 20
slow_destination_concurrency_limit = 10
default_destination_concurrency_limit = 10

Puis on redémarre la chose.

postmap /etc/postfix/transport
/etc/init.d/postfix restart
Laisser un commentaire

Export CSV des comptes

Il existe une commande zmprov pour exporter la liste totale des comptes mais on ne récupère que les adresses email…

Voici un script qui exporte les comptes « complets » : prénom, nom, nom affiché, adresse email.

#!/bin/bash
 
clear
echo -e "##############################################################################"
echo -e "# Zimbra getuserCSV.sh ver 0.1                                               #"
echo -e "##############################################################################"
 
# /* Paramètres */
echo ""
echo -n "Nom de domaine (ex : zimbra.com) : "
read NOM_DOMAINE
echo -n "Nom du fichier export (ex : /tmp/utilisateurs.csv) : "
read NOM_FICHIER
 
rm -f $NOM_FICHIER
 
touch $NOM_FICHIER
 
# Vérification version ZCS
VERSION=`su - zimbra -c 'zmcontrol -v'`;
ZCS_VER="/tmp/zcsver.txt"
 
# Récupération password LDAP
ZIMBRA_LDAP_PASSWORD=`su - zimbra -c "zmlocalconfig -s zimbra_ldap_password | cut -d ' ' -f3"`
LDAP_MASTER_URL=`su - zimbra -c "zmlocalconfig -s ldap_master_url | cut -d ' ' -f3"`
 
touch $ZCS_VER
echo $VERSION > $ZCS_VER
 
echo -e "Récupération utilisateurs"
 
grep "Release 5." $ZCS_VER
if [ $? = 0 ]; then
  USERS=`su - zimbra -c 'zmprov gaa'`;
fi
 
grep "Release 6." $ZCS_VER
if [ $? = 0 ]; then
  USERS=`su - zimbra -c 'zmprov -l gaa'`;
fi
 
grep "Release 7." $ZCS_VER
if [ $? = 0 ]; then
  USERS=`su - zimbra -c 'zmprov -l gaa'`;
fi
 
echo -e "Traitement utilisateurs"
for ACCOUNT in $USERS; do
   NAME=`echo $ACCOUNT`;
   DOMAIN=`echo $ACCOUNT | awk -F@ '{print $2}'`;
   ACCOUNT=`echo $ACCOUNT | awk -F@ '{print $1}'`;
   ACC=`echo $ACCOUNT | cut -d '.' -f1`
 
  if [ $NOM_DOMAINE == $DOMAIN ] ;
  then
        OBJECT="(&(objectClass=zimbraAccount)(mail=$NAME))"
        dn=`/opt/zimbra/bin/ldapsearch -H $LDAP_MASTER_URL -w $ZIMBRA_LDAP_PASSWORD -D uid=zimbra,cn=admins,cn=zimbra -x $OBJECT | grep dn:`
        displayName=`/opt/zimbra/bin/ldapsearch -H $LDAP_MASTER_URL -w $ZIMBRA_LDAP_PASSWORD -D uid=zimbra,cn=admins,cn=zimbra -x $OBJECT | grep displayName: | cut -d ':' -f2 | sed 's/^ *//g' | sed 's/ *$//g'`
        givenName=`/opt/zimbra/bin/ldapsearch -H $LDAP_MASTER_URL -w $ZIMBRA_LDAP_PASSWORD -D uid=zimbra,cn=admins,cn=zimbra -x $OBJECT | grep givenName: | cut -d ':' -f2 | sed 's/^ *//g' | sed 's/ *$//g'`
        #userPassword=`/opt/zimbra/bin/ldapsearch -H $LDAP_MASTER_URL -w $ZIMBRA_LDAP_PASSWORD -D uid=zimbra,cn=admins,cn=zimbra -x $OBJECT | grep userPassword: | cut -d ':' -f3 | sed 's/^ *//g' | sed 's/ *$//g'`
        cn=`/opt/zimbra/bin/ldapsearch -H $LDAP_MASTER_URL -w $ZIMBRA_LDAP_PASSWORD -D uid=zimbra,cn=admins,cn=zimbra -x $OBJECT | grep cn: | cut -d ':' -f2 | sed 's/^ *//g' | sed 's/ *$//g'`
        #initials=`/opt/zimbra/bin/ldapsearch -H $LDAP_MASTER_URL -w $ZIMBRA_LDAP_PASSWORD -D uid=zimbra,cn=admins,cn=zimbra -x $OBJECT | grep initials: | cut -d ':' -f2 | sed 's/^ *//g' | sed 's/ *$//g'`
        sn=`/opt/zimbra/bin/ldapsearch -H $LDAP_MASTER_URL -w $ZIMBRA_LDAP_PASSWORD -D uid=zimbra,cn=admins,cn=zimbra -x $OBJECT | grep sn: | cut -d ':' -f2 | sed 's/^ *//g' | sed 's/ *$//g'`
 
        if [ $ACC == "admin" ] || [ $ACC == "wiki" ] || [ $ACC == "galsync" ] || [ $ACC == "ham" ] || [ $ACC == "spam" ]; then
          echo "Utilisateur système non traité : $NAME"
        else
          echo "$NAME;'$displayName';'$givenName';'$sn'" >> $NOM_FICHIER
        fi
  else
    echo "Utilisateur $NAME non traité"
  fi
 
done
 
echo -e "Tous les comptes ont été exportés dans $NOM_FICHIER..."
Laisser un commentaire

Storage is cheap

A partir du moment où on choisit sa solution de stockage en fonction de ses besoins, storage is cheap.
Le SAN/NAS hardware n’est pas la solution ultime qui répond à toutes les problématiques, des alternatives sont possibles…

Quelques liens, en vrac, sur le sujet :
http://www.techrepublic.com/blog/datacenter/calculate-iops-in-a-storage-array/2182
http://constantin.glez.de/blog/2010/06/closer-look-zfs-vdevs-and-performance
http://blog.laspina.ca/ubiquitous/running-zfs-over-iscsi-as-a-vmware-vmfs-store (merci Tof)
http://www.seanodes.com/ (que nous distribuons)
http://www.nexentastor.org/
http://www.open-e.com/ (que nous distribuons aussi)
http://www.nimblestorage.com/
http://www.openfiler.com/
http://www.freenas.org/ (avec une version 8 qui support le ZFS et qui fonctionne TRES bien)

Dernière modification le 01/07/2011

Laisser un commentaire

Fixing email

Pour la réunion de la communauté francophone Zimbra, j’ai fait une présentation sur ce sujet.
Basée sur le white paper de Scott qui est à l’origine de ZCS.

Il est téléchargeable ici, entre autre : Top ten ways to fix email

Laisser un commentaire

Total quota par domaine

C’est pas moi qui l’ai écrit…

Etape initiale, installer php-cli sur votre serveur ZCS et coller le script PHP (appellons le quota.php) à un endroit où il est exécutable par le user zimbra.

Le code :

<?php
 
header('Content-Type: text/plain');
 
exec('zmprov gqu `zmhostname`', $lines);
ini_set('error_reporting',E_ALL & ~E_NOTICE);
 
$domains = array();
 
foreach($lines as $line)
{
        list($mail,$quota,$used) = explode(' ',trim($line));
        list($user,$domain) = explode('@',$mail);
        if(($user == 'wiki') || ($user == 'galsync'))
                continue;
 
        $domains[$domain]['total'] += $used;
        $domains[$domain]['users'][$user] = $used;
}
 
echo 'DOMAINS'."\n";
ksort($domains);
foreach($domains as $d => $dd)
{
        ksort($dd['users']);
        echo '- '.$d."\n";
        foreach($dd['users'] as $uid => $n)
        {
                echo '  . '.$uid.': '.sprintf('%.2f',round($n/1073741824,2))."GB\n";
        }
        echo '  Total: '.sprintf('%6.2f',round($dd['total']/1073741824,2)).'GB'."\n";
        echo "\n";
}
 
?>

Il ne reste qu’à lancer le script :

su - zimbra
php quota.php
Laisser un commentaire

LDAP callout et Zimbra

On a vu il y a longtemps qu’on pouvait utiliser le SMTP callout avec Zimbra.

Si votre relais ne gère pas le SMTP callout (c’est le cas de postfix), il gère peut-être le LDAP callout.
A chaque fois qu’un mail arrive, le relais fait une requête LDAP auprès du serveur Zimbra pour vérifier si le destinataire existe ou pas.

Facile et efficace mais attention, cela peut devenir très gourmand niveau LDAP sur le serveur ZCS…

Pour mettre en place un LDAP callout sur un postfix, c’est assez simple.
Il suffit, côté postfix, j’ajouter une ligne dans le fichier main.cf :

relay_recipient_maps = ldap:/etc/postfix/ldap_zcs.cf

Cette ligne indique à postfix que pour savoir quels sont les destinataires autorisés, il faut effectuer la requête LDAP définie dans le fichier ldap_zcs.cf.

On va ensuite créer ce fichier :

server_host = ldap://zcs.domain.tld:389
server_port = 389
search_base =
query_filter = (&(|(zimbraMailDeliveryAddress=%s)(zimbraMailAlias=%s(zimbraMailCatchAllAddress=%s))(zimbraMailStatus=enabled))
result_attribute = zimbraMailDeliveryAddress,zimbraMailAlias
version = 3
ldap_cache = yes
ldap_cache_expiry = 600
ldap_cache_size = 64256
bind = no
timeout = 30

Bien entendu, il faut remplacer « zcs.domain.tld » par le nom de votre serveur ZCS (tel qu’il est accessible depuis votre relais).

Si votre relais est en DMZ, il faudra bien entendu ouvrir le port LDAP au niveau du firewall vers le serveur ZCS.

Lorsque votre ZCS est offline (pendant une upgrade), je vous conseille fortement de mettre commenter la ligne définissant le LDAP callout dans postfix afin que celui-ci accepte tous les mails (même ceux pour des destinataires inexistants) et les spoole en attendant que le ZCS repasse online (et de décommenter la ligne).
Si vous ne le faites pas, les mails seront refusés car le serveur LDAP ne répondra pas (avec, en plus, un timeout de 30 secondes à chaque connexion SMTP).

Ce billet n’est pas destiné à vous donner la configuration complète « clefs en main » d’un postfix en relais « devant » un ZCS, uniquement les informations concernant le LDAP callout. Ainsi, il ne faudra pas oublier le reste de la configuration postfix (relay_domains, transport, networks, etc) et ne pas oublier non plus de faire ce qu’il faut pour que le relai puisse attaquer le ZCS en LDAP…
La requête LDAP est honteusement pompée d’un thread sur le forum US Zimbra.

Laisser un commentaire

Modifier la règle de filtrage automatique du spam

Ca se passe dans l’interface d’admin, en allant dans « Global Settings » puis l’onglet « AS/AV » : il s’agit du paramètre « Tag ».

100% correspondent à 20.
Par défaut, il y a 33%, ce qui correspond à la valeur 6.6 pour « required » dans le champ « X-Spam-Status » des headers d’un mail.
Si ce paramètre est passé à 20%, tous les mails avec une note supérieure à 5 seront classés dans le dossier « Spams ».

Il faut relancer ZCS après avoir modifié la valeur et il ne faut pas trop la baisser pour limiter les « faux positifs ».

Laisser un commentaire

Reconfigurer sendmail pour Zimbra

Plutôt que désactiver sendmail avant l’installation de Zimbra, je préfère le reconfigurer.
Ainsi, tous les outils en ligne de commande (logwatch and co) ou les outils web (php) peuvent continuer à s’en servir.

Pour cela, il faut commencer par installer le package sendmail-cf :

up2date sendmail-cf

Puis on va dans /etc/mail et on fait nos modifications :

cd /etc/mail
nano sendmail.mc

Dans ce fichier, on cherche la ligne de définition du smarthost pour donner le MTA de Zimbra (postfix) en smarthost à sendmail (en fait, on décommente la ligne) :

define(`SMART_HOST',`localhost')

Et, un peu plus loin, on modifie le port (par défaut « smtp ») en 2525 :

DAEMON_OPTIONS(`Port=2525,Addr=127.0.0.1, Name=MTA')dnl

Une fois que tout ça est fait et le fichier enregistré, il suffit de recompiler le sendmail.mc en sendmail.cf puis de redémarrer sendmail :

make 
service sendmail restart

Et voila (bien entendu, ce sont des instructions pour RHEL ou CentOS, à adapter à votre OS).

Merci à Carlos pour l’idée et l’article du wiki

Laisser un commentaire

SMTP callout et Zimbra

Si vous avez un MTA filtrant « avant » votre Zimbra (Barracuda, Mailcleaner, etc) et que ce MTA est capable d’utiliser du SMTP callout, il est assez simple de rejeter les destinataires inexistants à son niveau…

Bien entendu, cette configuration fonctionne également si vous n’avez pas de filtre « avant » le ZCS et que vous voulez filtrer directement au niveau du ZCS. Une fois configuré, votre serveur refusera dès la connexion SMTP les mails pour des destinataires inexistants : pas de temps/CPU/RAM perdu en antispam/antivirus pour rien, pas de queue incoming deferred qui augmente, etc…

En étant root sur votre serveur Zimbra, il suffit d’éditer /opt/zimbra/conf/zmmta.cf et de modifier une ligne (passage de no à yes) :

POSTCONF smtpd_reject_unlisted_recipient yes
Attention, il faut refaire la modification après chaque upgrade de Zimbra.

Si votre MTA filtrant (ou simple relai) ne gère pas le SMTP callout (c’est le cas de postfix), vous pouvez certainement faire la même chose via une requête LDAP (en tout cas postfix peut le faire)…

Laisser un commentaire