L'appartement

Aller au contenu | Aller au menu | Aller à la recherche

jeudi, janvier 3 2008

Comment remplacer 2007 par 2008 sur Debian Etch

apt-get remove --purge 2007
apt-get install 2008

OK, je sors ! Mais avant je vous souhaite une bonne année 2008 :)

vendredi, novembre 9 2007

Petite mise à jour du script de mass mailing

Mass

C'est une mise à jour mineure. Les fonctionnalités sont les même que celles de la première version

J'ai eu quelques soucis avec la classe Zend_Mail. Lors d'un envoi, suite à une mise à jour de Zend_Mail, je me suis retrouvé avec des groupes de destinataires en copie au lieu d'un envoi unitaire (pas très sérieux !).

J'ai donc utilisé le "bon vieux" PHPMailer. J'en ai aussi profité pour remplacer PEAR::DB par PDO. Ce qui rend le script plus léger et plus simple à installer ;) . Je l'ai également doté d'un fichier de configuration séparé.

Changelog :

  • Utilisation de PHPMailer à la place de Zend_Mail
  • Utilisation de PDO à la place de PEAR::DB
  • Changement esthétique.
  • Un fichier de configuration séparé.

Documentation

Vous devez télécharger PHPMailer, disposer de PHP5 et l'extension PDO.

Pour le reste, la documentation de la première mouture est toujours valable. Vous pouvez également utiliser toutes les options disponibles dans PHPMailer pour adapter ce script à votre convenance (je vous laisse chercher dans le script).

Important : Ce programme est fourni sans aucune garantie même si je l'utilise toutes les semaines pour une newsletter de 30 000 abonnés.

A faire :

  • une option pour préciser le chemin du fichier de configuration
  • en extra, toujours le gros boulot qui consiste à analyser les retours de mail (Delivery Error).

Téléchargement

télécharger le script

dimanche, novembre 4 2007

Installer DomainKeys sur Postfix (Debian Etch, Amavisd-new...)

Mise à jour le 12 mars 2008 : le même billet adapté pour DKIM est disponible : Installer la signature DKIM sur Postfix avec DKIMproxy.

Dans ma lutte incessante pour que mes messages n'aient pas comme destination finale les dossiers "courrier indésirable" des "grands" fournisseurs tels que Yahoo!, Hotmail/MSN, Gmail ect... Je vous propose aujourd'hui l'installation de la signature Domainkeys sur vos mails.

DomainKeys est un protocole de communication créé par Yahoo! (et défini par une RFC 4870). Wikipedia vous donnera un plus d'informations sur le sujet : DomainKeys sur Wikipedia

Même s'il fonctionne totalement et est déployé sur de nombreux serveurs, sachez qu'il est maintenant remplacé par une RFC plus "globale" : DKIM (Domain Keys Identified Mail). J'aborderais les différences et l'implémentation de DKIM dans un autre post.

D'autres liens :

DomainKeys bien reconnu chez Yahoo! (forcément ;)) DomainKeys

Voici la configuration du serveur de messagerie sur lequel se base ce tutoriel :

Nous allons mettre en place la configuration suivante :

postfix -> dkfilter -> postfix -> amavis -> postfix

Dkfilter est un proxy de signature et de vérification des signatures pour DomainKeys.

Ceci peut paraitre un peu lourd en regardant le schéma, mais postfix gère ce type de configuration très bien via les content filter

Comme je suis gentil et que l'informaticien est souvent fainéant, j'ai écris ce howto avec plein de copier/coller ;)

Lire la suite...

mercredi, octobre 31 2007

Connaitre les adresses IP des visiteurs derrière un reverse proxy

Ce qui est pénible quand on héberge un serveur web derrière un reverse proxy, c'est qu'on n'obtient pas, par défaut, les adresses IP réelles des visiteurs mais uniquement l'adresse IP du reverse proxy.

Un logiciel de statistiques qui utilise les logs du serveur web, Awstats par exemple, vous indiquera donc que vous n'avez qu'un seul et unique visiteur (snif !).

