Planquez (un peu) Proxmox

Proxmox est un outil intéressant, simple à prendre en main, offrant le moyen de gérer un serveur de virtualisation. Je l’utilise depuis pas mal de temps, avec des VM qemu-kvm comme des conteneurs openvz.

Concrètement, il s’agit d’une distribution GNU/Linux basée sur Debian embarquant les solutions de virtualisation/conteneurs suscitées, et une jolie interface web s’appuyant sur la lib JS ExtJS pour faciliter l’administration de tout ça. Le problème, c’est que cette interface est publique, accessible simplement via une URL, et il est possible de se connecter en root directement dessus (via un module pam). Or, je ne souhaite pas que l’on puisse avoir la main totale sur un serveur avec un simple mot de passe, fut-il d’une robustesse redoutable. Une authentification par mot de passe, c’est trop faible.

Apache

Du coup, ma solution est de reconfigurer le serveur web de Proxmox afin de passer par un tunnel SSH en tant que seul moyen d’accéder à la console. Le serveur web en question est un Apache, et il y a 2 fichiers à modifier pour sécuriser cette partie : pour les trouver, il suffit de rechercher les occurrences de « listen » dans le dossier d’Apache :

# grep -Rl Listen /etc/apache2/
/etc/apache2/sites-enabled/pve.conf
/etc/apache2/sites-available/pve.conf
/etc/apache2/ports.conf

Le fichier /etc/apache2/sites-enabled/pve.conf est une stricte copie de celui dans sites-available, donc la modification sera à répliquer dans les deux fichiers.

C’est la directive « Listen » d’Apache qui nous intéresse. On en trouve 2 dans ports.conf, et un dans pve.conf. Elle indique simplement sur quelle interface on désire faire écouter Apache. Si on précise seulement le port, on écoute sur toutes les interfaces. Mais il est heureusement possible de préciser l’adresse sur laquelle on souhaite écouter via « Listen <address>:<port> ». Concrètement, on va changer ces fichiers pour n’écouter que sur l’adresse locale (127.0.0.1).

Listen 127.0.0.1:80

N’oubliez pas de remplacer le port par celui de la ligne en question. Redémarrez le serveur (« service apache2 restart ») et constatez que l’interface web n’est plus accessible via son adresse publique.

SSH

Si Apache n’écoute plus que sur l’adresse localhost, il vous faut être sur cette machine pour accéder à l’interface. Mais je doute que lynx se comporte très bien avec une interface web pleine de JS, alors il nous faut une autre solution : le tunnel SSH, dont je parlais plus haut. Le principe est de se servir du serveur en tant que proxy encapsulé dans du SSH (ainsi, pas besoin d’ajouter un daemon sur la machine). La requête HTTP telle que vous la tapez sera donc réellement lancée depuis le point de sortie (le serveur). Et si vous faites pointer votre navigateur sur l’adresse 127.0.0.1, c’est bel et bien sur le serveur que vous vous retrouverez.

Mais pour que cette solution soit un tant soit peu efficace, il faut forcer l’utilisation de clés SSH pour se connecter au serveur, à cause de la problématique évoquée plus haut. Ma solution perso est de n’autoriser la connexion SSH qu’avec une clé, et uniquement sur un utilisateur n’ayant aucun droit, si ce n’est celui d’utiliser su pour passer en root. Il faudra donc posséder la bonne clé SSH (et sa passphrase) ainsi que le pass root pour pouvoir se connecter au serveur. Avant de modifier la configuration du serveur, il vaut mieux installer la clé SSH. Si vous n’en avez pas sur votre poste, créez-en une (à taper sur votre poste local) :

$ ssh-keygen

Je vous laisse le soin de choisir les options de votre clé. Par principe, utilisez le maximum de bits possibles selon l’algorithme choisi. Choisissez soigneusement votre passphrase, de sorte à la retenir sans négliger sa robustesse.

Il nous faut maintenant créer un utilisateur sur le serveur, sur lequel on se connectera :

# useradd -m poney # choisissez un nom pas trop évident
# passwd poney # choisissez un mot de passe temporaire

Nous spécifions un mot de passe pour cet utilisateur, car il faudra s’y connecter une première fois pour y stocker la clé. On supprimera le mot de passe tout à l’heure.

Ensuite, utilisez ssh-copy-id pour ajouter votre clé sur le serveur (toujours à taper sur votre poste local) :

$ ssh-copy-id poney@<adresse du serveur>

Si besoin, spécifiez via l’option -i le fichier de clé à envoyer au serveur. Le mot de passe du compte poney vous est demandé.

Ensuite, nous sommes prêts à modifier la configuration du serveur. Voici donc les lignes à modifier dans /etc/ssh/sshd_config :

Port 9347 # on modifie le port par défaut, pour éviter les scanners idiots, choisissez-en un inutilisé au hasard
PermitRootLogin no
PasswordAuthentication no # on ne permet pas la connexion par un mot de passe

Redémarrez le serveur via service ssh restart, ne vous déconnectez surtout pas, au cas où votre configuration ait rendu toute nouvelle connexion impossible, puis tentez de vous connecter depuis votre utilisateur fraîchement créé (par le biais de sa clé) :

$ ssh -p 9347 poney@<adresse du serveur>

Si tout se passe bien, ce ne sera plus le mot de passe du compte poney qui sera demandé, mais la passphrase de votre clé SSH (possiblement dans une fenêtre graphique, selon votre configuration). Si vous accédez au shell de poney après ça, c’est que tout est bon. Vous pouvez maintenant accéder au root en tapant « su - » (le tiret final permet de réinitialiser les variables d’environnement, pour éviter que d’éventuelles saloperies ayant infecté poney ne soient transmises à root), suivi de votre mot de passe root.

