<?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 coin du sysadmin &#187; Scripting</title>
	<atom:link href="http://laurent.cligny.net/index.php/category/scripting/feed/" rel="self" type="application/rss+xml" />
	<link>http://laurent.cligny.net</link>
	<description>La connaissance s&#039;accroit en la partagant</description>
	<lastBuildDate>Tue, 15 Feb 2011 08:45:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Grapher l&#8217;activité de PF grâce à pfstat</title>
		<link>http://laurent.cligny.net/index.php/2009/02/11/graph-pfstat/</link>
		<comments>http://laurent.cligny.net/index.php/2009/02/11/graph-pfstat/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 12:57:51 +0000</pubDate>
		<dc:creator>laurent</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[OpenBSD PF]]></category>
		<category><![CDATA[pfstat]]></category>

		<guid isPermaLink="false">http://laurent.cligny.net/?p=95</guid>
		<description><![CDATA[Aujourd&#8217;hui, point de bidouille, point de manipulations absconses, mais plutôt de jolis graphiques où l&#8217;on voit avec tendresse s&#8217;ébattre notre pare-feu OpenBSD PF. Comment celà peut-il être dans le domaine du possible ? Tout simplement grâce à l&#8217;outil pfstat, écrit par le créateur de PF lui-même. Afin de ne pas vous perdre en cours de [...]]]></description>
			<content:encoded><![CDATA[<p>Aujourd&#8217;hui, point de bidouille, point de manipulations absconses, mais plutôt de jolis graphiques où l&#8217;on voit avec tendresse s&#8217;ébattre notre pare-feu OpenBSD PF.</p>
<p>Comment celà peut-il être dans le domaine du possible ? Tout simplement grâce à l&#8217;outil pfstat, écrit par <a href="http://www.benzedrine.cx/dhartmei.html">le créateur de PF</a> lui-même.<span id="more-95"></span></p>
<p>Afin de ne pas vous perdre en cours de lecture pour cause de démotivation devant les sigles cryptiques et autres incantations shellmaniques qui parsèment comme à l&#8217;accoutumée mes billets techniques, voici un aperçu de ce que nous allons obtenir:</p>
<div id="attachment_99" class="wp-caption aligncenter" style="width: 522px"><a rel="attachment wp-att-99" href="http://laurent.cligny.net/index.php/2009/02/11/graph-pfstat/pfstat_screenshot1/"><img class="size-full wp-image-99" title="pfstat_screenshot1" src="http://laurent.cligny.net/wp-content/uploads/pfstat_screenshot1.png" alt="Pfstat Screenshot" width="512" height="466" /></a><p class="wp-caption-text">Pfstat Screenshot</p></div>
<p>Passons donc maintenant dans le vif du sujet. Nous allons créer les graphiques montrants les octets que PF à laissé passer sur l&#8217;interface sis0, ainsi que les packets passés et bloqués sur cette même interface sur une période de 24 heures.</p>
<p>Tout d&#8217;abord il faut installer pfstat:</p>
<p># pkg_add -r pfstat</p>
<p>Puis on créé un fichier de configuration adéquat /usr/local/etc/pfstat.conf contenant ceci:</p>
<table border="0" align="center">
<tbody>
<tr>
<td>
<p style="line-height: normal;"><span style="color: #008000;">#On indique l&#8217;interface réseau, l&#8217;état, l&#8217;unité de mesure, le sens, le protocole, et si les données sont différentielles</span> <span style="color: #008000;">pour chaque valeur.</span></p>
<p><span style="color: #0000ff;">collect 1 = interface &#8220;sis0&#8243; pass bytes in ipv4 diff<br />
 collect 2 = interface &#8220;sis0&#8243; pass bytes out ipv4 diff</span></p>
<p><span style="color: #0000ff;"><span style="color: #008000;">#On indique le chemin complet de l&#8217;image générée par pfstat, et qui sera affichée par notre serveur web</span><br />
 image &#8220;/usr/local/www/data/pfstat/images/pfstat-bandwidth-day.png&#8221;      {</span></p>
<p><span style="color: #0000ff;"><span style="color: #008000;">#On donne la période affichée et la taille de l&#8217;image générée en pixels</span><br />
 from 24 hours to now<br />
 width 1000 height 400</span></p>
<p><span style="color: #008000;">#On dit ce qu&#8217;on affiche comme données dans notre image</span></p>
<p><span style="color: #0000ff;"><span style="color: #008000;">#L&#8217;axe Y du graphique &#8220;1&#8243; (voir &#8220;collect 1&#8243; plus haut) se trouvera à gauche, les données sont de type bps, puis viennent les options pour la légende (nom du graphe, unité de mesure et couleur)</span><br />
 left<br />
 graph 1 bps &#8220;in&#8221; &#8220;byte/s&#8221; color 0 192 0 filled<br />
 right<br />
 graph 2 bps &#8220;out&#8221; &#8220;byte/s&#8221; color 0 0 255<br />
 }</span></p>
<p><span style="color: #0000ff;"><span style="color: #008000;">#Les même graphiques que précédemment, mais en générant une image plus petite. Seuls les noms de l&#8217;image générée, et la taille de l&#8217;image en pixels change. De même on peut créer les graphiques pour la semaine, le mois et l&#8217;année passée en modifiant l&#8217;option &#8220;from&#8221;</span><br />
 image &#8220;/usr/local/www/data/pfstat/images/pfstat-bandwidth-day-small.png&#8221;        {<br />
 from 24 hours to now<br />
 width 500 height 200<br />
 left<br />
 graph 1 bps &#8220;in&#8221; &#8220;byte/s&#8221; color 0 192 0 filled<br />
 right<br />
 graph 2 bps &#8220;out&#8221; &#8220;byte/s&#8221; color 0 0 255<br />
 }</span></p>
<p><span style="color: #0000ff;"><span style="color: #008000;">#On procède de la même manière avec les paquets, mais on y ajoute les paquets bloqués (ce qui n&#8217;avait pas sens dans les premiers graphiques qui eux affichent des octets)</span><br />
 collect 3 = interface &#8220;sis0&#8243; pass packets in ipv4 diff<br />
 collect 4 = interface &#8220;sis0&#8243; pass packets out ipv4 diff<br />
 collect 5 = interface &#8220;sis0&#8243; block packets in ipv4 diff<br />
 collect 6 = interface &#8220;sis0&#8243; block packets out ipv4 diff<br />
 image &#8220;/usr/local/www/data/pfstat/images/pfstat-packets-day.png&#8221;        {<br />
 from 24 hours to now<br />
 width 1000 height 400<br />
 left<br />
 graph 3 &#8220;pass in&#8221; &#8220;pkt/s&#8221; color 0 192 0 filled,<br />
 graph 4 &#8220;pass out&#8221; &#8220;pkt/s&#8221; color 0 0 255<br />
 right<br />
 graph 5 &#8220;block in&#8221; &#8220;pkt/s&#8221; color 255 0 0,<br />
 graph 6 &#8220;block out&#8221; &#8220;pkt/s&#8221; color 192 192 0<br />
 }<br />
 image &#8220;/usr/local/www/data/pfstat/images/pfstat-packets-day-small.png&#8221;  {<br />
 from 24 hours to now<br />
 width 500 height 200<br />
 left<br />
 graph 3 &#8220;pass in&#8221; &#8220;pkt/s&#8221; color 0 192 0 filled,<br />
 graph 4 &#8220;pass out&#8221; &#8220;pkt/s&#8221; color 0 0 255<br />
 right<br />
 graph 5 &#8220;block in&#8221; &#8220;pkt/s&#8221; color 255 0 0,<br />
 graph 6 &#8220;block out&#8221; &#8220;pkt/s&#8221; color 192 192 0<br />
 }</span></p>