Il existe heureusement une solution simple qui se trouve dans la variable d'environnement X-Forwarded-For.

Sur un serveur Apache (sur lighttp, ca sera sensiblement pareil), il faut donc changer la ligne :

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

En :

LogFormat "%{X-Forwarded-For}i - %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

Et voilà des jolies statistiques pleines de visiteurs ;)

lundi, septembre 10 2007

Recherche Fulltext et InnoDB avec Mysql

Logo MysqlLes avantages de l'utilisation du moteur de stockage InnoDB par rapport à MysIsam sur une base de données Mysql (à partir de la version 5.02) sont non négligeables sur certains projets. Il permet l'utilisation :

  • de contraintes d'intégrité (Foreign Key ect...)
  • de triggers (déclencheurs en français dans le texte).
  • de procédures stockées
  • ...

Un inconvénient est, par contre, particulièrement pénalisant dès qu'on envisage un moteur de recherche en "texte intégral". Il est en effet impossible de créer des index FULLTEXT avec le moteur InnoDB ! L'utilisation des MATCH et autres joyeusetés est donc impossible. Le classement pertinent des résultats devient plus compliqué à mettre en oeuvre.

Je me suis retrouvé confronté à ce problème récemment et voici comment je l'ai contourné. Je résume, pour l'exemple, en une unique table, ma structure de données qui en compte quelques dizaines.

J'ai donc une table "texts" qui utilise InnoDB avec quelques champs dont le "title" sur lequel je souhaite faire les recherches (la clé primaire s'appelle "idtext").

J'ai créé une table "searchs_texts" avec le moteur MyIsam, deux champs - idtext/title - et un index FULLTEXT sur le champ "title".

Cette table contient, vous l'aurez compris, l'exacte correspondance des champs idtext/title de la table texts.

Reste à tenir à jour cette table sans modifier le code de tous le site. Les triggers vont nous être bien utile pour ça :

Un pour l'INSERT :

CREATE TRIGGER trigger_insert_texts
AFTER INSERT ON texts
FOR EACH ROW
INSERT INTO searchs_texts SET idtext=NEW.idtext, title=NEW.title;


Un pour l'UPDATE :

CREATE TRIGGER trigger_update_texts
AFTER UPDATE ON texts
FOR EACH ROW
UPDATE searchs_texts SET title=NEW.title WHERE idtext=OLD.idtext;


Et enfin, un pour le DELETE :

CREATE TRIGGER trigger_delete_texts
AFTER DELETE ON texts
FOR EACH ROW
DELETE FROM searchs_texts WHERE idtext=OLD.idtext;

Et voilà. Le tour est joué ! Maintenant, votre moteur de recherche pourra utiliser tous ce qui est disponible et bientôt concurrencer Google ;)

lundi, septembre 3 2007

Liens symboliques avec Pure-ftpd sur Debian Etch

Une chose manquait cruellement dans le binaire de pure-ftpd sur Debian Sarge : la gestion des liens symboliques. Il fallait passer par des "mount --bind ..." pour arriver à ses fins (cf. la documentation sur le sujet).

Fort heureusement, sur Debian Etch c'est résolu... Encore faut-il le trouver ! Il y a deux binaires pure-ftpd-mysql et pureftp-mysql-virtualchroot (dans mon cas, vous l'aurez deviné, j'utilise le support Mysql).

Pour activer le "virtualchroot", éditez le fichier /ect/default/pure-ftpd-common et ajoutez la ligne

VIRTUALCHROOT=true

Relancez le tout avec /etc/init.d/pure-ftpd-mysql restart

Supprimez vos mount --bind ;)

jeudi, août 23 2007

Si tu respectes pas les RFCs t'es niqué

Une mésaventure m'est arrivée aujourd'hui. Un client me signale que les mails que je lui envois sur sa boîte Gmail n'arrive pas.

Après vérification, ils arrivent en fait directement dans le dossier Spam de son compte Gmail ! Moi un spammeur ! Le comble de l'horreur ;) Pourtant, j'ai blindé le serveur de messagerie avec et le domaine avec SPF et tout le toutim pour éviter ça.

