Table des matières

Questions de sécurité

Reste encore à traiter quelques points de détail.

  1. Web-cyradm pose des drapeaux dans la base de données. Nous n'avons pas tenu compte de ces indicateurs qui devraient permettre d'autoriser ou non tel ou tel utilisateur :
    • à recevoir des messages ;
    • à en envoyer ;
    • à accéder à sa boite aux lettres ;
    • à utiliser le langage Sieve ;
  2. L'utilisateur cyrus a tous les droits sur tous les comptes de messagerie. Peut-on limiter cet utilisateur à ne pouvoir se connecter que localement ?
  3. Le fait d'utiliser saslauthd avec PAM implique que les authentifications passent en clair sur le réseau. Le moyen simple de contourner ce problème est d'employer systématiquement TLS, aussi bien pour les connexions IMAP/POP3 que pour les connexions SMTP de la part de nos utilisateurs.
  4. Il faut combattre autant que l'on peut les virus et les spams. Nous avons déjà vu comment le faire, mais n'avons pas encore implémenté la solution ici.
  5. web-cyradm, c'est bien, mais il faut ajouter plusieurs choses sur notre serveur, qui peuvent apporter des risques :
    • apache ;
    • php ;
    • le code php de web-cyradm.

Contrôler finement les accès

Si nous prenons le temps de bien regarder l'interface de web-cyradm, et aussi la structure des tables MySQL associée, nous constatons qu'il existe par compte créé quatre « flags » qui sont :

Nous n'avons pas vraiment tenu compte de ces « flags ». Pour imap, pop, sieve et smtpauth, il s'agit d'autoriser ou non l'authentification, donc il faut agir sur saslauthd, donc sur PAM, donc sur les fichiers correspondants dans /etc/pam.d/.

Le jour où vous trouverez une documentation sur les syntaxes possibles dans les fichiers de configuration de PAM avec MySQL, vous pourrez vérifier que l'on peut faire ceci :

Pour imap