Respirez, on est presque à la fin.

Maintenant que l’on sait se connecter au serveur via un utilisateur tiers et via une clé SSH uniquement, on peut supprimer le mot de passe de cet utilisateur :

# passwd -d poney

La partie serveur est maintenant un peu plus sécurisée qu’avant. Il reste une dernière chose à faire pour pouvoir accéder de nouveau à l’interface web.

Poste client

Avant d’oublier, nous allons utiliser le fichier de configuration ~/.ssh/config sur notre poste client pour faciliter la syntaxe de la connexion :

Host mon-serveur # remplacez par le nom que vous souhaitez
HostName <ip du serveur>
User poney
Port 9347

Ceci vous permettra de vous connecter par cette simple commande :

$ ssh mon-serveur

Maintenant, nous allons enfin configurer le tunnel SSH. Rien de bien complexe, c’est intégré dans OpenSSH :

$ ssh -ND 1234 mon-serveur # utilisez un port de votre choix

La connexion SSH se fait, et un proxy SOCKS5 est mis en place sur le port 1234 de votre adresse locale. Celui-ci sort sur le serveur. Il suffit alors de configurer votre navigateur pour utiliser ce proxy. Sous Firefox, par exemple, la configuration se trouve dans Édition → Préférences → Avancé → Réseau → Connexion → Paramètres. Renseignez « 127.0.0.1 » comme hôte SOCKS, en mode SOCKS v5, avec le port choisi plus haut. Surtout, supprimez les exceptions dans le champ du dessous, car sinon vous ne pourrez pas accéder à l’interface Proxmox (étant donné qu’elle sera sur l’adresse 127.0.0.1).

Configuration du proxy
dans Firefox

Maintenant, faites pointer votre navigateur sur l’adresse 127.0.0.1 Si tout va bien, vous serez redirigé sur le port 8006 en SSL, car c’est la configuration par défaut de Proxmox, et vous pourrez accéder à l’interface comme avant.

Lorsque vous aurez fini ce que vous aviez à faire sur l’interface, reconfigurez votre navigateur pour utiliser votre ancienne configuration de proxy, déconnectez votre tunnel SSH (en tapant simplement « exit » ou en appuyant sur ctrl-D). Si vous voulez y accéder de nouveau :

  1. lancez le tunnel SSH (ssh -ND 1234 nom-serveur)
  2. configurez les paramètres de proxy de votre navigateur
  3. visitez http://127.0.0.1 dans votre navigateur

Listes en compréhension en Python

J’aime principalement deux choses dans le langage Python : la redoutable simplicité de sa syntaxe, et l’incroyable puissance des listes en compréhension, permettant d’effectuer des traitements en une seule ligne imbuvable. Oui, c’est parfaitement contraire au premier point. Je vais donc revenir sur ces listes en compréhensions.

De quoi parle-t-on ?

Les listes en compréhension sont une syntaxe présente dans le langage Python (entre autres) permettant de filtrer un itérable (comme une liste). En gros, cela permet l’écriture d’une boucle for dont la finalité est de créer une liste. Un exemple sera plus parlant.

resultat = []
for i in range(10):
    resultat.append(i*2)

Cette syntaxe classique utilise 3 lignes pour générer la simple liste [0,2,4,6,8,10,12,14,16,18,20]. Voyons maintenant comment écrire cela autrement :

resultat = [i*2 for i in range(10)]

Voila. Rien de plus. Nous arrivons au même résultat avec une écriture bien plus concise. Il est possible de compléter l’exemple précédent :

resultat = []
for i in range(10):
    if(i % 2 == 0):
        resultat.append(i)

On itère i de 0 à 9, et on insère i dans resultat si celui-ci est pair (c’est à dire si le résultat de sa division par 2 est nul).

Voyons maintenant la version en liste en compréhension :

resultat = [i for i in range(10) if i % 2 == 0]

On peut donc, grâce à la version verbeuse de l’expression, isoler les différentes parties :

  • Un itérable, ici range(10), qui va nous servir de donnée de base ;
  • Une valeur, calculée pour chaque passage dans la boucle (il n’est pas obligatoire d’utiliser une valeur provenant de la source) ;
  • Une condition optionnelle, indiquée après l’itérable source.

La puissance des listes en compréhension est incroyable. Pensez que l’itérable source de votre liste en compréhension peut lui aussi être une liste en compréhension !

Expressions génératrices

Si vous ne connaissez pas les générateurs en Python, il s’agit de structures itérables dont la valeur est calculée au moment où on tente d’y accéder, et non pas à l’assignation. Ce qui permet d’itérer sur de très gros volumes de données, mais également d’itérer à l’infini sur une valeur.

>>> def sq(n):
...     print('sq(%d)' % d) # on affiche quelque chose à chaque exécution
...     return n**2
...
>>> l = [sq(i) for i in range(10)]
sq(0)
sq(1)
sq(2)
sq(3)
sq(4)
sq(5)
sq(6)
sq(7)
sq(8)
sq(9)

Comme on le constate, avec une simple liste en compréhention, la fonction sq() est appelée à l’assignation de la liste, car les valeurs sont calculées à ce moment. Ce n’est pas le cas des expressions génératrices.

>>> g = (sq(i) for i in range(10))

Rien n’est affiché. Notre fonction sq() n’est donc pas appelée. Elle le sera à chaque fois qu’on cherchera à accéder à un élément du générateur.

>>> for i in g:
...     print(i)
... 
sq(0)
0
sq(1)
1
sq(2)
4
sq(3)
9
sq(4)
16
sq(5)
25
sq(6)
36
sq(7)
49
sq(8)
64
sq(9)
81

