24 May 2013

Carl Chenet

Publication de Debian GNU/Hurd 2013

Suivez-moi aussi sur Identi.ca ou sur Twitter.

Une nouvelle à peu près passée inaperçue et qui m’apparaît pourtant fort intéressante à plusieurs points de vue : Debian GNU/Hurd 2013, le système d’exploitation offrant conjointement Hurd et la suite des outils et paquets de Debian est disponible depuis deux jours.

debian-gnu

Le Hurd est le noyau du système d’exploitation GNU/Hurd que promeut le projet GNU fondé par Richard Stallman. Le Hurd est une suite de programmes et de bibliothèques autour d’un micro-noyau nommé Mach qui s’oppose par son fonctionnement au noyau monolithique modulaire comme Linux.

À la différence du port Debian GNU/kFreeBSD – qui offre conjointement le noyau du système d’exploitation FreeBSD avec la suite des outils et paquets Debian – ce nouveau croisement n’est pas une mouture officielle de Debian Wheezy 7.0 car il repose sur les paquets présents pour Sid. Il reste donc pour l’instant un port non-officiel.

De plus, ce port n’est pour l’instant disponible que pour l’architecture i386 mais propose près de 75% des paquets disponibles dans l’archive officielle du projet Debian.

Quels sont les apports de ce nouveau port ? Bien qu’il reste encore assez expérimental, les buts possibles sont à terme de rejoindre le fonctionnement du port Debian GNU/kFreeBSD, à savoir offrir la plus grande diversité possible de choix à l’utilisateur du système Debian. Certains utilisateurs préfèrent le noyau kFreeBSD au noyau Linux, pour sa plus grande robustesse (supposée) ou certaines options offertes par ce noyau. Pour Debian GNU/Hurd, l’objectif sera le même, donner accès aux avantages et points forts offerts par le noyau Hurd (à priori une plus grande stabilité offerte théoriquement par les micro-noyaux) tout en restant dans la suite d’outils et de paquets Debian. Debian s’inscrit ainsi dans sa ligne d’être le système d’exploitation universel.

Les informations de configuration ainsi que la foire aux questions seront à lire pour ceux qui tenteront l’aventure.

Et vous, que pensez-vous de ce port Debian GNU/Hurd et plus généralement du développement des ports non-officiels et officiels de Debian ?

gnu-debian-banner

Encore quelques ressources intéresantes sur le sujet :


24 May, 2013 05:57PM par Carl Chenet

21 May 2013

Philippe Latu

NIS, NFSv4, autofs5 & dual stack IPv4 + IPv6

Pour employer une formule marketing à 2€cts, la collection des acronymes donnés dans le titre constitue un «savoureux mélange» entre anachronisme et modernité. Ceci-dit, je me doute bien qu'à la lecture du même titre, d'aucuns auront déjà trouvé que la mixture est on ne peut plus indigeste ! Enfin, n'ayant plus du peur du ridicule, voici une petite introduction sur ce faux-nouveau support : Association NIS, NFSv4 et autofs.

Après avoir adapté les supports de la rubrique développement à IPv6, je me suis posé la question de faire le même travail sur les autres supports de travaux pratiques. Écrire une version IPv6 séparée pour chaque séance de travaux pratiques obligerait à maintenir deux versions pour un même document. Au delà de la quantité de travail, il y a fort à parier qu'une version IPv6 isolée ne serait jamais utilisée vu ce que l'on sait de l'engouement général pour adopter rapidement ce protocole. Il restait donc l'option du document unique double pile ou dual stack dans le jargon. À titre d'entraînement, j'ai repris un vieux support abandonné qui associe trois services.

  • Network Information Service (NIS) permet le partage des paramètres de compte utilisateur. C'est un service démodé qui ne fonctionne qu'avec la pile IPv4 ; ce qui le rend intéressant dans le contexte présent.
  • Network File System (NFS) est le système de fichiers réseau de prédilection dans le monde Unix. Sa version 4 fonctionne très bien avec la pile IPv6.
  • Automounter (autofs) permet l'accès transparent au système de fichiers réseau. On l'utilise lors de la connexion d'un utilisateur pour accéder simplement à son répertoire. Normalement, ce service fonctionne avec IPv6. J'ai découvert avec surprise que son utilisation d'IPv6 est assez singulière puisqu'il semble s'appuyer exclusivement sur les enregistrements DNS.

Même si le but recherché était de «croiser» les usages des deux piles de protocole de couche réseau, le résultat a dépassé mes attentes puisqu'en trois services on dispose de trois modes opératoires distincts.

Pour être complet, il faut ajouter les appels de procédures distants (RPC) sur lesquels sont basés NIS et NFS. C'est justement ce mécanisme qui autorise le mixage entre les deux piles IPv4 et IPv6.

# rpcinfo -s ip6-srvr.fake.domain
   program version(s) netid(s)                         service     owner
    100000  2,3,4     local,udp,tcp,udp6,tcp6          portmapper  superuser
    100004  1,2       tcp,udp                          ypserv      superuser
    100009  1         udp                              yppasswdd   superuser
    100003  4,3,2     udp6,tcp6,udp,tcp                nfs         superuser
    100227  3,2       udp6,tcp6,udp,tcp                -           superuser
    100021  4,3,1     tcp6,udp6,tcp,udp                nlockmgr    superuser
 600100069  1         tcp,udp                          fypxfrd     superuser
    100007  1,2       tcp,udp                          ypbind      superuser
    100005  3,2,1     tcp6,udp6,tcp,udp                mountd      superuser

autofs troubleshooting

Comme je l'ai dit plus haut la version du paquet autofs fourni dans la branche testing semble se baser uniquement sur les enregistrements DNS. Voyons comment je suis parvenu à cette conclusion.

  1. On commence par un montage statique de l'arborescence depuis le poste client.
    # mount -t nfs4 [2001:db8:feb2:10::12]:/home /ahome
    root@clnt:/home/etu# ls -lAh /ahome/etu-nis/
    total 16K
    -rw------- 1 etu-nis etu-nis  385 mai   21  2013 .bash_history
    <snip/>
    
    # mount | grep nfs4
    [2001:db8:feb2:10::12]://home on /ahome type nfs4 \
      (rw,relatime,vers=4,rsize=65536,wsize=65536,namlen=255,hard,proto=tcp6, \
       timeo=600,retrans=2,sec=sys,clientaddr=2001:db8:feb2:10::11,minorversion=0, \
       local_lock=none,addr=2001:db8:feb2:10::12)
    Le montage statique utilisant les adresses IPv6 fonctionne. Rien d'original.
  2. On passe à l'utilisation du démon automount avec des fichiers de configuration complétés directement sur le poste client, toujours avec une adresse IPv6 numérique.
    # cat /etc/auto.master
    /ahome          /etc/auto.home
    
    # cat /etc/auto.home 
    * -port=2049,-fstype=nfs4 [2001:db8:feb2:10::12]:/home/&
    
    # service autofs start
    [ ok ] Starting automount....
    # automount -m
    
    autofs dump map information
    ===========================
    
    global options: none configured
    
    Mount point: /ahome
    
    source(s):
    
      instance type(s): file 
      map: /etc/auto.home
    
      * | -port=2049,-fstype=nfs4 [2001:db8:feb2:10::12]:/home/&
    La configuration a bien été prise en compte par le démon ...
    # ls -lAh /ahome/etu-nis
    ls: impossible d'accéder à /ahome/etu-nis: Aucun fichier ou dossier de ce type
    
    # tail -3 /var/log/syslog 
    clnt automount[3652]: attempting to mount entry /ahome/etu-nis
    clnt automount[3652]: mount(nfs): no hosts available
    clnt automount[3652]: failed to mount /ahome/etu-nis
    Catastrophe ! Le montage automatique échoue.
  3. On reprend la même expérience avec un nom d'hôte DNS dont les enregistrements AAAA et PTR sont valides.
    # service autofs start
    [ ok ] Starting automount....
    # automount -m
    
    autofs dump map information
    ===========================
    
    global options: none configured
    
    Mount point: /ahome
    
    source(s):
    
      instance type(s): file 
      map: /etc/auto.home
    
      * | -port=2049,-fstype=nfs4 vm2.fake.domain:/home/&
    
    # dig +short aaaa vm2.fake.domain
    2001:db8:feb2:10::12
    root@clnt:/home/etu# dig +short -x 2001:db8:feb2:10::12
    vm2.fake.domain.
    L'adresse IPv6 utilisée est bien identique à celle du test précédent.
    # ls -lAh /ahome/etu-nis
    total 16K
    -rw------- 1 etu-nis etu-nis  385 mai   21 23:44 .bash_history
    <snip/>
    
    # tail -3 /var/log/syslog 
    clnt automount[3759]: mounted indirect on /ahome with timeout 300, freq 75 seconds
    clnt automount[3759]: attempting to mount entry /ahome/etu-nis
    clnt automount[3759]: mounted /ahome/etu-nis
    Bingo ! Cette fois-ci le montage se fait correctement. Enfin, si les paramètres de configuration sont publiés via NIS, ça fonctionne aussi.

Voilà. On peut considérer que le choix consistant à associer les trois services est pertinent puisqu'il illustre des usages distincts de la pile IPv6. À mon niveau de connaissances, je ne sais pas si le fait d'imposer l'utilisation des enregsitrements DNS par le démon automount est volontaire.

Dans tous les cours sur IPv6, il est courant de dire que comme le format numérique des adresses IPv6 est très difficile à retenir, l'usage des enregistrements DNS est impératif. Pour généraliser l'utilisation de la double pile réseau, il semble qu'il faille revoir la séquence des travaux pratiques. Je vais devoir aborder le service DNS au tout début de façon à en bénéficier pour le cycle sur le stockage et les systèmes de fichiers réseau. En conclusion, le support de travaux pratiques DNS est le prochain sur la liste !

21 May, 2013 08:17PM par Philippe Latu

Carl Chenet

Vrac de mini-messages n°2

Suivez-moi aussi sur Identi.ca ou sur Twitter.

Pour cette catégorie d’article, je passe à une publication hebdomadaire :) Les liens d’origine sont enrichis des approfondissements que j’ai pu effectuer entre la publication du dent/tweet et la publication de cet article.

  1. #debian #wheezy 7.1 devrait être publiée samedi 15 juin http://ur1.ca/dvraj  => Information très intéressante qui n’a pas été beaucoup relayée. La première point release est à mon avis une bonne occasion pour les administrateurs système qui prévoient de mettre à jour leur parc de le faire, car on a essuyé les plâtres de la sortie et on est maintenant prêt à migrer plus facilement.
  2. Application de blog pour #django très sympa : #zinnia http://ur1.ca/dv6ja => tellement sympa que je la mets en place sur un site que je gère. Très content du résultat jusqu’ici, très conforme à mes attentes d’une application entièrement intégrée à Django. Je trouve le résult et le modèle de développement très professionnels.
  3. Sortie de #PostgreSQL 9.3 beta 1 http://b1t.it/dgb4 => je suis séduit par une fonctionnalité qui m’intéresse directement, à savoir
    Bascules d'urgence rapides (Failover) vers un serveur secondaire pour
    garantir la haute disponibilité de vos données 
  4. créer un dico avec #CPython2.7 avec dict() ou {} ? {} à privilégier d’après cet article http://ur1.ca/dulhv => c’est le genre d’article que j’apprécie beaucoup, qui va chercher la petite bête et pousse à utiliser les bons idiomes par rapport au langage et à l’interpréteur utilisés.
  5. Installer #Debian #Wheezy sur un #Qnap TS-219 PII http://ur1.ca/dtzo3 => grosse affluence sur l’article, de très bons retours dans les commentaires (merci à mes lecteurs).

Et vous ? Que pensez-vous des technologies et articles abordés ci-dessus ? N’hésitez pas à réagir dans les commentaires.


21 May, 2013 11:01AM par Carl Chenet

18 May 2013

Tuxicoman

Installer Debian

Le site officiel debian.org est connu pour être particulièrement abscon au profane informatique. Pour vous donner un exemple, lorsque l'on navigue sur le site pour télécharger une ISO d'installation pour clé USB on finit sur ça :

debian-installer2

Ce qui doit laisser plus d'un utilisateur potentiel très perplexe ! Je me suis moi-même creusé la tête en 2010.

Quelle bonne surprise de voir qu'une lueur (verte) de démagogie est apparue dans le coin droit de la page d'accueil : un lien vers une ISO net-install muti-arch(x86 x86-64) !!!

debian-installer

Encore un effort, et pour Debian 8 on aura "une" page expliquant en 3 étapes comment démarrer l'installeur Debian. Hé oui, l'utilisateur lambda ne sait pas quoi faire avec son fichier ISO dans sa main gauche et sa clé USB dans sa main droite. Pourquoi ne pas proposer un "easy mode" qui propose par défaut une sorte de UNetbootin ?

C'est vraiment dommage car c'est l'une des distributions les plus faciles à utiliser au quotidien (très peu de bug, peu d'admin système à faire, pas de maj tous les 6 mois...)

18 May, 2013 04:59PM par Tuxicoman

13 May 2013

Raphaël Hertzog

Mes activités libres en avril 2013

Voici le récapitulatif mensuel de toutes mes activités gravitant autour du logiciel libre. Si vous faites partie des personnes ayant fait un don pour soutenir mon travail (102,70 €, merci à tous !), c’est l’occasion de constater ce que je fais de votre argent. Sinon, c’est toujours quelques nouvelles intéressantes sur l’avancement de mes différents projets.

Debian France

Travaux sur Galette. J’ai passé pas mal de temps sur l’installation de Galette pour Debian France (l’application Web de gestion des membres), premièrement pour convertir sa base de données Postgres à l’UTF-8, ensuite pour la mettre à jour vers la version 0.7.4 tout en contournant plusieurs problèmes connus.

J’ai également créé des paquets Debian pour trois plugins que nous utilisons : (galette-plugin-paypal, galette-plugin-admintools et galette-plugin-fullcard).

Ceci étant, chaque fois que j’utilise Galette, j’ai tendance à trouver quelque chose qui mérite d’être remonté. J’ai créé 5 tickets ce mois-ci :

  • n°588: Galette devrait permettre l’envoi d’un mail de test lorsque les notifications mails sont paramétrées
  • n°589: la page d’export CSV contient un lien de téléchargement invalide
  • n°590: la page de confirmation d’un paiement PayPal réussi contient des champs vides
  • n°591: problème de sélection des destinataires d’un publipostage
  • n°595: Galette devrait ajouter un destinataire correct dans le champ « A : » des mails générés automatiquement.

J’ai testé plusieurs corrections préparées par l’auteur amont (trois des bogues ci-dessus sont déjà corrigés), ce qui a conduit à la version corrective 0.7.4.1.

Travaux préliminaires quant aux nouveaux statuts et règlement intérieur. J’ai mis en place un dépôt Git afin de rendre plus facile la collaboration autour de nos nouveaux statuts et règlement intérieur. Le but étant de faire de Debian France une organisation reconnue par Debian (« trusted organization »), ainsi que de rendre l’ensemble compatible avec la loi 1901 relative aux associations (l’association a actuellement un statut spécial réservé aux associations d’Alsace/Lorraine).

Kali Linux

Amélioration du support de l’accessibilité dans Debian Wheezy. Offensive Security souhaitait que Kali Linux soit parfaitement accessible aux handicapés. Dans la mesure où Wheezy souffrait de régressions importantes dans ce domaine, nous avons embauché Emilio Pozuelo Monfort afin de corriger les bogues n°680636 et n°689559 dans gdm3.

De mon côté, j’ai mis à jour le paquet finish-install de debian-installer afin qu’il pré-configure correctement le système lorsque vous réalisez une installation avec la synthèse vocale (patch soumis dans le bogue n°705599).

Grâce à des responsables de la publication accomodants, ce travail a déjà été intégré dans Wheezy et ne devra pas attendre la première mise à jour majeure.

Corrections de bogues dans l’installeur graphique de Debian’s live. Nous avons également voulu activer l’installeur graphique dans le live DVD de Kali. Tandis que nos premières tentatives d’il y a quelque mois avaient échoué, cela a marché ce coup-ci quasiment instantanément (ceci grâce à Ben Armstrong qui a réalisé les corrections nécessaires). J’ai quand même identifié quelques problèmes que j’ai corrigés dans le dépôt Git de debian-installer-launcher.