</td>
</tr>
</tbody>
</table>
<p><span style="color: #0000ff;"><span style="color: #000000;">Bien sûr, il y a beaucoup d&#8217;autres possibilités, comme grapher les files d&#8217;attentes, les états. La <a href="http://www.benzedrine.cx/pfstat.html">page pfstat</a> de l&#8217;auteur en montre un bon panel.</span></span></p>
<p><span style="color: #0000ff;"><span style="color: #000000;">Mais revenons à nos affaires. Il nous faut maintenant créer le répertoire ou seront hebergées la page web d&#8217;affichage de nos graphiques ainsi que les images:</span></span></p>
<p><span style="color: #0000ff;"><span style="color: #000000;"># mkdir -p /usr/local/www/data/pfstat/images</span></span></p>
<p><span style="color: #0000ff;"><span style="color: #000000;">Puis on vérifie que ça fonctionne:</span></span></p>
<p><span style="color: #0000ff;"><span style="color: #000000;"># pfstat -q -p</span></span></p>
<p><span style="color: #0000ff;"><span style="color: #000000;">Cette commande demande à pfstat de compiler les statistiques de pf(4) pour l&#8217;instant <em>t </em>et de créer les graphiques correspondant à l&#8217;emplacement renseigné dans notre fichier de configuration. On peut vérifier le bon fonctionnement par la présence d&#8217;un fichier /var/db/pfstat.db ainsi que celle des graphiques.</span></span></p>
<p># ls -l /var/db/pfstat.db<br />
 -rw&#8212;&#8212;-  1 root  wheel  8192 Feb  6 08:41 /var/db/pfstat.db<br />
 # ls -l /usr/local/www/data/pfstat/images/<br />
 total 846<br />
 -rw-r&#8211;r&#8211;  1 root  wheel  24063 Feb  6 08:41 pfstat-bandwidth-day-small.png<br />
 -rw-r&#8211;r&#8211;  1 root  wheel  64065 Feb  6 08:41 pfstat-bandwidth-day.png<br />
 -rw-r&#8211;r&#8211;  1 root  wheel  27066 Feb  6 08:41 pfstat-packets-day-small.png<br />
 -rw-r&#8211;r&#8211;  1 root  wheel  66568 Feb  6 08:41 pfstat-packets-day.png</p>