Les lignes « sq(×) » sont le signe que notre fonction sq() est exécutée à ce moment. Et donc, en cas de données lourdes, on ne charge pas tout en mémoire instantanément.

La seule chose qui distingue une expression génératrice d’une liste en compréhension, syntaxiquement parlant, est simplement l’usage de parenthèses autour de l’expression au lieu de crochets.

Sets en compréhension

Enfin, et parce que je préfère évoquer toutes les possibilités de cette syntaxe, sachez qu’il est possible de générer un set (c’est à dire une liste dédoublonnée) à partir d’une liste en compréhension. Il suffit pour cela d’utiliser les accolades au lieu de crochets autour de l’expression.

>>> s = [n % 5 for n in range(10)] # liste en compréhension
>>> s
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
>>> s = {n % 5 for n in range(10)} # set en compréhension, sans doublon
>>> s
{0, 1, 2, 3, 4}

Un exemple ?

La raison profonde pour laquelle j’ai voulu écrire cet article est le besoin récent que j’ai eu de convertir une chaîne binaire en texte, par conversion des octets en nombres décimaux, puis correspondance dans la table ascii. Malgré l’existence de nombreux convertisseurs en ligne (j’en ai moi-même écrit), je me suis dit qu’écrire un convertisseur en une ligne serait amusant, le tout sous les yeux d’une amie. Et donc, voici :

>>> s = '01010000011010010110111001101011011010010110010100100000010100000110100101100101001000000110100101110011001000000111010001101000011001010010000001100010011001010111001101110100'
>>> print(''.join([chr(int(b, 2)) for b in [s[i:i+8] for i in range(0, len(s), 8)]]))
Pinkie Pie is the best

Voilà.

Bon, ok, je vous fais la version longue et commentée :

s = '01010000011010010110111001101011011010010110010100100000010100000110100101100101001000000110100101110011001000000111010001101000011001010010000001100010011001010111001101110100'
conversion = [] # on stocke le résultat dans un tableau, qu’on convertira
                # ensuite en chaîne

# commençons par découper notre chaîne en octets (8 bits)
octets = []
# on doit itérer (taille de la chaîne / 8) arrondi au supérieur (au cas où)
for i in range( 0, len(s), 8 ):
    octets.append(s[i:i+8]) # vivent les slices d’itérable : on découpe
                            # à partir de i caractères jusqu’à 8 de
                            # plus au maximum
# on a maintenant nos octets séparés. Il ne reste plus qu’à les convertir en
# décimaux, puis récupérer la valeur de la table ascii correspondante
for octet in octets:
    octet_dec = int(octet, 2) # pour convertir à partir de la base 2
    conversion.append( chr( octet_dec ) )

print( ''.join( conversion ) ) # ENFIN !

Vous ne trouvez pas que la première version est plus, disons, succinte ?

[edit] Rogdham m’a suggéré une amélioration du convertisseur binaire

Exceptions en Python

Les exceptions sont un mécanisme de développement extrêmement pratique, mais pas forcément clair pour tout le monde. Suite à une petite discussion, voici leur fonctionnement en python3 :

Qu’est-ce qu’une exception ?

Il s’agit d’objets se comportant comme des erreurs de fonctionnement du programme. Toutes les erreurs, en python, sont des exceptions, et sont donc manipulables. Cela sert à pouvoir traiter soi-même les erreurs, au lieu de planter bêtement. Une structure existe pour effectuer ce traitement : son fonctionnement en langue française donnerait ceci :

Bon, effectue ces actions. Si jamais il y a une erreur à l’intérieur, traite-la comme ceci.

En python, ça se traduit par le bloc try … except :

try:
    do_some_actions()
except:
    print('Nous avons une erreur !')

Si le bloc try renvoie une exception (donc une erreur), le bloc except est exécuté. En l’occurrence, on affiche un message, puis on continue le programme. Avec une vraie exception, ça donnerait ça :

try:
    result = 10 / 0 # une division par zéro, c’est paaaaas bien
except:
    print('Nous avons une erreur !')

Cela reste néanmoins un fonctionnement très basique. On ne sait pas, à ce stade, quelle est l’erreur. L’exception étant un objet, pouvoir la manipuler est la base du traitement.

try:
    result = 10 / 0
except Exception, e:
    print('Nous avons une erreur : %s !' % e)

Voici la forme étendue du except : on lui spécifie un type d’exception à gérer, puis un nom de variable, qui contiendra notre exception. L’objet Exception définit la méthode spéciale __str__() appelée automatiquement lorsque l’on cherche à utiliser l’objet comme une chaîne de caractère (comme c’est le cas dans notre exemple), et renvoie l’attribut message. Voici donc le résultat des quelques lignes précédentes :

Nous avons une erreur : integer division or modulo by zero !

Pour savoir quel est le type de notre exception, consultez le nom de la classe : e.__class__.__name__. Ce qui nous permettrait d’effectuer un traitement comme ceci :

try:
    result = 10 / 0
except Exception, e:
    exception_type = e.__class__.__name__
    if exception_type == 'ZeroDivisionError':
        print('Erreur de division par zéro')
    else:
        print('Erreur %s : %s' % (exception_type, e))

Ainsi, vous traiterez différemment votre erreur selon son type. Mais la structure try … except permet de faciliter ça, en conditionnant la récupération des exceptions :

try:
    result = 10 / 0
except ZeroDivisionError, e:
    print('Erreur de division par zéro')
except Exception, e:
    print('Erreur %s : %s' % (e.__class__.__name__, e))