Empaquetage et travaux Debian divers

  • J’ai revu le travail de Charles Plessy qui a réalisé la première version d’une importante mise à jour de la charte Debian, afin de documenter les triggers dpkg (cf. n°582109)
  • J’ai revu le paquet libwebsockets préparé par Peter Pentchev (ITP n°697671)
  • J’ai découvert Tanglu et me suis inscrit à leur liste de diffusion afin de suivre son évolution (et peut-être l’utiliser comme banc de test pour de futurs développements d’infrastructure).
  • J’ai revu et poussé un patch de Robert Spencer concernant debian-cd (voir n°703431).
  • J’ai empaqueté la version 3.3 de cpputest (dans experimental). J’ai testé un nouvel instantané amont converti à autotools.

J’ai également passé un nombre d’heures certain à répondre aux questions des étudiants souhaitant participer au Google’s summer of code et qui sont intéressés par la réécriture du Système de Suivi des Paquets à l’aide de Python et Django. Certaines de ces discussions ont eu lieu sur la liste de diffusion debian-qa@lists.debian.org.

Merci

Rendez-vous au mois prochain pour un nouveau résumé de mes activités !

Ceci est une traduction de mon article My Free Software Activities in April 2013 contribuée par Weierstrass01.

Aucun commentaire pour le moment | Vous avez aimé ? Cliquez ici. | Ce blog utilise Flattr.

13 May, 2013 07:31AM par Raphaël Hertzog

09 May 2013

Tuxicoman

Ajouter un OS au bootloader de Wheezy

J'ai du installer un disque avec Windows à coté de celui avec ma Debian Wheezy.
Windows faisant semblant d'ignorer qu'il existe d'autres OS, on ne peut pas compter sur lui pour s'intégrer à votre système existant.

Déjà pour l'installer, il faut lui donner le disque principal mais en plus, le bootloader de Windows se fout complètement que vous ayez un autre OS sur l'autre disque et ne vous le propose pas au démarrage.

Heureusement, Debian Wheezy vient avec un outil magique pour rajouter automatiquement les autres OS à son bootloader. Vous avez juste 2 commandes à exécuter :

# os-prober
/dev/sda1:Windows 7 (loader):Windows:chain

# update-grub
Generating grub.cfg ...
Found background image: /usr/share/images/desktop-base/desktop-grub.png
Found linux image: /boot/vmlinuz-3.2.0-4-amd64
Found initrd image: /boot/initrd.img-3.2.0-4-amd64
Found Windows 7 (loader) on /dev/sda1
done

09 May, 2013 01:47AM par Tuxicoman

02 May 2013

Stéphane Blondon

Évolution du nombre de messages sur debian-l10n-fr et debian-users-fr avec pychart

Pychart est une bibliothèque Python permettant des graphiques directement en python. Un paquet Debian est disponible (nommé python-pychart) avec la dernière version 1.39 (qui date de 2006).

Debian utilise massivement des listes de diffusion pour la collaboration de ses membres. Parmi les nombreuses listes existantes, trois sont francophones :

  • debian-users-fr, dédiée aux questions des utilisateurs ;
  • debian-l10n-fr, dédiée aux traductions en français ;
  • debian-news-french, dédiée aux communiqués officiels. Elle est exclue du graphique car elle ne représente pas vraiment l’activité des listes de diffusion.

Pychart est utilisé pour créer un graphique montrant l’évolution du volume de messages postés sur ces deux listes pendant une année glissante (soit d’avril 2012 à avril 2013).

Le graphique

Le graphique représente le nombre de messages électroniques envoyés sur les deux listes par jour.

Volume des messages sur les listes de diffusion Debian francophones

On constate que les pics et les creux se font sur les mêmes mois. Par contre, les tendances générales sont inversées : en hausse pour la liste utilisateur, en baisse pour la liste dédiée aux traductions.

Réalisation

Le code Python est fourni à la fin de l’article. Pychart s’appuie sur de nombreuses inventions anciennes mais solidement éprouvées :

Invention de la poubelle (1884)

Toute la documentation fait des imports globaux (from pychart import *), comme beaucoup d’exemples disponibles sur le web. Pour éviter de polluer l’espace de nom, il suffit d’importer les différents sous-modules de manière classique (import pychart.sousmodule). Je n’ai pas eu besoin d’importer certains sous-modules bien qu’ils soient utilisés dans le script.

Création de postscript (1982)

Plusieurs formats de sortie sont disponibles (ps, pdf, png et svg). Par défaut, le fichier sera en PostScript.
Pour le changer vers le format png :

pychart.theme.output_format = "png"

Pour avoir une sortie en png, ghostscript doit être installé sur le système. PIL n’est pas nécessaire.

Invention de la télévision couleur (1938)

Par défaut, les graphiques seront uniquement en nuances de gris. Si on souhaite avoir plein de couleurs, il faut le déclarer de la manière suivante :

pychart.theme.use_color = True

Invention de l’écriture de travers (-3400)

Il est possible d’orienter le texte affiché (que ce soit pour les axes ou des boîtes de texte ad-hoc). Pour cela, il faut définir l’angle d’orientation (« /a » pour définir que l’on modifie l’angle, « -20 » pour baisser de 20 degrés par rapport à l’horizontale dans l’exemple ci-dessous) :

pychart.axis.X(label="Date", format="/a-20/hL%s")

La définition du formatage de la chaîne à afficher utilise le caractère « / » pour introduire un contrôle. Il est nécessaire de le doubler lorsque l’on souhaite l’afficher (pour une date par exemple).

Invention du dessin (Paléolithique)

pychart.line_plot.T(label=u"debian-user-french", #sert pour la légende
                    data=stats, #la structure des données à afficher
                    ycol=2, #la troisième colonne dans les données
                    line_style=_blue_line #le rendu des données
                    )

Invention du papier (IIième siècle avant JC)

La méthode draw() permet d’afficher les données sur la sortie standard. Il suffit simplement de la rediriger vers un fichier grâce au shell :

$ python volume.py  > volume.png

Code source et références

Le code qui a permis de créer le graphique :

# -*- coding: utf-8 -*-

import pychart.area
import pychart.line_plot
import pychart.theme


pychart.theme.output_format = "png"
pychart.theme.use_color = True
pychart.theme.default_font_size = 14
pychart.theme.title = "14"


stats = (("04//2012", 12.27, 14.43),
        ("05//2012", 10.71, 14.42),
        ("06//2012", 11.77, 13.10),
        ("07//2012", 10.19, 8.55),
        ("08//2012", 11.65, 14.68),
        ("09//2012", 13.00, 18.33),
        ("10//2012", 10.32, 15.06),
        ("11//2012", 6.87, 14.90),
        ("12//2012", 5.48, 10.48),
        ("01//2013", 5.29, 20.58),
        ("02//2013", 10.25, 22.39),
        ("03//2013", 9.74, 24.00),
        ("04//2013", 8.3, 19.80))


_area = pychart.area.T(size = (700, 450),
            y_grid_interval=5,
            x_coord=pychart.category_coord.T(stats, 0),
            x_axis=pychart.axis.X(label="Date", format="/a-20/hL%s"),
            y_axis=pychart.axis.Y(label="Nombre de messages par jour"),
            legend=pychart.legend.T(),
            y_range=(0, None))

_red_line = pychart.line_style.T()
_red_line.width = 2
_red_line.dash = (5, 5)
_red_line.cap_style = 2
_red_line.join_style = 2
_red_line.color = pychart.color.red
_blue_line = pychart.line_style.T()
_blue_line.width = 2
_blue_line.color = pychart.color.royalblue
_l10n_plot = pychart.line_plot.T(label=u"debian-l10n-french", data=stats, line_style=_red_line)
_user_plot = pychart.line_plot.T(label=u"debian-user-french", data=stats, ycol=2, line_style=_blue_line)
_area.add_plot(_l10n_plot, _user_plot)

_area.draw()

Les moyennes journalières ont été calculées préalablement. Elles sont exclues du code source pour ne pas l’alourdir inutilement. Voici les données brutes qui ont servi aux calculs des moyennes :
date debian-l10n-french debian-user-french nbre_jours
2012/04 368 433 30
2012/05 332 447 31
2012/06 353 393 30
2012/07 316 265 31
2012/08 361 455 31
2012/09 390 550 30
2012/10 320 467 31
2012/11 206 447 30
2012/12 170 325 31
2013/01 164 638 31
2013/02 287 627 28
2013/03 302 744 31
2013/04 190 594 30

Les données ont été récupérées à partir des versions publiques des archives des listes de traductions.

La documentation de pychart est disponible à http://home.gna.org/pychart/doc/pychart.html ou dans le paquet python-pychart-doc.

Enfin, Matplotlib répond au même besoin et semble être un projet plus vivant.


02 May, 2013 08:34AM par ascendances

15 April 2013

Florent Gallaire

Lucas Nussbaum élu DPL pour 2013

C’est Lucas Nussbaum qui vient d’être élu Debian Project Leader (DPL) pour l’année 2013, succédant ainsi au triple mandat de Stefano Zacchiroli.

Lucas Nussbaum devance Allan Moray et Gergely Nagy (déjà candidat malheureux en 2004 et 2012). Voici une représentation du résultat du scrutin qui utilise la méthode Condorcet.

Bravo à toi Lucas, et bonne chance dans la mise en œuvre de ton programme à partir du 17 avril !

flattr this!

15 April, 2013 01:41AM par fgallaire

14 April 2013

Raphaël Hertzog

Mes activités libres en mars 2013

Voici le récapitulatif mensuel de toutes mes activités gravitant autour du logiciel libre. Si vous faites partie des personnes ayant fait un don pour soutenir mon travail (114,19 €, merci à tous !), c’est l’occasion de constater ce que je fais de votre argent. Sinon, c’est toujours quelques nouvelles intéressantes sur l’avancement de mes différents projets.

Simple-CDD et debian-cd

J’ai essayé d’utiliser les versions présentes dans Wheezy de debian-cd et simple-cdd pour générer un installeur automatique. J’ai à cette occasion soumis plusieurs rapports de bogue concernant simple-cdd (n°701963 : le paquet type-handling a disparu et ne devrait pas être listé dans default.downloads, ainsi que le n°701998 : le paramètre --keyboard ne fonctionne pas avec la version debian-installer de Wheezy) et poussé quelques correctifs pour debian-cd :

  • r2518: ajuster le Makefile en fonction des nouveaux prérequis de xorriso ;
  • r2520: ajouter les dépendances manquantes à dosfstools ;
  • r2521: utiliser --no-check-gpg lors de l’interrogation de debootstrap ;
  • r2522: rendre debian-cd capable de fonctionner avec un miroir dépourvu de sources.

Debian France

J’ai achevé le nouveau site web de Debian France et l’ai mis en ligne. J’y ai intégré par la suite plusieurs améliorations réalisées par Tanguy Ortolo (et lui ai donné les droits de pousser des changements via git par la même occasion).

J’ai essayé de mettre à jour notre installation de Galette vers la dernière version amont, mais suis revenu à l’ancienne après avoir rencontré deux problèmes (consignés ici and ici). J’ai créé à cette occasion un paquet Debian pour ce logiciel (vous pouvez le récupérer sur git.debian.org).

J’ai également soumis une proposition d’amélioration concernant l’extension de paiement par Paypal, qui a été rapidement implémentée. J’ai par la suite mis à jour ce module déjà utilisé sur france.debian.net.

Travaux en lien avec Kali

J’ai aidé pendant plusieurs mois l’équipe de Kali à préparer cette nouvelle distribution dérivée de Debian. Maintenant qu’elle a été officiellement lancée, je peux déclarer certains de mes travaux Debian comme découlant de ma collaboration avec l’équipe de Kali.

Ce mois-ci, j’ai contribué plusieurs fonctionnalités et corrections pour debian-installer et live-build :

Après le lancement, nous avons signalé Kali dans le recensement des dérivés Debian. Paul Wise a rapidement remonté certains bogues mal renseignés par les premiers utilisateurs de Kali, et j’ai découvert que reportbug ne fonctionnait pas comme prévu même après avoir correctement mis à jour base-files (cf. le n°703678 pour reportbug et le n°703677 pour lsb-release).

Travaux d’empaquetage divers

  • J’ai parrainé une nouvelle version amont de dnsjava, car c’était requis par Jitsi ;
  • J’ai préparé la version 0.4.1.1 de rebuild, et l’ai envoyée vers le dépôt testing-proposed-updates, car elle corrige un bogue critique pour la publication ;
  • J’ai envoyé Publican dans sa version 3.1.5 vers experimental, et soumis le rapport de bogue n°703514 demandant une nouvelle version amont de docbook-xsl requise par Publican ;
  • J’ai créé le rapport de bogue n°703995 pour corriger la gestion par apt-setup de l’option preseed d’apt-setup/multiarch.

Election du DPL

J’ai également passé pas mal de temps à lire et participer aux discussions sur la liste debian-vote, étant donné que les candidats au poste de DPL étaient en pleine campagne électorale. (Bravo à Lucas Nussbaum qui vient d’être élu!)

Merci

Ce mois a été plutôt bien rempli si l’on prend en compte le fait que j’ai eu un second fils (Lucas) le 6 mars dernier…

Rendez-vous au mois prochain pour un nouveau résumé de mes activités !

Ceci est une traduction de mon article My Free Software Activities in March 2013 contribuée par Weierstrass01.

Un commentaire | Vous avez aimé ? Cliquez ici. | Ce blog utilise Flattr.

14 April, 2013 07:51PM par Raphaël Hertzog

06 April 2013

Vincent Bernat

Comptabilité d'une EURL avec GnuCash

Afin de mener une activité de conseils, j’ai monté une EURL. Une comptabilité à jour est une des obligations majeures pour une entreprise.

Dans le monde libre, il existe plusieurs solutions pour faire de la comptabilité d’entreprise. Cela va de systèmes plutôt simples comme GnuCash à des systèmes très compliqués comme OpenERP. Jonathan Corbet, l’éditeur de LWN a écrit un article assez intéressant sur l’état des logiciels de comptabilité libres pour petites entreprises. Sa conclusion était qu’il n’existait rien qui remplisse ses besoins. Il a toutefois apprécié Ledger, un système qui se manipule en ligne de commande et à travers un éditeur de texte classique. Il y a consacré un article.

J’ai pour ma part opté pour GnuCash. Il existe un peu de littérature sur le sujet, avec notamment le livre assez complet Gnucash 2.4 Small Business Accounting. Le très grande majorité des ressources est orientée vers la comptabilité dans les pays anglo-saxons. La comptabilité en France utilise des codes très différents.

Je propose donc de livrer mon expérience sur GnuCash dans le cadre suivant :

  • Gestion d’une EURL.
  • Pas de salariés. Étant gérant majoritaire, je me verse une indemnité et non un salaire.
  • Activité de conseil en informatique. Ni stock, ni marchandise.
  • Impôt sur les sociétés au réel simplifié. TVA au réel simplifié également.

Dans ce cadre, GnuCash est une solution tout à fait valable pour les opérations courantes. Il a quelques lacunes mais effectue globalement bien son boulot. Il dispose de plus d’une gestion des clients et des fournisseurs plutôt correcte. Il peut sortir tout un tas de rapports plus laids les uns que les autres.

Les opérations de fin d’année sont par contre une autre paire de manches. Il y a non seulement la complexité comptable mais également toutes les démarches administratives. Il me semble préférable de confier celles-ci à comptable1 et donc de vérifier que celui-ci acceptera les données issues de GnuCash.

À noter que je ne suis pas comptable et donc certains conseils peuvent être erronés.

Introduction à la comptabilité

La comptabilité est un outil permettant de recenser et d’évaluer tous les événements qui influent sur la valeur de l’entreprise. Un événement, cela peut être l’émission d’une créance vers un client, l’achat d’une agrafeuse, le recouvrement de la TVA collectée ou le don d’un tracteur agricole.

Comptabilité en partie double

En entreprise, la comptabilité s’effectue en partie double:

La comptabilité en partie double est la base du système comptable utilisé par toutes les entreprises et organisations. Elle est fondée sur l’idée selon laquelle les opérations et la situation financière d’une organisation peuvent être représentées par des comptes. Chaque compte contient l’historique des modifications de la valeur monétaire d’un aspect particulier de l’organisation. On parle de partie double quand l’enregistrement d’écriture est inscrit dans deux comptes (au moins) : un compte débité, et un compte crédité.

Pour chaque événement, il faut créditer un certain nombre de comptes et en débiter d’autres. De plus, le total des crédits doit être égal au total des débits.

La notion de débit et de crédit est assez compliquée à appréhender et peu intuitive. Ainsi, pour acheter une agrafeuse, on va créditer le compte bancaire et débiter le compte recensant les petits achats. Un événement implique toujours une ressource et un emploi. La ressource permet de financer l’emploi. Elle est toujours marquée au crédit d’un compte alors que l’emploi est toujours marqué au débit. Dans notre exemple d’agrafeuse, l’achat se fait avec l’argent du compte en banque qui est une ressource et il faut donc créditer le compte. Inversement, quand on vend une prestation à un client, la ressource est la prestation et l’emploi est le client. Il faut donc débiter le compte du client et créditer le compte des prestations.