<p>Maintenant que ça fonctionne, on automatise la récolte des statistiques de pf(4) grâce à une simple tâche cron(8). Ajoutons ceci dans /etc/crontab:</p>
<p>*    *    *    *    *    root    /usr/local/bin/pfstat -q -p -t 31:365</p>
<p>L&#8217;option -t, permet à pfstat de compresser les donnés vieilles de plus d&#8217;un mois et d&#8217;effacer celles de plus d&#8217;un an. Ainsi notre base /var/db/pfstat.db ne devrait pas grossir exagérément.</p>
<p>Il ne reste plus qu&#8217;à afficher tous ces jolis graphiques sur une page html (ou autre).</p>
<p>Par exemple:</p>
<p>Configuration Apache 2.2</p>
<p>Créer un fichier /usr/local/etc/apache22/Includes/pfstat.conf contenant</p>
<table border="0">
<tbody>
<tr>
<td><span style="color: #0000ff;">Alias /pfstat /usr/local/www/data/pfstat<br />
 DocumentRoot &#8220;/usr/local/www/data/pfstat&#8221;<br />
 &lt;Directory &#8220;/usr/local/www/data/pfstat&#8221;&gt;<br />
 DirectoryIndex index.html<br />
 Order deny,allow<br />
 Allow from all<br />
 Satisfy Any<br />
 &lt;/Directory&gt;<br />
 </span></td>