D'ailleurs, Gmail le confirme dans les entêtes :

Received-SPF: pass (google.com: domain of yves@monsuperdomaine.net designates 194.xxx.xxx.xxx as permitted sender) client-ip=194.xxx.xxx.xxx;
Authentication-Results: mx.google.com; spf=pass (google.com: domain of yves@monsuperdomaine.net designates 194.xxx.xxx.xxx as permitted sender) smtp.mail=yves@monsuperdomaine.net

Mais ca ne suffit pas. Mes mails passent directement dans le courrier indésirable de Gmail dès qu'il y a un lien hypertexte dans le message (j'ai justement le lien vers grafactory.net dans ma signature...).

Donc, un mail avec le corps du message suivant arrive dans la boîte de réception :

Salut c'est Yves

Le même avec ma signature va directement dans le dossier Spam :

Salut c'est Yves

--
http://www.grafactory.net

Je vérifie les entête chez Gmail, j'effectue moult essais pour toujours revenir à cette conclusion : un lien hypertexte dans mo message et il est considéré comme Spam.

Mais pourquoi donc l'antispam google ne veut pas de certains de mes messages ? Je suppose que je dois atteindre une note assez élevé dès que j'ajoute un lien dans mon message pour me retrouvé dans les indésirables...

Après fait quelques dizaines d'essais de configuration différentes, quelques incantations et brulé quelques cierges, je me décide à vérifier la configuration de mon domaine et du serveur de messagerie.

Tiens tiens ! DNSReport, me renvoit une erreur "Fatal" : je n'ai pas déclaré d'adresse postmaster sur le domaine grafactory.net.

Je décide de créer le compte postmaster "à tout hasard"... Et c'était bien ça !!! Me voilà de retour dans la boîte de réception de Gmail :)

Moralité, les RFCs, c'est pas pour les chiens ! Particulièrement pour le mail la RFC 1123 et la RFC 2142

mardi, juillet 17 2007

Passage sur Dotclear 2 Beta7

Apparement, il y avait une grosse faille de sécurité chez Dotclear. J'ai donc mis à jour. Pour mon blog, pas de problème. Pour la plateforme multiblogs que je gère, ca a été plus compliqué.

Le moteur utilisé par Dotclear 2 avec Mysql maintenant InnoDB. C'est bien. Il y a des belles contraintes d'intégrité partout ;)

Va savoir pourquoi, l'intégrité n'était plus de mise sur la base multiblogs, il y avait des enregistrements orphelins qui ne faisaient plus référence. J'ai du donc nettoyer un peu :

DELETE FROM `dc_post` WHERE blog_id NOT IN (SELECT blog_id FROM dc_blog);
DELETE FROM `dc_category` WHERE blog_id NOT IN (SELECT blog_id FROM dc_blog);
DELETE FROM `dc_link` WHERE blog_id NOT IN (SELECT blog_id FROM dc_blog);
DELETE FROM `dc_permissions` WHERE blog_id NOT IN (SELECT blog_id FROM dc_blog);
DELETE FROM `dc_setting` WHERE blog_id NOT IN (SELECT blog_id FROM dc_blog);
DELETE FROM `dc_spamrule` WHERE blog_id NOT IN (SELECT blog_id FROM dc_blog);
DELETE FROM `dc_media` WHERE user_id NOT IN (SELECT user_id FROM dc_user);
DELETE FROM `dc_comment` WHERE post_id NOT IN (SELECT post_id FROM dc_post);
DELETE FROM `dc_media` WHERE user_id NOT IN (SELECT user_id FROM dc_user);
DELETE FROM `dc_post_media` WHERE media_id NOT IN (SELECT media_id FROM dc_media);
DELETE FROM `dc_post_media` WHERE post_id NOT IN (SELECT post_id FROM dc_post);

Ca pourrait-être intégré dans le code de Dotclear avant une mise à jour ?!

dimanche, juillet 15 2007

PhpMyAdmin, Vista inside ?