Si vous êtes déjà perdus ici, pas de panique. L’important est d’être attentif aux exemples. De plus, GnuCash utilise par défaut des termes plus compréhensibles selon le type de compte (mais parfois mal francisés), à moins de choisir dans les préférences d’utiliser la terminologie comptable.

Chaque opération donne lieu à une écriture comptable qui va concerner un ou plusieurs comptes. Sur papier, il fallait écrire la même opération dans chaque compte. Profitant des progrés en informatique de ces dernières années, GnuCash gère cela tout seul. Si, si. Voici à quoi ressemble notre achat d’agrafeuse2 :

Compte Débit Crédit
512 Banque 35,88 €
6063 Petit matériel 30,00 €
4456 TVA déductible 5,88 €

Cette transaction a mis en jeu trois comptes. L’écriture va donc se trouver sur les trois comptes à la fois.

  • Le compte bancaire de l’entreprise qui a été crédité de 35,88 € qui est le prix toutes taxes comprises de notre agrafeuse. Le crédit de ce compte provoque un retrait de l’argent qui s’y trouvait et donc un appauvrissement de l’entreprise.
  • Le compte recensant les achats de petit matériel. Il a été débité de 30,00 € qui correspond au prix hors taxes de l’agrafeuse. Il s’agit d’une charge pour l’entreprise. L’agrafeuse ne rentre pas dans le patrimoine de l’entreprise.
  • Le compte recensant la TVA que l’on peut déduire de notre prochaine déclaration. L’État devient alors débiteur de la somme de 5,88 € qu’il devra nous rembourser lors de la prochaine déclaration.

On remarque que la somme des débits est égal à la somme des crédits. C’est obligatoire. Pour toute écriture, la balance doit être équilibrée.

Plan comptable général

Maintenant que vous avez vaguement compris comment marchait une écriture comptable, vous vous demandez peut-être quels sont les comptes qu’il faut utiliser. Le système comptable français définit très précisément les comptes à utiliser dans le plan comptable général.

Il existe en fait trois plans comptables :

  1. le système de base,
  2. le système abrégé comprenant moins de comptes,
  3. le système développé comprenant plus de comptes.

Le système à choisir dépend de la taille de l’entreprise. On choisit généralement le système correspondant au bilan et au compte de résultat demandé par les impôts en fin d’exercice. Pour une société au réel simplifié, il est possible d’opter pour le système abrégé. Le plan comptable général est disponible sur le site de l’autorité des normes comptables. Il fait plus de 400 pages. L’article correspondant de Wikipedia fournit la liste des comptes.

Chaque compte est identifié par un nombre. Le premier chiffre indique la classe du compte :

  1. Les comptes de capitaux (capitaux propres, emprunts).
  2. Les comptes d’immobilisation (peu utilisés dans notre cas).
  3. Les comptes de stocks et d’en-cours (peu utilisés également).
  4. Les comptes de tiers (les fournisseurs, les clients, l’État, vous).
  5. Les comptes financiers (le compte en banque).
  6. Les comptes de charges (ce qui appauvrit votre entreprise).
  7. Les comptes de produits (ce qui enrichit votre entreprise).

Les cinq premières classes de comptes sont les comptes de bilan. Ils permettent de savoir ce que votre entreprise possède (l’actif et le passif) à tout moment. Les deux dernières classes sont les comptes de résultat. Ils sont remis à zéro après chaque exercice. Ils permettent notamment de connaître le résultat d’une entreprise sur un exercice.

Parmi les comptes les plus importants, on notera :

Compte Description
101 Le capital de la société.
401 Les comptes des fournisseurs.
411 Les comptes des clients.
445 Les comptes pour la TVA.
455 Le compte de l’associé (pour se faire rembourser les frais).
512 Le compte bancaire de l’entreprise.
6063 Le compte pour l’achat de fournitures dont la valeur ne dépasse pas 500 €.
625 Le compte pour les frais liés aux déplacements et aux missions. On y colle notamment les frais de restauration.
6410 Le compte permettant de verser une indemnité au gérant.
706 Le compte où sont crédités les revenus liés à des prestations de service.

Il en existe bien d’autres. Si un compte dispose d’un sous-compte, il faut utiliser uniquement l’un des sous-comptes.

GnuCash n’a pas le plan comptable général parmi les plans comptables proposés par défaut. Vous pouvez soit télécharger le plan comptable mis à disposition par Vincent Laure, soit télécharger le plan comptable que j’utilise qui correspond au système abrégé avec quelques comptes supplémentaires et certains comptes retirés. Il comprend également un compte fournisseur et deux comptes clients dont l’un en devises américaines.

Écritures comptables

Pour chaque écriture comptable, il faut connaître les comptes à débiter et les comptes à créditer. Généralement, cela n’a pas grand chose à voir avec GnuCash. Il est donc possible de se référer à l’abondante littérature sur le sujet ainsi qu’aux nombreux forums spécialisés dans la comptabilité.

Généralement, je fais une recherche préfixée par « écriture comptable » pour trouver mon bonheur. Je regarde les deux ou trois premières réponses pour me faire une idée. Les numéros de comptes indiqués sont généralement à cinq chiffres. Il n’est pas nécessaire de créer le compte exact : il suffit d’utiliser le compte du système abrégé ayant le même préfixe.

Il est crucial de ne pas s’emmêler avec les débits et les crédits. Dans une représentation en colonnes, les débits sont toujours dans la colonne de gauche. Les crédits sont dans la colonne de droite.

Enfin, GnuCash propose d’associer un numéro à chaque requête. Je scanne chaque pièce justificative et indique son numéro et une description dans le nom de fichier.

Opérations de création

La création de l’entreprise entraîne un certain nombre d’écritures. Il est important de noter que les écritures ne peuvent pas être antérieures à la création de l’entreprise.

Capital initial

L’apport du capital initial se fait en deux fois. Chaque associé fait d’abord une promesse d’apport en capital. Il devient alors débiteur du capital promis sur un compte dédié à cet effet. Ensuite, lorsque l’argent arrive sur le compte de l’entreprise, l’associé est crédité de cet apport.

Compte Débit Crédit
456 Promesse d’apport 5000 €
101 5000 €
Compte Débit Crédit
456 Versement apport 5000 €
512 5000 €

Publication de l’annonce légale

Une des étapes de la création d’entreprise est la publication d’une annonce légale. Généralement, un associé avance l’argent et est remboursé après la création.

Compte Débit Crédit
623 Annonce légale 97,71 €
445 TVA déductible 19,16 €
455 116,87 €

Dépôt des statuts au greffe

Le dépôt des statuts au greffe suit la même logique.

Compte Débit Crédit
622 Greffe du tribunal 72,08 €
445 TVA déductible 14,13 €
455 86,21 €

Opérations courantes

Les opérations courantes impliquant un flux financier créditent soit le compte bancaire de l’entreprise (512) ou celui de l’associé (455). Dans ce sens, c’est généralement interchangeable. L’associé peut être crédité de l’argent que l’entreprise lui doit par une écriture débitant le compte de l’entreprise :

Compte Débit Crédit
455 Remboursement frais 100 €
512 100 €

Repas du midi

Une écriture courante est le remboursement du repas du midi. Il y a beaucoup de théories à ce sujet. Il peut y avoir un plafond (environ 17 €), une somme forfaitaire à déduire (environ 4 €) et la déductibilité ou non de la TVA. À noter que le paiement d’une somme forfaitaire pour le repas de midi ne semble pas admise. Tout repas doit venir avec un justificatif.

Pour ma part, je n’applique aucun plafond, je ne déduis aucune somme forfaitaire mais je ne déduis pas la TVA, à moins qu’il s’agisse d’une invitation. Je paie toujours avec ma carte de crédit personnelle.

Compte Débit Crédit
6256 Repas du midi 13,20 €
455 13,20 €

Indemnités kilométriques

Si vous vous déplacez avec votre véhicule personnel, vous pouvez vous verser des indemnités kilométriques. Si le trajet est régulier, il semble qu’il n’est pas nécessaire de tenir un journal des déplacements. À noter que le barème évolue chaque année et dépend de la distance parcourue dans l’année. Dans le cas de trajets réguliers, je ne fais qu’une seule écriture par mois.

Compte Débit Crédit
6251 IK pour trajet de X à Y, 20 jours 141,50 €
455 141,50 €

Le train, l’avion, le taxi, les voitures de location se notent de la même façon. À noter dans ce cas qu’il n’est jamais possible de récupérer la TVA sur un transport de personnes.

Abonnements téléphoniques & ADSL

S’il y a usage professionnel, il est possible de se faire rembourser tout ou partie d’un abonnement téléphonique ou ADSL. Il faudra pouvoir justifier de l’usage professionnel. Certains indiquant que la TVA n’est normalement déductible que si la facture est au nom de l’entreprise. Personnellement, je la déduis tout de même.

Compte Débit Crédit
626 Abonnement ADSL 10,89 €
445 TVA déductible 2,14 €
455 13,03 €

Je fais passer de la même façon les abonnements à des services Web comme Amazon ou l’achat de noms de domaine.

Autres frais déductibles

Si le siège de votre entreprise est votre domicile, il est également possible de déduire au prorata de la surface utilisée :

  • une partie du loyer (je ne fais pas),
  • une partie des factures EDF, d’eau, des charges locatives (compte 6061),
  • une partie de l’assurance locative (compte 616)
  • une partie de la taxe d’habitation (compte 635)

Achats divers

Pour l’achat d’un bouquin, il faut utiliser le compte 6181. Pour l’achat d’une fourniture ou d’un matériel dont la valeur n’excède pas 500 €, il faut utiliser le compte 6063. Je vous renvoie à l’exemple de l’agrafeuse en introduction.

Voici un autre exemple avec des frais de ports :

Compte Débit Crédit
512 35,88 €
6063 Petit matériel 27,00 €
624 Frais de ports 3,00 €
4456 TVA déductible 5,88 €

Pour les montants supérieurs à 500 €, l’achat devient une immobilisation et non une charge. Il faut de plus en gérer l’amortissement.

Facturation et paiement d’un client

La principale source de revenus provient normalement des paiements des clients. Il y a deux étapes :

  1. Il faut d’abord adresser une facture au client. Celui-ci est alors débiteur du montant demandé.
  2. Quelques jours, mois, années plus tard, le client paie. On crédite alors son compte et s’il a payé exactement la somme facturée, son solde devient nul.

Les deux opérations n’ont généralement pas lieu à la même date. Chaque client dispose de son propre compte sous le compte 411 : il ne faut pas utiliser directement le compte 411.

On effectue de plus la collecte de la TVA pour l’État. Si le client est un professionnel, il récupérera la TVA de son côté. Si le client se trouve dans l’Union Européenne et qu’il fournit un numéro de TVA intracommunautaire, il n’est pas nécessaire de lui faire payer la TVA. Sinon, la TVA française s’applique. Il semble être d’usage d’utiliser un compte spécial (7062 au lieu de 706) dans ce cas. S’il est hors Union Européenne, les prestations de service sont exonérées de TVA.

GnuCash dispose d’un module d’édition des factures qui fait assez bien son boulot. Je n’utilise toutefois pas la possibilité d’imprimer la facture. Le rendu est assez désolant et je préfère donc faire mes factures manuellement avec LaTeX.

GnuCash gère aussi la TVA, mais de manière partielle. L’entreprise n’est redevable de la TVA qu’au moment du paiement. Au moment de la facturation, la TVA est placée dans un compte de régularisation (4458). GnuCash va calculer automatiquement la TVA et placer l’écriture suivante au moment de valider la facture :

Compte Débit Crédit
411× Client Durant 1196 €
4458 TVA à régulariser 196 €
706 Prestation conseil 1000 €

Par contre, au moment du paiement, il va simplement créditer le compte du client et débiter le compte en banque. Il faut alors penser à ajouter manuellement le transfert de la TVA au crédit du compte de la TVA collectée (4457). L’écriture du paiement ressemble à ceci :

Compte Débit Crédit
411× Client Durant 1196 €
4457 TVA collectée 196 €
4458 TVA à régulariser 196 €
512 1196 €

Facturation avec des devises étrangères

Si votre client vous paie en devises étrangères, les choses se compliquent énormément. En effet, votre client va disposer dans votre système d’un compte en dollars (par exemple). Mais tous vos autres comptes sont en euros. GnuCash gère cette situation en permettant d’indiquer un taux de change. Voici l’écriture qui apparaîtra dans le compte du client :

Compte Débit Crédit
411× Client Scott 1000 $
706 Prestation conseil 1000 $

GnuCash va vous demander le taux de change actuel. Du coup, dans le compte 706, vous verrez :

Compte Débit Crédit
411× Client Scott 767 €
706 Prestation conseil 767 €

Au moment du paiement, les choses se compliquent. Votre client vous paie 1000 $. Toutefois, ce ne sont pas 767 € qui arrivent sur votre compte, mais seulement 738 €. En effet, au moment du paiement, le taux de change a évolué. Vous avez alors une perte de change. Cette parte va s’inscrire au compte 666. S’il y avait eu gain, ce serait le compte 766.

Une façon simple de gérer le problème est de passer l’écriture en euros de cette façon :

Compte Débit Crédit
512 738 €
666 Perte de change 29 €
411× Client Scott 767 €

Il faut alors réutiliser le taux de change initial. De cette façon, on obtient dans le compte du client :

Compte Débit Crédit
512 960,00 $
666 Perte de change 40,00 $
411× Client Scott 1000 $

Le problème de devises peut aussi se poser pour l’achat de services. Toutefois, si la valeur est assez faible, il me semble plus simple de passer ces services sous forme d’une charge en euros.

Facturation d’un fournisseur

Si vous achetez des prestations à un fournisseur et que les montants sont suffisamment élevés (sinon, vous pouvez les passer directement en charges), vous pouvez créer un compte pour le fournisseur. Le schéma est similaire à la facturation d’un client. Le fournisseur vous envoie une facture, vous l’enregistrez et créditez le compte du fournisseur et débitez le compte de charge correspondant. Au paiement, vous débitez le fournisseur et créditez le compte en banque. Par exemple, pour un serveur dédié en Allemagne (pas de TVA) :

Compte Débit Crédit
626 41 €
401x Fournisseur Albert 41 €

Au paiement de la facture :

Compte Débit Crédit
401x 41 €
512 Paiement facture 41 €

Frais bancaires

Tous les mois, la banque va vous adresser une facture pour ses services. C’est généralement plus salé que lorsqu’on est un particulier. Personne ne sait trop bien pourquoi.

Compte Débit Crédit
512 23,92 €
627 Frais mensuels XX 20,00 €
4456 TVA déductible 3,92 €

Paiement de la TVA

Une fois par trimestre, il va falloir verser un accompte sur la TVA collectée pour l’État. On en profite aussi pour se faire rembourser la TVA déductible. Il semble d’usage de passer par deux écritures comptables qui ont généralement lieu en même temps :

Compte Débit Crédit
4457 TVA collectée 2500 €
4456 TVA déductible 100 €
4455 TVA à décaisser 2400 €
Compte Débit Crédit
4455 TVA à décaisser 2400 €
512 Paiement TVA 2400 €

Le réglement se fait en ligne sur le site des impôts. Il y a deux cases à remplir :

  • la base hors taxe des opérations imposables pour la TVA à 19,6 % (12 755 € dans notre cas pour arriver à une TVA de 2500 €),
  • la TVA déductible sur les factures de 100 €.

En fin d’année, il y a un formulaire supplémentaire pour régulariser la situation. Il me semble plus simple de toujours payer exactement ce qu’il faut sur les accomptes. Cela ne vous dispense pas de remplir le formulaire adéquat.

Rémunération du gérant

De temps en temps, il est possible de vous verser une rémunération. Le versement est net. Il faudra payer des cotisations URSSAF et RSI par la suite. Il ne s’agit pas d’un salaire.

Compte Débit Crédit
6410 Rémunération Juin 3000 €
512 3000 €

Cotisations URSSAF & RSI

Lorsque vous payez vos cotisations URSSAF et RSI, vous devez obtenir un reçu indiquant la répartition des montants. Voici par exemple comme régler la première cotisation forfaitaire de 448 € pour l’URSSAF :

Compte Débit Crédit
645 Allocations familiales 144 €
63 CSG déductible 136 €
455 CSG non déductible 64 €
455 CRDS 13 €
63 Formation professionnelle 91 €
512 448 €