</tr>
</tbody>
</table>
<p><span style="color: #000000;">Créer un fichier /usr/local/www/data/pfstat/index.html contenant</span></p>
<p><br class="spacer_" /></p>
<table border="0">
<tbody>
<tr>
<td><span style="color: #0000ff;">&lt;!DOCTYPE HTML PUBLIC &#8220;-//W3C//DTD HTML 4.01 Transitional//EN&#8221;&gt;<br />
 &lt;html&gt;</p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
<p>&lt;head&gt;</p>
<p>&lt;meta http-equiv=&#8221;Content-Type&#8221; content=&#8221;text/html; charset=US-ASCII&#8221;&gt;<br />
 &lt;title&gt;PF Firewall Statistics&lt;/title&gt;</p>
<p>&lt;/head&gt;</p>
<p>&lt;body text=&#8221;#000000&#8243; bgcolor=&#8221;#FFFFFF&#8221; link=&#8221;#1919C0&#8243; vlink=&#8221;#101030&#8243; alink=&#8221;#FE0000&#8243;&gt;</p>
<p>&lt;h1&gt;PF Firewall Statistics for sis0 interface&lt;/h1&gt;</p>
<p>&lt;h2&gt;interface sis0 pass bytes ipv4, Bytes/s&lt;/h2&gt;<br />
 &lt;h3&gt;Daily statistics&lt;/h3&gt;<br />
 &lt;a href=&#8221;images/pfstat-bandwidth-day.png&#8221;&gt;&lt;img src=&#8221;images/pfstat-bandwidth-day-small.png&#8221; border=&#8221;0&#8243;&gt;&lt;/a&gt;<br />
 &lt;p&gt;</p>
<p>&lt;h2&gt;interface sis0 pass/block packets ipv4, Packets/s&lt;/h2&gt;<br />
 &lt;h3&gt;Daily statistics&lt;/h3&gt;<br />
 &lt;a href=&#8221;images/pfstat-packets-day.png&#8221;&gt;&lt;img src=&#8221;images/pfstat-packets-day-small.png&#8221; border=&#8221;0&#8243;&gt;&lt;/a&gt;<br />
 &lt;p&gt;</p>