Ici, soit nous récupérons une erreur ZeroDivisionError, soit nous récupérons… n’importe quelle autre erreur, car la récupération conditionnelle traite également les sous-types. Toute exception héritant de Exception, notre except Exception, e saura récupérer n’importe quelle exception, et agit donc comme le default d’un switch. Dans l’exemple précédent, la ligne 4 s’exécutera seulement si on intercepte une exception ZeroDivisionError (ou un type héritant de ZeroDivisionError. Si on obtient n’importe quelle autre exception, on exécute la ligne 6. Si une exception d’un type non-traité est levée, python s’arrêtera avec un traceback et un message d’erreur (qui sera celui de l’exception)

Le bloc inclus dans le try est du code, il n’a rien de particulier. Il est donc évidemment possible d’imbriquer des blocs try … except. Comme ceci :

try:
    do_something()
    try:
        do_something_else()
    except Exception, e:
        raise UserWarning(e.message)

    try:
        do_all_the_things()
    except Exception, e:
        raise UserWarning(e.message)

except UserWarning, e:
    print('Le programme s’est arrêté avec le message suivant : %s' % e)

Si do_something_else() renvoie une exception, celle-ci est récupérée par le except ligne 5, qui renvoie elle-même une exception (avec le mot-clé raise), qui est alors récupérée par le try parent : on entre alors dans le dernier except.

Pour finir, voyons comment créer nos exceptions :

class MyException(Exception):
    pass

C’est aussi simple que ça : créez une classe vide qui hérite d’Exception, ou d’une autre exception (par exemple, pour hiérarchiser vos exceptions), vu que le nom de classe est ce qui permettra de récupérer conditionnellement vos exceptions.

try:
    raise MyException('Message')
except MyException, e:
    print(e)

Notre exception est levée, et est traitable comme une autre.

Une dernière chose : le mot-clé finally, qui est exécuté après une structure try … except, quel que soit le bloc traité, autrement dit peu importe qu’une exception ait été levée ou pas :

try:
    do_something()
except Exception, e:
    print(e)
finally:
    print('Nous avons exécuté le bloc.')

Un finally est utile notamment pour libérer des ressources. Par exemple, si un fichier est ouvert dans le try mais qu’une exception est levée avant sa fermeture, le finally peut le fermer dans tous les cas.

La nécessité des commentaires

Je suis tombé sur cet article, expliquant en quoi les générateurs de blogs statiques, comme Pelican (utilisé ici même) étaient un danger pour le logiciel libre. En gros, c’est centré sur l’absence de commentaires, hormis en passant par un service tiers intégré en javascript (comme disqus). Je ne suis absolument pas d’accord avec ses arguments, et, suite à un débat avec l’ami Taziden, je pense nécessaire d’expliquer mon point de vue, au sujet des commentaires et le reste.

Pour commencer, et par honnêté, je dois bien dire que le choix de me passer de commentaires a été en partie imposé par le choix technologique de Pelican. En partie seulement, parce que c’est moi qui ai fait ce choix, en connaissance de cause.

Revenons aux principes du blog

Aujourd’hui, tout internaute lisant des blogs est habitué à pouvoir laisser son avis sur un billet en bas de celui-ci. Cette habitude provient des moteurs de blog très utilisés, comme Wordpress, ayant intégré cette fonctionnalité. Mais ne cédons pas à la généralisation technologique. Je me souviens encore de l’époque où « un blog » signifiait un truc sur « .skyblog.com », la fameuse plateforme infestée de contenus d’une médiocrité infinie. Aujourd’hui, on pourrait remplacer Skyblog par Wordpress. On a indéniablement évolué, étant donné que Wordpress est un logiciel libre, et qu’une importante partie des blogs existants sous cette plateforme sont hébergés sur des serveurs persos. Mais dans l’idée, on tend quand même vers cette généralisation : un blog a nécessairement des commentaires, comme un moteur de recherche, des catégories, mots-clés, etc.

Mais pourquoi serait-ce le cas ? Un blog, ce n’est rien de plus qu’un journal personnel. Un site web rédactionnel, peu importe que le contenu soit de la veille technologique, des opinions politiques, ou des créations artistiques. En fait, c’est un espace d’expression pour l’auteur, qui en fait ce qu’il veut. Les moyens techniques pour arriver là sont : le protocole HTTP, et le langage HTML. Le web, en somme, ni plus ni moins. Un simple éditeur de texte, un coin sur un serveur web, et on peut écrire une page basique, et du contenu à l’intérieur. On a un blog, pas moins vrai que le wordpress du voisin ou celui-ci. Un blog n’a donc pas à avoir de fonctionnalités particulières.

La valeur des échanges

Évidemment, je ne cherche pas à nier l’importance des commentaires de blog, parfois bien plus intéressants que l’article lui-même, souvent enrichissants, pour l’auteur et les lecteurs, qui assistent alors à la continuité d’un éventuel débat lancé par le billet, ou des corrections, ajouts, etc…

Mais il s’agit de quelque chose qu’on ne remet pas en question. Les commentaires vont sous l’article, et (Wordpress y a beaucoup contribué) ils sont structurés de façon conventionnelle : un fil de messages chronologiquement ordonnés, avec parfois des avatars récupérés depuis un service tiers fermé (dont le traitement des données personnelles est douteux), parfois avec la possibilité de répondre à un commentaire particulier… Cette dernière fonctionnalité est intéressante, parce qu’elle permet à la discussion d’évoluer. D’un échange entre l’auteur et ses lecteurs, on peut obtenir un débat autonome, mais restant posté sur le blog.

L’avis de Taziden là-dessus est qu’il est indispensable pour un blog de proposer une fonctionnalité de commentaires. Pour moi, c’est plus une habitude tenace qu’un besoin. Pourquoi ne remettrait-on pas plutôt en question cette fonctionnalité, pour la faire évoluer ? Pourquoi, au lieu de commentaires, ne pas développer un système d’annotations collaboratives, fonctionnant telles des calques sur le billet, pour enrichir l’article directement, comme on le peut le faire avec Etherpad ? Il s’agit d’une simple idée d’évolution, et je regrette que si peu de projets aient le courage de remettre à plat les usages et habitudes pour proposer quelque chose de novateur (en cela, le projet Discourse m’intéresse énormément), plutôt que de se sentir obligés d’intégrer les fonctionnalités « habituelles ».

Malgré cela, un blog reste un espace personnel. C’est l’espace de l’auteur. Celui-ci ne souhaite pas nécessairement que ses articles soient commentés. Il arrive d’ailleurs parfois d’écrire pour soi-même, et pas pour être lu. Les commentaires sous un billet sont quelque chose que l’auteur peut proposer. C’est un service supplémentaire. Souvent très enrichissant, mais toujours optionnel. Il n’y a pas, je pense, lieu d’exiger de quelqu’un qu’il mette à disposition un tel service, sous prétexte qu’il blogue. Et c’est tout à fait normal, un blog n’est pas un service public ou quelque chose de démocratique.

INTERNEEEEET

J’ai une confidence à vous faire : mon blog permet les commentaires. D’ailleurs, il en a régulièrement. Le fait qu’ils ne soient pas nécessairement écrits sous chaque billet ne les rend pas inexistants ou invisibles.

Après la publication d’une grande partie de mes billets, il m’arrive de recevoir un mail (chiffré ♥) contenant des remarques sur celui-ci, et avec un patch attaché, contenant des corrections de forme. Je trouve ça génial, et ce n’est pas le genre de chose qui aurait été possible avec un Wordpress. Mais encore, lorsque je publie, je diffuse l’article sur plusieurs canaux, comme IRC ou Statusnet (qui est ensuite renvoyé sur Twitter, qui est fermé), ou encore des mailing-lists. Là, les retours se font, les discussions, débats ou trolls, selon le sujet, se lancent. Et je n’ai aucun contrôle dessus. C’est quelque chose de fondamental. Sur mon blog, je peux valider, dévalider, supprimer, bannir quelqu’un, parce que j’en ai le contrôle (après tout, c’est mon espace). Mais une des grandes forces d’Internet, c’est que la communication est possible, quel qu’en soit le moyen. Je suis fortement attaché à la liberté d’expression, vous le savez. Et je considère simplement qu’on est plus libre de discuter par le moyen ou protocole qu’on veut, plutôt que de façon centralisée sur un site.

Disqus ? CÉMAL !

À ce titre, la solution proposée, notamment par Pelican, pour permettre les commentaires, est généralement le service Disqus. Il s’agit d’une application chargée en javascript qui va permettre de commenter un article via un service externe. Ce service est totalement centralisé, fermé, et sous son propre contrôle. J’ignore si un blogueur a la possibilité de supprimer un commentaire posté sur disqus, mais je sais que la plateforme elle-même a ce droit. Et je ne sais pas qui est derrière. Qu’est-ce qui me garantit que Disqus ne considèrera pas unilatéralement que mon commentaire est un spam, ou contrevient à son éthique ?

L’auteur de l’article évoqué plus haut appelle au développement d’un équivalent libre à Disqus. À cela, je réponds « NOPE NOPE NOPE NOPE ». Un service tiers centralisé, qu’il soit libre ou non, c’est mal. Ne serait-ce que parce que, peu importe sa licence, je ne connais pas les personnes qui s’en occupent. Je n’ai aucune garantie sur le service : est-ce qu’il risque de tomber en panne et ainsi rendre inopérables les commentaires sur un grand nombre de blogs ? Est-ce que les données sont sécurisées ? Est-ce que le service ne risque pas de fermer du jour au lendemain ?

Ceci dit, je suis mauvaise langue. Rien n’empêche la création d’un service de commentaires décentralisé, que l’on pourrait installer sur son propre serveur pour servir ses propres commentaires. Ce serait une solution acceptable. Mais l’inclusion dans le blog se ferait en javascript, ce qui n’est pas très accessible. Je préfère me passer de javascript autant que possible, donc je n’utiliserais vraisemblablement pas une telle solution.

Au lieu de cela, je laisse les retours se faire naturellement. On est sur Internet, bon sang, les moyens de communication ne manquent pas. En réagissant par le biais de protocoles plus adaptés pour ça, on ne dépend plus du blog, de son auteur, d’un service tiers, et de tous les risques de censure en découlant.

Un autre avantage indirect est la possibilité de développer son avis par un autre billet de blog qui se présentera en réponse du premier. Cela favorise la discussion, qui est alors d’autant plus profonde qu’elle ne pourrait l’être en 140 caractères. Mon dernier billet est dans ce cas : je voulais répondre en commentaire à Numendil, mais il les avait désactivés, alors j’ai pris le temps de faire un billet complet.

On n’est pas dans une salle de conférence

On m’a rétorqué qu’il était important que les commentaires soient proposés par le blog lui-même, en faisant le parallèle avec une conférence, où le public est invités à la fin à poser des questions. Cela n’a, pour moi, pas plus de sens que la tristement célèbre comparaison entre Internet et une autoroute. Les contraintes physique n’ont juste rien à voir. Une conférence se déroule dans un lieu clos et défini, à un moment défini, et les personnes, pour se faire entendre, parlent l’une après l’autre, et s’adressent au conférencier. Un blog n’a aucune de ces contraintes. Par ailleurs, à certaines conférences auxquelles j’ai pu participer (comme Passage En Seine), les retours se faisaient aussi sur IRC, donc leur décentralisation est déjà possibe IRL, donc je ne vois pas le problème de laisser les retours se faire ailleurs que sous l’article.

Bad-buzz friendly

Il n’y a pas que de gentils barbus (visuel non contractuel) qui s’expriment sur les Internets. Il y a aussi des politiques vaguement pourris, des boîtes qui cherchent à nous plumer sans trop que ça se voie, bref des gens qui ont un intérêt économique (entre autres) à ce qu’on ne leur crache pas trop bruyamment dessus. Et donc qui n’hésiteront pas à modérer sévèrement les moyens de communications qu’ils daignent mettre en place, pour éviter tout débordement ou diffusion d’une mauvaise image. Dans ce cas, l’utilisation de canaux tiers est parfaitement indispensable, parce que certaines choses méritent d’être sues. Si on se limite aux moyens autorisés, ce n’est plus du minitel 2.0 qu’on utilise, mais de la télé 2.0, où les diffuseurs sélectionnent ce qui a le droit d’être dit. C’est un modèle du passé, et il faut absolument éviter de restreindre la communication sur Internet à ces espaces de discussion qu’on veut bien nous laisser.

Donc non, un blog statique ne nuit pas au logiciel libre. À l’inverse, il encourage à l’utilisation épanouie d’Internet, c’est à dire à la décentralisation des échanges, à l’utilisation de protocoles prévus pour ça.

À ceux qui râlent

Je n’ai pas l’habitude d’écrire ce genre d’articles. Il s’agit d’une réponse à un billet de quelqu’un que je considère encore comme un ami de valeur, au sujet du féminisme, ou plus exactement des débats qu’il occasionne ces derniers temps. J’ai initialement voulu répondre directement en commentaire, mais parce qu’il avait fait le choix de les fermer, je me retrouve à écrire ici. J’en profite pour mettre à plat certaines de mes opinions à ce sujet, en espérant ne pas trop faire doublon avec mes articles précédents, notamment celui-ci.

Le féminisme extrémiste (celui avec des grandes dents)

Bon tout d’abord, je ne sais pas combien de fois il va falloir le rappeler : il n’y a pas « le » féminisme. Pour rappel, il s’agit de revendication de l’égalité des sexes et des genres. L’interprétation là-dessus est libre, ce qui donne un tas de militantismes différents. Et crois-moi Jérôme (prenez l’habitude, je m’adresse à une personne particulière dans ce billet), le féminisme extrémiste, ce n’est pas ce que tu vois. Le féministe extrémiste flirte sans gêne avec la misandrie, et ça se voit très vite. Et de tou·te·s les féministes que je connais, personne ne soutient ces idées. Si vraiment tu veux lire ce que je considère comme du féministe extrémiste (ce qui est revendication de l’auteure), je te conseille de lire ceci. Je préfère te prévenir, c’est vraiment violent. Ce que tu appelles « féminisme extrémiste », ce sont des gens très visibles sur twitter qui passent une grande partie de leur temps à se plaindre. Se plaindre de situations vécues, de réponses qu’on leur fait, d’articles lus, etc. Crois-moi, personne ne fait ça de gaieté de cœur. Seulement, quand on est sensibilisé au problème du sexisme, on a la fâcheuse tendance à le voir partout. Et tu sais particulièrement combien il est difficile de laisser couler des injustices qui sont sous notre nez.

La pilule rouge

Le fait est que ton article dénonce. Et qu’est-ce qu’il dénonce ? Le comportement de certain·e·s féministes. Ce qui est intéressant (et ce qui découle également de la discussion eue plus tôt avec deux autres hacktivistes), c’est justement le sens de cette dénonciation. Pierre, Élodie ou toi, vous êtes évidemment contre le sexisme. Dans les deux sens, je suis d’accord. Et quand vous écrivez sur le sujet, c’est immanquablement pour… taper sur des féministes. C’est révélateur, tu ne trouves pas ? N’aurait-il pas été plus utile, efficace ou que sais-je de dénoncer le sexisme concrètement ? Par exemple, dans ton billet, tu évoques des agressions que tu as subies, et que tu prends avec légèreté. Chacun réagit à sa façon à ce genre d’actes, et je n’ai rien à redire à la façon dont tu le prends. Contrairement à ce que l’on peut croire, je ne considère en aucun cas qu’être victime d’agression doit marquer à vie et nous forcer à vivre dans la honte et la culpabilité. Par contre, notre culture joue un rôle important là-dedans, dans le fait que pour toi ça n’ait pas été très grave. Car beaucoup de femmes prennent ce genre d’acte bien moins légèrement que toi. Peut-être que leur fréquence y est pour quelque chose ? Je soupçonne que oui, mais je n’en ai pas la preuve. Par contre, ce qui est avéré, c’est la culture du viol. Le fait que les jeunes filles, dès la puberté, apprennent à avoir peur, à redouter les agressions sexuelles. Agressions qui arrivent d’ailleurs en très grande majorité dans le cercle privé ou familial, mais c’est un autre sujet. Tu ne peux ignorer qu’on conseille aux femmes de ne pas sortir seules le soir, de faire attention à elles, etc. Face à ça, comprends-tu la gêne, la peur, quand un quelconque gentleman aborde une femme, qui n’a rien demandé, dans un espace qu’elle considère culturellement comme dangereux ? Sachant également que ce qu’on leur apprend à craindre est considéré comme banal, ne serait-ce qu’au moment de porter plainte si l’on en a le courage (difficile de porter plainte contre un membre de sa famille, surtout lorsque c’est sur nous que sera jetée la honte dans la majorité des cas…). Vois-tu où je veux en venir, et pourquoi ton ressenti face à des agressions (qui sont condamnables avec la même fermeté que si tu avais été une femme, fût-il utile de le préciser) est forcément différent de celui d’une femme ?

On me reproche, face à ça, de considérer les femmes comme des victimes en puissance. Ce n’est pas vrai. Les femmes sont ciblées par des actes sexistes à différentes échelles. Elles les subissent. Mais pourquoi une agression devrait-elle entraîner la honte ou peur de sa cible ? Encore une fois, toute cette discussion part de personnes qui ouvrent trop leur gueule. Qui n’ont justement pas du tout une posture de victime, mais au contraire, décident de ne plus se laisser faire, qu’il s’agisse de se défendre d’une agression physique ou de protester contre un geste commun de la vie quotidienne, mais qui participe à la société patriarcale. Car, quand on choisit la pilule rouge, qu’on accepte de remettre en cause notre culture, notre société, et, au fond, nous, on voit l’envers du décor, la matrice. On voit à quel point le sexisme est partout, et on perd facilement les pédales. C’est tout simplement ce qui arrive lorsque quelqu’un comme moi se met à réagir au quart de tour sur twitter. On pense constamment « Mais comment ne peuvent-ils pas voir ces injustices ? ». Je me trompe peut-être à ce sujet, mais je vous vois (vous, qui écrivez pour dénoncer l’attitude ou les propos de féministes énervé·e·s) comme des personnes, non pas ayant choisi la pilule bleue, mais surtout qui n’ont pas été confrontées à ce choix. Imaginez le film Matrix si, au lieu de latter des vilains en costard et lunettes noires, les héros avaient pour but d’expliquer à la population qu’ils sont dans la matrice… J’aime à penser que ça donnerait des situations similaires à ce que nous vivons. Ceci dit, dans mon analogie, le camp des héros est clairement défini, et il s’agit comme par hasard de celui que je m’attribue. J’aimerais beaucoup connaître votre avis là-dessus.

Quoi qu’il en soit, une fois la pilule rouge avalée, on commence à remettre en question notre environnement. Lors d’un débat, on s’aperçoit que la seule femme présente n’arrive pas à en placer une ou à se faire écouter. On remarque également les remarques, davantage tournées vers son apparence que vers ses idées. On tend un peu plus l’oreille quand on entend une femme se plaindre du comportement des gens dans la rue (et pas seulement des hommes). Parfois, et c’est plus difficile, on se prend soi-même à lâcher une parole qui autrefois n’aurait pas posé problème, mais qui aujourd’hui sonne faux, parce que vous remarquez qu’elle est discriminante et gratuite. Ça peut être quelque chose d’aussi insignifiant en apparence que le fait d’user de « Mademoiselle » pour s’adresser à une jeune femme, ou bien un glacial « t’as vu comment tu t’es habillée, aussi ? » à une femme qui raconte comment elle a failli être violée quelques instants plus tôt. Je comprends que cela provoque un agacement : on déterre toutes ces petites choses qui composent notre vie de tous les jours, toutes ces choses acquises, avec lesquelles on vit. Et remettre en question sa culture est une chose quand on a choisi d’ouvrir les yeux, mais se le prendre en pleine gueule alors qu’on ne s’en soucie pas peut effectivement mettre très mal à l’aise, et occasionner le l’agressivité en signe de défense.

C’est ce qui arrive lorsque que l’on dénonce le sexisme dans la société, mais c’est exactement pareil dans les communautés, comme les geeks. À la différence près que, quand on s’identifie comme geek, on s’attache à cette culture. Et inévitablement, on tombe dans le communautarisme. Que ce soit pour le milieu geek ou les autres. La réponse hautaine qu’on va tenir à un nouveau qui demande des conseils candides (et parfois un peu idiots) dans notre domaine d’expertise, c’est du communautarisme. On a notre communauté, et on veut naturellement s’assurer qu’on n’y entre pas n’importe comment, car c’est un espace familier. Quand on tape parfois brutalement sur Tris quand elle parle de sécu, quand bien même c’est argumenté, c’est du communautarisme, et je reconnais en faire moi-même. Voyez, je reconnais reproduire le problème, et j’en suis conscient. Et pourtant, je continue à lui dire ce que je pense, ce qui est rarement glorieux. Ridicule, vous ne trouvez pas ? D’ailleurs, je ne passe pas à côté du sexisme très installé dans certaines œuvres, comme la série Game of Thrones. Et pourtant, je l’aprécie. Parfois, le fait d’avoir cette analyse inconsciente des constructions genrées dans la fiction gâche le plaisir de la découverte. C’est comme ça, c’est ça le revers de la pilule rouge. On voit le monde encore plus sombre qu’avant. Mais on sait qu’on a alors les clés en main pour changer ça à notre échelle, en commençant par moins reproduire ces schémas. « Moins », et pas « plus », car la tâche est monumentale, et la seule façon de refuser du jour au lendemain toute forme de sexisme serait de couper tout lien avec la société, et de subir un lavage de cerveau. Ce qui ne serait pas très efficace. Alors on accepte de vivre dans ce monde sexiste, on continue d’aprécier des œuvres, même si elles se montrent sexistes. Il faut savoir faire des compromis, et connaître les limites de son militantisme.

Revenons au sujet

Dans ton article, Jérôme, tu persistes à expliquer en quoi tu réfutes le terme de féminisme pour parler d’égalité. Je suis égalitariste, tu le sais. Je ne souhaite pas inverser les privilèges, je souhaite que femmes et hommes soient au même niveau social, aient les même chances par défaut dans la vie.

Mais.

Être pour l’égalité sans aller plus loin, c’est une bien belle déclaration, qui n’a d’égale à son ardeur que son inutilité. C’est une déclaration de principe, rien de plus. Parce qu’il est impossible d’évoquer l’égalité hommes-femmes sans évoquer le patriarcat. Or, je te n’ai jamais vu ne serait-ce qu’employer ce mot. Sais-tu seulement ce qu’il signifie ? Il signifie que la société dans laquelle on vit a été pensée par et pour des hommes, et que les femmes y sont réduites à l’état de ressource. Évidemment, la société a évolué, et la place des femmes avec elle. Reste qu’historiquement, la domination était très claire : les hommes gouvernaient, et les femmes obéissaient. Aujourd’hui, est-ce différent ? « On n’est plus dans les années 50 », mais on n’est pas encore dans les années 10 000. Autrement dit, il y a beaucoup de chemin. Des exemples ? Le plafond de verre, qui symbolise l’extrême difficulté qu’ont les femmes à atteindre les postes à responsabilités. Ou l’inégalité salariale, ou encore la culture du viol, conçue pour culpabiliser les victimes et souvent d’excuser les auteurs. Ou encore la banalité que représente l’abordage d’une femme dans la rue, qui n’a rien demandé. Le patriarcat enseigne qu’on le peut, et qu’une femme doit se faire belle pour plaire aux hommes.

Le patriarcat, c’est une composante majeure de notre société. Il est normal que ça couine un peu quand on tape dessus. En tout cas, si tu souhaites lutter pour l’égalité, il y a une chose importante à faire. Et difficile. C’est le choix de la pilule, dont je parlais plus haut. Admettre l’existence du partiarcat, pour commencer (c’est pas si évident). Et surtout, admettre qu’en tant qu’homme, tu es naturellement privilégié. Ce n’est pas une honte, une critique ou quoi que ce soit. D’ailleurs tu n’y peux rien, tu n’as pas choisi ton genre. Mais c’est un fait, tu fais partie de la « caste » mise en avant par le patriarcat. Il y a fort à parier que l’immense majorité des gens qui liront ce billet sont privilégiés, d’une façon ou d’une autre. Toi, Pierre et moi, nous sommes des hommes blancs hétérosexuels cis (c’est à dire qui vivons notre genre assigné à la naissance). Cela fait 4 raisons d’être privilégiés. Nous sommes réellement quasiment au sommet de la pyramide sociale des discriminations. Ce sont les femmes qui sont victimes du patriarcat. Ce sont tous ceux dont la couleur de peau n’est pas celle des anciens conquérants européens qui sont victimes du racisme. Ce sont les homosexuel·le·s, bis, transgenres et queers qui sont victimes d’homophobie ou de transphobie. Pas nous. Je le répète, ce n’est pas un jugement, mais un constat. En admettant ses privilèges, on accepte de faire partie du problème. À ce moment, ça ne devient plus « des râleuses qui nous emmerdent avec leurs problèmes dont on n’a rien à faire ». On sait qu’on en est aussi, qu’on participe à ça. Après, on est libre de changer nos habitudes. D’accepter, non pas de renoncer à ces privilèges, mais de travailler à les partager. Ce n’est bien sûr pas un acte individuel, et je ne peux pas dire « tiens, prends ma place d’homme aux yeux de la société ». Pas par faute d’envie, mais parce que changer mon regard n’est qu’une pierre à l’édifice. Pour que ça ait un impact, il faut naturellement qu’une masse critique ait conscience de ce problème, et fasse un effort pour y remédier. Cette masse critique, c’est vous et moi, pas « les vilains misogynes ». Admettre ça, c’est lutter pour l’égalité des genres. C’est être féministe.

Et toi, Jérôme, qui es pour l’égalité, t’es-tu remis en question ? Ou te contentes-tu de taper sur celles et ceux qui s’efforcent de sensibiliser les autres ? Au contraire, ai-je envie de dire. Car quand tu dénonces le fait que le dossier de Mar_Lard pointe du doigt « les geeks », il est clair que tu te sens vexé, car on sous-entend que ta précieuse communauté pourrait avoir un problème, pire, que tu pourrais en faire partie. Non content d’être du communautarisme bien idiot, il s’agit d’un rejet pur et dur du problème. Tu préfères penser que le sexisme, bien sûr que ça existe, mais ce sont « les autres ». Pas de ça autour de toi, sinon tu l’aurais vu, n’est-ce pas ? Et si c’était le simple fait de ne pas le remarquer qui te mettait mal à l’aise ? Tu sais, depuis le (faible) temps que je milite pour l’égalité, j’ai fini par repérer les patterns courants de ceux qui tapent sur le féminisme, mais qui sont d’accord sur le principe, hein, mais… Mais faut pas crier aussi fort, mais faut pas généraliser sur les geeks, y’en a des biens… Et là, je ne te fais que les réponses construites. Parce que dans leur immense majorité, les réactions sont purement haineuses. As-tu jeté un œil sur les commentaires du moindre article rédigé par Mar_Lard ? Toi qui parles d’égalité, et de ses billets, n’as-tu pas trouvé pertinent, même si tu souhaitais critiquer intelligemment, de signaler cet état de fait ? D’ailleurs, qu’en penses-tu, toi qui, sans le vouloir, participes à la levée de boucliers qui suit inévitablement ce pavé dans la mare ?

Non pas que le dossier dont il est question ne soit pas critiquable. Au contraire. Il s’agit du travail personnel de quelqu’un de passionnée par le sujet, et dont ce n’est pas le métier. Ça se ressent, évidemment. Mais on va lui reprocher de ne pas parler de quelque chose, d’avoir un ton incorrect. Tout est prétexte à critiquer son texte. Ça a quelque chose de malsain, et je dois dire que je t’en veux de ne pas avoir vu plus loin que ça.

Finalement, tu as raison, tas de pixels. C’est bien une question de binaire. La pilule rouge ou bleue. La reconnaissance du problème ou son déni.