On notera qu’une partie de la CSG est imputée en charges pour l’entreprise tandis qu’une partie est payée par l’associé.

Opérations de fin d’exercice

Les opérations courantes sont relativement simples à appréhender après les premiers mois. Les opérations de fin d’exercice sont par contre beaucoup plus complexes. Je vous conseillerais plutôt de prendre un comptable pour cette partie. Ce qui suit est à prendre avec des pincettes : personne n’est venu vérifier la validité de ma comptabilité.

Toutes les écritures sont à passer à la date du dernier jour de l’exercice. Elles doivent normalement régulariser les écritures concernant l’exercice passé. On y trouve :

  • régularisation du compte bancaire avec le relevé bancaire,
  • régularisation des charges et des produits

Les charges (ou les produits) qui sont à cheval sur deux exercices (comme le réglement d’une prime d’assurance, un abonnement de trois mois, …) doivent faire l’objet d’une écriture pour charges constatées d’avance. Dans le cas d’une petite entreprise, il semble que l’exercice soit optionnel si les sommes mises en jeu sont faibles.

Il existe d’autres écritures mais qui ne nous concernent pas s’il n’y a pas eu d’écritures correspondantes dans l’année passée :

  • régularisation des stocks
  • régularisation des immobilisations
  • régularisation des placements
  • régularisation des amortissements
  • régularisation des dépréciations
  • régularisation des provisions

Provisions pour rémunération

C’est aussi le bon moment pour décider de compléter votre rémunération. En effet, le bénéfice de l’entreprise peut être distribuée en rémunérations (soumises à l’IR) ou en dividendes. Dans le second cas, la somme destinée à cet effet sera d’abord soumise à l’impôt sur les sociétés. Le calcul peut être effectué via un simulateur. Les dividendes étant taxés comme des revenus à partir de 2013 pour la part dépassant les 10 % du capital de la société, il n’est pas très intéressant de se verser des dividendes.

Si vous voulez compléter votre rémunération de 10 000 €, il suffirait de passer l’écriture suivante au dernier jour de l’exercice :

Compte Débit Crédit
6410 Provision pour rémunération 10 000 €
455 10 000 €

Il faudra alors ensuite provisionner les charges correspondantes.

Provisions pour charges sociales

Il est possible de provisionner les sommes qui seront demandées par les différents organismes sociaux (URSSAF, CIPAV, RSI) et de les déduire du résultat. Il faut donc déterminer une approximation des cotisations qui seront réclamées à l’aide d’un des nombreux simulateurs que l’on trouve sur le web. Ensuite, l’écriture semble être la suivante3 :

Compte Débit Crédit
645 Maladie/Vieillesse/AF 4000 €
63 CSG déductible 1000 €
43 Provisions pour charges 5000 €

Pour chaque paiement, il faudra débiter le compte 43 au lieu des comptes 645 et 63. Par exemple, pour les cotisations URSSAF, on ferait :

Compte Débit Crédit
43 Allocations familiales 144 €
43 CSG déductible 136 €
455 CSG non déductible 64 €
455 CRDS 13 €
43 Formation professionnelle 91 €
512 448 €

Si la provision s’avère trop importante en fin d’année suivante, il faudra affecter le surplus au compte 787.

Clôture des comptes

Une fois les régularisations effectuées, on passe aux travaux de clôture et de réouverture des comptes. Il s’agit de solder tous les comptes de charges (dont le numéro commence par 6) et de produits (dont le numéro commence par 7). Solder signifie mettre la balance du compte à zéro.

Si le compte 709 est débiteur, il faut le solder manuellement dans un autre compte (le 706 par exemple). Si les comptes 609, 619 ou 629 sont créditeurs, il faut les solder avec l’un des voisins (par exemple, 6063, 6181 et 6251). Ces comptes sont particuliers car ils fonctionnent dans le sens inverse des comptes de la même catégorie.

Vient ensuite la clôture proprement dite. GnuCash dispose d’une fonction pour vous aider à la réaliser. Dans le menu « Outils », choisir la fonction « Clôturer le livre ». Indiquer la date de clôture (dernier jour de l’exercice) et les comptes à utiliser pour les revenus et les dépenses. Dans le cadre du système abrégé, il s’agit du compte 12. On obtient l’écriture suivante :

Compte Débit Crédit
706 Prestations conseil 50 000 €
627 Services bancaires 100 €
63 Impôts et taxes 200 €
6251 Voyages et déplacements 1000 €
6256 Frais de missions 1000 €
6410 Rémunération du gérant 20 000 €
645 Charges sociales 8000 €
6063 Petit matériel 1000 €
12 Transfert des charges 31 300 €
12 Transfert des produits 50000 €

On se retrouve avec un résultat bénéficiaire de 18 700 €.

Pour la réouverture des comptes, il était d’usage d’utiliser des livres papiers différents pour chaque exercice. Certains préconisent de faire de même en repartant de zéro pour le nouvel exercice. J’ai personnellement choisi de garder tous les exercices dans un seul fichier GnuCash. Cela dispense de fastidieuses écritures de bilan.

Calcul de l’impôt sur les sociétés

Le bénéfice permet de calculer l’impôt dû pour l’exercice précédent. Sur le bénéfice calculé précédemment, l’impôt dû est de 15 % pour la partie inférieure à 38 120 € et de 33,3 % pour le reste. Dans notre exemple, l’impôt dû est donc de 2 805 €.

Avec cette information, vous pouvez revenir quelques étapes en arrière en annulant la clôture des comptes (il suffit d’effacer les deux écritures) et en ajustant la provision pour rémunération. Dans le cas contraire, vous pourrez toujours récupérer le résultat en dividendes mais l’imposition est plutôt prohibitive.

Une fois que votre calcul est définitif, il faut passer l’écriture suivante :

Compte Débit Crédit
695 Paiement de l’IS 2 805 €
444 2 805 €

Puis clôturer de nouveau le compte 6954 :

Compte Débit Crédit
12 Transfert des charges 2 805 €
695 2 805 €

Établissement du compte de résultat et du bilan

Le compte de résultat s’intéresse à ce qui s’est passé durant l’exercice au niveau des comptes de charges et de produits. Le bilan donne une image des autres comptes au dernier jour de l’exercice.

Le plan comptable général comprend les modèles adéquats pour le compte de résultat et le bilan. Il existe un notamment modèle adapté au système abrégé. On peut aussi le trouver sous un format exploitable par un tableur. Malheureusement, il n’y a pas la correspondance entre les diverses cases à remplir et les numéros de comptes.

Le compte de résultat est assez simple à remplir. Toutes les informations nécessaires sont dans les écritures de clôture (celles vers le compte 12). Il suffit donc de les inspecter et de les ventiler dans les cases appropriées.

J’ai reporté la ventilation que j’ai adoptée dans un modèle de compte de résultat (sources). Une fois le total effectué, on en calcule la différence et on a le reporte soit sur la ligne « solde créditeur » (en cas de bénéfices), soit sur la ligne « solde débiteur » (en cas de pertes). Cette différence doit être le solde du compte 12. Les totaux généraux sont alors équilibrés.

Le bilan est un peu plus délicat pour deux raisons :

  • les comptes de tiers (4xx) mélangent à la fois l’actif et le passif
  • les amortissements et les provisions doivent être déduits de l’actif

Le second point est pour moi tout théorique car je n’ai ni amortissement, ni provision. Le premier point est plus problématique et il faudra donc faire attention à bien comptabiliser les créances des tiers au niveau de l’actif et vos dettes au niveau du passif. J’ai indiqué la difficulté dans mon modèle de bilan par une étoile.

Pour établir le bilan, GnuCash peut nous aider en demandant dans le menu « Rapports » l’établissement du bilan. Il convient ensuite de ventiler attentivement. Si tout se passe bien, les totaux généraux s’équilibrent.

Affectation du résultat

Une fois le bénéfice correctement calculé, le bilan dressé et le compte de résultat établi, il est possible d’affecter le résultat si celui-ci est créditeur5 :

  • le résultat est diminué du report à nouveau de l’exercice précédent s’il est débiteur,
  • si la réserve légale n’est pas égale à au moins 10 % du capital social total, 5 % du résultat restant sont affectés à celle-ci,
  • le résultat est augmenté du report à nouveau de l’exercice précédent s’il est créditeur,
  • le résultat peut alors être distribué sous forme de dividendes s’il reste créditeur,
  • le reste du résultat est crédité au compte du report à nouveau (11).

Sachant qu’il est désormais prohibitif de se distribuer le résultat en dividendes en France (au-delà de la limite de 10 % du capital social), il est donc peu intéressant d’avoir un résultat important. Voici un exemple de distribution dans le cas où la réserve légale n’existe pas encore :

Compte Débit Crédit
120 Résultat 2012 15 895 €
1061 Réserve légale 794 €
457 Dividendes à payer 1000 €
11 Report à nouveau 14 101 €

Ces transactions sont datées au 31 décembre 2012. Lors du paiement effectif des dividendes, il faudra penser à retirer les prélevements sociaux (15,5 % pour 2013) et les créditer sur le compte 442 ou 447.

Déclaration de l’IS

L’épreuve finale est désormais la déclaration de résultats auprès des impôts. Dans l’optique de faire supporter les coûts de déclaration au contribuable, l’administration impose désormais une télétransmission au format EDI via un partenaire tierce6 qu’il vous faudra rétribuer. Comptez environ 200 €.

L’intermédiaire peut demander les balances sous un certain format. Dans mon cas, il est possible de fournir les balances au format CSV. Malheureusement, GnuCash n’est pas particulièrement brillant dans ce domaine. Il existe une entrée dans la FAQ à ce sujet, mais cela consiste généralement à effectuer des manipulations complexes.

J’ai simplement formaté manuellement la balance dans un fichier CSV. Il s’agit plus ou moins de refaire une nouvelle fois son bilan car il faut donner les détails :

  1. Recopier le détail du compte de résultat en s’aidant simplement des écritures des comptes de charges et de produits vers le compte 12.
  2. Recopier l’état des autres comptes tels qu’ils étaient avant l’écriture comptable de l’affectation du résultat. Ne pas recopier le compte 12 (sinon, il n’y a pas équilibre).
  3. Inclure l’écriture comptable du compte 695 vers le compte 444.

La balance est normalement équilibrée et le logiciel de saisie retrouve le même résultat comptable.

Il reste ensuite à compléter correctement les 11 formulaires de déclaration. Chaque case peut faire l’objet d’une recherche approfondie sur le sujet. Par exemple, sur le formulaire 2033—B, faut-il reporter les charges sociales dans la case 380 ? Il semble que dans le cas d’une EURL à l’IS, il n’y a pas d’exploitant et il faut donc laisser cette case vide, malgré la remarque attachée à la case 252.

Bref, un comptable sera d’une grande aide.


  1. Outre la vérification, le comptable pourra aussi prendre en charge la télétransmission qui est actuellement obligatoire pour l’IS et qui pourrait le devenir pour d’autres déclarations. Voir la section dédiée à cet effet. 

  2. Une écriture comptable doit également comporter la date et une description. Je les omets ici pour ne pas surcharger la présentation. 

  3. À noter qu’il existe un compte de provisions pour les charges (681). Il peut sembler idéal pour ce type d’opération. Toutefois, ce compte ne doit être utilisé que pour une charge probable. Si la charge est certaine (comme c’est le cas ici), il n’y a pas lieu d’utiliser ce compte. 

  4. Il semble que cette façon de faire soit contestable. Toutefois, je ne vois pas comment s’assurer que ce compte ne perturbe pas l’exercice suivant s’il n’est pas soldé. 

  5. Si le résultat est débiteur, il est simplement enregistré au débit du report à nouveau. 

  6. Il est possible de devenir soi-même partenaire EDI. Il suffit de passer une convention avec la direction des impôts qui peut accepter ou refuser. Il faudra ensuite vous palucher les specs du protocole basé sur le standard EDIFACT, respecter le cahier des charges annuel et obtenir le label nécessaire pour pouvoir télétransmettre. Nul doute que l’ensemble est fait dans la plus totale obscurité. Nous vous attendez pas à trouver un dépôt GitHub. 

06 April, 2013 07:52PM par Vincent Bernat

29 March 2013

Tanguy Ortolo

Pré-compresser des fichiers statiques avec le Serveur HTTP Apache

Quand on publie un site Web constitué de fichiers statiques avec le Serveur HTTP Apache, on peut réduire le débit utilisé pour servir ces fichiers en activant la compression à la volée, avec le mod_deflate. Ainsi, si le client annonce qu'il prend cela en charge, Apache compressera les fichiers avant de les lui envoyer, et le client les décompressera à la réception.

Plume

Pré-compression

L'inconvénient de cette approche, c'est que le serveur doit effectuer la compression pour chaque requête ; il est plus efficace de pré-compresser les fichiers une fois pour toute, en conservant le fichier original pour les clients qui ne prennent pas en charge la décompression :

$ ls
index.html
$ gzip < index.html > index.html.gz
$ ls
index.html index.html.gz

On peut ensuite servir ces fichiers directement en indiquant qu'ils sont compressés. Cela se fait avec le mod_mime, en déclarant un nouvel « encodage » gzip — terme désignant une encapsulation dans le langage de la norme HTTP :

LoadModule mime_module /usr/lib/apache2/modules/mod_mime.so
AddEncoding x-gzip .gz .tgz

Négociation de contenu

Cela suffit à servir des fichiers pré-compressés, mais seulement pour les clients qui les demandent explicitement, par exemple index.html.gz. Ce n'est pas très utile, on peut donc utiliser le mod_negociation pour servir automatiquement le fichier compressé en réponse à une requête normale, index.html dans ce cas. Pour activer cette fonctionnalité :

LoadModule negotiation_module /usr/lib/apache2/modules/mod_negotiation.so
Options +MultiViews

Le problème, c'est que la « négociation de contenu », qui permet à Apache de servir un fichier parmi plusieurs candidats selon la langue, le codage et la compression pris en charge par le client, ne se déclenche que si aucun fichier ne correspond exactement à la requête. Or, même si index.html.gz serait un bon candidat pour une requête sur index.html, il y a justement un fichier index.html qui correspond à cette requête, et la négociation de contenu n'entre donc pas en jeu. Il faut donc renommer le fichier original :

$ mv index.html index.html.raw
$ ls
index.html.gz index.html.raw

… et déclarer un nouveau type de (non-)compression :

AddEncoding identity .raw

Avec cela, et en redémarrant le Serveur HTTP Apache, le fichier index.html.raw sera servi aux clients qui ne prennent pas en charge la compression, et le fichier index.html.gz à ceux qui la prennent en charge.

29 March, 2013 11:21AM par Tanguy

Olivier Berger (pro)

Managing Python code with UTF-8 (french chars) in org-mode + babel + minted for LaTeX export

The goal of this article is to illustrate how to manage Python code which includes comments in UTF-8 characters inside a latin-1 source org-mode for LaTeX export.

Note that I’ve pasted in wordpress the HTML generated by org-mode, so I hope it isn’t broken too much.

My typical use case is a french lecture on Python where the text is written in french, as well as some of the code comments and examples

We’ll use org-mode’s babel module to include and manage the Python
examples. The goal is to write the source of the Python programs
directly in the same org source as the class book’s text, and to extract them into a subdir (with the “tangle” feature), so that they can be shipped to the students to experiment with.

The minted LaTeX environment is used, for babel, to make the Python syntax highlighting.

1.1 Issues

  • The source org-mode is in latin-1 so that it compiles with pdflatex
  • The examples source-code will be in UTF-8 so that Python 2.7 executes them well on a modern Linux desktop
  • Minted relies on pygmentize wich doesn’t seem to handle UTF-8 so well

1.2 Solution

We’ll show how to “patch” minted’s use of pygmentize to take advantage
of its conversion capacity to convert the Python sources from UTF-8 to
latin-1 at document rendering time (LaTeX compilation).

It’s a hack, but works.

The current document’s source shows how this works

1.2.1 Customization

The org document should contain the following headers :

#+LANGUAGE:  fr
#+LaTeX_HEADER: \usepackage[latin1]{inputenc}
#+LaTeX_HEADER: \usepackage[french]{babel}
#+LaTeX_HEADER: \usepackage{color}\usepackage{minted}

and the footers :

# Local Variables:
# coding: latin-1
# org-src-preserve-indentation: true
# tab-width: 4
# End:

Also note that pdflatex should use the -shell-escape option necessary for minted

Now, the document should also include the following “patch” for minted :