Phpmyadmin Erreur

Une erreur windowsienne :)

jeudi, juillet 5 2007

Plugin importer des auteurs

Logo importer des auteursUn nouvelle version de mon plugin SPIP qui permet de créer des auteurs en masse à partir d'un fichier csv.

Outre l'ajout de plusieurs fonctionnalités, j'ai fais en sorte que le code soit modifiable assez facilement pour une personne ayant quelques connaissances en PHP. On m'a en effet plusieurs fois demandé comment modifier le plugin pour choisir les identifiants et mot de passe, avoir un mot de passe identique à l'identifiant...

Plus d'informations sur l'article Importer des auteurs v-0.5

dimanche, juillet 1 2007

Passage du blog sous Dotclear 2

dotclear_pw.png Etant un utilisateur de la première heure de Dotclear, je me devais de passer sur Dotclear 2 Beta6. Utilisation du plugin Flat Export, changement des chemins d'images avec une ou deux requête SQL bien placée*, mise en place des redirections des anciennes URL vers les nouvelles... Reste plus que le thème à changer pour remettre le mien.

  • mes requêtes SQL pour le changement de /blog/images en /blog/public/images dans les champs post_content et post_content_xhtml de la table dc_post :
UPDATE dc_post SET post_content = replace(post_content,'blog/images','blog/public/images');
UPDATE dc_post SET post_content_xhtml = replace(post_content_xhtml,'blog/images','blog/public/images');

samedi, juin 30 2007

De retour

reload.pngIl y a quelques temps (en 2005), j'écrivais un billet intitulé "ce blog n'est pas mort". En ce moment, on peux se le demander. Un peu démotivé peut-être et surtout surbooké au boulot. Enfin, j'ai décide de reprendre la main.

Voilà quelques trucs en vrac de ces derniers mois :

  • déjà, un peu d'auto-promo avec quelques nouveaux sites : un lagarce.net réalisé avec SPIP. Un refactoring complet de galeriecimaise.com avec mon framework Grafomatic, un studio103.fr réalisé avec le même framework et du jQuery dedans. Plus quelques trucs secrets top secrets;
  • je bosse actuellement sur un bon gros projet pour la gestion complète de theatre-contemporain.net. On va essayer de devenir le Wikipedia du théâtre contemporain. Rien de moins. En tout cas l'interface sera très Ajax Web 3.0 ;)
  • finalement, je n'utiliserais pas le framework Symphony. Je crois que c'est Jelix qui va être mon choix pour mes prochains projets. Surtout que ce qui me manquait semble être au programme;
  • jQuery ca roxe grave. On le savait déjà mais je n'en fini plus de m'amuser avec et d'améliorer sensiblement mes interfaces.
  • je cherche à changer de taf (voir un prochain post sur ce sujet)

Encore plus en vrac : un nouveau bi-xéon de chez Sivit sur lequel j'héberge du gros site, mon MacBook Pro ne fait plus de bruit, je n'ai vraiment pas eu le temps de me mettre au C, je cherche un VTT d'occase, j'ai nouveau canon Ixus 850...

vendredi, avril 13 2007

Le plein de navigateurs

Voilà un petit truc qui évite d'avoir plein de machines virtuelles pour tester vos sites sur IE6+IE7+IE5+Opéra+Firefox ect... Une compilation de navigateur qui se lance en "standalone" sous Winchose. (je n'ai pas Win mais j'ai au moins une VM de test)

Standalone et Portable browser

N'oubliez quand même pas de tester sous Safari, Konqueror, Epiphany et Lynx ;)

dimanche, mars 11 2007

Mon père, ce héros... sous Linux

En 1920, mon père est né du côté de Namur, en Belgique.

En 2007, à 87 ans, après avoir trainé, jusqu'à un problème de disque dur, son Windows 98 (un passage par Mac OS 8 pour son initiation à l'informatique), il utilise maintenant Ubuntu GNU/Linux.

Un système d'exploitation libre ! Lui qui était dans la résistance en 1940, ça tombe bien :) !

