Table des matières

Installation d'un serveur mail multi-domaine

Installer Postfix, Courier et Saslauthd

Installer Postfix, Courier et Saslauthd se fait simplement avec cette commande :

# apt-get install postfix postfix-mysql postfix-doc courier-authdaemon courier-authlib-mysql courier-pop courier-pop-ssl courier-imap courier-imap-ssl libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql openssl --purge

Patch Postfix pour la gestion des quotas

Il faut patcher les sources de postfix de votre distribution. Récupérer sur ce site le patch spécifique à votre version de postfix : Postfix VDA

Voici la procédure pour patcher votre postfix.

cd /usr/src
apt-get source postfix
wget http://vda.sourceforge.net/VDA/postfix-2.5.5-vda-ng.patch.gz
gunzip postfix-2.5.5-vda-ng.patch.gz
cd postfix-2.5.5
patch -p1 < ../postfix-2.5.5-vda-ng.patch
dpkg-buildpackage
cd ..
dpkg -i postfix_2.5.5-1.1_amd64.deb
dpkg -i postfix-mysql_2.5.5-1.1_amd64.deb

Il faut que vous protégiez votre postfix des mises à jours.

Modifier le fichier /etc/apt/preferences et ajouter les lignes suivantes :

Package: postfix
Pin: version 2.5.5
Pin-Priority: 1001

Package: postfix-mysql
Pin: version 2.5.5
Pin-Priority: 1001

Package: postfix-dev
Pin: version 2.5.5
Pin-Priority: 1001

Ensuite lancer les commandes de mises à jours :

# apt-get update
# apt-get upgrade

Vous verrez que postfix n'est pas mis à jour :

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages have been kept back:
  postfix postfix-mysql
0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.

Création des tables MySQL pour Postfix/Courier

CREATE TABLE postfix_domains (
domain varchar(50) NOT NULL,
PRIMARY KEY (domain) )
TYPE=MyISAM;

CREATE TABLE postfix_forwardings (
source varchar(80) NOT NULL,
destination TEXT NOT NULL,
PRIMARY KEY (source) )
TYPE=MyISAM;

CREATE TABLE postfix_users (
email varchar(80) NOT NULL,
password varchar(20) NOT NULL,
quota INT(10) DEFAULT '10485760',
PRIMARY KEY (email)
) TYPE=MyISAM;

CREATE TABLE postfix_transport (
domain varchar(128) NOT NULL default '',
transport varchar(128) NOT NULL default '',
UNIQUE KEY domain (domain)
) TYPE=MyISAM;

Configuration de Postfix

Maintenant nous devons dire à Postfix où il peut trouver toutes les informations. Nous allons donc créer six fichiers.

N'oubliez pas de modifier mail_admin, mail_admin_password, mail, et hosts selon votre serveur MySQL.

/etc/postfix/mysql/virtual_domains.cf

user = mail_admin
password = mail_admin_password
dbname = mail
table = postfix_domains
select_field = 'virtual'
where_field = domain
hosts = 127.0.0.1

/etc/postfix/mysql/virtual_forwardings.cf

user = mail_admin
password = mail_admin_password
dbname = mail
table = postfix_forwardings
select_field = destination
where_field = source
hosts = 127.0.0.1

/etc/postfix/mysql/virtual_mailboxes.cf

user = mail_admin
password = mail_admin_password
dbname = mail
table = postfix_users
select_field = CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/')
where_field = email
hosts = 127.0.0.1

/etc/postfix/mysql/virtual_email2email.cf

user = mail_admin
password = mail_admin_password
dbname = mail
table = postfix_users
select_field = email
where_field = email
hosts = 127.0.0.1

/etc/postfix/mysql/virtual_transports.cf

user = mail_admin
password = mail_admin_password
dbname = mail
table = postfix_transport
select_field = transport
where_field = domain
hosts = 127.0.0.1

/etc/postfix/mysql/virtual_mailbox_limit_maps.cf

user = mail_admin
password = mail_admin_password
dbname = mail
table = postfix_users
select_field = quota
where_field = email
hosts = 127.0.0.1

Exécutez les commandes suivantes :

chmod o= /etc/postfix/mysql/virtual_*.cf
chgrp postfix /etc/postfix/mysql/virtual_*.cf

Nous allons créer maintenant un utilisateur et groupe appelé vmail avec comme répertoire /var/mail/vmail. C'est là que toutes les boites mails seront stockées.

groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/mail/vmail -m

Puis nous allons configurer postfix :

postconf -e 'myhostname = server1.example.com'
postconf -e 'mydestination = server1.example.com, localhost, localhost.localdomain'
postconf -e 'mynetworks = 127.0.0.0/8'
postconf -e 'virtual_alias_domains ='
postconf -e 'virtual_alias_maps = proxy:mysql:/etc/postfix/mysql/virtual_forwardings.cf, mysql:/etc/postfix/mysql/virtual_email2email.cf'
postconf -e 'virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql/virtual_domains.cf'
postconf -e 'virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql/virtual_mailboxes.cf'
postconf -e 'virtual_mailbox_base = /var/mail/vmail'
postconf -e 'virtual_uid_maps = static:5000'
postconf -e 'virtual_gid_maps = static:5000'
postconf -e 'smtpd_sasl_auth_enable = yes'
postconf -e 'broken_sasl_auth_clients = yes'
postconf -e 'smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination'
postconf -e 'smtpd_use_tls = yes'
postconf -e 'smtpd_tls_cert_file = /etc/postfix/smtpd.cert'
postconf -e 'smtpd_tls_key_file = /etc/postfix/smtpd.key'
postconf -e 'transport_maps = proxy:mysql:/etc/postfix/mysql/virtual_transports.cf'
postconf -e 'virtual_create_maildirsize = yes'
postconf -e 'virtual_mailbox_extended = yes'
postconf -e 'virtual_maildir_extended = yes'
postconf -e 'virtual_mailbox_limit_maps = proxy:mysql:/etc/postfix/mysql/virtual_mailbox_limit_maps.cf'
postconf -e 'virtual_mailbox_limit_override = yes'
postconf -e 'virtual_maildir_limit_message = "The user you are trying to reach is over quota."'
postconf -e 'virtual_overquota_bounce = yes'
postconf -e 'virtual_trash_count = yes'
postconf -e 'virtual_trash_name = ".Trash"'
postconf -e 'proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps'

Il faut aussi créer les certificats de sécurité :

cd /etc/postfix/
openssl req -new -outform PEM -out smtpd.cert \
   -newkey rsa:2048 -nodes -keyout smtpd.key -keyform PEM \
   -days 365 -x509

Activation du service SMTP Sécurisé, décommenter les lignes suivantes dans /etc/postfix/master.cf :

smtps     inet  n       -       -       -       -       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

Configuration pour éviter le SPAM, dans le fichier /etc/postfix/main.cf, modifier comme suit :

smtpd_recipient_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_unauth_destination,
  reject_invalid_hostname,
  reject_non_fqdn_sender,
  reject_unknown_sender_domain,
  reject_non_fqdn_recipient,
  reject_unknown_recipient_domain,
  reject_sender_login_mismatch,
  reject_authenticated_sender_login_mismatch,
  reject_rbl_client sbl-xbl.spamhaus.org,
  reject_rbl_client zen.spamhaus.org,
  reject_rbl_client bl.spamcop.net,
  permit

Rien que ces quelques lignes vous débarrasse du spam, reject_rbl_client sert à rejeter une connexion si l'adresse IP est blacklisté dans des listes spécialisés. Ajout d'une modification anti-usurpation d'identité

Rajouter ces lignes dans /etc/postfix/main.cf :

smtpd_sender_login_maps = mysql:/etc/postfix/mysql/virtual_forwardings.cf

smtpd_sender_restrictions = 
   reject_unknown_sender_domain,
   reject_non_fqdn_sender,
   reject_unknown_sender_domain,
   reject_sender_login_mismatch,
   reject_authenticated_sender_login_mismatch,
   reject_rbl_client sbl-xbl.spamhaus.org,
   reject_rbl_client zen.spamhaus.org,
   reject_rbl_client bl.spamcop.net

Les lignes qui nous intéressent ici sont reject_sender_login_mismatch et reject_authenticated_sender_login_mismatch. La première permet de vérifier que l'utilisateur authentifié posséde bien l'adresse email par laquelle il envoit, la seconde permet de dire à Postfix que la vérification ne se fera qu'aux utilisateurs authentifié, dans le cas contraire, le mail et l'utilisateur seront rejetés du serveur.