#+LATEX_HEADER: \makeatletter
#+LATEX_HEADER: \renewcommand\minted@pygmentize[2][\jobname.pyg]{
#+LATEX_HEADER:   \def\minted@cmd{pygmentize -l #2 -f latex -F tokenmerge
#+LATEX_HEADER:     \minted@opt{gobble} \minted@opt{texcl} \minted@opt{mathescape}
#+LATEX_HEADER:     \minted@opt{startinline} \minted@opt{funcnamehighlighting}
#+LATEX_HEADER:     \minted@opt{linenos} -P "verboptions=\minted@opt{extra}"
#+LATEX_HEADER:     -O encoding=UTF-8,outencoding=iso-8859-1 -o \jobname.out.pyg #1}
#+LATEX_HEADER:   \immediate\write18{\minted@cmd}
#+LATEX_HEADER:   % For debugging, uncomment:
#+LATEX_HEADER:   %\immediate\typeout{\minted@cmd}
#+LATEX_HEADER:   \ifthenelse{\equal{\minted@opt@bgcolor}{}}
#+LATEX_HEADER:    {}
#+LATEX_HEADER:    {\begin{minted@colorbg}{\minted@opt@bgcolor}}
#+LATEX_HEADER:   \input{\jobname.out.pyg}
#+LATEX_HEADER:   \ifthenelse{\equal{\minted@opt@bgcolor}{}}
#+LATEX_HEADER:    {}
#+LATEX_HEADER:    {\end{minted@colorbg}}
#+LATEX_HEADER:   \DeleteFile{\jobname.out.pyg}}
#+LATEX_HEADER: \makeatother

The important change is the addition of the -O encoding=UTF-8,outencoding=iso-8859-1 option of pygmentize, that will convert the UTF-8 source code to latin-1.

Hopefully most of the characters will convert fine, for a document written in french.

2 Examples

2.1 Basic Python

This is a generic verbatim example, which doesn’t use babel / minted.

$ python
Python 2.7.3 (default, Jan  2 2013, 16:53:07) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print "Hello, world!"
Hello, world!
>>>

2.2 Python source code for french speakers

Here, we first include the source code, so that it can be exported to
an examples/ subdir, with the following (note that the #+ BEGIN_src / #+ END_src should be changed to get rid of the space
character between + and BEGIN / END, and that the :shebang and following text should be on the BEGIN_SRC line… I seem to have not quoted
these properly in this document):

#+name: helloworld
#+ BEGIN_src python :tangle examples/helloworld.py :noweb yes \\
:shebang #!/usr/bin/python :padline no :exports none
# -*- coding: utf-8 -*-

# Ceci est un exemple d'affichage d'une chaîne accentuée

name = raw_input("Quel est vôtre nom ? ")

print "J'espère que ça va bien aujourd'hui", name
#+ END_src

Editing it with “C-c ‘” will open an UTF-8 buffer, so hopefully, this will be consistent with the utf-8 coding system declared on the second line.

The regeneration of the examples/helloworld.py file is made with C-c C-v t (babel “tangling”).

Note that we don’t add the #!/usr/bin/python first line in the source, as we want it to be added by the tangling process (which will also make the script executable).

Once this is done, the script may be run :

$ python examples/helloworld.py 
Quel est vôtre nom ? François
J'espère que ça va bien aujourd'hui, cher François

Now, to add the colorized rendering in the lecture book, we do (here again, remove the spaces):

# +BEGIN_latex
\inputminted{python}{examples/helloworld.py}
# +END_latex

And here it is, rendered by minted:

# -*- coding: utf-8 -*-

# Ceci est un exemple d'affichage d'une chaîne accentuée

name = raw_input("Quel est vôtre nom ? ")

print "J'espère que ça va bien aujourd'hui, cher", name

Here are links to : the source, the PDF result, and the generated Python program.

29 March, 2013 10:44AM par Olivier Berger

28 March 2013

Tanguy Ortolo

Nouvelle planète auto-hébergement

Comme prévu, je viens de remplacer l'ancien Planet auto-hébergement par une nouvelle version basée sur Planet Venus sur mon propre serveur.

La Terre entourée d'un petit maillage de fibres optiques

Vous pouvez donc maintenant venir découvrir la nouvelle Planète auto-hébergement, qui propose :

Si vous tenez un blog ou vous parlez d'auto-hébergement, il n'est pas trop tard pour me l'indiquer !

La configuration de Planet Venus est intéressante, et il faudra sans doute que je rédige un article synthétisant mon expérience avec ce logiciel, mais j'attends d'abord que les débats actuels se calment un peu pour pouvoir finaliser un autre projet de Planète Catholique…

28 March, 2013 12:17PM par Tanguy

18 March 2013

Olivier Berger (pro)

Conférence “L’économie du logiciel libre et la percée d’OpenStack dans le cloud” le 27/03 à Évry

L’association Minet organise une conférence le 27/03 dans les locaux de Télécom SudParis et Télécom École de Management à Évry, qui promet d’être intéressante.

Elle portera à la fois sur l’économie du logiciel libre et sur l’essort d’OpenStack dans le cloud.

N’hésitez pas à venir nombreux sur le campus pour écouter les interventions de Jonathan Le Lous, Julien Brichard et Raphaël Ferreira, et rencontrer votre serviteur ;-)

Plus de détails sur le site de Minet.

18 March, 2013 12:49PM par Olivier Berger

16 March 2013

Debian France

Debian France aux Solutions Linux/Open Source 2013

Stand Debian France aux Solutions Linux/Open Source 2013

Le salon Solutions Linux/Open Source aura lieu les 28 et 29 mai 2013, au CNIT à La Défense.

Ce salon, essentiellement destiné aux professionnels, comporte comme chaque année un « village associatif » qui regroupe différentes associations du monde du logiciel libre. Debian France y tiendra un stand, où vous pourrez :

  • vous informer sur le système d'exploitation et la communauté Debian ;
  • acheter des accessoires pour afficher votre attachement à Debian : polos, autocollants…

Stand Debian France aux SL 2011

Si vous souhaitez aider, nous cherchons quelques volontaires pour tenir le stand.

Pour plus d'informations :

16 March, 2013 06:41PM

14 March 2013

Florent Gallaire

La syntaxe des sets en Python

Pour comprendre la génèse de la syntaxe des sets, il faut étudier celle des types conteneurs historiques de Python qui sont :

  • les listes, délimitées par les crochets [ et ]
  • les tuples, délimités par les parenthèses ( et )
  • les dictionnaires, délimités par les accolades { et }

Ces types conteneurs sont donc dotés d’une syntaxe légère et facilement utilisable :

>>> l = [1, 2, 3]
>>> l
[1, 2, 3]
>>> t = (1, 2, 3)
>>> t
(1, 2, 3)
>>> d = {1: '1', 2: '2', 3: '3'}
>>> d
{1: '1', 2: '2', 3: '3'}

Les tuples, qui sont en fait des listes immutables et que l’on ne peut donc pas modifier, sont souvent oubliés car assez peu utilisés, en tout cas de manière consciente. En effet, une simple énumération sans syntaxe spécifique est en fait un tuple :

>>> e = 1, 2, 3
>>> e
(1, 2, 3)

Si l’on peut donc dire que globalement, les listes et les dictionnaires répondent à la grande majorité des besoins des programmeurs, un quatrième type conteneur s’est lentement mais sûrement fait une place au soleil des pythonistes : les sets.

Un set est un ensemble, c’est-à-dire une collection non ordonnée d’éléments uniques, ce qui se révèle très pratique dans beaucoup d’usages courants. Ce nouveau type conteneur étant fourni en deux saveurs, l’une mutable (comme les listes), et l’autre immutable (comme les tuples).

D’abord introduits dans Python 2.3 sous la forme d’un nouveau module sets ajouté à la bibliothèque standard. Il est ensuite devenu un type built-in dans Python 2.4, ce qui représentait une amélioration syntaxique non négligeable. Plus besoin d’écrire :

>>> import sets
>>> s_mutable = sets.Set([1, 2, 3])
>>> s_immutable = sets.ImmutableSet([1, 2, 3])

On pouvait dorénavant se contenter de :

>>> s_mutable = set([1,2,3])
>>> s_immutable = frozenset([1,2,3])

Et de bénéficier en plus d’une implémentation du type set en C et non plus en Python, avec la belle augmentation de performance qui va avec.

L’intégration des sets mutables (les plus utiles) dans le core du langage Python, au même niveau que les tuples, les listes et les dictionnaires, se heurtait encore à une limitation syntaxique : il fallait écrire set([1, 2, 3]). En effet, il n’y a que trois signes de ponctuation ASCII 7 bits fonctionnant par paire et facilement accessibles sur un clavier, les parenthèse, les crochets et les accolades, qui comme on l’a vu sont déjà utilisés respectivement par les tuples, les listes et les dictionnaires.

Mais que pouvait-on alors faire pour mieux intégrer syntaxiquement les sets à Python ? C’est dans Python 3.0 que la solution a été trouvée : si les tuples et les listes sont des énumérations que l’on ne pourrait distinguer des sets, les dictionnaires sont eux bien différents, et l’on peut donc utiliser les accolades { et } pour une énumération sans risque de confusion :

>>> s = {1, 2, 3}
>>> s
{1, 2, 3}

Il reste cependant une petite exception qui rend cette solution syntaxique imparfaite, et potentiellement génératrice d’erreurs ou d’incompréhensions, c’est le cas de l’ensemble vide. En effet, {} ne peut pas représenter à la fois le dictionnaire vide et le set vide :

>>> s = {}
>>> s
{}
>>> isinstance(s, set)
False
>>> isinstance(s, dict)
True

De manière logique et rétrocompatible, {} représente donc toujours le dictionnaire vide, et c’est set() qui permet de créer un set vide :

>>> s = set()
>>> s
set()
>>> s.add(1)
>>> s
{1}

Enfin, ce sucre syntaxique de Python 3 a été backporté dans Python 2.7.

 

flattr this!

14 March, 2013 01:45AM par fgallaire

07 March 2013

Julien Vehent

DIY eMail @ Home

A few weeks ago, I presented my personal email architecture to PLUG, the Philadelphia Linux User Group. I have been using this setup for years now, and every time someone sends me an email at julien[at]linuxwall.info, it reaches one of these server.

A lot of this is documented on http://wiki.linuxwall.info. Maybe some day I'll get around writing an actual documentation. In the meantime, check out the links in the slides below.


<iframe allowfullscreen="allowfullscreen" frameborder="0" height="421" marginheight="0" marginwidth="0" mozallowfullscreen="mozallowfullscreen" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/16989081?rel=0" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" webkitallowfullscreen="webkitallowfullscreen" width="512"> </iframe>
DIY eMail@Home from jvehent

07 March, 2013 01:13AM par Julien Vehent

05 March 2013

Philippe Latu

Initiation au développement IPv4 + IPv6

La rubrique dev vient d'être enrichie d'un nouveau support sur l'Initiation au développement C sur les sockets IPv4 & IPv6.

Ce qui, au départ, ne devait être qu'un complément au précédent document utilisant seulement IPv4 a finalement abouti à une progression en quatre étapes ou programmes. J'ai conservé l'idée initiale d'échange de chaîne de caractères entre un client et un serveur. Cette forme rudimentaire de chat est très bien accueillie par les étudiants.

La première étape est un plagiat éhonté du programme showip du livre Beej's Guide to Network Programming. La technique de parcours des enregistrements addrinfo issus de l'appel à getaddrinfo() est ensuite reprise dans tous les autres programmes du document. À la deuxième étape, le programme client se contente d'ouvrir la première prise réseau ou socket disponible. Jusque là, tout va bien ! C'est avec le programme serveur que les choses se compliquent. Faut-il utiliser une ou deux prises réseau ?

dual stack single socket

Franchement, je n'ai pas le recul nécessaire pour prendre parti sur cette question. Ce qui est sûr, c'est que la solution «académique» est plus séduisante pour un prof. Le code de la couche application est indépendant des protocoles de la couche réseau et la quantité de code est plus réduite. Ça n'empêche pas de souffrir un peu sur l'utilisation de l'option bindv6only et sur l'interprétation des codes d'erreurs associés. J'ai fini par aboutir au tableau de tests suivant. Les deux étapes restantes proposent les programmes serveurs avec une puis deux prises réseau.

client ou talker

Serveur ou listener

socket unique

bindv6only = 0

Serveur ou listener

socket double

bindv6only = 1 -> socket IPv6

Client dual stack

disable_ipv6 = 0

IPv6

IPv6

Client single stack

disable_ipv6 = 1

IPv6

IPv4-mapped IPv6 addresses

IPv4

Une fois la difficulté de gestion des options sur les sockets franchie, la dernière étape avec le codage d'un serveur dual stack à deux prises réseau permet de se familiariser avec l'utilisation de la fonction select() et des macros associées.

Pour conclure, l'utilisation conjointe des deux protocoles IPv4 et IPv6 entraîne un niveau de difficulté plus important dans la manipulation des enregistrements d'adresses IP. Ce pas supplémentaire peut être délicat à franchir pour un public débutant. C'est certainement la raison pour laquelle les enseignants préfèrent s'en remettre à des bibliothèques de plus haut niveau pour aborder les sockets. En Génie Électrique, les développements sont très proches de l'espace noyau et le langage C reste incontournable, ce qui rend le compromis délicat à négocier.

Comme d'habitude, si quelqu'un à le courage de s'attaquer à la lecture du document, je serais très content de lire toutes les remarques ou critiques !

05 March, 2013 07:54PM par Philippe Latu

04 March 2013

Ulrich L.

Configuration de Bind9 avec wildcard et Apache2 avec VirtualHost dynamique

Je viens de refaire mon serveur de développement et j'en ai profité pour rendre sa configuration plus facile. Je travaille sur plusieurs projets et devoir configurer le DNS et le serveur apache pour chaque projet n'est pas des plus passionnant, surtout appliqué dans une entreprise avec une equipe d'une dizaine de développeurs, ou comment perdre 20 minutes. Dans cet article je vous présente la configuration que j'ai mis en place d'Apache et de Bind.

04 March, 2013 11:00PM

20 February 2013

Vincent Bernat

lldpd 0.7.1

Il y a quelques semaines, une nouvelle version de lldpd, une implémentation de 802.1AB (norme aussi connue sous le nom LLDP), a été publiée.

LLDP est un protocole destiné à remplacer d’autres protocoles de niveau 2 tels que EDP et CDP. Son but est de fournir un mécanisme standard pour envoyer des informations aux périphériques réseau voisins.

De manière plus pragmatique, LLDP permet de savoir exactement sur quel port est branché un serveur (et réciproquement). Pour illustrer son usage, j’ai réalisé quelques images à la xkcd:

Exemple d'utilisation de LLDP

Pour plus d’informations sur lldpd, rendez-vous sur le nouveau site web qui lui est dédié. Ce journal est destiné à présenter les grands changements techniques qui ont affectés lldpd depuis la précédente version majeure sortie il y a un an.

Version & journal des modifications

MISE À JOUR : Guillem Jover m’a indiqué comment il avait fait pour libbsd :

  1. Sauvegarder la version issue de git dans .dist-version et la réutiliser si elle existe. Cela permet de pouvoir reconstruire le ./configure à partir de l’archive publiée sans perdre la version, ce qui permet de répondre à la critique de Thorsten Glaser sans perdre en souplesse.
  2. Inclure le fichier CHANGELOG dans DISTCLEANFILES.

C’est une meilleure façon de faire que j’ai donc adoptée. Les deux sections suivantes sont donc en partie obsolètes dans leur réalisation technique.

Version automatique

Le numéro de version était précédemment en dur dans le fichier configure.ac. Il fallait donc penser à modifier la ligne correspondante avant chaque publication :

AC_INIT([lldpd], [0.5.7], [bernat@luffy.cx])

Cette information est déjà présente dans l’arbre git et il est donc possible de l’en extraire automatiquement de manière assez simple :

AC_INIT([lldpd],
        [m4_esyscmd_s([git describe --tags --always --match [0-9]* 2> /dev/null || date +%F])],
        [bernat@luffy.cx])

Si HEAD est étiqueté 0.7.1, ce sera exactement ce numéro de version qui sera utilisé. Sinon, l’étiquette la plus proche est utilisée suivie du nombre de commits depuis celle-ci ainsi que du hash courant. Par exemple : 0.7.1-29-g2909519.

Pour que cela fonctionne, il est donc nécessaire de générer le ./configure depuis l’arbre git et non depuis l’archive finale qui ne contient plus cette information.

Construction du journal des modifications

La construction automatique du journal des modifications à partir de l’arbre git est une pratique assez répandue. Il y a toutefois quelques subtilités pour l’intégrer correctement dans le processus de publication. Voici ma tentative avec l’aide de automake :

dist_doc_DATA = README.md NEWS ChangeLog

