Si comme moi vous utilisez un reverse proxy pour desservir plusieurs sites web, vous devez avoir connu le problèmes du relayage des adresses IP du proxy dans les logs des serveurs web (aka backends).

J’en ai parlé dans cet article ici

Maintenant j’ai le même souci avec Zimbra. En effet Zimbra utilise un mécanisme de reverse proxy basé sur du NGINX et Memcached; la configuration de celui-ci inclus de nombreuses variables basée sur des attributs LDAP. Lorsque utilise les briques natives de Zimbra, dans les fichiers de logs des Mailbox on retrouve bien le « oip » (Originating IP); mais lorsqu’on utilise un proxy maison, celui-ci n’est évidement pas pris en compte. On peux voir ça dans les logs du serveur Zimbra (mailbox.log) :

2013-10-02 00:01:39,190 INFO  [btpool0-12://mail.domain.tld/service/soap] [name=wolfy@les-titans.com;mid=8;ip=reverse_proxy_IP;] soap - EndSessionRequest

Pour modifier cela il faut renseigner notre reverse proxy dans la configuration de Zimbra. Pour cela passer en tant qu’utilisateur Zimbra puis effectuez les commandes suivantes :

[zimbra@zimbra ~]$ zmprov ms `zmhostname` +zimbraMailTrustedIP reverse_proxy_IP
[zimbra@zimbra ~]$ zmprov ms `zmhostname` +zimbraMailTrustedIP reverse_proxy_IP_n°2

Pensez bien a mettre le « + » devant l’attribut sinon cela écrasera les autres occurrences.

Une fois l’opération effectué, redémarrez Zimbra et vous verrez ce changement dans les logs :

2013-10-03 13:43:06,994 INFO  [btpool0-13://mail.domain.tld/service/soap/SearchRequest] [name=wolfy@les-titans.com;mid=8;ip=reverse_proxy_IP;oip=Client_IP;ua=ZimbraWebClient - FF3.0 (Win)/7.2.5_GA_2906;] soap - SearchRequest elapsed=5

Introduction

Vous avez sans doute eu le souci lors de l’utilisation d’un reverse proxy pour desservir des machines web type Apache. Dans les logs des backend, l’adresse IP retourné est celle du reverse proxy; logique puisque c’est lui qui effectue les requêtes. Cela peut être gênant si vous voulez lever des statistiques sur vos visiteurs.

Pour que le backend traite les trames les frontend ajoute dans les headers l’occurrence X-Forwarded-For. Voici comment cela se présente :

X-Forwarded-For: client, proxy1, proxy2

En premier lieu on l’adresse ip d’origine (celle du client) puis le ou les proxy par lesquels la demande est passée.

Nginx

Pour configurer cela sous NGINX, il faut d’abord vérifier que votre version de NGINX a été compilé avec. Pour cela :

nginx -V

piuis vérifier que l’occurrence suivante apparait bien dans la ligne des compilations :

--with-http_realip_module

si cela est présent vous n’avez simplement qu’a rajouter dans votre virtualhost ces deux lignes :

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Coté backend il faut maintenant prendre en compte ces headers pour cela sur

CentOS

On installe le module mod_extract_forwarded disponible dans les repository EPEL puis :

yum install mod_extract_forwarded

Une fois le module installé, il faut le configurer pour accepter les headers de la part de certains proxy (un peu de sécurité que diable !).

Pour cela éditer le fichier /etc/httpd/conf.d/mod_extract_forwarded.conf et ajouter la ligne suivante :

MEFaccept reverse_proxy_IP
MEFaccept reverse_proxy_IP2

Puis on redémarre apache

service httpd restart

On vérifie que le module est bien chargé :

apachectl -M | grep frowarded

et normalement dans vos logs ça roulera.

Debian

Même topo que pour CentOS, a la différence que c’est le module rpaf que l’on installe :

apt-get install libapache2-mod-rpaf

Puis on modifie le fichier /etc/apache2/mods-enabled/rpaf.conf pour ajouter l’IP du reverse proxy

Je continue sur ma lancé avec la supervision de NGINX avec zabbix. Plusieurs sites effectue cette opération via des scripts. Comme je l’ai dis dans mon précédent article, je préfèré une solution qui fonctionne « out of the box » (comme dirait les commerciaux).

Nginx dispose d’un module de status (a la apache) . Si vous voulez avoir plus d’informations sur ce qu’il monitore, je vous conseil de lire la documentation officiel.

Maintenant que l’on sais ce que l’on va monitorer, voici comment il faut faire :

Création d’un virtualhost spécifique accessible uniquement par l’agent zabbix :

Au niveau de votre serveur NGINX, il faut créer un virtualhost avec la configuration suivante :

server {
      listen 127.0.0.1:8080; # écoute en local sur un port différent
      location / {
          stub_status on; # on charge le module de status
          access_log off; # on ne logge pas inutilement les accès
          allow 127.0.0.1; # autorisation uniquement depuis le localhost
          deny all; # on refuse tout le reste
       }
 }

et bien sur faire un reload de NGINX a la fin de votre configuration

Modification du fichier zabbix_agentd.conf

Afin que le système prenne en compte les futurs checks contenu dans le template on ajoute ces paramètres utilisateurs à la configuration de l’agent zabbix (zabbix_agentd.conf):

UserParameter=nginx.active[*],wget -O- -q $1:$2 | awk ‘/^Active/ {print $NF}’
UserParameter=nginx.reading[*],wget -O- -q $1:$2 | awk ‘/Reading/ {print $$2}’
UserParameter=nginx.writing[*],wget -O- -q $1:$2 | awk ‘/Writing/ {print $$4}’
UserParameter=nginx.waiting[*],wget -O- -q $1:$2 | awk ‘/Waiting/ {print $$6}’
UserParameter=nginx.accepted[*],wget -O- -q $1:$2 | awk ‘/^[ \t]+[0-9]+[ \t]+[0-9]+[ \t]+[0-9]+/ {print $$1}’
UserParameter=nginx.handled[*],wget -O- -q $1:$2 | awk ‘/^[ \t]+[0-9]+[ \t]+[0-9]+[ \t]+[0-9]+/ {print $$2}’
UserParameter=nginx.requests[*],wget -O- -q $1:$2 | awk ‘/^[ \t]+[0-9]+[ \t]+[0-9]+[ \t]+[0-9]+/ {print $$3}’

Il ne reste plus qu’a importer et associer à vos hosts le template Zabbix qui suit : Template_nginx

Il a longtemps de cela j’avais installé un z-push pour attaquer mon serveur Zimbra. A l’époque javais pas mal galéré avec l’intégration de z-push. 3 ans plus tard (ah ouai quand même 🙂 ) j’ai de nouveau tenté l’expérience avec la nouvelle version de z-push avec le backend pour zimbra.

Je refait un petit tuto pour le monter sur un nginx. Pour ça on commence par télécharger l’archive, la décompacter et la renommer :


cd /var/www/
wget http://zarafa-deutschland.de/z-push-download/final/2.0/z-push-2.0.6-1616.tar.gz
tar xzvf z-push-2.0.6-1616.tar.gz
mv z-push-2.0.6-1616 z-push

Puis le backend pour Zimbra:

wget http://downloads.sourceforge.net/project/zimbrabackend/Release55/zimbra55-zpush2--zimbra54-zpush1-as12.1.tgz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fzimbrabackend%2F
tar xzvf zimbra55-zpush2--zimbra54-zpush1-as12.1.tgz
mkdir z-push/backend/zimbra
cp zimbra55/z-push-2/* z-push/backend/zimbra/

une fois le système mis en place on modifie le config.php situé dans le dossier de z-push


define('BACKEND_PROVIDER', "BackendZimbra");
define('ZIMBRA_URL', 'http://zimbra.domain.tld');
define('ZIMBRA_USER_DIR', 'zimbra');
define('ZIMBRA_SYNC_CONTACT_PICTURES', true);
define('ZIMBRA_VIRTUAL_CONTACTS',true);
define('ZIMBRA_VIRTUAL_APPOINTMENTS',true);
define('ZIMBRA_VIRTUAL_TASKS',true);
define('ZIMBRA_IGNORE_EMAILED_CONTACTS',true);
define('ZIMBRA_HTML',true);
define('ZIMBRA_ENFORCE_VALID_EMAIL',true);
define('ZIMBRA_SMART_FOLDERS',false);
define('ZIMBRA_RETRIES_ON_HOST_CONNECT_ERROR',5);
define('ZIMBRA_DEBUG',false);
define('ZIMBRA_LOCAL_CACHE', false);

Puis on modifie la timezone dans le fichier z-push/lib/core/zpush.php

date_default_timezone_set('Europe/Amsterdam');
vers date_default_timezone_set('Europe/Paris');

Enfin on créé les fichiers/dossiers nécessaires au bon fonctionnement de z-push :
mkdir /var/log/z-push/ && touch /var/log/z-push/z-push.log /var/log/z-push/z-push-error.log && chown nginx: /var/log/z-push/z-push.log /var/log/z-push/z-push-error.log

et cela fonctionne directement ! Plus besoin de modifier le code pour qu’il fonctionne avec nginx 🙂

Référence : ZimbraBackend

Si comme moi vous êtes un fervent admirateur de NGINX, vous passez beaucoup de temps à modifier les fichiers de configuration de celui-ci.
Quoi de plus énervant de ne pas avoir de coloration syntaxique qui vous permet de valider qu’il ne manque pas un point virgule à la fin d’une ligne.
Pour l’instant cette coloration n’est pas incluse de base dans vim, mais les fichiers existe bien. Afin de l’installer sur votre serveur, il faut exécuter ces quelques lignes de commandes :

mkdir -p ~/.vim/syntax/
 echo "au BufRead,BufNewFile /usr/local/nginx/conf/* set ft=nginx" >> ~/.vim/filetype.vim
 wget http://www.vim.org/scripts/download_script.php?src_id=14376 -O ~/.vim/syntax/nginx.vim

et le tour est joué 🙂

Update : Nouvelle version !

Ayant un serveur de messagerie personnel sous Zimbra, je voulais le synchroniser avec mon téléphone. Pour cela j’ai d’abord utilisé Funambol mais le logiciel tournant sous Java, il me prenait trop de ressources sur mon petit serveur Kimsufi. De plus il faut installer un logiciel supplémentaire sur le téléphone alors que j’ai déjà un logiciel qui permet de synchroniser via activesync.

J’ai donc fait le tour des solutions existantes qui dispose d’un connecteur pour Zimbra et malheureusement il n’y a pas grand chose de disponible à l’heure actuelle. Le projet le plus intéressant et c’est celui que j’ai mis en place est z-push qui fait partie de la solution Zarafa. Via un plug-in développé par la communauté cela me permet de synchroniser mes mails/calendrier/contacts/tâches grâce au logiciel déjà disponible sur mon téléphone.

Ce logiciel tournant sous php il n’était pas difficile de l’ajouter à mon serveur existant sans consommer de ressources supplémentaire. Le plus compliqué c’est que celui-ci tourne sous nginx et qu’il n’y a aucune documentation existante pour faire fonctionner z-push avec nginx. J’ai du pas mal tâtonner avant de réussir à le faire fonctionner correctement.  J’espère que ce tutoriel vous conviendra et qu’il sera fonctionnel pour tout le monde (les mystères de l’informatique sont parfois impénétrables 🙂 )

Votre serveur nginx doit être paramétré pour tourner avec PHP (par ex.  fastcgi php-fmp ). Il est indispensable de faire tourner PHP avec nginx car z-push s’articule entièrement autour de scripts en PHP.

Une fois que tout fonctionne correctement, rendez-vous dans votre répertoire de site web pour installer z-push

[code lang= »bash »]
cd /var/www/
wget http://download.berlios.de/z-push/z-push-1.4.3.tar.gz
wget http://downloads.sourceforge.net/project/zimbrabackend/Release47/zimbra47.tgz
tar xzvf http://download.berlios.de/z-push/z-push-1.4.3.tar.gz
tar xzvf zimbra47.tgz -C z-push/backend/
chmod 740 z-push/state
chown www-data:www-data z-push/state
[/code]

ok une fois que tous est installé on va configurer z-push pour attaquer Zimbra en backend. Pour cela modifiez le fichier le fichier config.php comme suit :

[code]
$BACKEND_PROVIDER = "BackendZimbra";
define(‘MAPI_SERVER’, ‘file:///var/run/zarafa’);
define(‘ZIMBRA_URL’, ‘http://zimbra.domain.com’);
define(‘ZIMBRA_USER_DIR’, ‘zimbra’);
define(‘ZIMBRA_SYNC_CONTACT_PICTURES’, true);
define(‘ZIMBRA_VIRTUAL_CONTACTS’,true);
define(‘ZIMBRA_VIRTUAL_APPOINTMENTS’,true);
define(‘ZIMBRA_VIRTUAL_TASKS’,true);
define(‘ZIMBRA_IGNORE_EMAILED_CONTACTS’,true);
define(‘ZIMBRA_HTML’,false);
define(‘ZIMBRA_ENFORCE_VALID_EMAIL’,true);
define(‘ZIMBRA_NOKIA_MFE_FIX’,true);
define(‘ZIMBRA_NOKIA_MFE_ALWAYS_OVERWRITE’,true);
#Si jamais vous voulez debuger passer l’option suivante a true
define(‘ZIMBRA_DEBUG’,false);
#Et enfin si vous voulez gérer vos appareils mobile depuis une interface web passer l’option suivante
#a true et suivez les instruction que vous trouverez ici :
#http://downloads.sourceforge.net/project/zimbrabackend/Release47/Release%20Notes%20-%20Revision%2047.txt
define(‘PROVISIONING’, false);
[/code]

Comme on utilise nginx avec fastcgi il faut faire quelques modifications afin que les requêtes web soient traité correctement par z-push

Il faut ajouter ces lignes à la fin du fichier compat.php juste avant « ?> »

[code lang= »bash »]
if (!function_exists(‘apache_request_headers’)) {
function apache_request_headers() {
$header = array();
$header[‘Ms-Asprotocolversion’] = $_SERVER[‘HTTP_MS_ASPROTOCOLVERSION’];
$header[‘X-Ms-Policykey’] = $_SERVER[‘HTTP_X_MS_POLICYKEY’];
$header[‘User-Agent’] = $_SERVER[‘HTTP_USER_AGENT’];

return $header;
}

list($_SERVER[‘PHP_AUTH_USER’], $_SERVER[‘PHP_AUTH_PW’]) = explode(‘:’ , base64_decode(substr($_SERVER[‘HTTP_AUTHORIZATION’], 6)));
}
[/code]

et commenter la ligne suivante dans le fichier index.php

[code lang= »bash »]
//header("Content-Length: $len");
[/code]

enfin configurez votre virtualhost

[code language= »bash »]server {
listen 80;
server_name push.domain.com;
access_log  /var/log/nginx/z-push.access.log  combined;
error_log /var/log/nginx/z-push.error.log;

location / {
root   /var/www/z-push;
index  index.php index.html;

if (!-f $request_filename) {
rewrite  ^(.*)$  /index.php?q=$1  last;
break;
}
}

location ~ \.php$ {
include /etc/nginx/fastcgi_params;
proxy_read_timeout 120;
proxy_connect_timeout 120;
fastcgi_pass  127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME /var/www/z-push/$fastcgi_script_name;
}
}[/code]

Si comme moi vous avez un autre serveur qui fait office de reverse proxy en frontal, n’oubliez pas d’ajouter ces lignes dans votre nginx.conf  sinon votre serveur n’arrivera pas à communiquer avec votre téléphone :

[code lang= »bash »]
##Sert a recuperer l’adresse ip d’origine dans les headers
##Ref : http://wiki.nginx.org/HttpRealIpModule
set_real_ip_from        XX.XX.XX.XX; <= IP du Frontal
real_ip_header          X-Real-IP;[/code]

Et voila il ne reste plus qu’a configurer votre téléphone et le tour est joué.

Références :

http://z-push.sourceforge.net/phpbb/viewtopic.php?f=4&t=1245&p=4762&hilit=apache_request_headers#p4762
http://www.jopa.fr/index.php/2009/08/05/push-mail-sur-serveur-imap-gmail/

22 bis Rue de Trey