Il faut ensuite ajouter une entrée dans la table forwarding pour chaque compte mail, par exemple le compte est contact@domaine.fr Il faut donc insérer dans la table forwarding comme source et destination contact@domaine.fr

Si vous seul avez accès à ce domaine et voulez ajouter plusieurs autres comptes, au lieu de mettre dans source l'adresse du compte, mettre @domaine.fr puis dans destination votre adresse principale du compte. Cela vous évitera d'insérer une nouvelle entrée pour chaque compte.

Configuration de Saslauthd

# mkdir -p /var/spool/postfix/var/run/saslauthd

Éditez /etc/default/saslauthd. Remplacez START=no en START=yes et modifiez le paramètre OPTION. Faites bien attention à modifier aussi la dernière ligne Le fichier devrait ressembler à ceci :

#
# Settings for saslauthd daemon
# Please read /usr/share/doc/sasl2-bin/README.Debian for details.
#

# Should saslauthd run automatically on startup? (default: no)
START=yes

# Description of this saslauthd instance. Recommended.
# (suggestion: SASL Authentication Daemon)
DESC="SASL Authentication Daemon"

# Short name of this saslauthd instance. Strongly recommended.
# (suggestion: saslauthd)
NAME="saslauthd"

# Which authentication mechanisms should saslauthd use? (default: pam)
#
# Available options in this Debian package:
# getpwent  -- use the getpwent() library function
# kerberos5 -- use Kerberos 5
# pam       -- use PAM
# rimap     -- use a remote IMAP server
# shadow    -- use the local shadow password file
# sasldb    -- use the local sasldb database file
# ldap      -- use LDAP (configuration is in /etc/saslauthd.conf)
#
# Only one option may be used at a time. See the saslauthd man page
# for more information.
#
# Example: MECHANISMS="pam"
MECHANISMS="pam"

# Additional options for this mechanism. (default: none)
# See the saslauthd man page for information about mech-specific options.
MECH_OPTIONS=""

# How many saslauthd processes should we run? (default: 5)
# A value of 0 will fork a new process for each connection.
THREADS=5

# Other options (default: -c -m /var/run/saslauthd)
# Note: You MUST specify the -m option or saslauthd won't run!
#
# WARNING: DO NOT SPECIFY THE -d OPTION.
# The -d option will cause saslauthd to run in the foreground instead of as
# a daemon. This will PREVENT YOUR SYSTEM FROM BOOTING PROPERLY. If you wish
# to run saslauthd in debug mode, please run it by hand to be safe.
#
# See /usr/share/doc/sasl2-bin/README.Debian for Debian-specific information.
# See the saslauthd man page and the output of 'saslauthd -h' for general
# information about these options.
#
# Example for postfix users: "-c -m /var/spool/postfix/var/run/saslauthd"
OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r"

Créez ensuite le fichier /etc/pam.d/smtp. Il ne doit contenir seulement ces deux lignes (changez les différents paramètre):

auth required pam_mysql.so user=mail_admin passwd=mail_admin_password host=127.0.0.1 db=mail table=postfix_users usercolumn=email passwdcolumn=password crypt=1
account sufficient pam_mysql.so user=mail_admin passwd=mail_admin_password host=127.0.0.1 db=mail table=postfix_users column=email passwdcolumn=password crypt=1

Ensuite, créez le fichier /etc/postfix/sasl/smtpd.conf comme suit :

pwcheck_method: saslauthd
mech_list: plain login
allow_plaintext: true
auxprop_plugin: mysql
sql_hostnames: 127.0.0.1
sql_user: mail_admin
sql_passwd: mail_admin_password
sql_database: mail
sql_select: select password from postfix_users where email = '%u'

Redémarrez Postfix et Saslauthd:

# /etc/init.d/postfix restart
postfix check
# /etc/init.d/saslauthd restart

Correction d'un bug de permission

# dpkg-statoverride --add root sasl 710 /var/spool/postfix/var/run/saslauthd
adduser postfix sasl
# /etc/init.d/saslauthd restart

Configuration de Courier

Nous allons maintenant configurer Courier pour utiliser notre base de données. Editez /etc/courier/authdaemonrc et changez la valeur de authmodulelist comme suit :

authmodulelist="authmysql"

Ensuite éditez /etc/courier/authmysqlrc. Il devrait ressembler à ceci :

MYSQL_SERVER localhost
MYSQL_USERNAME mail_admin
MYSQL_PASSWORD mail_admin_password
MYSQL_PORT 0
MYSQL_DATABASE mail
MYSQL_USER_TABLE postfix_users
MYSQL_CRYPT_PWFIELD password
#MYSQL_CLEAR_PWFIELD password
MYSQL_UID_FIELD 5000
MYSQL_GID_FIELD 5000
MYSQL_LOGIN_FIELD email
MYSQL_HOME_FIELD "/var/mail/vmail"
MYSQL_MAILDIR_FIELD CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/')
#MYSQL_NAME_FIELD
MYSQL_QUOTA_FIELD concat(quota,'S')

Continuons avec les modifications à apporter à chaque service (POP3, IMAP) :

Service POP3, fichiers /etc/courier/pop3d et /etc/courier/pop3d-ssl, modifier la (dernière) ligne :

MAILDIRPATH=.

Vérifier par la même occasion que POP3DSTART est bien à YES :

POP3DSTART=YES

Faire de même pour le service IMAP, fichiers /etc/courier/imapd et /etc/courier/imapd-ssl :

IMAPDSTART=YES
MAILDIRPATH=.

Redémarrez Courier:

# /etc/init.d/courier-authdaemon restart
# /etc/init.d/courier-imap restart
# /etc/init.d/courier-imap-ssl restart
# /etc/init.d/courier-pop restart
# /etc/init.d/courier-pop-ssl restart

Installation de POP-Before-SMTP

Installer

L'installation est relativement simple. Comme toute installation sur système Debian on passe par la commande apt-get

# apt-get install pop-before-smtp 

Configurer

La configuration se fait en 2 étapes :

Mettre à jour le fichier de configuration

# vi /etc/pop-before-smtp/pop-before-smtp.conf 
# A 30-minute grace period before the IP address is expired.
$grace = 10*60;

Remplacer :

# For Courier-POP3 and Courier-IMAP:
#$pat = '^[LOGTIME] (?:\[|\S+ )(?:pop3|imap|couriertcp)(?:d|d-ssl|login)\]?: ' .
#    'LOGIN, user=\S+, ip=\[[:f]*(\d+\.\d+\.\d+\.\d+)\]';
#$out_pat = '^[LOGTIME] (?:\[|\S+ )(?:pop3|imap|couriertcp)(?:d|d-ssl|login)\]?: ' .
#    '(?:LOGOUT|DISCONNECTED), user=\S+, ip=\[[:f]*(\d+\.\d+\.\d+\.\d+)\]';

Par :

# For Courier-POP3 and Courier-IMAP:
$pat = '^(... .. ..:..:..) \S+ (?:courier)?(?:pop3|imap)(?:login|d|d-ssl): ' .
    'LOGIN, user=\S+, ip=\[[:f]*(\d+\.\d+\.\d+\.\d+)\]';
# /etc/init.d/pop-before-smtp restart 

Configurer Postfix

 # vi /etc/postfix/main.cf 
mynetworks = 127.0.0.1 hash:/var/lib/pop-before-smtp/hosts 
 # /etc/init.d/postfix restart 

ClamAv / SpamAssassin

Installation du connecteur Amavis

Installation

# apt-get install amavisd-new

Paramétrage de Postfix

Ajout des lignes :

# Amavid-new adding
strict_rfc821_envelopes = yes
# for tests purpose, soft_bounce must be disabled after
soft_bounce = yes
content_filter=amavisfeed:[127.0.0.1]:10024

Ajout des lignes :

# amavisd-new dedicated lmtp client
amavisfeed unix    -       -       n        -      2     lmtp
    -o lmtp_data_done_timeout=1200
    -o lmtp_send_xforward_command=yes
    -o disable_dns_lookups=yes
    -o max_use=20

# amavisd-new reinjection
127.0.0.1:10025 inet n    -       n       -       -     smtpd
    -o content_filter=
    -o smtpd_delay_reject=no
    -o smtpd_client_restrictions=permit_mynetworks,reject
    -o smtpd_helo_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o smtpd_data_restrictions=reject_unauth_pipelining
    -o smtpd_end_of_data_restrictions=
    -o smtpd_restriction_classes=
    -o mynetworks=127.0.0.0/8
    -o smtpd_error_sleep_time=0
    -o smtpd_soft_error_limit=1001
    -o smtpd_hard_error_limit=1000
    -o smtpd_client_connection_count_limit=0
    -o smtpd_client_connection_rate_limit=0
    -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters
    -o local_header_rewrite_clients=