.PHONY: $(distdir)/ChangeLog
dist-hook: $(distdir)/ChangeLog
$(distdir)/ChangeLog:
        $(AM_V_GEN)if test -d $(top_srcdir)/.git; then \
          prev=$$(git describe --tags --always --match [0-9]* 2> /dev/null) ; \
          for tag in $$(git tag | grep -E '^[0-9]+(\.[0-9]+){1,}$$' | sort -rn); do \
            if [ x"$$prev" = x ]; then prev=$$tag ; fi ; \
            if [ x"$$prev" = x"$$tag" ]; then continue; fi ; \
            echo "$$prev [$$(git log $$prev -1 --pretty=format:'%ai')]:" ; \
            echo "" ; \
            git log --pretty=' - [%h] %s (%an)' $$tag..$$prev ; \
            echo "" ; \
            prev=$$tag ; \
          done > $@ ; \
        else \
          touch $@ ; \
        fi
ChangeLog:
        touch $@

Les entrées sont groupées par version. Je maintiens manuellement un résumé des modifications les plus importantes dans un fichier NEWS.

Cœur

C99

J’ai récemment lu le livre 21st Century C qui est globalement très positif. J’ai depuis adopté l’initialisation des membres d’une structure lors de la déclaration. Étant donné qu’il s’agit également d’une extension de GCC depuis longtemps, cela ne représente pas un problème de compatibilité majeur.

Sans cette fonctionnalité :

struct netlink_req req;
struct iovec iov;
struct sockaddr_nl peer;
struct msghdr rtnl_msg;

memset(&req, 0, sizeof(req));
memset(&iov, 0, sizeof(iov));
memset(&peer, 0, sizeof(peer));
memset(&rtnl_msg, 0, sizeof(rtnl_msg));

req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
req.hdr.nlmsg_type = RTM_GETLINK;
req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
req.hdr.nlmsg_seq = 1;
req.hdr.nlmsg_pid = getpid();
req.gen.rtgen_family = AF_PACKET;
iov.iov_base = &req;
iov.iov_len = req.hdr.nlmsg_len;
peer.nl_family = AF_NETLINK;
rtnl_msg.msg_iov = &iov;
rtnl_msg.msg_iovlen = 1;
rtnl_msg.msg_name = &peer;
rtnl_msg.msg_namelen = sizeof(struct sockaddr_nl);

Et avec cette fonctionnalité :

struct netlink_req req = {
    .hdr = {
        .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
        .nlmsg_type = RTM_GETLINK,
        .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP,
        .nlmsg_seq = 1,
        .nlmsg_pid = getpid() },
    .gen = { .rtgen_family = AF_PACKET }
};
struct iovec iov = {
    .iov_base = &req,
    .iov_len = req.hdr.nlmsg_len
};
struct sockaddr_nl peer = { .nl_family = AF_NETLINK };
struct msghdr rtnl_msg = {
    .msg_iov = &iov,
    .msg_iovlen = 1,
    .msg_name = &peer,
    .msg_namelen = sizeof(struct sockaddr_nl)
};

Journaux

La journalisation de lldpd était assez pauvre. Généralement, pour répondre à un rapport de bug, je demandais à l’ateur d’ajouter quelques printf() par-ci, par-là. J’ai ajouté des appels à log_debug() à de nombreux endroits ainsi qu’une possibilité de filtre. Par exemple, pour obtenir des informations détaillés sur la découverte des interfaces, il est possible de lancer lldpd avec les arguments -ddd -D interface.

De plus, la sortie sur un terminal est faite en couleurs. Cela peut paraître futile, mais il est beaucoup plus aisé de repérer rapidement les erreurs et les avertissements de cette façon.

Sortie en couleurs de lldpd

libevent

lldpd 0.5.7 utilisait sa propre boucle d’événements à base de select(). Cela ne posait pas de problèmes particuliers mais je ne voulais pas étendre cette boucle pour aboutir à une boucle d’événements complète alors qu’il existe des bibliothèques solides dédiées à cet usage. J’ai donc remplacé celle-ci par libevent.

La version minimale de libevent requise est la 2.0.5. Le site Upstream Tracker permet de consulter les changements d’API et d’ABI d’une bibliothèque et donc de vérifier la version nécessaire. Cette version de libevent n’est pas disponible dans de nombreuses distributions. Par exemple, Debian Squeeze et Ubuntu Lucid n’ont que la version 1.4.13. Je tente également de maintenir la compatibilité avec des distributions beaucoup plus anciennes, telles que RHEL 2, qui peuvent ne pas avoir libevent du tout.

Pour certains utilisateurs, compiler une bibliothèque tierce préalablement à la compilation d’un logiciel est pénible. Aussi, j’ai inclus le code source de libevent dans lldpd (en tant que sous-module git). Il n’est utilisé que si la version présente sur le système n’est pas suffisamment récente.

Jetez un œil à m4/libevent.m4 et src/daemon/Makefile.am pour comprendre comment est réalisée cette inclusion conditionnelle.

Client

Sérialisation

Afin d’afficher les voisins découverts par lldpd, lldpctl communique avec ce dernier via une socket Unix. Chaque structure devant être sérialisée était décrite avec une chaîne de caractères. Par exemple :

#define STRUCT_LLDPD_DOT3_MACPHY "(bbww)"
struct lldpd_dot3_macphy {
        u_int8_t                 autoneg_support;
        u_int8_t                 autoneg_enabled;
        u_int16_t                autoneg_advertised;
        u_int16_t                mau_type;
};

Je ne voulais pas utiliser de bibliothèques telles que Protocol Buffers car elles nécessitent l’utilisation d’une structure intermédiaire dans laquelle il aurait fallu copier les données.

Toutefois, le processus de sérialisation de lldpd ne permettait pas de gérer les pointeurs vers d’autres structures, les listes ou les références circulaires. J’ai donc écrit une version plus avancée utilisant des annotations à l’aide de macros :

struct lldpd_chassis {
    TAILQ_ENTRY(lldpd_chassis) c_entries;
    u_int16_t        c_index;
    u_int8_t         c_protocol;
    u_int8_t         c_id_subtype;
    char            *c_id;
    int              c_id_len;
    char            *c_name;
    char            *c_descr;

    u_int16_t        c_cap_available;
    u_int16_t        c_cap_enabled;

    u_int16_t        c_ttl;

    TAILQ_HEAD(, lldpd_mgmt) c_mgmt;
};
MARSHAL_BEGIN(lldpd_chassis)
MARSHAL_TQE  (lldpd_chassis, c_entries)
MARSHAL_FSTR (lldpd_chassis, c_id, c_id_len)
MARSHAL_STR  (lldpd_chassis, c_name)
MARSHAL_STR  (lldpd_chassis, c_descr)
MARSHAL_SUBTQ(lldpd_chassis, lldpd_mgmt, c_mgmt)
MARSHAL_END;

Seuls les pointeurs doivent être annotés. Le reste de la structure est simplement copiée avec memcpy()1. Je suis encore assez partagé sur le résultat et il est sans doute possible d’améliorer les choses. En vrac : mettre les annotations directement dans la structure, utiliser un parseur de code C ou utiliser la sortie AST de LLVM

Bibliothèque

lldpd 0.5.7 disposait de deux points d’entrée pour interagir avec lldpd :

  1. À travers le support SNMP. Seules les informations contenues dans la LLDP-MIB sont alors exportées. Les aspects spécifiques à l’implémentation ne sont donc pas disponibles. De plus, le support est actuellement en lecture seulement.
  2. À travers lldpctl. Grâce à une contribution de Andreas Hofmeister, la sortie peut être produite sous forme d’un document XML.

L’intégration de lldpd dans une pile réseau était donc limitée à l’un de ces deux canaux. À titre d’exemple, il est possible de regarder comment Vyatta a effectué cette intégration à l’aide de la seconde solution.

Afin de fournir une solution plus robuste, une bibliothèque partagée, liblldpctl, existe désormais. J’ai suivi les grandes directions suivantes dans sa conception2 :

  • Une convention de nommage uniforme. Tous les symboles exportés sont préfixés par lldpctl_. Pas de pollution de l’espace de nommage.
  • Une convention des valeurs de retour uniforme. En cas d’erreurs, les fonctions retournant des pointeurs retournent NULL, celles retournant des entiers retournent -1.
  • Pas de variables globales. Réentrant et possibilité d’utiliser des threads.
  • Un seul fichier d’entête bien documenté.
  • Une API asynchrone pour les entrées/sorties. La bibliothèque délègue ces dernières à l’utilisateur en lui demandant de fournir les fonctions nécessaires. Ces dernières peuvent retarder leurs effets. Dans ce cas, l’utilisateur doit appeler des fonctions particulières de la bibliothèque quand les données deviennent disponibles. L’intégration dans une boucle d’évènement existente est alors triviale. Une fine couche synchrone est également fournie.
  • Des types opaques avec des fonctions d’accès.

L’accès aux informations est fait à travers un « atome » qui est un conteneur opaque de type lldpctl_atom_t. D’un atome, il est possible d’extraire des entiers, des chaînes de caractères, des tampons ou d’autres atomes. La liste des ports est un atome, chaque port de cette liste est également un atome, la liste des VLAN présents sur ce port est un atome ainsi que chaque VLAN de cette liste. Le nom d’un VLAN est par contre une chaîne de caractères dont la validité est limitée par la validité de l’atome englobant. Accéder à une propriété d’un atome se fait via des fonctions génériques telles que lldpctl_atom_get_str() en spécifiant la clef correspondant à la propriété voulue. Par exemple, voici comment afficher le nom et l’identifiant de tous les VLAN attachés à un port :

vlans = lldpctl_atom_get(port, lldpctl_k_port_vlans);
lldpctl_atom_foreach(vlans, vlan) {
    vid = lldpctl_atom_get_int(vlan,
                               lldpctl_k_vlan_id));
    name = lldpctl_atom_get_str(vlan,
                                lldpctl_k_vlan_name));
    if (vid && name)
        printf("VLAN %d: %s\n", vid, name);
}
lldpctl_atom_dec_ref(vlans);

En interne, un atome est typé et maintient un compteur des références. La taille de l’API est limitée grâce à ce concept. Actuellement, il est possible d’extraire plus d’une centaine de propriétés de lldpd.

À terme, la bibliothèque doit également permettre la configuration complète de lldpd plutôt que d’utiliser des paramètres en ligne de commande. Cette bibliothèque ne remplace pas lldpctl qui est toujours le client à utiliser dans la majeure partie des cas.

CLI

La possibilité de configurer lldpd via un fichier de configuration était demandé depuis bien longtemps. Je ne voulais toutefois pas inclure un analyseur syntaxique pour limiter l’inflation du nombre de lignes de code. De plus, il était déjà possible de configurer divers aspects liés à LLDP-MED via lldpctl. Il m’a donc semblé naturel de continuer dans cette voie : permettre à lldpctl de lire un fichier de configuration et d’en transmettre les effets à lldpd. En bonus, les instructions de configuration pourraient être entrées de manière interactive à la façon d’un équipement réseau.

Analyse syntaxique & complétion

Un analyseur syntaxique généré par YACC limite les possibilités telles que la complétion. Aussi, les commandes sont définies par un arbre dont chaque nœud accepte un mot. Un nœud est défini ainsi :

struct cmd_node *commands_new(
    struct cmd_node *,
    const char *,
    const char *,
    int(*validate)(struct cmd_env*, void *),
    int(*execute)(struct lldpctl_conn_t*, struct writer*,
        struct cmd_env*, void *),
    void *);

On y trouve :

  • le nœud parent,
  • optionnellement, le mot accepté,
  • une description pour l’aide,
  • optionnellement, une fonction de validation,
  • optionnellement, une fonction qui sera exécutée si le mot est validé.

Le parcours de l’arbre est effectué en maintenant un environnement contenant à la fois des associations clef-valeur arbitraires ainsi qu’une pile des positions rencontrées dans l’arbre. La fonction de validation peut s’aider de l’environnement pour juger de la validité d’un mot (le mot clef foo ne sera accepté que s’il n’a pas déjà été rencontré, par exemple). La fonction d’exécution peut enregistrer la valeur courante dans une association mais également remonter dans l’arbre avant de continuer l’exécution.

À titre d’exemple, voici comment les nœuds permettant de configurer la localisation par coordonnées géographiques sont définis :

/* Le nœud principal */
struct cmd_node *configure_medloc_coord = commands_new(
    configure_medlocation,
    "coordinate", "MED location coordinate configuration",
    NULL, NULL, NULL);

/* Le nœud de sortie
   La fonction de validation vérifie si l'utilisateur
   a fourni latitude et longitude. */
commands_new(configure_medloc_coord,
    NEWLINE, "Configure MED location coordinates",
    cmd_check_env, cmd_medlocation_coordinate,
    "latitude,longitude");

/* Stockage de la valeur de la latitude. On remonte ensuite
   de deux positions en arrière. La latitude ne peut être
   entrée qu'une fois. */
commands_new(
    commands_new(
        configure_medloc_coord,
        "latitude", "Specify latitude",
        cmd_check_no_env, NULL, "latitude"),
    NULL, "Latitude as xx.yyyyN or xx.yyyyS",
    NULL, cmd_store_env_value_and_pop2, "latitude");

/* De même pour la longitude */
commands_new(
    commands_new(
        configure_medloc_coord,
        "longitude", "Specify longitude",
        cmd_check_no_env, NULL, "longitude"),
    NULL, "Longitude as xx.yyyyE or xx.yyyyW",
    NULL, cmd_store_env_value_and_pop2, "longitude");

Les définitions sont encore un peu verbeuses mais ce système semble être un bon équilibre entre puissance et simplicité. Il couvre tous les cas nécessaires.

Readline

Face à une interface en ligne de commande, l’utilisateur s’attend généralement à disposer d’un historique, d’une aide en ligne et de la complétion. La bibliothèque la plus souvent utilisée pour cet usage est la bibliothèque GNU Readline. Toutefois, en raison de sa licence (GPL), j’ai d’abord cherché une alternative. Il en existe de nombreuses :

Les trois premières bibliothèques supportent la même API que GNU Readline. Elles disposent en sus d’une API commune native. Cette dernière gère également l’analyse lexicale. J’ai donc en premier lieu adopté cette API3.

Malheureusement, j’ai remarqué par la suite que ces bibliothèques ne sont pas beaucoup répandues dans le monde Linux. En utilisant l’API native, il n’est pas possible de se rabattre sur la GNU Readline. J’ai donc changé mon fusil d’épaule et opté pour l’API de la GNU Readline. Une macro issue de l’archive Autoconf (légèrement modifiée) règle les disparités en ce qui concerne la compilation et la liaison.

L’absence d’analyseur lexical intégré m’a obligé à écrire le mien. L’API est également assez mal documentée et il est difficile de savoir quels symboles sont disponibles dans quelle version. Je me suis limité aux symboles suivants :

  • readline(), addhistory(),
  • rl_insert_text(),
  • rl_forced_update_display(),
  • rl_bind_key()
  • rl_line_buffer et rl_point.

Malheureusement, les implémentations de libedit ne gèrent pas correctement rl_bind_key(). Aussi, la complétion et l’aide en ligne ne sont pas disponibles avec celle-ci. La plupart des BSD viennent avec la GNU Readline préinstallée (elle bénéficie alors de l’exception liée aux bibliothèques systèmes). Pour le reste, il est toujours possible de se lier avec libedit et éviter ainsi les problèmes de licence. Dans ce cas, l’aide peut être obtenue avec la commande help.

Changements spécifiques à un OS

Précédemment, la liste des interfaces était récupérée via getifaddrs(). lldpd utilise désormais directement Netlink sur Linux. Ce n’est pas un changement majeur car la bibliothèque C utilisait déjà Netlink à cet effet. Les informations supplémentaires que l’on peut obtenir par ce biais ne sont pour le moment pas exploitées : elles sont toujours récupérées via sysfs ou ioctl(). Toutefois, lldpd est notifié lors du moindre changement.

Comme beacoup d’autres projets, j’ai réécrit ma propre implémentation de Netlink au lieu d’utiliser des bibliothèques telles que libnl qui incluent tout le nécessaire et bien plus encore. Pourquoi ?

  1. La dernière version de libnl est très jeune et n’est pas disponible dans de nombreuses distributions, dont par exemple Debian Squeeze. Comme pour libevent, il aurait été possible de contourner la difficulté en incluant cette bibliothèque dans lldpd et en l’utilisant lorsqu’il n’y a pas d’alternative dans le système. Mais…

  2. La licence de libnl est la LGPL 2.1. La liaison statique est alors un exercice périlleux. Il n’est pas clair si le résultat est une œuvre dérivée ou non. L’interprétation la plus courante est que la liaison statique est autorisée suivant les mêmes termes que dans la LGPL 3. C’est un problème pour de nombreux projets. Par exemple, OGRE a ajouté une exception pour autoriser la liaison statique dans sa version 1.6 puis s’est tourné vers la licence MIT dans sa version 1.7.