<p>&lt;/body&gt;</p>
<p>&lt;/html&gt;</p>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
<p></span></td>
</tr>
</tbody>
</table>
<p><br class="spacer_" /></p>
<p>N&#8217;oublions pas de recharger la configuration d&#8217;apache:</p>
<p># /usr/local/etc/rc.d/apache22 reload</p>
<p>Vous pouvez bien sûr vous inspirer ma de propre <a href="http://www.cligny.net/pfstat">page pfstat</a> pour compléter le tout.</p>
<p>A bientôt chers (et de plus en plus nombreux) lecteurs <img src='http://laurent.cligny.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://laurent.cligny.net/index.php/2009/02/11/graph-pfstat/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Extraire des données Active Directory pour Postfix</title>
		<link>http://laurent.cligny.net/index.php/2008/09/09/extraire-des-donnees-active-directory-pour-postfix/</link>
		<comments>http://laurent.cligny.net/index.php/2008/09/09/extraire-des-donnees-active-directory-pour-postfix/#comments</comments>
		<pubDate>Tue, 09 Sep 2008 10:06:25 +0000</pubDate>
		<dc:creator>laurent</dc:creator>
				<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://laurent.cligny.net/?p=7</guid>
		<description><![CDATA[Ou comment extraire les mails valides d&#8217;un domaine Active Directory pour les fournir à Postfix. &#8220;Pourquoi faire ?&#8221; Me direz-vous. Et bien c&#8217;est simple, refuser un mail envoyé à une adresse mail qui n&#8217;existe pas, avant de la relayer à votre infrastructure Exchange, c&#8217;est chouette. Un peu comme un retour de la poste &#8220;N&#8217;habite plus [...]]]></description>
			<content:encoded><![CDATA[<p>Ou comment extraire les mails valides d&#8217;un domaine Active Directory pour les fournir à Postfix.</p>
<p>&#8220;Pourquoi faire ?&#8221; Me direz-vous. Et bien c&#8217;est simple, refuser un mail envoyé à une adresse mail qui n&#8217;existe pas, avant de la relayer à votre infrastructure Exchange, c&#8217;est chouette. Un peu comme un retour de la poste &#8220;N&#8217;habite plus à l&#8217;adresse indiquée&#8221; en somme. <span id="more-7"></span></p>
<p><strong> 1. Configuration de Postfix</strong></p>
<p>Pour demander à Postfix d&#8217;y regarder à deux fois avant d&#8217;accepter un mail, il faut lui dire dans quelle liste il va devoir chercher une occurrence. Pour ça on ajoute la ligne suivante dans <em>main.cf</em>:</p>
<p><span style="color: #0000ff;">relay_recipient_maps = hash:/usr/local/etc/postfix/relay_recipients</span></p>
<p>Ce qui à pour effet de demander à Postfix de regarder dans ce fichier à chaque fin de commande RCPT To: qu&#8217;il reçoit et de répondre par une erreur s&#8217;il ne trouve rien qui corresponde.</p>
<p>Formidable n&#8217;est-ce pas ? Mais maintenant il faut le remplir ce fichier (sous la forme mailaddress@example.com OK pour un fichier de type &#8220;hash&#8221;). Donc soit on embauche quelqu&#8217;un pour réactualiser ce fichier à chaque nouvelle adresse-mail (sans oublier le &#8220;<em>postmap /usr/local/etc/postfix/relay_recipients</em>&#8221; après chaque modif), soit on demande (gentiment) à son serveur de le faire à notre place <img src='http://laurent.cligny.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Mais juste avant ça, regardons les différents options (non exhaustives, cf &#8220;<em>man 5 postconf</em>&#8221; pour les curieux) qui s&#8217;offrent à nous pour stocker nos belles adresses e-mails valides dans notre infrasctructure Exchange.</p>
<ul>
<li>Soit on les met tel quels dans notre fichier plat avec un &#8220;<em>postmap &lt;relay_recipients&gt;</em>&#8221; qui va bien pour en faire un &#8220;&lt;relay_recipients.db&gt;&#8221; au format BerkeleyDB.</li>
<li>Soit on met nos jolies adresses dans une base de donnée type MySQL ou PostgreSQL.</li>
<li>Soit on est un bourrin et on fait directement des requêtes LDAP dans Active Directory pour chaque vérification d&#8217;adresse (et à plusieurs par seconde sur un serveur mail d&#8217;entreprise moyen, vos serveurs Active Directory vont faire une drôle de tronche).</li>
</ul>
<p>Etant de nature mi-figue mi-raisin, et puisque mon serveur dispose déjà du moteur de base de donnée MySQL, j&#8217;opte pour la deuxième option. <strong></strong></p>
<p><strong> 2. Ca va scripter chérie !</strong></p>
<p>Résumons ! Nous voulons demander des infos à <strong>ActiveDirectory</strong> donc <strong>LDAP</strong>, les mettre sous la forme &#8220;mailaddress@example.com&#8221; et les écrire dans une base <strong>MySQL </strong>(qu&#8217;on appellera <em>postfix</em>). Et pour ça le moteur de script <strong>Perl</strong> c&#8217;est super ! Pourquoi ? Parcequ&#8217;il existe une foultitude de modules Perl pour moult moteurs de base de données, protocoles réseaux, serveurs, j&#8217;en passe et des meilleures. Ce qui fait qu&#8217;en un script, on peut faire tout ce qu&#8217;il nous faut et même plus (par contre pour faire café, voyez plutôt avec Java).</p>
<p><strong>2.1 Avant de &#8220;coder&#8221;</strong></p>
<p>Avant de vous lancer à corps perdu dans le copier-col^WWécriture de ce script, veuillez noter les pré requis dont vous aurez besoin en matière de modules Perl (attention ce sont les noms des ports FreeBSD):</p>
<ul>
<li>perl 5.8.x (Le moteur de script mondialement connu)</li>
<li>p5-DBD-mysql50 (Le module pour parler à sa base de donnée)</li>
<li>p5-perl-ldap (Le module pour parler LDAP dans le texte)</li>
<li>p5-DBI (Le module dont dépend p5-DBD pour fonctionner)</li>
<li>p5-Storable (Le module dont dépend p5-DBI pour fonctionner)</li>
</ul>
<p>Assurez-vous aussi de créer une table dans votre base de donnée  avec un index pour accueillir vos adresses e-mails. Ce n&#8217;est pas l&#8217;objet de ce (long) billet mais voici comment qu&#8217;on fait (on part du principe d&#8217;être déjà connecté à MySQL):</p>
<pre><em>mysql&gt; CREATE DATABASE postfix;</em></pre>
<pre><em>mysql&gt; CREATE TABLE valid_emails (mail_addresses VARCHAR(128) NOT NULL) type=MyISAM;</em></pre>
<pre><em>mysql&gt; CREATE UNIQUE INDEX id_valid_emails_01 ON valid_emails(mail_addresses);</em></pre>
<p><strong>2.2 Le script</strong></p>
<p>Evidement (quoique&#8230;) le script va se partager en trois actions, la récolte d&#8217;infos, leur mise en forme et leur mise à jours dans la base de donnée. Et comme un exemple vaut mieux qu&#8217;un long discours:</p>
<pre><span style="color: #0000ff;">#!/usr/bin/perl
</span><span><span style="color: #008000;"># On déclare ci-dessus que c'est un script perl

</span></span><span style="color: #0000ff;"><span style="color: #008000;"># On charge nos modules Perl. Notez le "Paged" du module LDAP, il va nous permettre
# d'extraire les données d'Active Directory en contournant la limite de 100 résultats
# par requêtes de celui-ci</span>
</span></pre>
<pre><span style="color: #0000ff;">use DBI();
use Net::LDAP;
use Net::LDAP::Control::Paged;
use Net::LDAP::Constant ( "LDAP_CONTROL_PAGED" );
</span></pre>
<pre><span style="color: #0000ff;"><span style="color: #008000;"># On (est un con, je sais) déclare les constantes pour nos contrôleurs de domaine</span>
$dc1="nameserver1";
$dc2="nameserver2";</span><span style="color: #0000ff;">
$hqbase="dc=example,dc=com"; <span style="color: #008000;"># Votre nom de domain complet</span>

</span><span style="color: #0000ff;"><span style="color: #008000;"># Les login et mot de passe d'un compte ayant les droits en lecture (et seulement en lecture)
# dans Active Directory.</span>
$ldapuser="user";
$ldappasswd="passwd";</span></pre>
<pre><span style="color: #0000ff;"><span style="color: #008000;"># Le nom d'hôte abritant MySQL, le type de base de donnée, le nom de la base et
# de la table à remplir et un login/mot de passe d'un utilisateur MySQL ayant
# les droits INSERT et DELETE sur votre table et <span style="text-decoration: underline;">seulement</span> celle-ci, histoire
# d'éviter les bêtises.</span>
$dbhost="localhost";</span><span style="color: #0000ff;">
$dbtype="mysql";</span><span style="color: #0000ff;">
$dbname="postfix";</span><span style="color: #0000ff;">
$dbtable="valid_emails";
$dbcolumn="mail_addresses";
$dbuser="user";
$dbpasswd="passwd";</span></pre>
<pre><span style="color: #0000ff;"><span style="color: #008000;"># On se connecte à Active Directory avec une gestion d'erreur en cas de problème</span>
$noldapserver=0;
$ldap = Net::LDAP-&gt;new($dc1) or
   $noldapserver=1;
if ($noldapserver == 1)  {
   $ldap = Net::LDAP-&gt;new($dc2) or
      die "Error connecting to specified domain controllers $@ \n";
}

$mesg = $ldap-&gt;bind ( dn =&gt; $ldapuser,
                     password =&gt;$ldappasswd);
if ( $mesg-&gt;code()) {
    die ("error:", $mesg-&gt;code(),"\n","error name: ",$mesg-&gt;error_name(),
        "\n", "error text: ",$mesg-&gt;error_text(),"\n");
}

<span style="color: #008000;"># On se connecte au moteur de base de donnée MySQL</span>
my $dbh = DBI-&gt;connect("DBI:$dbtype:database=$dbname;host=$dbhost","$dbuser","$dbpasswd");

<span style="color: #008000;"># On prépare notre requête LDAP en prenant bien soin de ne pas dépasser une taille de 1000
# réponses par mise en cache de la requête.
<span style="color: #0000ff;">$page = Net::LDAP::Control::Paged-&gt;new( size =&gt; 990 );
<span style="color: #008000;">
# On applique un filtrage des résultats LDAP pour ne garder que ce qui nous intéresse
# (voir aussi RCF 4515, </span></span></span></span><span style="color: #008000;">LDAP:String Representation of Search Filters</span><span style="color: #0000ff;"><span style="color: #008000;"><span style="color: #0000ff;"><span style="color: #008000;">)
</span></span></span></span><span><span><span><span><span style="color: #0000ff;"><span style="color: #008000;"><span style="color: #0000ff;"><span style="color: #008000;"># Et on recherche l'attribut proxyAddresses qui contient les adresses e-mails sous forme
# multivaluée</span></span></span></span></span></span></span></span>

<span style="color: #0000ff;"><span style="color: #008000;"><span style="color: #0000ff;">@args = ( base     =&gt; $hqbase,
          filter =&gt; "(&amp; (mailnickname=*)(| (&amp;(objectCategory=person)
                     (objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*)))
                     (&amp;(objectCategory=person)(objectClass=user)(|(homeMDB=*)
                     (msExchHomeServerName=*)))
                     (objectCategory=group)(objectCategory=publicFolder)))",
          control  =&gt; [ $page ],
          attrs  =&gt; "proxyAddresses",
);</span>

# On commence la recherche pour de vrai
<span style="color: #0000ff;">my $cookie;
while(1) {
  my $mesg = $ldap-&gt;search( @args );

<span style="color: #008000;"># Et on filtre les résulats</span>
  foreach my $entry ( $mesg-&gt;entries ) {

<span style="color: #008000;">    # En ne gardant que les lignes contenant "proxyAddresses".</span>
     foreach my $mail ( $entry-&gt;get_value( "proxyAddresses" ) ) {
     <span style="color: #008000;"># On dégage les vilains </span></span></span></span><span style="color: #008000;"><span><span>"smtp:" et "SMTP:"</span></span> qui se trouvent devant nos adresses e-mails</span><span style="color: #0000ff;"><span style="color: #008000;"><span style="color: #0000ff;">
      if ( $mail =~ s/^(smtp|SMTP)://gs ) {
	 <span style="color: #008000;"># On passe tout en minuscule pour Postfix</span>
	 $mail = lc($mail);
         <span style="color: #008000;"># On écrit le tout dans notre base de donnée</span>
         <span style="color: #008000;"># Notez que REPLACE ici est très pratique car il permet à la fois de mettre à jour
         # les données lorsqu'elles existent, grâce à l'index, et de les INSERT-er si elles
         # n'existent pas encore. Voyez aussi le (</span></span></span></span><span style="color: #008000;"><span><span>" . $dbh-&gt;quote("$mail") . "</span></span>) qui permet
         # d'insérer nos donnéesau format caractère.</span>
<span style="color: #0000ff;"><span style="color: #008000;"><span style="color: #0000ff;">	 $dbh-&gt;do("REPLACE INTO $dbtable ($dbcolumn) VALUES (" . $dbh-&gt;quote("$mail") . ")");
        }
     }
  }

  <span style="color: #008000;"># J'avoue le morceau qui suit n'est pas de moi, je laisse donc les commentaires d'origine
  # En gros on s'assure que les requêtes LDAP mises en cache se passent bien
  # Only continue on LDAP_SUCCESS</span>
  $mesg-&gt;code and last;

  <span style="color: #008000;"># Get cookie from paged control</span>
  my($resp)  = $mesg-&gt;control( LDAP_CONTROL_PAGED ) or last;
  $cookie    = $resp-&gt;cookie or last;

  <span style="color: #008000;"># Set cookie in paged control</span>
  $page-&gt;cookie($cookie);
}

if ($cookie) {
  <span style="color: #008000;"># We had an abnormal exit, so let the server know we do not want any more</span>
  $page-&gt;cookie($cookie);
  $page-&gt;size(0);
  $ldap-&gt;search( @args );
  <span style="color: #008000;"># Also would be a good idea to die unhappily and inform OP at this point</span>
     die("LDAP query unsuccessful");
}

</span></span></span></pre>
<p><span style="color: #0000ff;"><span style="color: #008000;"><span style="color: #0000ff;"><span style="color: #000000;">Rendez votre script exécutable avec <em>chmod +x</em> et voilà ! Evidemment, faites un petit <em>SELECT</em> sur votre table afin de vérifier que les mails sont bien dans la table <em>valid_emails</em>, et que ces valeurs ne se retouvent pas en double quand on lance deux fois le script coup sur coup.<br />
</span></span></span></span></p>
<p><strong><span style="color: #000000;">3. Postfix, le retour</span></strong></p>
<p>Tout ça c&#8217;est bien gentil, mais à la base nous voulons permettre à Postfix de faire une requête dans notre table toute chaude, afin d&#8217;y vérifier que les destinataires existent bien.</p>
<p>Pour ça il faut modifier un chouilla notre ligne <em>relay_recipient_maps</em> dans <em>main.cf</em>:</p>
<p><span style="color: #0000ff;">relay_recipient_maps = <span style="text-decoration: underline;">mysql</span>:/usr/local/etc/postfix/relay_recipients</span></p>
<p>Puis modifier le contenu de ce fichier pour qu&#8217;il ressemble à ça:</p>
<pre><span style="color: #008000;"># Autant dans le script il nous fallait un utilisateur MySQL ayant des droits d'écriture sur
# la table "valid_emails", autant ici un utilisateur MySQL en lecture seule fera l'affaire.</span>
<span style="color: #0000ff;">user = dbuser
password = dbpasswd
dbname = postfix
query = SELECT mail_addresses FROM valid_emails WHERE mail_addresses='%s'</span></pre>
<p>N&#8217;oubliez pas de recharger la conf de Postfix:</p>
<p><em># /usr/local/etc/rc.d/postfix reload</em></p>
<p>Le tout suivi d&#8217;un:</p>
<p><em>% postmap /usr/local/etc/postfix/relay_recipients</em></p>
<p>Puis on teste notre requête via postmap:</p>
<p><em>% postmap -q &#8220;mailaddress@example.com&#8221; mysql:/usr/local/etc/postfix/relay_recipients</em></p>
<p>Si tout fonctionne, l&#8217;email demandé est affiché sur la sortie standard, sinon rien n&#8217;est affiché et il faut tout vous retaper du début <img src='http://laurent.cligny.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>Voilà ! Postfix rejette maintenant tous les mails envoyés à des adresses mails non valides sur notre domaine Active Directory, c&#8217;est déjà ça en moins à traiter pour votre serveur mail adoré.</p>
]]></content:encoded>
			<wfw:commentRss>http://laurent.cligny.net/index.php/2008/09/09/extraire-des-donnees-active-directory-pour-postfix/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