Certes, ce n'est pas facile tous les jours de perdre ses repères - oui Papa, le menu "Système" c'est l'équivalent du panneau de configuration. Et non, on ne peux pas installer l'utilitaire Canon qui indique le niveau d'encre avec de jolies couleurs. Oui, c'est normal qu'il n'y ai plus d'antivirus - mais hormis ces changements géographiques et graphiques, il est convaincu.

Qui dit encore que Linux c'est pour les geeks ?!

lundi, février 5 2007

eZ Publish et "Instant Publishing" avec WebDav

eZ Publish Je n'utilise pas encore eZ Publish mais va falloir sérieusement y réfléchir. Pourquoi ? Parceque la gestion d'un site par glisser/déposer de fichiers OpenOffice (Word aussi avec OpenXML ?) via un partage WebDav, c'est trop fort ;)

Un petit ''trailer'' en Flash pour s'en convaincre. Si vous n'êtes pas patient, attaquez directement le chapitre "Instant Publishing".

Démonstration de eZ Publish

mercredi, janvier 24 2007

Un système de template ultra-minimaliste

Voici un petit bout de code php5 qui permet de créer simplement des fichiers à partir d'un modèle. Comme mon explication est loin d'être évidente ;) voici un exemple avec un fichier de zone DNS. Ici, tout ce qui est mis entre accolade doit être remplacé par sa valeur.

$TTL 3600
{domain}.               IN  SOA {ns1}.   {contactzone}. (
            {timestamp}
            10800
            3600
            604800
            3600 )

{domain}.               IN  NS      {ns1}.
{domain}.               IN  NS      {ns2}.

; Enregistrements Spf

{domain}.               IN  TXT     "v=spf1 a mx ~all"
mail.{domain}.          IN  TXT     "v=spf1 a -all"

www.{domain}.           IN  A       {ipl}
{domain}.               IN  A       {ipl}
ftp.{domain}.           IN  A       {ipl}
mail.{domain}.          IN  A       {ipl}

{domain}.               IN  MX  10  mail.{domain}.
{domain}.               IN  MX  20  mx-backup.sivit.fr.

smtp.{domain}.          IN  CNAME   mail.{domain}.
pop.{domain}.           IN  CNAME   mail.{domain}.

Voici donc la méthode en question qui s'intégrera parfaitement dans votre classe :

<?php
   /** Création de fichier de configuration
    *
    * Mini système de template pour créer des fichiers de configuration à partir d'un squelette
    * en remplaçant {pattern} par la valeur
    *
    * @access   public
    * @return    bool
    * @param    string  $orig         Fichier "template"
    * @param    string  $dest        Fichier de destination
    * @param    array   $keywords Mots à rechercher dans le template
    * @param    array   $values     Valeur de remplacement
    */

    public function setConfigFile($orig,$dest,$keywords,$values)
    {

        // contenu du fichier dans un variable
        $content = file_get_contents($orig);

        // ajout pattern
        foreach($keywords as $key=>$value) {
            $patterns[] = "/{".$value."}/imSU";
        }

        // remplacement
        $output_content = preg_replace($patterns, $values, $content);

        // variable dans un fichier ou exception
        if(!file_put_contents($dest,$output_content)) {
            throw new Exception('Erreur dans la creation du fichier');
        }

        return true;
       
    }

    // }}}
?>

Pour notre exemple, je passe sur l'instanciation de la classe, On utiliserais la méthode de la façon suivante :

<?php

// on a un objet obj

// à remplacer...
$keywords = array('domain','ns1','ns2','timestamp','contactzone');

// par :
$values = array('toto.com','ns1.toto.com','ns2.toto.com',date('Ymdi'),'technique.toto.com');

// go !
$obj->setConfigFile('zonedns.tpl','/var/cache/bind/toto.com.hosts', $keywords, $values);
?>

Ce script n'a rien de révolutionnaire mais je trouve ça pratique. Ca ressemble de très loin à un système de template minimaliste ;)

PS : pour les allergiques à l'orienté objet, vous pouvez bien entendu l'utiliser comme une simple fonction