J’ai eu une courte discussion avec Thomas Graf à propos de ce problème et il semble disposé à ajouter une telle exception. Cela risque de prendre un peu de temps mais une fois le changement réalisé, j’utiliserai alors la libnl et en profiterai pour mieux exploiter Netlink.

Support des BSD

La version 0.5.7 de lldpd ne supportait que Linux. La réécriture utilisant Netlink a été l’occasion d’abstraire correctement le traitement des interfaces et de porter le tout sous les différents BSD. Le premier port a eu lieu pour Debian GNU/kFreeBSD, puis pour FreeBSD, OpenBSD et NetBSD. La structure est la même pour les trois BSD :

  • getifaddrs() pour obtenir la liste des interfaces,
  • bpf(4) pour s’attacher à une interface et envoyer et recevoir des paquets,
  • PF_ROUTE pour être notifié lors d’un changement.

Chaque BSD utilise ses propres ioctl() pour récupérer les informations liées aux VLAN, aux ponts et aux aggrégats mais ils sont souvent assez similaires. Le code est généralement repris de ifconfig.c.

Les ports pour les BSD ont les mêmes fonctionnalités que le port pour Linux, à l’exception de NetBSD qui ne dispose pas du support pour l’inventaire LLDP-MED car je n’ai pas su comment récupérer ces informations.

Le port d’OpenBSD offre de plus une plus grande sécurité en filtrant les paquets envoyés et en interdisant le processus non privilégié de retirer le filtre mis en place :

/* Install write filter (optional) */
if (ioctl(fd, BIOCSETWF, (caddr_t)&fprog) < 0) {
    rc = errno;
    log_info("privsep", "unable to setup write BPF filter for %s",
        name);
    goto end;
}

/* Lock interface */
if (ioctl(fd, BIOCLOCK, (caddr_t)&enable) < 0) {
    rc = errno;
    log_info("privsep", "unable to lock BPF interface %s",
        name);
    goto end;
}

C’est une fonctionnalité très appréciable. lldpd est découpé en deux processus. Un processus privilégié s’attache au port et transmet celui-ci à un processus non privilégié. Sans cette fonctionnalité, le second processus peut simplement retirer le filtre BPF. J’ai porté la possibilité d’interdire le retrait d’un filtre sous Linux. Toutefois, il me reste toujours à écrire le nécessaire pour le filtre des paquets sortants.

Support d’OS X

Une fois le support pour FreeBSD fonctionnel, celui d’OS X fut assez simple. J’ai obtenu de xcloud.me une machine virtuelle sous OS X pour m’aider dans cette tâche. Le port n’a ensuite pris que deux jours dont une partie du temps à chercher comment ne pas fournir un numéro de carte de crédit à Apple pour pouvoir télécharger Xcode !

Afin de faciliter l’installation de lldpd, j’ai également écrit une formule pour Homebrew qui semble le gestionnaire de paquets le plus populaire actuellement pour OS X.

Support de upstart et systemd

De nombreuses distributions proposent désormais upstart ou systemd en remplacement ou en alternative au système d’init historique. Comme de nombreux démons, lldpd se détache du terminal et tourne en tâche de fond en forkant deux fois lorsqu’il est prêt (pour lldpd, cela signifie simplement que la socket Unix a été mise en place). Bien qu’il soit possible de garder ce comportement avec upstart et systemd, il est préférable de ne plus forker. Comment indiquer alors que le démon est prêt à remplir sa tâche ?

Avec upstart, lldpd s’envoie le signal SIGSTOP. upstart va détecter son état et lui envoyer le signal SIGCONT. De plus, il va considérer que le démon est prêt. Voici comment faire :

const char *upstartjob = getenv("UPSTART_JOB");
if (!(upstartjob && !strcmp(upstartjob, "lldpd")))
    return 0;
log_debug("main", "running with upstart, don't fork but stop");
raise(SIGSTOP);

La configuration de upstart ressemble à ceci :

# lldpd - LLDP daemon

description "LLDP daemon"

start on net-device-up IFACE=lo
stop on runlevel [06]

expect stop
respawn

script
  . /etc/default/lldpd
  exec lldpd $DAEMON_ARGS
end script

systemd emploie une socket sur laquelle le démon envoie la chaîne READY=1 quand il est prêt. En utilisant la bibliothèque destinée à cet effet, il suffit d’appeler sd_notify("READY=1\n"). La fonction sd_notify() pouvant être réécrite en moins de 30 lignes, il m’a semblé plus simple de le faire plutôt que d’ajouter une dépendance externe. Voici la configuration de systemd :

[Unit]
Description=LLDP daemon
Documentation=man:lldpd(8)

[Service]
Type=notify
NotifyAccess=main
EnvironmentFile=-/etc/default/lldpd
ExecStart=/usr/sbin/lldpd $DAEMON_ARGS
Restart=on-failure

[Install]
WantedBy=multi-user.target

Fichiers d’entête spécifique à Linux

Les fichiers d’entête issus du noyau ont toujours été très problématiques. Ils peuvent contenir des erreurs les rendant difficile à utiliser en espace utilisateur ou être simplement manquants. Il y a longtemps, ils faisaient partie de la bibliothèque C et étaient synchronisés très rarement. Ils ont ensuite été extraits du noyau sans aucun changement et ne correspondaient pas forcément au noyau par défaut de la distribution4.

Il s’agit d’un problème qui tend à disparaître aujourd’hui. D’un côté, les distributions empaquettent désormais les entêtes correspondant au noyau par défaut. De l’autre, les développeurs noyau séparent les entêtes propres au noyau des entêtes destinés à être utilisés par l’espace utilisateur. Toutefois, il faut toujours gérer l’historique.

Un bon exemple est linux/ethtool.h:

  • Il peut simplement être absent alors que les fonctionnalités associées sont supportées depuis très longtemps.
  • Il peut utiliser les types u8, u16 qui sont spécifiques au noyau. Pour contourner ce problème, il faut altérer les types.
  • Certaines définitions telles que SPEED_10000 peuvent manquer. Dans ce cas, on peut soit compléter les définitions dans un autre fichier et se retrouver avec une copie du fichier d’entête dans laquelle les définitions sont entralacées avec des #ifdef, soit n’utiliser les symboles que s’ils sont présents. La dernière solution n’est pas plus pratique et elle interdit d’utiliser des fonctionnalités qui sont pourtant présentes dans le noyau.

Une solution très simple pour résoudre ce problème est simplement d’inclure les fichiers d’entête dans l’arbre de source du projet. Grâce à Google qui a recopié maladroitement ceux-ci pour sa bibliothèque C Bionic, nous savons désormais que la copie des entêtes du noyau dans un programme ne constitue pas une œuvre dérivée.


  1. L’utilisation des types u_int16_t et u_int8_t est un reste du système précédent où le sérialiseur devait connaître la taille de chaque membre. 

  2. Pour des conseils plus élaborés, jetez un œil sur Writing a C library

  3. L’analyse lexicale n’est pas le seul avantage de cette API native. Elle est également beaucoup mieux conçue, ne repose pas sur des variables globales et est bien documentée. Ses implémentations sont de plus sous licence BSD

  4. Par exemple, dans Debian Sarge, le noyau était un 2.6.8 (2004) tandis que les entêtes du noyau provenaient d’un noyau antérieur au 2.6. 

20 February, 2013 08:28AM par Vincent Bernat

06 February 2013

Rodolphe Quiédeville

PyDeb from PyPI to .deb

Dans mon précédent billet j'évoquais les paquets debian que j'avais réalisé pour Django au sein du projet Pyrede. Cette activité de packaging ayant pris de l'ampleur les paquets seront désormais disponibles au sein du Projet Pydeb.

Le projet PyDEB se compose d'un dépôt de paquets et d'un blog sur lequel je publie les nouveaux paquets ainsi que leurs mises à jour.

Les derniers paquets réalisés sont redis, hamlpy, vectorformats, ...

Le projet Pyrede d'analyse de fichier requirements.txt continue son activité avec PyDEB comme ressource bien évidemment.

06 February, 2013 12:01PM par Rodolphe Quiédeville

29 January 2013

Rodolphe Quiédeville

Paquets Debian pour Django

Si j'aime les virtualenv quand je code je reste attachés aux paquets pour le déploiement et j'essaye tant que faire se peut de résister aux 'pip install -r requirements.txt' sur mes machines de production. C'est dans ce contexte que j'ai packagé quelques paquets relatifs à Django que je vais essayer de maintenir au sein du projet Pyrede.

http://pyrede.quiedeville.org/debian/

Le fichier repo.key contient la signature utilisée pour signer les paquets.

29 January, 2013 12:23PM par Rodolphe Quiédeville

25 January 2013

David Curé

exFAT 1.0.0 et Debian squeeze

Après mon dernier billet sur la gestion du exfat pour les cartes SDXC, la version 1.0.0 du driver fuse supportant exfat est disponible.

J'ai mis à jour les paquets exfat-fuse et exfat-utils pour Debian squeeze amd64. Ils sont disponibles dans mon dépôt.

25 January, 2013 09:48PM par David (nospam@example.com)

17 January 2013

Debian France

Bilan de la deuxième Mini-Debconf Paris

Bilan de la deuxième Mini-Debconf Paris

La deuxième édition de la Mini-Debconf Paris s'est tenue les 24 et 25 novembres 2012 dans les locaux de l'Epitech au Kremlin-Bicètre.

Plus de 150 personnes se sont retrouvées pour deux jours de conférence assurées par des intervenants venus de toute l'Europe. Plusieurs équipes Debian ont été présentées, notamment l'équipe noyau et l'importante release team. L'installateur Debian a été décortiqué. GNOME a été à l'honneur avec une présentation des relations entre GNOME et les distributions (dont Debian) mais aussi des explications sur l'administration à grande échelle de postes bureautiques GNOME. Retrouvez les diapositives de toutes les autres présentations sur le site dédié.

photo-groupe.jpg

L'association tenait un stand de merchandising où les visiteurs ont pu se procurer polos, stickers, parapluie et autres t-shirts. Les futurs contributeurs ont eu l'occasion de faire signer leurs clés GPG par les développeurs Debian présents.

ksp.jpg

Merci aux nombreux sponsors qui ont soutenu l'événement: Logilab, SmartJog, Bearstech, IRILL et Evolix.

Quelques photos supplémentaires sont disponibes sur la page wiki de cette mini-debconf.

17 January, 2013 11:22AM

13 January 2013

David Curé

Carte SDXC, exfat 0.9.8 et Debian Squeeze

Ayant acquis une carte SDXC en pensant naïvement que c'était juste une simple évolution des SDHC, je fus une peu surpris en voyant que je n'arrivais pas à la lire. Après une recherche rapide, je vois que le format de la carte, exFAT, est une évolution du vénérable FAT et qu'il est incompatible.

Je regarde alors ce qui est disponible pour Debian squeeze et installe à partir de squeeze-backport la version 0.9.7 de exfat-fuse et exfat-utils. Et pas de chance, cette version me renvoie un bug lors du montage de ma carte.

Une nouvelle version 0.9.8 est disponible sur le site de l'auteur mais aussi dans experimental. J'ai donc utilisé ces paquets pour en réaliser une version pour Debian squeeze amd64 et là je peux enfin lire ma carte SDXC ;-)

Les paquets exfat-fuse et exfat-utils en version 0.9.8 sont donc disponibles dans mon dépôt pour squeeze amd64.



13 January, 2013 02:17PM par David (nospam@example.com)

12 January 2013

Stéphane Blondon

Déterminer quelle est la meilleure distribution grâce à Python et PIL

N’avez-vous jamais discuté des mérites de telle ou telle distribution Linux (ou BSD) avec d’autres personnes (chacun essayant de démontrer que celle qu’il utilise au quotidien est la meilleure) ? Grâce à cet article, vous n’aurez toujours pas La réponse mais vous aurez une réponse indiscutable : il s’agit de la jouer aux cartes. Les cartes sont créées avec Python Imaging Library, une bibliothèque Python de manipulation d’image. L’article explique la façon de les réaliser.

Carte de jeu pour Debian

Chaque carte possède un ensemble de caractéristiques, la plus forte remporte le pli. Ce principe de jeu existe depuis les années 70 (Ace_Trumps, Super Top Ass). L’ensemble des 26 cartes créées est visible ici.

L’objectif de l’article est de montrer comment on peut concevoir la création de la carte, pas le détail des paramètres de chaque fonction. Pour cela, la documentation et de nombreuses explications foisonnent déjà sur le web. C’est pourquoi, par exemple, les calculs de dimensionnement ne seront pas expliqués.

Prérequis : installer PIL (ou Pillow)

Deux possibilités :

  • utiliser le système de paquet de votre distribution (python-imaging pour Debian) ;
  • utiliser Pypi : PIL n’est pas disponible, il faut installer Pillow. Cela ne change pas la façon d’utiliser la bibliothèque :
    from PIL import Image, ImageDraw, ImageFont
    

Image sert à instancier une image, ImageDraw à la modifier, ImageFont à choisir une police de caractère.

Créer une carte

La base consiste à instancier un objet image sur lequel les modifications vont être apportées. Une fois les modifications réalisées, on enregistre le résultat sur le disque :

def draw_card(distrib):
    img = Image.open(BACKGROUND_PATH)
    #ajout des textes, images, etc.
    img.save(distrib["img_name"] + ".png")

La carte est une superposition de couches, qui sont toutes fusionnées en une seule image. On a donc un fond sur lequel les autres éléments sont superposés.
Parmi les éléments remarquables :

Textes dans un cartouche

Le titre et les caractéristiques des distributions sont faits de la même manière. Il n’existe pas d’effet avec PIL pour dessiner automatiquement une bordure. Elle est réalisée en plaçant deux rectangles l’un sur l’autre, celui de dessous étant plus large et haut.

Montage du titre

def draw_title(img, title):
    """
    pour dessiner le titre avec le fond et la bordure autour

    img est l'image PIL
    title est la chaine de caracteres a afficher ("Distribution")
    """
    draw = ImageDraw.Draw(img)
    draw_cartouche(draw, 25, 55)
    font = ImageFont.truetype(FONT_PATH, TITLE_FONT_SIZE)
    width, height = draw.textsize(title, font=font)
    x = center(width)
    draw.text((x, 29), title, font=font, fill=TEXT_COLOR)

def draw_cartouche(draw, upper_height, lower_height):
    """pour dessiner les deux rectangles"""
    draw.rectangle(((MARGIN_LEFT, upper_height), (CARD_WIDTH - MARGIN_RIGHT, lower_height)),
                   fill="#8e6f32")
    BORDER = 5
    draw.rectangle(((MARGIN_LEFT + BORDER, upper_height + BORDER), (CARD_WIDTH - MARGIN_RIGHT - BORDER, lower_height - BORDER)),
                   fill="#e9b654")

draw.textsize() permet de connaître les dimensions que prendrait la chaîne passée en paramètre. Cela permet de faire un calcul (dans la fonction center(), omise dans l’extrait ci-dessus) pour centrer le texte.

Le logo de la distribution

Montage du logo

L’affichage du logo suit la même logique en intercalant une image (nommée supernova.png) entre le fond et le logo de la distribution. Pour avoir un joli rendu , on décale simplement en hauteur l’image (y) car les deux images n’ont pas la même taille.

def draw_logo(img, filename):
    """on colle supernova
       puis le fichier correspondant au parametre filename"""
    image_path = SRC_IMGS_DIR + "supernova.png"
    nova = Image.open(image_path)
    nova_width, nova_height = nova.size
    x = center(nova_width)
    y = 60
    img.paste(nova.convert("RGBA"),
              (x, y, x + nova_width, y + nova_height),
              mask=nova.convert('RGBA'))
    image_path = SRC_IMGS_DIR + filename + ".png"
    distro = Image.open(image_path)
    distro_width, distro_height = distro.size
    x = center(distro_width)
    y = 90
    img.paste(distro.convert("RGBA"),
              (x, y, x + distro_width, y + distro_height),
              mask=distro.convert('RGBA'))

L’exercice de factorisation de cette fonction est laissé aux lecteurs qui s’ennuient et qui ne sont pas partis faire autre chose (ce que je ne comprend pas d’ailleurs).

Le numéro de la carte

Le numéro de la carte en bas à gauche est affiché de biais. Si les images peuvent subir une rotation, les textes ne sont affichés qu’horizontalement. La solution est donc de coller le texte dans une image intermédiaire. Cette image subira une rotation puis sera collée sur l’image finale de la même manière que précédemment :