Nous modifions le fichier /etc/pam.d/imap comme ceci : (déroulez bin les lignes jusqu'au bout) :

auth sufficient pam_mysql.so user=mail passwd=epikoi host=localhost db=mail table=accountuser usercolumn=username passwdcolumn=password where=accountuser.imap=1 crypt=1
account required pam_mysql.so user=mail passwd=epikoi host=localhost db=mail table=accountuser usercolumn=username passwdcolumn=password where=accountuser.imap=1 crypt=1

Pour pop

Même méthode, mais avec le « flag » pop. Le fichier /etc/pam.d/pop doit ressembler à ceci :

auth sufficient pam_mysql.so user=mail passwd=epikoi host=localhost db=mail table=accountuser usercolumn=username passwdcolumn=password where=accountuser.pop=1 crypt=1
account required pam_mysql.so user=mail passwd=epikoi host=localhost db=mail table=accountuser usercolumn=username passwdcolumn=password where=accountuser.pop=1 crypt=1

Pour sieve

Le fichier /etc/pam.d/sieve :

auth sufficient pam_mysql.so user=mail passwd=epikoi host=localhost db=mail table=accountuser usercolumn=username passwdcolumn=password where=accountuser.sieve=1 crypt=1
account required pam_mysql.so user=mail passwd=epikoi host=localhost db=mail table=accountuser usercolumn=username passwdcolumn=password where=accountuser.sieve=1 crypt=1

Pour Submission

Et enfin le fichier /etc/pam.d/smtp :

auth sufficient pam_mysql.so user=mail passwd=epikoi host=localhost db=mail table=accountuser usercolumn=username passwdcolumn=password where=accountuser.smtpauth=1 crypt=1
account required pam_mysql.so user=mail passwd=epikoi host=localhost db=mail table=accountuser usercolumn=username passwdcolumn=password where=accountuser.smtpauth=1 crypt=1

Pour les destinataires

Ici, ce n'est pas PAM qui va intervenir, mais le fichier /etc/postfix/db/virtual-alias.cf, avec son flag status. Ceci est déjà pris en compte puisque nous avons la requête :

query = SELECT dest FROM virtual WHERE alias = '%s' AND status ='1'

Restreindre l'utilisateur cyrus

Dans notre configuration actuelle, l'utilisateur cyrus peut se connecter à distance et utiliser par exemple l'outil cyradm sur le serveur distant, ce qui présente un danger potentiel.

Il est cependant possible d'utiliser plusieurs fichiers de configuration différents, suivant certains cas. Pour réaliser ceci, il faut se plonger un peu plus profondément dans le cyrus.conf :

SERVICES {
	# --- Normal cyrus spool, or Murder backends ---
	# add or remove based on preferences
	imap		cmd="imapd -U 30" listen="imap" prefork=0 maxchild=100
	#imaps		cmd="imapd -s -U 30" listen="imaps" prefork=0 maxchild=100
	pop3		cmd="pop3d -U 30" listen="pop3" prefork=0 maxchild=50
	#pop3s		cmd="pop3d -s -U 30" listen="pop3s" prefork=0 maxchild=50
	#nntp		cmd="nntpd -U 30" listen="nntp" prefork=0 maxchild=100
	#nntps		cmd="nntpd -s -U 30" listen="nntps" prefork=0 maxchild=100

La ligne pointée dit en français que :

La documentation est assez parcimonieuse, mais le manuel de cyrus.conf indique qu'il est possible :

Ainsi, si l'on modifie cyrus.conf comme suit :

SERVICES {
	# --- Normal cyrus spool, or Murder backends ---
	# add or remove based on preferences
	imap		cmd="imapd -U 30" listen="192.168.10.7:imap" prefork=0 maxchild=100
        imaplocal       cmd="imapd -U 30 -C /etc/imapd-local.conf" listen="127.0.0.1:imap" prefork=0 maxchild=100
	#imaps		cmd="imapd -s -U 30" listen="imaps" prefork=0 maxchild=100
	pop3		cmd="pop3d -U 30" listen="pop3" prefork=0 maxchild=50
	#pop3s		cmd="pop3d -s -U 30" listen="pop3s" prefork=0 maxchild=50
	#nntp		cmd="nntpd -U 30" listen="nntp" prefork=0 maxchild=100
	#nntps		cmd="nntpd -s -U 30" listen="nntps" prefork=0 maxchild=100
Nous aurons :

  1. une instance de imapd (nommée imap), qui n'écoutera que sur l'interface connectée au réseau (adresse IP de l'interface) et qui utilisera le fichier de configuration par défaut(/etc/imapd.conf) ;
  2. une instance de imapd (nommée imaplocal), qui n'écoutera que sur l'interface locale (adresse IP 127.0.0.1) et qui utilisera le fichier de configuration explicite /etc/imapd-local.conf.

Nous allons donc copier notre imapd.conf dans imapd-local.conf, puis nous commenterons la ligne admins: cyrus dans imapd-conf. l'utilisateur cyrus pourra toujours se connecter à distance, mais n'aura plus les droits d'administration.

Utiliser TLS

Aussi bien Cyrus que Postfix supportent la commande STARTTLS, qui permet au client :

Ainsi le login, bien que transmis en clair, circulera à travers la connexion chiffrée.

Il est donc possible de forcer les utilisateurs à utiliser TLS au tout au moins le leur permettre. Les forcer, bien que plus totalitaire, est tout de même plus sûr pour tout le monde.

Nous allons faire ça à peu près bien, en créant des certificats signés par une autorité racine « de confiance » : la notre. TinyCA fera tout à fait l'affaire. Nous réalisons une CA pour le domaine nain-t, puis créons un certificat serveur pour cyrus.nain-t.net. Ensuite, nous exportons ce certificat sous le nom de cyrus.nain-t.net.cert et la clé privée associée, sans protection par mot de passe, sous le nom de cyrus.nain-t.net.key, ainsi que le certificat de l'autorité sous le nom de Root_nain-t.net-cacert.pem. Enfin, nous les plaçons à l'endroit habituel (/etc/ssl/certs pour le certificat et /etc/ssl/private pour la clé privée), en attribuant les bons droits :

cyrus:/etc/ssl/certs# chmod 644 cyrus.nain-t.net.cert Root_nain-t.net-cacert.pem       
cyrus:/etc/ssl/private# chown root:ssl-cert cyrus.nain-t.net.key 
cyrus:/etc/ssl/private# chmod 640 cyrus.nain-t.net.key 

Pour Postfix

Dans notre main.cf, nous avons déjà la ligne :

smtpd_use_tls=yes

Qui fait que TLS est possible. Des certificats de tests sont même déjà disponibles (snakeoil). Pour utiliser les nôtres, remplaçons les lignes :

smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key

Par celles-ci :

smtpd_tls_cert_file=/etc/ssl/certs/cyrus.nain-t.net.cert
smtpd_tls_key_file=/etc/ssl/private/cyrus.nain-t.net.key
smtpd_tls_CAfile=/etc/ssl/certs/Root_nain-t.net-cacert.pem

Si nous voulons obliger les clients sur le port submission à utiliser TLS, il nous faut modifier master.cf comme suit :

submission inet n       -       -       -       -       smtpd
  -o smtpd_enforce_tls=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject

Pour Cyrus-imapd

Nous allons d'abord ajouter ces lignes dans /etc/imapd.conf :

tls_cert_file: /etc/ssl/certs/cyrus.nain-t.net.cert
tls_key_file: /etc/ssl/private/cyrus.nain-t.net.key
tls_ca_file: /etc/ssl/certs/Root_nain-t.net-cacert.pem
tls_ca_path: /etc/ssl/certs
tls_session_timeout: 1440
tls_cipher_list: TLSv1+HIGH:!aNULL:@STRENGTH

En suite, nous allons vérifier que cyrus peut bien lire les certificats et la clé.

Habituellement, tout le monde peut lire les certificats (644), mais en ce qui concerne les clés, il n'y a que root et les membres du groupe ssl-cert qui le peuvent. Nous avons respecté cette règle lorsque nous avons ajouté nos certificats et notre clé. DOnc il nous faut mettre cyrus dans le groupe ssl-cert.

A quel(s) groupe(s) cyrus appartient-il ?

# groups cyrus
cyrus : mail sasl

Il faut bien ajouter cyrus à ssl-cert :

usermod -a -G ssl-cert cyrus

Nous relançons cyrus et TLS devrait fonctionner.

Pour empêcher que les utilisateurs puissent ouvrir de session sans utiliser TLS, il faut dans imapd.conf mettre :

allowplaintext: no

A la place de allowplaintext: yes

Ceci aura pour effet de rendre impossible le login sans chiffrement de la connexion.

Il est également possible de n'ouvrir que imaps pour l'extérieur, en conservant imaplocal, nécessaire pour l'administration de cyrus.

Amavis

il suffit de reprendre ce qui a été vu dans le chapitre Postfix + Dovecot :

Interface web

Web-cyradm va nous servir à gérer les comptes. S'il n'y avait que ça, un jeu de scripts bien sentis ferait sans doute tout aussi bien l'affaire, mais nous désirons fournir à nos utilisateurs deux fonctionnalités intéressantes :

Alors, Apache et php se justifient, mais il n'y a rien de bien sécurisé là dedans. Peut-être faire tourner web-cyradm dans un virtualhost dont l'accès serait contrôlé, et utiliser https en plus ?

limites du système

Si nous avons toutes les informations nécessaires présentes dans la base mail, cyrus utilise sa propre base pour la gestion des boîtes aux lettres. Suivant les manipulations, il peut se faire que bes BALs qui ont été supprimées dans la base MySQL soient restées dans Cyrus. Ce n'est pas très grave, puisque vis-à-vis de Postfix, ces boîtes n'existant plus, leur destination sera refusée (si l'on a bien supprimé la ligne local_recipient_maps = dans main.cf) et ne recevront plus de messages. De même, elles ne seront plus accessibles ni en imap ni en pop, sasl s'appuyant sur MySQL.

Pour rester propre, il faudra tout de même vérifier de temps en temps que la synchronisation des comptes est correcte.