Configuration Amavis

Fichier **/etc/amavis/conf.d/05-node_id**

Modifier la ligne :

#$myhostname = "mail.example.com"
$myhostname = "kereska.dragon.druidesmetal.org";

Fichier **/etc/amavis/conf.d/20-debian_defaults**

Pour mettre la Quarantaine en Base de Données

Ajouter les lignes suivantes :

@storage_sql_dsn = ( ['DBI:mysql:database=AMAVIS;host=127.0.0.1;port=3306', 'amavis', 'amavis']);

$interface_policy{'9998'} = 'AM.PDP';

$policy_bank{'AM.PDP'} = {
    protocol => 'AM.PDP',
    inet_acl => [qw( 127.0.0.1 [::1] 192.168.1.26 )],
};

$inet_socket_port = [10024,9998];   # default listening socket
$inet_socket_bind = undef;

@mynetworks = qw( 127.0.0.1 192.168.1.0/24 );
@inet_acl = qw( 127.0.0.1 192.168.1.0/24 );

$notify_method  = 'smtp:[127.0.0.1]:10025';
$forward_method = 'smtp:[127.0.0.1]:10025';

$banned_files_quarantine_method = 'sql:';
$spam_quarantine_method         = 'sql:

Créer la base et ajoutez le user :

CREATE DATABASE AMAVIS;
GRANT ALL PRIVILEGES ON AMAVIS.* TO amavis@'localhost IDENTIFED BY 'amavis';

Puis insérer ceci pour la création des tables :

$sql_allow_8bit_address = 1; # maddr.email: VARCHAR (0), VARBINARY/BYTEA (1)

CREATE TABLE users (
  id         int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,  -- unique id
  priority   integer      NOT NULL DEFAULT '7',  -- sort field, 0 is low prior.
  policy_id  integer unsigned NOT NULL DEFAULT '1',  -- JOINs with policy.id
  email      varbinary(255) NOT NULL UNIQUE,
  fullname   varchar(255) DEFAULT NULL,    -- not used by amavisd-new
  local      char(1)      -- Y/N  (optional field, see note further down)
);

CREATE TABLE mailaddr (
  id         int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
  priority   integer      NOT NULL DEFAULT '7',  -- 0 is low priority
  email      varbinary(255) NOT NULL UNIQUE
);

CREATE TABLE wblist (
  rid        integer unsigned NOT NULL,  -- recipient: users.id
  sid        integer unsigned NOT NULL,  -- sender: mailaddr.id
  wb         varchar(10)  NOT NULL,  -- W or Y / B or N / space=neutral / score
  PRIMARY KEY (rid,sid)
);

CREATE TABLE policy (
  id  int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
                                    -- 'id' this is the _only_ required field
  policy_name      varchar(32),     -- not used by amavisd-new, a comment

  virus_lover          char(1) default NULL,     -- Y/N
  spam_lover           char(1) default NULL,     -- Y/N
  banned_files_lover   char(1) default NULL,     -- Y/N
  bad_header_lover     char(1) default NULL,     -- Y/N

  bypass_virus_checks  char(1) default NULL,     -- Y/N
  bypass_spam_checks   char(1) default NULL,     -- Y/N
  bypass_banned_checks char(1) default NULL,     -- Y/N
  bypass_header_checks char(1) default NULL,     -- Y/N

  spam_modifies_subj   char(1) default NULL,     -- Y/N

  virus_quarantine_to      varchar(64) default NULL,
  spam_quarantine_to       varchar(64) default NULL,
  banned_quarantine_to     varchar(64) default NULL,
  bad_header_quarantine_to varchar(64) default NULL,
  clean_quarantine_to      varchar(64) default NULL,
  other_quarantine_to      varchar(64) default NULL,  

  spam_tag_level  float default NULL, -- higher score inserts spam info headers
  spam_tag2_level float default NULL, -- inserts 'declared spam' header fields
  spam_kill_level float default NULL, -- higher score triggers evasive actions
                                      -- e.g. reject/drop, quarantine, ...
                                     -- (subject to final_spam_destiny setting)
  spam_dsn_cutoff_level        float default NULL,
  spam_quarantine_cutoff_level float default NULL,

  addr_extension_virus      varchar(64) default NULL,
  addr_extension_spam       varchar(64) default NULL,
  addr_extension_banned     varchar(64) default NULL,
  addr_extension_bad_header varchar(64) default NULL,

  warnvirusrecip      char(1)     default NULL, -- Y/N
  warnbannedrecip     char(1)     default NULL, -- Y/N
  warnbadhrecip       char(1)     default NULL, -- Y/N
  newvirus_admin      varchar(64) default NULL,
  virus_admin         varchar(64) default NULL,
  banned_admin        varchar(64) default NULL,
  bad_header_admin    varchar(64) default NULL,
  spam_admin          varchar(64) default NULL,
  spam_subject_tag    varchar(64) default NULL,
  spam_subject_tag2   varchar(64) default NULL,
  message_size_limit  integer     default NULL, -- max size in bytes, 0 disable
  banned_rulenames    varchar(64) default NULL  -- comma-separated list of ...
        -- names mapped through %banned_rules to actual banned_filename tables
);

CREATE TABLE maddr (
  partition_tag integer   DEFAULT 0,   -- see $sql_partition_tag
  id         bigint unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
  email      varbinary(255) NOT NULL,  -- full mail address
  domain     varchar(255)   NOT NULL,  -- only domain part of the email address
                                       -- with subdomain fields in reverse
  CONSTRAINT part_email UNIQUE (partition_tag,email)
) ENGINE=InnoDB;

CREATE TABLE msgs (
  partition_tag integer    DEFAULT 0,   -- see $sql_partition_tag
  mail_id    varbinary(12) NOT NULL PRIMARY KEY,  -- long-term unique mail id
  secret_id  varbinary(12)   DEFAULT '',  -- authorizes release of mail_id
  am_id      varchar(20)   NOT NULL,    -- id used in the log
  time_num   integer unsigned NOT NULL, -- rx_time: seconds since Unix epoch
  time_iso   char(16)      NOT NULL,    -- rx_time: ISO8601 UTC ascii time
  sid        bigint unsigned NOT NULL, -- sender: maddr.id
  policy     varchar(255)  DEFAULT '',  -- policy bank path (like macro %p)
  client_addr varchar(255) DEFAULT '',  -- SMTP client IP address (IPv4 or v6)
  size       integer unsigned NOT NULL, -- message size in bytes
  content    binary(1),                 -- content type: V/B/S/s/M/H/O/C:
     -- virus/banned/spam(kill)/spammy(tag2)/bad-mime/bad-header/oversized/clean
    -- is NULL on partially processed mail
    -- use binary instead of char for case sensitivity ('S' != 's')
  quar_type  binary(1),                 -- quarantined as: ' '/F/Z/B/Q/M/L
                                        --  none/file/zipfile/bsmtp/sql/
                                        --  /mailbox(smtp)/mailbox(lmtp)
  quar_loc   varbinary(255) DEFAULT '', -- quarantine location (e.g. file) 
  dsn_sent   char(1),                   -- was DSN sent? Y/N/q (q=quenched)
  spam_level float,                     -- SA spam level (no boosts)
  message_id varchar(255)  DEFAULT '',  -- mail Message-ID header field
  from_addr  varchar(255)  DEFAULT '',  -- mail From header field,    UTF8
  subject    varchar(255)  DEFAULT '',  -- mail Subject header field, UTF8
  host       varchar(255)  NOT NULL,    -- hostname where amavisd is running
  FOREIGN KEY (sid) REFERENCES maddr(id) ON DELETE RESTRICT
) ENGINE=InnoDB;
CREATE INDEX msgs_idx_sid      ON msgs (sid);
CREATE INDEX msgs_idx_mess_id  ON msgs (message_id); -- useful with pen pals
CREATE INDEX msgs_idx_time_num ON msgs (time_num);