def draw_card_index(img, number):
    """pour dessiner 'number' de biais"""
    HEIGHT = WIDTH = 19
    num_img = Image.new("RGBA",
                        (WIDTH, HEIGHT),
                        (0, 0, 0, 0))
    num_draw = ImageDraw.Draw(num_img)
    font = ImageFont.truetype(SANS_PATH, TEXT_FONT_SIZE)
    num_draw.text((0, 0), number, font=font, fill="brown")
    n = num_img.rotate(-45)
    X, Y = 7, 378
    img.paste(n, (X, Y, X + WIDTH, Y + HEIGHT), mask=n)

À noter que la rotation faite ici prend peu de précaution et les nombres à deux chiffres sont légèrement tronqués. Le paramètre expand peut être ajouté à rotate() pour éviter la perte, mais l’image est automatiquement agrandie.

Code source et ressources

La documentation de PIL est précieuse.
Un tutoriel dont certains effets ont été réutilisés pour les cartes.

Les données sur les cartes proviennent principalement de Distrowatch. Les logos des distributions sont aussi ceux affichés sur Distrowatch. « first stable » représente la première version stable avec le nom actuel de la distribution ou ce qui pourrait être considéré comme équivalent. « based on » indique le nom de la distribution parente. La valeur « Indep. » signifie qu’elle n’est basée sur aucune autre distribution. Si elle est suivie d’une étoile, cela signifie qu’elle est maintenant indépendante mais a été basée sur une autre distribution par le passé.

Le fond de carte et l’effet supernova ont été réalisés avec The Gimp.

L’archive contenant le code source du script au cas où quelqu’un voudrait le réutiliser, ainsi que les logos et les cartes générées est fournie au format .tar.xz. Le code a été écrit dans un but de démo. Il est bien perfectible…


12 January, 2013 09:39AM par ascendances

09 January 2013

David Mercereau

[rkhunter] Warning The file properties have changed

Rkhunter sert à détecter les rootkits, portes dérobées et exploits. Il se base en partie sur les Inodes des exécutables. Après avoir fait des aptitude safe-upgrade. vos exécutables changent…  Il faut donc en avertir Rkhunter…

Après mon premier upgrade j’ai reçu le mail suivant :

Warning: The file properties have changed:
File: /bin/bash
Current inode: 21372580 Stored inode: 44044163

Warning: The file properties have changed:
File: /usr/sbin/cron
Current inode: 25046249    Stored inode: 44305975
[...]

Il faut donc mettre la base Rkhunter à jour avec les nouveaux inodes.

Méthode manuel :

Lancer les commandes suivantes :

$ rkhunter --update
$ rkhunter --propupd

Méthode automatique

Si comme moi, vous êtes un chouilla fainéant créer le script /etc/apt/apt.conf.d/98-rkhunter avec le contenu suivant :

$ cat /etc/apt/apt.conf.d/98-rkhunter 
DPkg::Post-Invoke {
    "rkhunter --update;"
    "rkhunter --propupd";
};

Ainsi la base Rkhunter sera remis à jour à chaque fois que vous utiliserez apt/aptitude.

Astuce trouvé sur le forum debian-fr.org

09 January, 2013 06:00AM par David

05 December 2012

David Mercereau

Script de sauvegarde Mysql par base “mysql_dump.sh”

EDIT – 13/05/2013 : v0.3 du script avec prise en compte des suggestions d’améliorations de David M + Trap

EDIT – 06/12/2012 : v0.2 du script avec prise en compte des commentaires de l’article

Un énième script de sauvegarde à plat de bases Mysql sur internet. Celui-ci crée un fichier texte (.sql) par base et compresse le tout ensuite.

J’utilise ce script depuis plus de 3 ans, ça tourne bien et surtout ça dépanne bien !

Attention : ce script est à coupler avec un système de sauvegarde complet et distant…

Préparation

Il faut créer un utilisateur Mysql (appelé dump) avec des droits restreints en lecture sur toutes les bases :

$ mysql -u root -p -e "CREATE USER 'dump'@'localhost' IDENTIFIED BY 'LEMOTDEPASSE';"
$ mysql -u root -p -e "GRANT SELECT , SHOW DATABASES , LOCK TABLES , SHOW VIEW ON * . * TO 'dump'@'localhost' IDENTIFIED BY 'LEMOTDEPASSE' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;"

Le script

Copier le contenu du script dans un fichier mysql_dump.sh puis faite un chmod +x mysql_dump.sh afin de le rendre exécutable. Ajouter ensuite ce script dans vos tâches crons pour qu’il s’exécute toutes les nuits (par exemple).

Note : les remarques sont les bienvenus…

#!/bin/bash 

# Inspiré d'un script trouvé sur phpnews.fr (plus en ligne)
# Version 0.3 13/05/2013

# Script sous licence BEERWARE

set -eu

## Paramètres
USER='dump'
PASS='LEMOTDEPASSE' 
# Répertoire de stockage des sauvegardes
DATADIR="/var/backups/mysql"
# Répertoire de travail (création/compression)
DATATMP=$DATADIR
# Nom du dump
DATANAME="dump_$(date +%d.%m.%y@%Hh%M)"
# Compression
COMPRESSIONCMD="tar -czf" 
COMPRESSIONEXT=".tar.gz"
# Rétention / rotation des sauvegardes
RETENTION=30
# Exclure des bases
EXCLUSIONS='(information_schema|performance_schema)'
# Email pour les erreurs (0 pour désactiver
EMAIL=0
# Log d'erreur
exec 2> ${DATATMP}/error.log

## Début du script

ionice -c3 -p$$ &>/dev/null
renice -n 19 -p $$ &>/dev/null

function cleanup {
    if [ "`stat --format %s ${DATATMP}/error.log`" != "0" ] && [ "$EMAIL" != "0" ] ; then
        cat ${DATATMP}/error.log | mail -s "Backup MySQL $DATANAME - Log error" ${EMAIL}
    fi
}
trap cleanup EXIT

# On crée sur le disque un répertoire temporaire
mkdir -p ${DATATMP}/${DATANAME}

# On place dans un tableau le nom de toutes les bases de données du serveur 
databases="$(mysql -u $USER -p$PASS -Bse 'show databases' | grep -v -E $EXCLUSIONS)"

# Pour chacune des bases de données trouvées ... 
for database in ${databases[@]} 
do
    echo "dump : $database"
    mysqldump -u $USER -p$PASS --quick --add-locks --lock-tables --extended-insert $database  > ${DATATMP}/${DATANAME}/${database}.sql
done 

# On tar tous
cd ${DATATMP}
${COMPRESSIONCMD} ${DATANAME}${COMPRESSIONEXT} ${DATANAME}/
chmod 600 ${DATANAME}${COMPRESSIONEXT}

# On le déplace dans le répertoire
if [ "$DATATMP" != "$DATADIR" ] ; then
    mv ${DATANAME}${COMPRESSIONEXT} ${DATADIR}
fi

# Lien symbolique sur la dernier version
cd ${DATADIR}
set +eu
unlink last${COMPRESSIONEXT}
set -eu
ln ${DATANAME}${COMPRESSIONEXT} last${COMPRESSIONEXT}

# On supprime le répertoire temporaire 
rm -rf ${DATATMP}/${DATANAME}

echo "Suppression des vieux backup : "
find ${DATADIR} -name "*${COMPRESSIONEXT}" -mtime +${RETENTION} -print -exec rm {} \;

05 December, 2012 11:00AM par David

02 November 2012

Benoit Peccatte

Signer ses logs

Niveau :      
Résumé : syslog | openssl dgst

Vous êtes vous déjà posé la question de la sécurisation de vos logs ? Sont-ils accessibles ? modifiables ? Peut-on détecter une falsification ?

Comment faire pour que les logs ne soient pas altérés par une personne de peu de principes ? Je vous propose une solution qui n'est pas une solution miracle, mais c'est une solution qui sera une brique de plus dans votre défense en profondeur.

Nous allons signer cryptographiquement les logs pour que tout altération devienne visible comme le nez au milieu de la figure.

Signature et validation des logs

Je vous au préparé pour cela deux programmes (lien en fin d'article), l'un pour signer les logs, l'autre pour les valider. Bien sûr, on ne va pas signer les fichiers de logs directement, ça laisserait tout le temps à un attaquant de les modifier avant la signature. Nous allons plutôt nous insérer dans le système syslog pour disposer des lignes au fur et à mesure. Mais nous n'allons pas non plus signer toutes les lignes, ce serait trop lourd. Nous allons plutôt signer des blocs de lignes, par exemple une signature toutes les 100 lignes, sans oublier un timeout pour éviter que 99 lignes restent en mémoire trop longtemps..

Enfin une des fonctionnalités importante de ces outil est le chaînage. Le chaînage est le fait d'utiliser la signature du bloc précédent comme faisant partie du bloc suivant. Ceci garanti qu'il ne peut y avoir suppression ou ajout d'un bloc eu milieu d'une chaîne de blocs. Et tant qu'on y est nous pouvons aussi chaîner les fichiers pour obtenir le même résultat au niveau fichier.

Au final toute modification, ajout ou suppression de ligne entraine l'invalidation de la signature. Toute modification, ajout ou suppression de bloc ou de fichier de log entraine l'invalidation de la signature.

Voici donc un exemple d'usage sous forme de pipe :

$ openssl genrsa -out key.pem 1024 # il nous fait une clé de signature
$ echo "Log important" | signlogger -k key.pem -f logfile

Notez que c'est utilisable avec syslog puisque celui-ci vous permet d'utiliser un pipe à la place d'un fichier. Je ne détaille pas cela ici car cela dépend du sylog que vous utilisez (syslogd, syslog-ng, rsyslog ...).

Et pour vérifier que votre fichier de log n'a pas été modifié ?

$ openssl rsa -in key.pem -pubout > pubkey.pem # on récupère la version publique de la clé
$ signvalidator -k pubkey.pem -f logfile

Si vous voulez utilisez cet outil avant logger ou avant l'envoi à un serveur centralisé, il faudra modifier signvalidator pour qu'il ignore les éléments ajoutés par syslog dans la vérification de la signature (date, pid, ...).

Usage

Dans la vraie vie quand on parle de sécurité, il faut se demander de quoi on veut se prémunir.

Signer les logs a pour but d'éviter qu'on puisse modifier les logs a posteriori, puisqu'on n'empêche personne de transformer les logs avant qu'ils ne soient envoyés à syslog. Mais toute personne qui a accès en écriture aux logs a posteriori, a les mêmes droits que le processus qui écrit les logs. Il a donc accès au système de signature.

Mais alors qu'a-t-on gagné ?

Tout d'abord, un difficulté légèrement accrue pour un attaquant, c'est pas grand chose, mais ça peut toujours servir. Ensuite, il nous suffit maintenant de séparer les droits du système de chiffrement de ceux du système d'écriture pour enfin détecter la modification par une personne possédant les droits d'écriture.

Pour cela vous avez plusieurs moyens à votre disposition :

  • utiliser des pipes et des des utilisateurs séparés pour la signature et pour l'écriture
  • utiliser l'attribut append only des fichiers de log pour interdire toute modification du fichier a posteriori (sauf par root qui peut retirer l'attribut)
  • utiliser un medium read only pour écrire les logs
  • utiliser un HSM pour interdire la réutilisation de la clé
  • déporter les logs vers un serveur syslog

Ou toute combinaison de ceux-ci.

Vous remarquerez que ces techniques ont déjà pour but d'empêcher la modification des logs a posteriori. La signature n'apporte qu'une preuve supplémentaire.

Mais prenez l'exemple du serveur syslog centralisé. On ne peut plus modifier les logs depuis le client, mais on le peut toujours depuis le serveur. La signature, si elle est effectuée côté client permet d'apporter une garantie supplémentaire puisqu'il faut cette fois un accès coté client ET côté serveur pour effecture la modification.

Si on y ajoute l'append only, il faut être root, si on y ajoute le HSM, il faut disposer d'une carte à puce ou d'un mot de passe, si on y ajoute un media read only, il faut disposer d'un accès physique pour le modifier. Et chacun de ces éléments peut être géré par une personne différente pour rendre impossible toute modification par une unique personne malintentionnée.

A vous de choisir votre niveau de sécurité !

En détail

Je vous colle ici l'usage complet des commandes (c'est du perl pour ceux qui veulent savoir)

$ signlogger --help
Usage:
    signlogger [options]

      Options
            --key|-k keyfile         Use private key for signing (PEM encoded)
            --file|-f file           Log to file instead of stdout
            --lastsig|-l line        Use line as last signature (used for chaining)
            --initfile|-i file       Use last line of file as last signature (used for chaining)
            --blocksize|-b lines     Insert signature each "lines" count (default 50)
            --timestamp|-t seconds   Insert signature each "seconds" seconds (default 30mn)
            --help|-h                This help

$ signvalidator --help
Usage:
    signvalidator [options]

      Options
            --key|-k keyfile        Use public key for validation (PEM encoded)
            --file|-f file          Read file instead of stdin
            --lastsig|-l line       Use line as last signature (used for chaining)
            --initfile|-i file      Use last line of file as last signature (used for chaining)
            --help|-h               This help

Et pour les télécharger :

Tags:,

02 November, 2012 02:46PM par peck

12 September 2012

Benoit Peccatte

Log de l’historique

Niveau :      
Résumé : trap DEBUG ; PROMPT_COMMAND

Voici comment loguer l'activité d'un utilisateur.

Mais tout d'abord, commençons par apprendre comment envoyer une ligne dans syslog. C'est simple, il suffit d'appeler logger avec les options qui vous intéressent (toutes optionnelles) et un message :

$ logger -i -p local5.info -t bash "$(tty): Bonjour syslog"

On enregistre le pid (option -i) pour permettre la corrélation avec d'autres lignes de logs.

On utilise la facility local5 qui est une sorte de tag utilisé par syslog pour savoir dans quelle catégorie mettre les logs. Les facilities servent essentiellement à faire des règles de tri des logs (par exemple il y a une facility authpriv pour tout ce qui est authentification). Il y a 8 facilities disponible pour les administrateur qui voudraient utiliser des valeurs qui ne sont pas standard. J'ai choisi local5.

On utilise le niveau de log info qui est quelque chose de standard parmi les systèmes de logs en général et permet de filtrer facilement.

On en profite pour loguer le tty en cours pour permettre une corrélation avec la commande last (on ne sait jamais).

Nous avons aussi besoin de la commande capable de nous donner la dernière commande tapée :

# lister la dernière commande sans son numéro
$ fc -ln -1

Il n'y a plus qu'à mettre l'une de ces lignes dans le fichier /etc/profile qui est lu par bash au lancement de sessions interactives :

# envoyer la commande dans syslog pour chaque commande AVANT exécution
$ trap 'logger -i -p local5.info -t bash "$USER $(tty): $(fc -ln -1)"' DEBUG

# envoyer la commande dans syslog pour chaque commande APRES exécution
$ PROMPT_COMMAND='logger -i -p local5.info -t bash "$USER $(tty): $(history 1)"'
# fc ne marche pas correctement dans PROMPT_COMMAND

Pourquoi

Enregistrer cette info peut être utile puisque les logs ne sont pas modifiables par un utilisateur simple. Et si vous avez un serveur syslog centralisé, ils ne le sont même pas par root depuis la machine d'origine.

Mais ceci ne doit pas vous faire oublier eux choses.

Tout d'abord le shell est un processus lancé par l'utilisateur, ce qui veut dire que l'enregistrement de cette information est nécessairement soumis à la bonne volonté de l'utilisateur. Un utilisateur peut supprimer le trap ou remplacer le PROMPT_COMMAND. Et supposons que vous trouviez un moyen pour l'en empêcher, l'utilisateur peut toujours tuer son propre shell, lui faire faire un exec vers un autre shell n'ayant pas de logs, tracer son shell pour modifier son activité etc.

Ensuite il faut être bien conscient de ce qu'on enregistre. On enregistre l'activité interactive d'un shell. Ceci exclue les transferts de fichiers (scp,...), les exécutions automatiques (cron, ...), les exécutions via un code (vi script; ./script). Et si on regarde bien ce dernier cas, on comprend qu'à moins de loguer tous les appels systèmes avec tous leurs paramètres, il est impossible de garantir qu'un utilisateur malveillant n'a pas exécuté une commande.

En conclusion ce système n'est pas là pour garantir l'enregistrement de toute activité d'un utilisateur plus ou moins malveillant, mais ça peut être une piste de recherche parmi d'autres lorsqu'un problème survient (qui a supprimé ma libc ?).

Tags:

12 September, 2012 07:03PM par peck