<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Le blog à Nono &#187; LDAP</title>
	<atom:link href="http://blogs.glou.org/arnaud/tag/ldap/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.glou.org/arnaud</link>
	<description>C'est l'histoire d'un geek...</description>
	<lastBuildDate>Tue, 03 Aug 2010 16:01:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Alias mail et LDAP</title>
		<link>http://blogs.glou.org/arnaud/2010/03/26/alias-mail-et-ldap/</link>
		<comments>http://blogs.glou.org/arnaud/2010/03/26/alias-mail-et-ldap/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 20:34:06 +0000</pubDate>
		<dc:creator>nono</dc:creator>
				<category><![CDATA[geekeries]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[postfix]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blogs.glou.org/arnaud/?p=183</guid>
		<description><![CDATA[- Dis, Nono, comment on fait pour gérer des alias mail avec un annuaire LDAP ?
- Bouge pas mon gars, je te sers un café et je te montre.
Les fiches LDAP
Chez moi, une fiche LDAP peut comprendre jusqu&#8217;à 4 attributs différents liés au mail :

mail contient l&#8217;adresse « officielle » de l&#8217;utilisateur
mailLocalAddress contient ses alias locaux [...]]]></description>
			<content:encoded><![CDATA[<p><em>- Dis, Nono, comment on fait pour gérer des alias mail avec un annuaire LDAP ?</em><br />
<em>- Bouge pas mon gars, je te sers un café et je te montre.</em></p>
<h1>Les fiches LDAP</h1>
<p>Chez moi, une fiche LDAP peut comprendre jusqu&#8217;à 4 attributs différents liés au mail :</p>
<ul>
<li><em>mail</em> contient l&#8217;adresse « officielle » de l&#8217;utilisateur</li>
<li><em>mailLocalAddress</em> contient ses alias locaux ; ils seront réécrits et remplacés par la valeur de l&#8217;attribut <em>mail</em> en sortie de site</li>
<li><em>mailAcceptingAddress</em> contient des alias « en réception seule », typiquement pour les groupes de travail</li>
<li><em>mailRoutingAddress</em> contient la destination des messages envoyés aux <em>mailAcceptingAddress</em> et <em>mailLocalAddress</em> de la fiche</li>
</ul>
<p>En termes de schéma LDAP, nous avons ajouté ça au schéma de base d&#8217;OpenLDAP :</p>
<pre>attributetype ( 1.3.6.1.4.1.7568.1.1.10
    NAME 'mailAcceptingAddress'
    DESC 'RFC822 alternate email address of this recipient'
    EQUALITY caseIgnoreIA5Match
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )

objectclass ( 1.3.6.1.4.1.7568.1.2.2 NAME 'ircamLocalMailRecipient' AUXILIARY
    DESC ''
    MAY ( mailAcceptingAddress ) )

objectclass ( 1.3.6.1.4.1.7568.1.2.10 NAME 'ircamAlias' SUP top STRUCTURAL
    DESC ''
    MAY ( mailRoutingAddress ) )</pre>
<p>La classe d&#8217;objet <em>ircamAlias</em> ne sert que pour la gestion des alias indépendants des utilisateurs (listes de diffusion et redirections « vers l&#8217;extérieur » notamment). Nous allons la laisser de côté pour le moment.<br />
Concrètement, un utilisateur ressemble à ça :</p>
<pre>dn: uid=empion, ou=People, dc=example, dc=com
objectClass: account
objectClass: top
objectClass: inetLocalMailRecipient
objectClass: ircamLocalMailRecipient
objectClass: inetOrgPerson
objectClass: pilotPerson
objectClass: ircamAccount
objectClass: shadowAccount
objectClass: organizationalPerson
objectClass: person
objectClass: ircamPerson
uid: empion
mailRoutingAddress: empion@mailboxes.example.com
mailAcceptingAddress: tout-le-monde@example.com
mailAcceptingAddress: groupe-de-travail@example.com
mailLocalAddress: tartempion@example.com
mailLocalAddress: tarte.empion@example.com
mail: Tarte.Empion@example.com
sn: Empion
cn: Tarte Empion
uidNumber: 12345
gidNumber: 333</pre>
<h1>La configuration de Postfix</h1>
<p>Postfix, c&#8217;est bien. Si, si. Je sais que vous en êtes déjà convaincus, mais c&#8217;est encore une occasion de le dire. Pour utiliser ce qui précède, il suffit de ces quelques lignes de config dans <em>main.cf</em> :</p>
<pre>sender_canonical_classes = envelope_sender, header_sender
sender_canonical_maps = ldap:ldapcanon
ldapcanon_server_host = ldap.example.com
ldapcanon_server_port = 389
ldapcanon_search_base = dc=example,dc=com
ldapcanon_query_filter = (&#038;(mailLocalAddress=%s)(mail=*))
ldapcanon_result_attribute = mail

virtual_maps = ldap:ldapvirt
ldapvirt_server_host = ldap.example.com
ldapvirt_server_port = 389
ldapvirt_search_base = dc=example,dc=com
ldapvirt_query_filter = (|(mailLocalAddress=%s)(mailAcceptingAddress=%s))
ldapvirt_result_attribute = mailRoutingAddress</pre>
<p>C&#8217;est tout, rien de tordu à faire. Une fois ce bout de config en place, l&#8217;adresse source <em>tartempion@example.com</em> sera réécrite en <em>Tarte.Empion@example.com</em> (techniquement, <em>tarte.empion@example.com</em> sera réécrite aussi, mais ça ne fera ni chaud ni froid à la plupart des systèmes de courrier électronique actuels), et les messages envoyés à <em>tarte.empion@example.com</em>, <em>tartempion@example.com</em>, <em>tout-le-monde@example.com</em> et <em>groupe-de-travail@example.com</em> seront renvoyés à <em>empion@mailboxes.example.com</em> (et éventuellement à d&#8217;autres si ces mêmes alias sont aussi définis dans d&#8217;autres fiches). Elle est pas belle, la vie ?</p>
<h1>Les scripts</h1>
<p>OK, maintenant on sait à quoi les données peuvent ressembler, mais est-ce qu&#8217;il y a un outil plus simple que ldapvi pour les mettre dans l&#8217;annuaire ? Oui et non. J&#8217;ai bricolé récemment une petite série de scripts pour éditer l&#8217;attribut <em>mailAcceptingAddress</em> d&#8217;une fiche ; en pratique, c&#8217;est le seul qui varie plus ou moins souvent, les autres sont fixés à la création du compte. Les outils en question sont téléchargeables <a href="http://files.glou.org/blog/mail-ldap-tools-20100326.tar.gz">ici</a>. L&#8217;archive contient :</p>
<ul>
<li>le module <em>ircamldap.py</em> qui initialise quelques variables utiles (serveur LDAP, mot de passe admin&#8230;)</li>
<li>son fichier de configuration <em>ircamldap.cfg</em></li>
<li>les scripts <em>add-mail-alias</em>, <em>remove-mail-alias</em> et <em>get-mail-aliases</em> qui font l&#8217;essentiel du vrai boulot.</li>
</ul>
<p>Pour l&#8217;utilisation de ces derniers, j&#8217;ai essayé de faire assez simple pour mes deux neurones ; en pratique, ça donne ça :</p>
<pre><strong>% get-mail-aliases empion</strong>
tout-le-monde@example.com
groupe-de-travail@example.com
<strong>% add-mail-alias empion monnouvelaliasquilestbien@example.net</strong>
<strong>% get-mail-aliases empion</strong>
tout-le-monde@example.com
groupe-de-travail@example.com
monnouvelaliasquilestbien@example.net
<strong>% remove-mail-alias empion monnouvelaliasquilestbien@example.net tout-le-monde@example.com</strong>
<strong>% get-mail-aliases empion</strong>
groupe-de-travail@example.com
<strong>%</strong></pre>
<p>Pour le moment, ces outils marchent à peu près mais il ne faut pas leur en demander trop. Entre autres, leur gestion des erreurs est assez minimale, et ils ne positionnent pas forcément toujours leur code de retour comme il faudrait. Ce sera pour la prochaine version. <img src='http://blogs.glou.org/arnaud/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Bien entendu, je suis preneur de toute suggestion, amélioration, patch ou autre « mais t&#8217;es con, ça fait 10 ans que ça existe en mieux ».</p>
<p><em>- Il est bizarre, ton café.<br />
- Normal, c&#8217;est une bière. Tu es admin système ou pas ?</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.glou.org/arnaud/2010/03/26/alias-mail-et-ldap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nagios et LDAP, partie 2</title>
		<link>http://blogs.glou.org/arnaud/2009/08/27/nagios-et-ldap-partie-2/</link>
		<comments>http://blogs.glou.org/arnaud/2009/08/27/nagios-et-ldap-partie-2/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 09:58:42 +0000</pubDate>
		<dc:creator>nono</dc:creator>
				<category><![CDATA[geekeries]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Nagios]]></category>

		<guid isPermaLink="false">http://blogs.glou.org/arnaud/?p=135</guid>
		<description><![CDATA[Une petite mise à jour du stockage de la configuration LDAP dans Nagios, puisque j&#8217;ai eu besoin de différencier les périodes de surveillance : nous avons une application web qui est arrêtée pendant la nuit pour des opérations de maintenance genre sauvegarde et nettoyage des logs.
Le schéma LDAP
J&#8217;ai ajouté un attribut optionnel timePeriod à la classe [...]]]></description>
			<content:encoded><![CDATA[<p>Une petite mise à jour du <a href="http://blogs.glou.org/arnaud/2009/08/25/stocker-la-configuration-de-nagios-dans-un-annuaire-ldap/">stockage de la configuration LDAP dans Nagios</a>, puisque j&#8217;ai eu besoin de différencier les périodes de surveillance : nous avons une application web qui est arrêtée pendant la nuit pour des opérations de maintenance genre sauvegarde et nettoyage des logs.</p>
<h1>Le schéma LDAP</h1>
<p>J&#8217;ai ajouté un attribut optionnel <em>timePeriod</em> à la classe <em>nagiosHost</em>. Il doit contenir le nom d&#8217;une période définie ailleurs dans la config (chez moi elles sont en dur dans <em>localhost.cfg</em>, ça vient de la configuration d&#8217;origine de Nagios) ; s&#8217;il n&#8217;est pas renseigné, on conviendra qu&#8217;il vaut <em>24&#215;7</em> par défaut.</p>
<p>En langage schéma LDAP, ça se dit comme ça :</p>
<p><code>attributetype ( 1.3.6.1.4.1.7568.1.1.33 NAME ( 'timePeriod' ) SUP name )<br/><br />
objectclass ( 1.3.6.1.4.1.7568.1.2.12 NAME 'nagiosHost' SUP top AUXILIARY<br />
        DESC ''<br />
        MAY ( nagiosService $ nagiosName $ timePeriod ) )</code></p>
<p>Notez que je ne fais pas de différence entre les différents services associés à un hôte, ils sont tous surveillés ou pas en même temps. Dans mon cas ça se justifie, puisque je n&#8217;installe qu&#8217;une seule application par machine (virtuelle). Si vous avez besoin de surveiller plusieurs services sur la même machine de façon différenciée, je suppose que vous pouvez créer plusieurs fiches LDAP pour la machine en question, mais ça me semble un peu compliqué et ça risque d&#8217;avoir des effets de bord pour les autres applications qui s&#8217;appuient sur le même annuaire.</p>
<h1>Les scripts</h1>
<p>Le script <em>gen-nagios-services-hosts</em> de la dernière fois demande quelques modifications minimes pour s&#8217;adapter au nouveau schéma. Le patch étant presque aussi long que le script lui-même, voici <a href="http://files.glou.org/blog/gen-nagios-services-hosts-v2.txt">la nouvelle version</a> directement en ligne.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.glou.org/arnaud/2009/08/27/nagios-et-ldap-partie-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stocker la configuration de Nagios dans un annuaire LDAP</title>
		<link>http://blogs.glou.org/arnaud/2009/08/25/stocker-la-configuration-de-nagios-dans-un-annuaire-ldap/</link>
		<comments>http://blogs.glou.org/arnaud/2009/08/25/stocker-la-configuration-de-nagios-dans-un-annuaire-ldap/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 15:52:39 +0000</pubDate>
		<dc:creator>nono</dc:creator>
				<category><![CDATA[geekeries]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Nagios]]></category>

		<guid isPermaLink="false">http://blogs.glou.org/arnaud/?p=90</guid>
		<description><![CDATA[À ma gauche, un serveur Nagios. À ma droite, un annuaire LDAP. Le but de la manoeuvre est de générer automatiquement la configuration du premier à partir du deuxième. L&#8217;intérêt de la chose : s&#8217;assurer que le serveur Nagios est toujours à jour et surveille bien ce qu&#8217;il doit (étant entendu que l&#8217;annuaire LDAP est [...]]]></description>
			<content:encoded><![CDATA[<p>À ma gauche, un serveur <a href="http://www.nagios.org/">Nagios</a>. À ma droite, un annuaire LDAP. Le but de la manoeuvre est de générer automatiquement la configuration du premier à partir du deuxième. L&#8217;intérêt de la chose : s&#8217;assurer que le serveur Nagios est toujours à jour et surveille bien ce qu&#8217;il doit (étant entendu que l&#8217;annuaire LDAP est lui-même tenu à jour, ce qui devrait être le cas).</p>
<p>Tout ça s&#8217;applique à Nagios 2.x ; je l&#8217;utilise simplement parce que c&#8217;est la version immédiatement installable sur mon OS de prédilection (<a href="http://www.centos.org/">CentOS</a> 5 avec <a href="https://fedoraproject.org/wiki/EPEL">EPEL</a>). Je n&#8217;ai pas regardé à quoi ressemblait Nagios 3 mais j&#8217;imagine que les principes sont facilement adaptables.</p>
<h1>Vue d&#8217;ensemble</h1>
<p>Je suis parti de la configuration par défaut dont j&#8217;ai gardé trois fichiers : <em>nagios.cfg</em>, <em>localhost.cfg</em> et <em>cgi.cfg</em>, auxquels j&#8217;ai juste apporté les quelques modifications nécessaires pour les adapter à mon installation locale. La seule partie que je vais détailler est la liste des inclusions au début du fichier <em>nagios.cfg</em>, qui ressemble à ça :</p>
<p><code># host and service definitions for monitoring this machine<br />
cfg_file=/etc/nagios/localhost.cfg<br/><br />
# human-maintained parts, if any<br />
cfg_dir=/etc/nagios/admin<br />
cfg_dir=/etc/nagios/hosts<br />
cfg_dir=/etc/nagios/services<br/><br />
# script-generated parts<br />
cfg_file=/etc/nagios/commands.cfg<br />
cfg_file=/etc/nagios/hosts.cfg<br />
cfg_file=/etc/nagios/services.cfg</code></p>
<p>Le premier fichier, <em>localhost.cfg</em>, provient tel quel de la distribution Nagios. Les répertoires <em>admin</em>, <em>hosts</em> et <em>services</em> sont là au cas où je voudrais ajouter des bouts de config à la main. Les trois derniers fichiers sont générés par les scripts dont on va parler dans la suite.</p>
<h1>Les commandes</h1>
<h2>Définitions</h2>
<p>Une commande, au sens Nagios, se compose d&#8217;un nom (le paramètre <em>command_name</em> dans le fichier de config) et d&#8217;une ligne de commande (le paramètre <em>command_line</em>). J&#8217;ai donc ajouté une classe regroupant ces deux attributs à mon schéma LDAP. J&#8217;ai aussi crée un attribut <em>command</em> qui n&#8217;existait pas. Au final, ça donne ça :</p>
<p><code>attributetype ( 1.3.6.1.4.1.7568.1.1.32 NAME ( 'command' ) SUP name )<br/><br />
objectclass ( 1.3.6.1.4.1.7568.1.2.15 NAME 'nagiosCommand' SUP top STRUCTURAL<br />
        DESC 'Nagios command definition'<br />
        MUST ( cn $ command )<br />
        MAY ( description ) )</code></p>
<h2>Données</h2>
<p>Une fois le schéma à jour, une commande se définit comme ça :</p>
<p><code>dn: cn=check_ldap,ou=commands,ou=nagios,ou=tools,dc=ircam,dc=fr<br />
objectClass: nagiosCommand<br />
objectClass: top<br />
cn: check_ldap<br />
command: $USER1$/check_ldap -H $HOSTADDRESS$ -b dc=ircam,dc=fr -3</code></p>
<p>Pour ceux que ça intéresse, j&#8217;ai bricolé un bout de script Perl pour convertir le fichier <em>commands.cfg</em> d&#8217;origine au format LDIF ; il est disponible <a href="http://files.glou.org/blog/commands2ldif.txt">ici</a>. Attention, il ne fonctionnera pas sur un fichier qui n&#8217;est pas écrit comme le <em>commands.cfg</em> d&#8217;origine de Nagios (disposition différente des espaces ou autres variantes du genre).</p>
<h2>Génération</h2>
<p>Maintenant qu&#8217;on a nos commandes dans l&#8217;annuaire, il suffit de les relire pour générer le fichier <em>commands.cfg</em>. Je fais ça avec <a href="http://files.glou.org/blog/gen-nagios-commands.txt">ce script Python</a>.</p>
<p>Le serveur et le DN de base LDAP y sont codés en dur, promis, dans la prochaine version, je mets des options. <img src='http://blogs.glou.org/arnaud/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h1>Les machines et les services</h1>
<p>Dans mon esprit, les machines et les services « vont ensemble » ; je génère donc les fichiers <em>hosts.cfg</em> et <em>services.cfg</em> en même temps.</p>
<h2>Définitions</h2>
<p>Un service Nagios, tout comme une commande, est défini avant tout par un nom et une commande à exécuter (la commande en question n&#8217;a rien à voir avec celles du paragraphe précédent, mais peu importe, on n&#8217;a pas besoin de définir un attribut LDAP différent). Il doit aussi avoir une description (pas peut, doit, sinon Nagios râle très fort). Dans mon cas, les autres options (contacts, périodicités et autres) sont communes à tous les services et codées en dur dans le script de génération. Encore une fois, on verra dans la prochaine version pour une approche plus propre.</p>
<p>Une machine, quant à elle, est définie par un nom d&#8217;hôte, une adresse IP (tous deux définis dans la classe d&#8217;objet <em>ipHost</em>), une liste de services et éventuellement un alias qui apparaîtra dans l&#8217;interface web. Tout comme pour les services, tout le reste est pour le moment défini en dur dans le script de génération.</p>
<p>En termes de schéma LDAP, ça nous donne ça :</p>
<p><code>attributetype ( 1.3.6.1.4.1.7568.1.1.28 NAME ( 'nagiosService' ) SUP name )<br />
attributetype ( 1.3.6.1.4.1.7568.1.1.29 NAME ( 'nagiosName' ) SUP name )<br/><br />
objectclass ( 1.3.6.1.4.1.7568.1.2.14 NAME 'nagiosServiceType' SUP top STRUCTURAL<br />
        DESC 'Nagios service definition'<br />
        MUST ( cn $ command $ description ) )<br/><br />
objectclass ( 1.3.6.1.4.1.7568.1.2.12 NAME 'nagiosHost' SUP top AUXILIARY<br />
        DESC ''<br />
        MAY ( nagiosService $ nagiosName ) )</code></p>
<h2>Données</h2>
<p>Maintenant qu&#8217;on sait ce que sont un service et une machine, on peut en ajouter dans l&#8217;annuaire. Il y a quelques bricoles pas strictement indispensables pour nous dans ce qui suit ; l&#8217;annuaire LDAP ne sert pas que pour Nagios. <img src='http://blogs.glou.org/arnaud/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><code>dn: cn=ldap,ou=services,ou=nagios,ou=tools,dc=ircam,dc=fr<br />
objectClass: nagiosServiceType<br />
objectClass: top<br />
cn: ldap<br />
command: check_ldap<br />
description: LDAP<br/><br />
dn: cn=ldap4.ircam.fr,ou=virtuels,ou=Hosts,dc=ircam,dc=fr<br />
cn: ldap4.ircam.fr<br />
ipHostNumber: 129.102.6.196<br />
objectClass: top<br />
objectClass: device<br />
objectClass: ircamDevice<br />
objectClass: ieee802Device<br />
objectClass: bootableDevice<br />
objectClass: ipHost<br />
objectClass: nagiosHost<br />
nagiosService: ldap</code></p>
<h2>Génération</h2>
<p>On utilise <a href="http://files.glou.org/blog/gen-nagios-services-hosts.txt">le petit frère du script précédent</a>. Il crée deux fichiers <em>hosts.cfg</em> et <em>services.cfg</em> dans le répertoire courant sans se poser de questions ; attention à ne pas effacer de données importantes !</p>
<h1>Servez chaud !</h1>
<p>En cadeau puisque vous êtes sages, le bout de Makefile qui va bien pour utiliser tout ça :</p>
<p><code>all:<br />
        /usr/local/sbin/gen-nagios-hosts-services<br />
        /usr/local/sbin/gen-nagios-commands > commands.cfg<br />
        /bin/chmod 0644 hosts.cfg services.cfg commands.cfg<br />
        /sbin/service nagios restart<br />
</code></p>
<p>La semaine prochaine, si j&#8217;ai le temps, vous aurez la classe puppet qui va avec. <img src='http://blogs.glou.org/arnaud/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><em>Edit 26/08/2009 : la description des services est obligatoire.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.glou.org/arnaud/2009/08/25/stocker-la-configuration-de-nagios-dans-un-annuaire-ldap/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