CREATE TABLE msgrcpt (
  partition_tag integer    DEFAULT 0,    -- see $sql_partition_tag
  mail_id    varbinary(12) NOT NULL,     -- (must allow duplicates)
  rid        bigint unsigned NOT NULL,   -- recipient: maddr.id (dupl. allowed)
  ds         char(1)       NOT NULL,     -- delivery status: P/R/B/D/T
                                         -- pass/reject/bounce/discard/tempfail
  rs         char(1)       NOT NULL,     -- release status: initialized to ' '
  bl         char(1)       DEFAULT ' ',  -- sender blacklisted by this recip
  wl         char(1)       DEFAULT ' ',  -- sender whitelisted by this recip
  bspam_level float,                     -- spam level + per-recip boost
  smtp_resp  varchar(255)  DEFAULT '',   -- SMTP response given to MTA
  FOREIGN KEY (rid)     REFERENCES maddr(id)     ON DELETE RESTRICT,
  FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE INDEX msgrcpt_idx_mail_id  ON msgrcpt (mail_id);

CREATE INDEX msgrcpt_idx_rid      ON msgrcpt (rid);

CREATE TABLE quarantine (
  partition_tag integer    DEFAULT 0,    -- see $sql_partition_tag
  mail_id    varbinary(12) NOT NULL,     -- long-term unique mail id
  chunk_ind  integer unsigned NOT NULL,  -- chunk number, starting with 1
  mail_text  blob          NOT NULL,     -- store mail as chunks of octets
  PRIMARY KEY (mail_id,chunk_ind),
  FOREIGN KEY (mail_id) REFERENCES msgs(mail_id) ON DELETE CASCADE
) ENGINE=InnoDB;

INSERT INTO policy (id, policy_name,
  virus_lover, spam_lover, banned_files_lover, bad_header_lover,
  bypass_virus_checks, bypass_spam_checks,
  bypass_banned_checks, bypass_header_checks, spam_modifies_subj,
  spam_tag_level, spam_tag2_level, spam_kill_level) VALUES
  (1, 'Non-paying',    'N','N','N','N', 'Y','Y','Y','N', 'Y', 3.0,   7, 10),
  (2, 'Uncensored',    'Y','Y','Y','Y', 'N','N','N','N', 'N', 3.0, 999, 999),
  (3, 'Wants all spam','N','Y','N','N', 'N','N','N','N', 'Y', 3.0, 999, 999),
  (4, 'Wants viruses', 'Y','N','Y','Y', 'N','N','N','N', 'Y', 3.0, 6.9, 6.9),
  (5, 'Normal',        'N','N','N','N', 'N','N','N','N', 'Y', 3.0, 6.9, 6.9),
  (6, 'Trigger happy', 'N','N','N','N', 'N','N','N','N', 'Y', 3.0,   5, 5),
  (7, 'Permissive',    'N','N','N','Y', 'N','N','N','N', 'Y', 3.0,  10, 20),
  (8, '6.5/7.8',       'N','N','N','N', 'N','N','N','N', 'N', 3.0, 6.5, 7.8),
  (9, 'userB',         'N','N','N','Y', 'N','N','N','N', 'Y', 3.0, 6.3, 6.3),
  (10,'userC',         'N','N','N','N', 'N','N','N','N', 'N', 3.0, 6.0, 6.0),
  (11,'userD',         'Y','N','Y','Y', 'N','N','N','N', 'N', 3.0,   7, 7);

-- sender envelope addresses needed for white/blacklisting
INSERT INTO mailaddr VALUES (1, 5, '@example.com');
INSERT INTO mailaddr VALUES (2, 9, 'owner-postfix-users@postfix.org');
INSERT INTO mailaddr VALUES (3, 9, 'amavis-user-admin@lists.sourceforge.net');
INSERT INTO mailaddr VALUES (4, 9, 'makemoney@example.com');
INSERT INTO mailaddr VALUES (5, 5, '@example.net');
INSERT INTO mailaddr VALUES (6, 9, 'spamassassin-talk-admin@lists.sourceforge.net');
INSERT INTO mailaddr VALUES (7, 9, 'spambayes-bounces@python.org');

-- whitelist for user 14, i.e. default for recipients in domain sub1.example.net
INSERT INTO wblist VALUES (14, 1, 'W');
INSERT INTO wblist VALUES (14, 3, 'W');

-- whitelist and blacklist for user 17, i.e. u1@example.org
INSERT INTO wblist VALUES (17, 2, 'W');
INSERT INTO wblist VALUES (17, 3, 'W');
INSERT INTO wblist VALUES (17, 6, 'W');
INSERT INTO wblist VALUES (17, 7, 'W');
INSERT INTO wblist VALUES (17, 5, 'B');
INSERT INTO wblist VALUES (17, 4, 'B');
Envoi des notifications au postmaster

Ajouter les lignes suivantes :

$virus_admin = "postmaster\@druidesmetal.org"; # due to D_DISCARD default
$mailfrom_notify_admin = "postmaster\@druidesmetal.org";
$hdrfrom_notify_admin = "postmaster\@druidesmetal.org";
$hdrfrom_notify_sender = "postmaster\@druidesmetal.org";
Redémarrer Amavis
# /etc/init.d/amavis restart

Intégration d’un Antivirus : ClamAv

Installation des packages nécessaires

Afin d'avoir une version plus récente que celle de votre distribution de base, il faut ajouter la ligne suivante dans les sources APT :

# vi /etc/apt/sources.list
deb http://volatile.debian.org/debian-volatile etch/volatile main contrib non-free

Puis faite une mise à jour avec :

# apt-get update

Maintenant installez ClamAv :

# apt-get install clamav clamav-daemon clamav-freshclam gzip bzip2 unzip unrar zoo arj

Pour que tout ce passe correctement, il faut maintenant s’assurer que l’utilisateur utilisé par "clamav" fasse partie du groupe "amavis".

# adduser clamav amavis

Activation du support antivirus pour Amavis

# vi /etc/amavis/conf.d/15-content_filter_mode
@bypass_virus_checks_maps = ( 
    \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);

Configuration de Amavis

# vi /etc/amavis/conf.d/20-debian_defaults
$final_virus_destiny      = D_BOUNCE;

Redémarrage des services

# /etc/init.d/clamav-daemon restart 
# /etc/init.d/amavis restart

Intégration d’un AntiSpam : SpamAssassin

Installation de Spamassassin et des outils anti-spam

# apt-get install spamassassin libnet-dns-perl razor pyzor

Activation du démon spamd

# vi /etc/default/spamassassin
CRON=1

MAJ des règles Spamassassin

# sa-update

Configuration de Spamassassin

# vi /etc/spamassassin/local.cf
report_safe 0 
lock_method flock 
 
# Bayes-related operations 
use_bayes 1 
use_bayes_rules 1 
bayes_auto_learn 1 
bayes_auto_expire 1 
bayes_path /var/lib/amavis/.spamassassin/bayes 
 
# External network tests 
 
dns_available yes 
skip_rbl_checks 0 
use_razor2 1 
use_pyzor 1 
 
# Use URIBL (http://www.uribl.com/about.shtml) 
urirhssub       URIBL_BLACK  multi.uribl.com.        A   2 
body            URIBL_BLACK  eval:check_uridnsbl(’URIBL_BLACK’) 
describe        URIBL_BLACK  Contains an URL listed in the URIBL blacklist 
tflags          URIBL_BLACK  net 
score           URIBL_BLACK  3.0 
 
urirhssub       URIBL_GREY  multi.uribl.com.        A   4 
body            URIBL_GREY  eval:check_uridnsbl(’URIBL_GREY’) 
describe        URIBL_GREY  Contains an URL listed in the URIBL greylist 
tflags          URIBL_GREY  net 
score           URIBL_GREY  0.25 
 
# Use SURBL (http://www.surbl.org/) 
urirhssub       URIBL_JP_SURBL  multi.surbl.org.        A   64 
body            URIBL_JP_SURBL  eval:check_uridnsbl(’URIBL_JP_SURBL’) 
describe        URIBL_JP_SURBL  Has URI in JP at http://www.surbl.org/lists.html 
tflags          URIBL_JP_SURBL  net 
score           URIBL_JP_SURBL  3.0

Configuration de razor en utilisant l’utilisateur amavis

# su - amavis 
$ razor-admin -d --create 
$ razor-admin -register 
$ razor-admin -discover

Configuration de pyzor en utilisant l’utilisateur amavis

# su - amavis 
$ pyzor discover

Activation du support anti-spam pour amavis

# vi /etc/amavis/conf.d/15-content_filter_mode
@bypass_spam_checks_maps = ( 
    \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);

Il faut maintenant définir le comportement de Amavis lorsque Spamassassin a analysé le message. Comme indiqué précédemment, Spamassassin affecte un score au message. Amavis va maintenant comparé ce score au seuil défini par la variable FIXME. Si le score est supérieur à cette valeur, Amavis va appliquer les règles destinées aux messages indésirables. Le score affecté par Spamassassin n’étant jamais fiable à cent pour cent, il faire prendre beaucoup de précautions lors de la définition des règles d’Amavis.

Toute cette configuration ce fait dans le fichier /etc/amavis/conf.d/20-debian_defaults :

# vi /etc/amavis/conf.d/20-debian_defaults
$sa_spam_subject_tag    = ’***SPAM*** ’; 
$sa_tag_level_deflt  = -999; 
$sa_tag2_level_deflt = 5.00; # add 'spam detected' headers at that level
$sa_kill_level_deflt = 5.00; # triggers spam evasive actions
$final_banned_destiny     = D_BOUNCE; 
$final_spam_destiny       = D_BOUNCE; 
$final_bad_header_destiny = D_PASS;

Redémarrage des services

# /etc/init.d/amavis restart

Pour vérifier le bon fonctionnement de l’anti-SPAM, on peut par s’envoyer un mail (depuis l’extérieur) content la chaine de test suivante (GTUBE) :

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

Cette chaine de test est reconnue par la plupart des anti-SPAM et doit forcement être reconnue par SpamAssassin. Si le mail contenant cette chaine n’est pas identifiée comme SPAM, il faut revoir la configuration de Amavis et de SpamAssassin : elle n’est surement pas correcte.

Horde Groupware Webmail Edition

pré-requis

/usr/bin/apt-get install libapache2-mod-php5 php5-gd php5-mysql php5-mcrypt php5-imap php5-tidy php5-cli php-pear

Afin que Horde fonctionne sans soucis, nous augmentons la limite d'utilisation mémoire du module PHP d'Apache 2 :

/bin/sed -i -e 's/memory_limit = .*/memory_limit = 128M/' /etc/php5/apache2/php.ini

De plus, vous pouvez augmenter les performances de Horde en installant memcached :

apt-get install memcached php5-memcache

Nous mettons à jour l'installation de PEAR :

/usr/bin/pear channel-update pear.php.net
/usr/bin/pear upgrade-all

Nous installons maintenant les extensions PEAR et PECL recommandées par Horde. En premier lieu, nous installons les logiciels nécessaires à la compilation de l'extension :

/usr/bin/apt-get install libmagic-dev libgeoip-dev make php5-dev

Et nous compilons et installons les extensions PECL :

* fileinfo : Cette extension permet d'améliorer la gestion des pièces jointes.

/usr/bin/pecl install fileinfo
/bin/echo "extension=fileinfo.so" | /usr/bin/tee /etc/php5/conf.d/fileinfo.ini

* lzf : Cette extension permet de réduire la taille des sessions (et donc l'occupation mémoire du serveur).

/usr/bin/pecl install lzf
/bin/echo "extension=lzf.so" | /usr/bin/tee /etc/php5/conf.d/lzf.ini

* geoip : Cette extension améliore la géolocalisation des adresses IP. Cependant, du à des problèmes de version, elle n'est pas installable simplement sur Etch. Si vous utilisez ce guide sur Debian 5.0 Lenny, vous n'êtes pas soumis à cette limitation :

if [ "$(/bin/cat /etc/debian_version)" != "4.0" ]; then
 /usr/bin/pecl install geoip
 /bin/echo "extension=geoip.so" | /usr/bin/tee /etc/php5/conf.d/geoip.ini
fi

* idn : Cette extension apporte le support des noms de domaines internationalisés. Cependant, à l'heure ou j'écris ce guide, cette extension est encore en Beta.

Une fois ces extensions installées, redémarrez votre serveur Apache pour les prendre en compte :

/etc/init.d/apache2 force-reload

Nous renseignons la dernière version de Horde Groupware Webmail Edition :

VERSION=1.2.2

Nous téléchargeons Horde Groupware Webmail Edition :

/usr/bin/wget http://ftp.horde.org/pub/horde-webmail/horde-webmail-$VERSION.tar.gz \
    --output-document=/tmp/horde-webmail-$VERSION.tar.gz

Nous décompressons le fichier téléchargé :

/bin/tar --directory /opt -xzf /tmp/horde-webmail-$VERSION.tar.gz

Nous renommons le dossier ainsi obtenu :

/bin/mv /opt/horde-webmail-$VERSION /opt/horde-webmail

Et nous le rendons disponible via le serveur HTTP :

/bin/ln -s /opt/horde-webmail /var/www/

Remarque : Si vous souhaitez que Horde soit disponible à la racine d'un domaine dédié (pour obtenir une URL du type http://mail.domaine.com/), vous trouverez les informations nécessaires à la mise en place d'une telle configuration dans mon guide Installer et configurer Apache2 sur Debian 4.0 Etch.

Nous pouvons maintenant passer à la configuration de ce logiciel.

Configuration de Horde

Remarque : Horde nécessite l'accès à une base de donnée. Si vous le souhaitez, vous pouvez installer un serveur MySQL ou créer une base de donnée sur un tel serveur en suivant mon guide MySQL sur Debian 4.0 Etch ou 5.0 Lenny.

La configuration de Horde est assez complexe tellement sont nombreux les paramètres. Je vous invite donc à lire la documentation de Horde pour que votre système soit configuré aux petits oignons. Ce guide se contente de mettre en place une configuration fonctionnelle, mais basique. Pour ce faire nous allons utiliser le petit script fourni avec Horde :

/usr/bin/php /opt/horde-webmail/scripts/setup.php

Répondez aux questions posées par ce script.

Remarque : Dans la section "Configure database settings", choisissez "mysqli" comme type de base de données.

Important : si votre serveur IMAP n'est pas sur le serveur ou est installé Horde, ou s'il nécessite une identification par TLS, vous devez modifier la configuration de IMP :

/usr/bin/vim /opt/horde-webmail/imp/config/servers.php

Plusieurs valeurs sont possibles pour l'entrée 'protocol' :

Pour information, voici la configuration que j'utilise pour brancher Horde avec un serveur Cyrus IMAP installé à l'aide du guide Installer le serveur IMAP Cyrus sur Debian 4.0 Etch et 5.0 Lenny.

$servers['imap'] = array(
    'name' => 'IMAP Server',
    'server' => 'cyrus.domain.xen',
    'hordeauth' => false,
    'protocol' => 'imap/tls/novalidate-cert',
    'port' => 143,

    'quota' => array(
        'driver' => 'imap',
        'params' => array(),
    ),
    'acl' => array(
        'driver' => 'rfc2086',
    ),
);

Une fois la configuration terminée, vous pouvez vérifier qu'il ne manque rien en visitant :

Remarque : Ne tenez pas compte de l'erreur sur la limite mémoire. 128 Mo devraient suffire. Domaine d'email par défaut

Nous allons maintenant configurer l'email de contact utilisé lorsqu'un utilisateur rencontre des problème, et le domaine des email des utilisateurs de Horde, lorsque ce dernier ne peut le détecter. Pour ce faire, renseignez les valeurs à appliquer :

CONTACT_MAIL=contact@votre-domaine.com
DEFAULT_MAIL_DOMAIN=votre-domaine.com

Appliquez maintenant ces paramètres :

/bin/sed -i -e "s/^\(.*problems.*email.*=\).*;/\1 '${CONTACT_MAIL}';/" \
            -e "s/^\(.*problems.*maildomain.*=\).*;/\1 '${DEFAULT_MAIL_DOMAIN}';/" \
         /opt/horde-webmail/config/conf.php

* Fichier log

Nos modifions l'emplacement du fichier log de horde :

/bin/mkdir --parent /var/log/horde
/bin/chown www-data:www-data /var/log/horde
/bin/chmod 0750 /var/log/horde
/bin/sed -i -e 's/\/tmp\/horde\.log/\/var\/log\/horde\/horde\.log/' /opt/horde-webmail/config/conf.php

Nous mettons en place la rotation de ces fichiers log :

/bin/cp /opt/horde-webmail/scripts/horde.logrotate /etc/logrotate.d/horde

Et nous l'adaptons à notre besoin :

/bin/sed -i -e 's|/var/log/horde\.log|/var/log/horde/horde.log|' /etc/logrotate.d/horde

* Cache mémoire

En premier lieu, assurez vous d'avoir installer le cache mémoire :

apt-get install memcached php5-memcache
/etc/init.d/apache2 force-reload

Nous activons le support de memcached :

/bin/sed -i -e 's/^\(.*memcache.*enabled.*=\).*;/\1 true;/' /opt/horde-webmail/config/conf.php

Et nous le configurons :

/bin/sed -i -e "/^\(.*conf.*memcache.*enabled.*=\).*/i\
\$conf['memcache']['hostspec'] = array('localhost');\n\
\$conf['memcache']['port'] = array('11211');\n\
\$conf['memcache']['weight'] = array();\n\
\$conf['memcache']['persistent'] = false;\n\
\$conf['memcache']['compression'] = false;\n\
\$conf['memcache']['large_items'] = true;" /opt/horde-webmail/config/conf.php

* Emplacement du cache

Nous créons un dossier de cache sécurisé pour Horde :

/bin/mkdir /var/cache/horde
/bin/chown www-data:root /var/cache/horde
/bin/chmod 0700 /var/cache/horde

Et nous configurons Horde afin qu'il l'utilise :

/bin/sed -i -e "/^\(.*conf.*umask.*=\).*/a\
\$conf['tmpdir'] = '/var/cache/horde';" /opt/horde-webmail/config/conf.php

De même, nous configurons le nettoyage régulier des fichiers caches générés par Horde :

/bin/cp /opt/horde-webmail/scripts/temp-cleanup.cron /etc/cron.daily/horde-temp-cleanup
/bin/chmod +x /etc/cron.daily/horde-temp-cleanup
/bin/sed -i -e 's/^\(TMP_DIR=\).*/\1\/var\/cache\/horde/' /etc/cron.daily/horde-temp-cleanup

* Envoi des emails d'alerte

Nous configurons maintenant l'envoi des emails d'alertes par Horde :

/bin/echo "# /etc/cron.d/horde : crontab fragment for horde
# Horde Alarms
*/5 * * * * /usr/bin/php /opt/horde-webmail/scripts/alarms.php" \
    | /usr/bin/tee /etc/cron.d/horde

* Outil d'administration des sessions

Si vous souhaitez que l'outil d'administration des sessions de Horde soit fonctionnel, exécutez la ligne de commande suivante :

/bin/chown www-data /var/lib/php5

Attention : Ceci peut engendrer des problèmes de sécurité, aussi je ne le recommande pas. Gestion des pièces jointes

Si vous souhaitez pouvoir visionner vos pièces jointes directement dans Horde sans avoir à les télécharger, voici la ligne de commande vous permettant d'installer les logiciels nécessaires :

/usr/bin/apt-get install unrtf libwpd-tools xlhtml source-highlight ppthtml rpm wv enscript

Une fois ceci fait, nous corrigeons la configuration des chemins vers ces utilitaires dans Horde :

sed -i -e 's/\/usr\/local\/bin\/xlhtml/\/usr\/bin\/xlhtml/' \
       -e 's/\/usr\/local\/bin\/ppthtml/\/usr\/bin\/ppthtml/' \
    /opt/horde-webmail/config/mime_drivers.php

Enfin, nous activons les outils rendu disponibles :

sed -i -e "s/\/\/ \('deb'\)/\1/g" \
       -e "s/\/\/ \('enscript'\)/\1/g" \
       -e "s/\/\/ \('msword'\)/\1/g" \
       -e "s/\/\/ \('msexcel'\)/\1/g" \
       -e "s/\/\/ \('mspowerpoint'\)/\1/g" \
       -e "s/\/\/ \('rpm'\)/\1/g" \
       -e "s/\/\/ \('rtf'\)/\1/g" \
       -e "s/\/\/ \('srchighlite'\)/\1/g" \
       -e "s/\/\/ \('webcpp'\)/\1/g" \
       -e "s/\/\/ \('wordperfect'\)/\1/g" \
    /opt/horde-webmail/config/mime_drivers.php

Enfin, nous indiquons à Horde ou se trouve la base de donnée des informations Mime :

/bin/sed -i -e "/^\(.*conf.*sessionhandler.*type.*=\).*/a\
\$conf['mime']['magic_db'] = '/usr/share/file/magic';" /opt/horde-webmail/config/conf.php

Configuration de IMP

Afin de rendre la lecture des emails plus agréable, nous allons améliorer la configuration par défaut d'IMP : Affichage en ligne des messages HTML

Par défaut, vous devez télécharger les messages au format HTML afin de pouvoir les lire. Ce n'est pas très agréable. Les lignes de commande suivantes modifient cette configuration :

/bin/sed -i -e '/.*mime_drivers.*imp.*html.*=.*array.*/{n;d}' /opt/horde-webmail/imp/config/mime_drivers.php
/bin/sed -i -e "/.*mime_drivers.*imp.*html.*=.*array.*/a\
    'inline' => true," /opt/horde-webmail/imp/config/mime_drivers.php

Adaptation aux défauts de Thunderbird

Afin d'adapter les dossiers utilisé par Horde à ceux utilisé par Thunderbird, nous allons modifier quelques options :

* Le dossier des courriers envoyés :

/bin/sed -i -e "/.*_prefs.*'sent_mail_folder'.*/,/^\([^\/]*'value'\).*/{s|^\([^/]*'value'\).*|\1 => 'INBOX/Sent',|}" \
          /opt/horde-webmail/imp/config/prefs.php

* Le dossier des brouillons :

/bin/sed -i -e "/.*_prefs.*'drafts_folder'.*/,/^\([^\/]*'value'\).*/{s|^\([^/]*'value'\).*|\1 => 'INBOX/Drafts',|}" \
          /opt/horde-webmail/imp/config/prefs.php

* Le dossier de la corbeille :

/bin/sed -i -e "/.*_prefs.*'trash_folder'.*/,/^\([^\/]*'value'\).*/{s|^\([^/]*'value'\).*|\1 => 'INBOX/Trash',|}" \
          /opt/horde-webmail/imp/config/prefs.php

* Le dossier des indésirables :

/bin/sed -i -e "/.*_prefs.*'spam_folder'.*/,/^\([^\/]*'value'\).*/{s|^\([^/]*'value'\).*|\1 => 'INBOX/Junk',|}" \
          /opt/horde-webmail/imp/config/prefs.php

Adaptation aux défauts de Outlook

Si vous n'utilisez pas Thunderbird, mais Outlook, voici les lignes de commande à utiliser :

* Le dossier des courriers envoyés :

/bin/sed -i -e "/.*_prefs.*'sent_mail_folder'.*/,/^\([^\/]*'value'\).*/{s|^\([^/]*'value'\).*|\1 => '\&AMk-l\&AOk-ments envoy\&AOk-s',|}" \
          /opt/horde-webmail/imp/config/prefs.php

* Le dossier des brouillons :

/bin/sed -i -e "/.*_prefs.*'drafts_folder'.*/,/^\([^\/]*'value'\).*/{s|^\([^/]*'value'\).*|\1 => 'Brouillons',|}" \
          /opt/horde-webmail/imp/config/prefs.php

* Le dossier de la corbeille :

/bin/sed -i -e "/.*_prefs.*'trash_folder'.*/,/^\([^\/]*'value'\).*/{s|^\([^/]*'value'\).*|\1 => '\&AMk-l\&AOk-ments supprim\&AOk-s',|}" \
          /opt/horde-webmail/imp/config/prefs.php

Prévisualisation des pièces jointes

Afin de rendre disponible la prévisualisation en ligne des pièces jointe, exécutez la commande suivante :

/bin/sed -i -e 's/^\(.*mailbox.*show_preview.*=\).*;/\1 true;/' /opt/horde-webmail/imp/config/conf.php

Activation du cache

Afin que l'affichage des messages soit plus réactif, il vous faut activer l'utilisation du cache par IMP. Pour ce faire, exécutez la commande suivante :

/bin/sed -i -e 's/^\(.*mboxcache.*use_mboxcache.*=\).*;/\1 true;/' /opt/horde-webmail/imp/config/conf.php

Et de le configurer :

/bin/sed -i -e "/^\(.*conf.*mboxcache.*use_mboxcache.*=\).*/i\
\$conf['mboxcache']['use_compress'] = false;\n\
\$conf['mboxcache']['preview_size'] = 1000;\n\
\$conf['mboxcache']['lifetime'] = 2592000;" /opt/horde-webmail/imp/config/conf.php

De même, pour cacher la liste des messages :

/bin/sed -i -e 's/^\(.*mlistcache.*use_mlistcache.*=\).*;/\1 true;/' /opt/horde-webmail/imp/config/conf.php
/bin/sed -i -e "/^\(.*conf.*mlistcache.*use_mlistcache.*=\).*/i\
\$conf['mlistcache']['lifetime'] = 604800;" /opt/horde-webmail/imp/config/conf.php

Affichage de la priorité et de la présence de pièces jointes dans la liste des messages

Pour afficher la priorité et la présence de pièces jointes dans la liste des messages, utilisez la commande suivante (l'activation du cache est recommandée) :

/bin/sed -i -e 's/^\(.*mailbox.*show_attachments.*=\).*;/\1 true;/' \
            -e 's/^\(.*mailbox.*show_xpriority.*=\).*;/\1 true;/' \
         /opt/horde-webmail/imp/config/conf.php

Mise en cache du JavaScript et du CSS

Afin d'accélérer le chargement des pages, il est possible de créer des fichiers Javascripts et CSS allégé. C'est ce que fait cette configuration :

* Pour le cache JavaScript :

/bin/sed -i -e 's/^\(.*server.*cachejs.*=\).*;/\1 true;/' /opt/horde-webmail/imp/config/conf.php
/bin/sed -i -e "/^\(.*conf.*server.*cachejs.*=\).*/i\
\$conf['server']['cachejsparams']['timeout'] = 86400;\n\
\$conf['server']['cachejsparams']['mtime'] = false;" /opt/horde-webmail/imp/config/conf.php

* Pour le cache CSS :

/bin/sed -i -e 's/^\(.*server.*cachecss.*=\).*;/\1 true;/' /opt/horde-webmail/imp/config/conf.php
/bin/sed -i -e "/^\(.*conf.*server.*cachecss.*=\).*/i\
\$conf['server']['cachecssparams']['timeout'] = 86400;\n\
\$conf['server']['cachecssparams']['mtime'] = false;" /opt/horde-webmail/imp/config/conf.php

Remarque : Si DIMP est présent, vous pouvez activer le cache du JavaScript et CSS pour cette interface :

* Pour le cache JavaScript :

/bin/sed -i -e 's/^\(.*server.*cachejs.*=\).*;/\1 true;/' /opt/horde-webmail/dimp/config/conf.php
/bin/sed -i -e "/^\(.*conf.*server.*cachejs.*=\).*/i\
\$conf['server']['cachejsparams']['timeout'] = 86400;\n\
\$conf['server']['cachejsparams']['mtime'] = false;" /opt/horde-webmail/dimp/config/conf.php

* Pour le cache CSS :

/bin/sed -i -e 's/^\(.*server.*cachecss.*=\).*;/\1 true;/' /opt/horde-webmail/dimp/config/conf.php
/bin/sed -i -e "/^\(.*conf.*server.*cachecss.*=\).*/i\
\$conf['server']['cachecssparams']['timeout'] = 86400;\n\
\$conf['server']['cachecssparams']['mtime'] = false;" /opt/horde-webmail/dimp/config/conf.php

Finitions

Vous trouverez dans cette sections diverses petites choses qui sans être obligatoires, amélioreront grandement votre Horde. Dimp comme application par défaut

Dans la configuration standard de Horde, Imp est l'application par défaut. Si vous souhaitez utiliser Dimp sans trop vous fouler, voici la ligne de commande à appliquer pour en faire le défaut de Horde :

/bin/sed -i -e "/\$_COOKIE\['default_imp_view'\]/,/\$browser→isMobile().*'imp'/{ s/^\(.*$browser→isMobile().*\)'imp'\(.*\)\$/\1'dimp'\2/ ;}" /opt/horde-webmail/imp/login.php

* Fortunes

Pour avoir un message d'accueil sympa lorsque vous vous identifiez. Commencez par installer le logiciel nécessaire :

/usr/bin/apt-get install fortunes-fr

Et configurez Horde pour l'utiliser :

/bin/sed -i -e "/^\(.*conf.*portal.*fixed_blocks.*=\).*/a\
\$conf['fortune']['exec_path'] = '/usr/games/fortune';" /opt/horde-webmail/config/conf.php

* Correction orthographique

Afin de disposer d'un correcteur d'orthographe lors de la rédaction de vos messages, commencez par installer aSpell :

/usr/bin/apt-get install aspell-en aspell-fr

Et configurez IMP pour l'utiliser :

/bin/sed -i \
  -e "s/^\(.*spell.*driver.*=\).*;/\1 'aspell';/" \
  -e "/^\(.*conf.*spell.*driver.*=\).*/i\
\$conf['spell']['path'] = '/usr/bin/aspell';" /opt/horde-webmail/imp/config/conf.php

* Encryption

Si vous souhaitez disposer du support de GnuPG pour crypter vos messages, commencez par installer GnuPG si besoin :

/usr/bin/apt-get install gnupg

Et configurez IMP pour l'utiliser :

/bin/sed -i -e "/^\(.*conf.*utils.*gnupg_keyserver.*=\).*/i\
\$conf['utils']['gnupg'] = '/usr/bin/gpg';" /opt/horde-webmail/imp/config/conf.php

De même, nous configurons Mnemo pour l'utiliser :

/bin/sed -i -e "/^\(.*conf.*menu.*print.*=\).*/i\
\$conf['utils']['gnupg'] = '/usr/bin/gpg';" /opt/horde-webmail/mnemo/config/conf.php

* Utilisation de OpenSSL

Bon, la j'ai pas très bien compris à quoi cela pouvait servir… mais si cette fonctionnalité vous intéresse, voici comment l'activer. En premier lieu, installez OpenSSL :

/usr/bin/apt-get install openssl ca-certificates

Et configurez IMP pour l'utiliser :

/bin/sed -i -e "/^\(.*conf.*utils.*gnupg_timeout.*=\).*/a\
\$conf['utils']['openssl_cafile'] = '/etc/ssl/certs';\n\
\$conf['utils']['openssl_binary'] = '/usr/bin/openssl';" /opt/horde-webmail/imp/config/conf.php

* Autres

Voici une liste non exhaustive de ce que je ne documente pas dans ce guide, mais que vous pouvez trouver dans l'interface de configuration de Horde :

Je vous invite a explorer la configuration de Horde si ces outils vous intéressent. Configuration pour Cyrus Imap

Si vous disposez d'un serveur Cyrus Imap, vous souhaitez probablement que Horde vous permette de configurer vos filtres de messages via Sieve. Pour ce faire, nous devons installer un paquet PEAR supplémentaire :

/usr/bin/pear install Net_Sieve

Une fois ceci fait, vous devez modifier le backend sieve de Ingo :

/usr/bin/vim /opt/horde-webmail/ingo/config/backends.php

Vous trouverez dans ce fichier un backend nommé 'sieve'. Il vous suffit normalement d'adapter les informations 'preferred' et 'hostspec' à vos besoins, puis de supprimer ou commenter les autres backends pour permettre à Ingo d'utiliser Sieve comment moteur de filtrage.

Il vous faut aussi modifier le parmètre 'hordeauth', il faut le passer de "true" à "'full'" :

'hordeauth' ⇒ 'full',

* Liste noire des utilisateurs

Si vous souhaitez disposer d'une mécanique d'interdiction d'utilisation de Horde pour certain utilisateurs, vous pouvez le faire en utilisant le hook "preauthenticate". Pour ce faire, en premier lieu, autorisez l'utilisation de ce hook:

/bin/sed -i -e "s/^\(.*hooks.*preauthenticate.*=\).*;/\1 true;/" /opt/horde-webmail/config/conf.php

Ajoutez ensuite un paramètre de configuration pour la liste noire des utilisateurs :

/bin/sed -i -e "/^\(.*auth.*driver.*=\).*/a\
\$conf['auth']['blacklist'] = array( /* 'my_blacklisted_login', */ );" /opt/horde-webmail/config/conf.php

Et enfin, ajoutez la fonction de hook personnalisée au fichier hooks.php :

echo "
// Here is an _horde_hook_preauthenticate that allow you to black list logins.
if (! function_exists('_horde_hook_preauthenticate')) {
    function _horde_hook_preauthenticate(\$userID, \$credential, \$realm)
    {
        return ! in_array(\$userID, \$GLOBALS['conf']['auth']['blacklist']);
    }
}" | /usr/bin/tee -a /opt/horde-webmail/config/hooks.php

Par la suite, vous pouvez ajouter un nouveau login à la liste noire avec les commandes suivantes. Commencez par renseignez le login à blacklister :

LOGIN=blacklisted_user

Et exécutez la commande suivante pour l'ajouter à la liste noire :

/bin/sed -i -e "s/^\(.*auth.*blacklist.*=.*\));.*/\1 '$LOGIN',);/" /opt/horde-webmail/config/conf.php

Utilisation avec reverse proxy

Si vous souhaitez utiliser Horde derrière un reverse proxy Apache, voici les modifications à effectuer (pour un serveur intermédiaire utilisant le HTTPS et donc Horde est la racine):

* dans le fichier /opt/horde-webmail/config/conf.php :

    $conf['use_ssl'] = 1;
    $conf['server']['name'] = $_SERVER['SERVER_NAME'];
    $conf['server']['port'] = 443;

Résolution des problèmes

Si vous rencontrez des problèmes avec votre configuration de Horde, il est possible qu'augmenter le niveau de verbosité des fichiers journaux vous aide. Pour ce faire, utilisez cette ligne de commande :

/bin/sed -i -e 's/^\(.*log.*priority.*=\).*;/\1 PEAR_LOG_DEBUG;/' \
         /opt/horde-webmail/config/conf.php

Vous pouvez alors observer le fichier journal de Horde à l'aide de la commande :

/usr/bin/tail -n 50 -f /var/log/horde/horde.log

Une fois le problème diagnostiqué correctement, vous pouvez revenir au niveau normal de verbosité du fichier journal à l'aide de cette commande :

/bin/sed -i -e 's/^\(.*log.*priority.*=\).*;/\1 PEAR_LOG_NOTICE;/' \
         /opt/horde-webmail/config/conf.php

* Sécurisation

Attention : n'effectuez cette étape que lorsque votre Horde est parfaitement configuré. Mais avant de le rendre accessible aux internautes.

Afin de rendre Horde plus robuste aux attaques, nous allons modifier les permissions des fichiers de configuration :

/usr/bin/find /opt/horde-webmail -type f -wholename "*config/*" | /usr/bin/xargs /bin/chown -R root:www-data
/usr/bin/find /opt/horde-webmail -type f -wholename "*config/*" | /usr/bin/xargs /bin/chmod 0440

Nous désactivons les fichiers test.php :

/usr/bin/find /opt/horde-webmail -type f -name "test.php" | /usr/bin/xargs /bin/chmod a-rwx

Nous restreignons l'accès aux scripts de configuration à l'utilisateur root :

/usr/bin/find /opt/horde-webmail -type d -name "scripts" | /usr/bin/xargs /bin/chown -R root:root
/usr/bin/find /opt/horde-webmail -type d -name "scripts" | /usr/bin/xargs /bin/chmod -R go-rwx

Et pour faire bonne mesure, nous interdisons la modification de l'ensemble du code source de Horde :

/bin/chmod -R ugo-w /opt/horde-webmail

Nous désactivons l'affichage de code PHP aux utilisateurs lors d'erreurs :

/bin/echo "# Secure PHP for horde
expose_php = Off
display_errors = Off
log_errors = On
register_globals = Off
" | tee /etc/php5/conf.d/horde.ini

Et nous redémarrons Apache 2 pour prendre en compte cette configuration :

/etc/init.d/apache2 force-reload

Je vous recommande également d'utiliser Horde à travers une connexion HTTPS afin que les mots de passe des comptes email ne circulent pas en clair sur le réseau. Amélioration de la sécurité à l'aide d'Apache

Si vous le souhaitez, il est possible d'améliorer encore la sécurité de votre installation Horde en configurant proprement Apache.

Dans le fichier qui correspond à votre installation de Horde, ajoutez ces lignes. Elles font en sorte que les dossiers de configuration de Horde restent privés :

# Deny access to files that are not served directly by the webserver
<DirectoryMatch "^/opt/horde-webmail/(.*/)?(config|lib|locale|po|scripts|templates)/(.*)?">
  order deny,allow
  deny  from all
</DirectoryMatch>

Une fois ceci fait, n'oubliez pas de recharger la configuration d'Apache :

/etc/init.d/apache2 force-reload

Interface de gestion de la Quarantaine : MailZu

Installation

Télécharger MailZu à l'URL suivante :

http://sourceforge.net/projects/mailzu/

Décompresser l'archive dans la Home d'Apache

Configuration

Un seul fichier à modifier : config/config.php

Renseigner les lignes suivantes :

$conf['db']['dbType'] = 'mysql';

// Database user who can access the amavisd database
$conf['db']['dbUser'] = 'amavis';

// Password for above user to access the amavisd database
$conf['db']['dbPass'] = 'amavis';

// Name of database
$conf['db']['dbName'] = 'AMAVIS';

// Database host specification (hostname[:port]) [localhost]
$conf['db']['hostSpec'] = 'localhost:3306';

$conf['auth']['serverType'] = 'sql';

$conf['auth']['dbType'] = 'mysql';

// Database host specification (hostname[:port]) [localhost]
$conf['auth']['dbHostSpec'] = 'localhost:3306';

// Database user who can access the auth database
$conf['auth']['dbUser'] = 'mail';  

// Password for above user to auth database
$conf['auth']['dbPass'] = 'mail1974';

// Name for auth database
$conf['auth']['dbName'] = 'MAIL';

// Name for auth table that contains usernames and passwords
$conf['auth']['dbTable'] = 'postfix_users';

// Name of the Username field of the SQL table
$conf['auth']['dbTableUsername'] = 'email';

// Name of the password field of the SQL table
$conf['auth']['dbTablePassword'] = 'password';

// Name of the 'first name' or 'full name' field of the SQL table
// This is used for the welcome message
// If such a field does not exist, leave it blank
$conf['auth']['dbTableName'] = 'prenom';

// Name of the 'mail address' field of the SQL table
$conf['auth']['dbTableMail'] = 'email';

$conf['auth']['s_admins'] = array ('postmaster@druidesmetal.org');

$conf['app']['weburi'] = 'https://mail.druidesmetal.org/mailzu';

Scripts Divers et Crontab

Scripts

# more /usr/local/bin/rmreturn.sh
#!/bin/bash

/usr/sbin/postqueue -p | grep MAILER-DAEMON | awk '{print $1}' | /usr/sbin/postsuper -d -
# more /usr/local/bin/archive_del_mail.sh
#!/bin/bash

MYSQL_USER="mail"
MYSQL_PASSWD="mail1974"
MYSQL_BDD="MAIL"

HOME_MAIL="/var/mail/vmail"
HOME_BACKUP="/var/mail/backup"

for DOMAINE in `ls ${HOME_MAIL}`
do
        for USER in `ls ${HOME_MAIL}/${DOMAINE} | egrep -v '(cur|new|tmp)'`
        do
                EMAIL=`echo "select count(*) from postfix_users where email = '${USER}@${DOMAINE}';" | /usr/bin/mysql --user=${MYSQL_USER} --password=${MYSQL_PASSWD} ${MYSQL_BDD}`
                NBEMAIL=`echo ${EMAIL} | awk '{print $2}'`
                if [ ${NBEMAIL} -eq 0 ]
                then
                        echo "------------------------------------------------"
                        echo "Email ${USER}@${DOMAINE} non present en base !!!"
                        echo "Archive puis suppression de sa Boite aux lettres !!"
                        /bin/tar cfz ${HOME_BACKUP}/${DOMAINE}_${USER}.tgz ${HOME_MAIL}/${DOMAINE}/${USER}
                        /bin/rm -rf ${HOME_MAIL}/${DOMAINE}/${USER}
                        echo "------------------------------------------------"
                fi
        done
done
# more /usr/local/bin/create_arbo_horde.sh
#!/bin/bash

HOME="/var/mail"
HOMEMAIL="${HOME}/vmail"

TEMPLATE="${HOME}/template_mail"

TEMP="/var/tmp"

for FIC in `ls ${TEMP}/newemail_*.txt`
do
        EMAIL=`cat ${FIC} | awk -F"@" '{print $1}'`
        DOMAIN=`cat ${FIC} | awk -F"@" '{print $2}'`

        cp -Rp ${TEMPLATE}/.??* ${HOMEMAIL}/${DOMAIN}/${EMAIL}/

        rm -f ${FIC}
done

Crontab

/etc/crontab

# Archive et Suppression des Boites aux lettres
00 3 * * * root /usr/local/bin/archive_del_mail.sh 2>/dev/null

# Suppression des MAILER-DAEMON
00 * * * * root /usr/local/bin/rmreturn.sh 2>/dev/null

# Creation Arborescence pour Horde
*/5 * * * * root /usr/local/bin/create_arbo_horde.sh 2>/dev/null

# Quota
0 0 * * * vmail /usr/local/bin/quota_notify &> /dev/null