lundi, janvier 1 2007

Ne cherchons pas l'originalité

Simplement une bonne année à toi, lecteur de ce modeste blog. Mes résolutions de l'année 2007 :

  • finir mes projets en cours
  • concurencer google
  • prendre des vacances
  • travailler plus efficacement
  • revoir la résolution de 2006

Cherchez les erreurs ;)

jeudi, novembre 30 2006

Les mots de passe des utilisateurs de Mysql 4 dans Mysql 5

Le système de hashage des mots de passe utilisateurs de Mysql a changé depuis Mysql 4.1. Il est plus sécurisé, dixit le manuel. Le souci, c'est que certains clients Mysql ne semble pas encore gérer correctement la communication avec ce nouveau type de mot de passe.

La solution - certes au détriment de la nouvelle sécurité proposée - est d'utiliser la commande OLD_PASSWORD pour attribuer un mot de passe compatible "ancien hashage" à un utilisateur.

Plus d'informations dans la documentation officielle de Mysql : Hashage de mots de passe en MySQL 4.1

Ce post après un temps de prise de tête à cause de ce changement

samedi, novembre 25 2006

Découverte du framework Symfony

Symfony Voici quelques jours, j'ai décidé de me lancer à l'assaut du framework Symfony dont j'entendais parler ici et là depuis déjà quelques temps.

Développé à la base par une société française (sous licence MIT), ce framework veut se la jouer Ruby On Rails par sa puissance pour mettre en oeuvre rapidement une application complète.

Il a récemment connu une publicité inespérée. Yahoo! a en effet annoncé sont utilisation pour la réalisation de sa nouvelle plateforme "social networking" de gestion de bookmark.

Un "Admin Generator" puissant, des outils complet en ligne de commande, des fichiers de descriptions d'interfaces simplifiés en XML ou en YAML... Bref, tout ce qu'il faut pour construire une application fonctionnelle sans aucune ligne de PHP (j'exagère un peu quand même).

Symfony utilise à fond les possibilités objet de PHP5 et repose notamment sur le pattern ORM (Object-relational mapping) via propel pour vous générer en quelques secondes et sans effort vos modèles de base d'accès aux données (le fameux CRUD : Create, Read, Update and Delete).

Courez donc vite sur le site de Symfony pour y découvrir quelques vidéos et exemples qui vous donnerons sans doute envie d'aller plus loin.

Si vous êtes convaincu et que vous cherchez à débuter en français, voici deux liens :

Ensuite, en anglais, pour l'instant un howto en 21 épisodes pour construire de A à Z une application :

Vivement plus de documentation francophone sur le sujet ;)

vendredi, novembre 3 2006

Ubuntu Edgy Eft, Beryl Xgl et tout le reste

UbuntuCelà fait maintenant plus de 2 ans que ma station de travail principale fonctionne sous Linux. Hier, je suis passé à la dernière version de la distribution que j'affectionne pour le moment, j'ai nommé Ubuntu Edgy Eft.

Une fois n'est pas coutume, j'ai lancé dist-upgrade via le gestionnaire graphique de mises à jour fourni par Ubuntu. J'ai été bluffé par les améliorations apportées et l'efficacité générale de l'outil (sans langue de bois : ça a fonctionné pile-poil).

Cette nouvelle mouture va toujours dans le sens d'une évolution positive tant au niveau de l'ergonomie que des fonctionnalités, qui font de Ubuntu Linux un système pratique à utiliser au quotidien.

En vrai geek, j'ai bien entendu essayé Beryl (alias XGL) dans la foulée. Enfin ! La véritable transparence des fenêtres et la fluidité des effets est géniale. Le bureau Mac OSX n'a qu'a bien se tenir !

Petit reproche au projet beryl cependant : les réglages par défaut transforme la machine en montagnes russes et j'ai passé quelques temps à trouver quelques choses de moins "folklorique". On a un peu l'impression que c'est uniquement pour démontrer (à juste titre, certes) la puissance des effets disponibles.

- page 2 de 9 -