Le jeu de caractères des afficheurs VFD Matrix Orbital

Auteur :  x0r Publié le   Nombre de commentaires : 0
Mots-clefs : vfd matrix orbital charset

Sur une de mes machines servant de HTPC, j'utilise un afficheur fluorescent (ou VFD) Matrix Orbital VK202-25-USB.

C'est un magnifique petit afficheur, bien pratique pour lire de la musique pendant que seule la machine est allumée et que la télé est éteinte. Le seul problème, c'est que la documentation comporte des erreurs et que le jeu de caractères qui y est présenté est erronné et incomplet.

Quelques lignes de Perl et d'Imagemagick plus tard, je vous concocte donc une image résumant le jeu de caractères de l'afficheur pour les points de code allant de 128 à 253 inclus.

Jeu de caractères du VK202-25-USB

Notez que la place faite aux katakana et autres caractères japonais font que les lettres accentuées comme "é", "è", etc. ne peuvent pas être représentées. C'est bien dommage, car ces caractères figureraient dans le charset des afficheurs LCD qu'ils vendent (et non les VFD, la seule option réellement intéresante pour mon application). Dommage, car pour le reste, ils sont plutôt agréables à programmer.

Reprendre le contrôle de son adressage avec DHCPv6 et Dibbler

Auteur :  x0r Publié le   Nombre de commentaires : 0
Mots-clefs : sysadmin ipv6 dibbler dhcpv6 dhcp reseau

Dans un article précédent, nous avons vu comment faire fonctionner son réseau avec l'IPv6 de Free en étant derrière son propre routeur OpenWRT. Je m'étais alors limité à l'autoconfiguration automatique (dit SLAAC, pour Stateless Address Autoconfiguration), pour des raisons de simplicité.

Cependant, la partie "stateless" fait que le routeur se contente de donner le préfixe /64 et éventuellement d'autres informations. Le client choisit alors lui-même les 64 derniers bits de l'adresse qu'il décide d'utiliser, moyennant quelques précautions pour éviter d'utiliser une adresse utilisée par quelqu'un d'autre (DAD, ou Duplicate Address Detection). Une adresse peut alors être générée à partir de l'adresse MAC, comme c'est souvent le cas sous Linux, mais elle peut aussi être choisie de manière complètement aléatoire, et renouvelée toutes les dix minutes, comme sous Windows et Mac OS. On parle d'utilisation d'adresses temporaires pour le second cas.

J'utilise Privoxy sur mon réseau. Il s'agit d'un proxy qui permet entre autres de filtrer les pubs et autres petits trucs indésirables (comme par exemple ces fameux boutons « J'aime » de Facebook, qui ont le malin plaisir d'utiliser un cookie pour tracer des utilisateurs, y compris ceux qui n'ont pas de compte chez eux – mais cela n'est pas l'objet principal de cet article). Il s'avère que de temps en temps, Chrome sous Windows ne parvient pas à se connecter au proxy (erreur net::ERR_PROXY_CONNECTION_FAILED pour ceux qui veulent des détails), alors que le reste du réseau fonctionne. Aucun paquet TCP, ni même un seul paquet SYN, ne parvient au serveur lorsque cela arrive.

J'ai donc conjecturé que c'était la faute de l'utilisation des adresses temporaires. J'ai donc eu l'idée d'expérimenter avec Dibbler, un petit serveur DHCPv6 portable, qui est entre autres packagé sous OpenWRT. Mon expérience est à la fois justifiée par ma conjecture et par le désir d'attribuer des reverse DNS pour les machines sur lesquelles je ne peux pas me permettre d'attribuer des IPv6 statiques à la main.

Dans ce post, je vais donc expliquer en détail ce que j'ai fait pour mettre en place un serveur DHCPv6 sur mon routeur, tout en explicitant les différences avec l'« ancien » DHCP d'IPv4. Je reviendrai d'abord sur le fonctionnement de radvd, avant de traiter de l'installation de Dibbler, de sa configuration et du test du service, pour ensuite conclure sur mes observations quant aux implémentations de dhcpcd et de Windows.

Retour sur radvd

Au moment où nous avions mis en place la connectivité IPv6 pour notre réseau, nous avions installés radvd, qui sert à répondre aux Router Solicitations (RS) d'ICMPv6 avec des Router Announcement (RA). Ces paquets contiennent deux types de flags.

Premièrement, les flags du paquet sont les suivants :

  • M (Managed) : si ce flag est à 1, utiliser DHCPv6 pour récupérer son adresse IP. Sinon, se contenter de SLAAC ;
  • O (Other) : si ce flag est à 1, utiliser DHCPv6 pour récupérer d'autres informations que l'adresse (par exemple les serveurs DNS).

Nous avions mis ces deux flags à 0 lorsque nous avions configuré radvd, signifiant que seuls des paquets RS et RA sont nécessaires pour l'autoconfiguration des clients. En passant à DHCPv6, nous mettrons le flag M à 1, et si nous souhaitons également fournir aux clients les adresses des serveurs DNS, nous ferons de même avec le flag O.

Ensuite, pour chaque préfixe signalé dans un RA, il y a également plusieurs flags, mais nous nous focaliserons surtout sur le suivant :

  • A (Autonomous) : si ce flag est à 1, le client utilise SLAAC pour obtenir une adresse dans le préfixe correspondant.

Ce flag était à 1 dans notre configuration initiale. Comme nous utilisons DHCPv6, nous pouvons la passer à 0 pour s'assurer, entre autres, que les clients n'utilisent pas d'adresses temporaires.

Installation de Dibbler

L'installation de Dibbler est très simple. En tant que root sur le routeur :

# opkg install dibbler-server

Configuration de Dibbler

La configuration de Dibbler se fait dans /etc/dibbler/server.conf. Voici un petit exemple de configuration attribuant des IP aléatoires dans son /64, tout en attribuant certaines IP fixes pour certaines machines.

# Logging level range: 1(Emergency)-8(Debug)
log-level 7

# Don't log full date
log-mode short

# set preference of this server to 0 (higher = more prefered)
preference 0

iface "br-lan" {
 // also ranges can be defines, instead of exact values
 t1 1800-2000
 t2 2700-3000
 prefered-lifetime 3600
 valid-lifetime 7200

# assign addresses from this pool

 class {
   pool 2001:db8:0:42/64
 }

 option domain example.com
 option dns-server 2001:db8:0:42::b
 option ntp-server 2001:db8:0:42::17
 option time-zone  CET

 client duid 00:01:00:01:18:92:e4:e9:aa:bb:cc:dd:ee:ff
 {
   address 2001:db8:0:42::cafe
 }

 client duid 00:01:00:01:18:5a:14:81:01:23:45:67:89:ab
 {
   address 2001:db8:0:42::c0ca
 }
}

La plupart des directives sont plutôt évidentes. Il y a cependant deux choses auxquelles il faut faire attention :

  • Dibbler 0.8.2 semble avoir un bug qui oblige les adresses statiques à être obligatoirement dans un préfixe déclaré avec la directive class. Cela signifie qu'il est pour le moment impossible de donner des IP dans deux plages disjointes selon qu'il s'agisse d'une machine connue ou inconnue.

  • On n'attribue plus d'adresses en fonction d'adresses MAC, mais en fonction d'identifiants uniques appelés DUID (plus de détails dans la RFC 3315, section 9 – lecture très recommandée). Ces DUID sont généralement générés une fois à l'installation du système (ou à la première utilisation de DHCPv6...).
    L'inconvénient majeur est le fait que ces DUID sont imprévisibles ; il faut donc regarder dans /var/lib/dibbler/server-cache.xml pour retrouver celui qui correspond à la bonne adresse.

Mis à part l'utilisation de DUID, il n'y a pas grand-chose de sensiblement différent comparé au DHCP traditionnel.

Tester le service

Sous Linux, on peut tester le bon fonctionnement avec le client fourni avec Dibbler. Il suffit de lancer dibbler-client run en tant que root, puis de faire un petit ifconfig pour voir si on obtient une adresse IP par DHCPv6.

Windows 7 implémente déjà un client DHCPv6, donc il suffit de rebooter la carte ou la machine. En faisant un petit ipconfig dans une invite de commandes, on voit que ça marche tout seul.

Conclusion

Bien que l'utilisation de DHCPv6 n'ait pas résolu le problème avec le proxy sous Chrome mentionné en introduction (ou alors ce sont des gremlins qui s'amusent avec la carte réseau), cela m'a ensuite permis de mettre en place assez facilement les enregistrements reverse DNS pour ma plage d'adresses IPv6. Pas forcément nécessaire, mais toujours appréciable.

Pour le moment, dhcpcd, le client DHCP utilisé par wicd entre autres, ne prend pas encore en charge DHCPv6, donc pour ceux qui utilisent ce démon, vous n'avez pas de chance ; vous n'aurez que du SLAAC. Ou sinon, il faudra compiler et installer la version 5.99.

Du côté des serveurs, dnsmasq implémenterait également un serveur DHCPv6, mais cela contraint de supprimer radvd, ce que je ne souhaitais pas. In fine, la solution que j'ai retenue est celle qui fournit le plus de flexibilité, et permet théoriquement de s'affranchir de cette problématique récurrente d'administration réseau qu'est l'adressage.

minicurses 0.4

Auteur :  x0r Publié le   Nombre de commentaires : 0
Mots-clefs : programmation c minicurses minitel

Après quelques mois de développement, de tests et de stagnation par manque de temps, j'ai décidé de faire une release de la version 0.4 de minicurses, rendant obsolète la version 0.3.2.

Cette mise à jour mineure apporte la gestion de fenêtres à minicurses. J'ai également eu l'occasion d'écrire un programme d'exemple tout pourri et bugué, que je n'ose pas encore publier, pour tester les diverses fonctionnalités que j'ai ajoutées à minicurses.

Téléchargements

ou, toujours, pour ceux qui souhaitent récupérer la toute dernière version de développement :

% hg clone https://bitbucket.org/xtab/minicurses

Comme d'habitude, je vous invite à consulter les pages de man sur le wiki.

Oui, un jour, je ferai peut-être de la doc un peu plus poussée.

Changelog

  • Ajout de la prise en charge de fenêtres : newwin(3), delwin(3), ainsi que les fonctions wfoobar() et mvwfoobar() (si pertinent) des familles addstr(3), addch(3), clear(3), attron(3), attroff(3), attrset(3), addimg(3), refresh(3) et autres.

Roadmap

Pour la version 0.5, voici les modifications les plus importantes que je prévois :

  • Gérer les frappes au clavier ;
  • Aligner la gestion des paires de couleurs à celle de ncurses pour améliorer la compatibilité source de minicurses.

Minitel sur Raspberry Pi

Auteur :  x0r Publié le   Nombre de commentaires : 10
Mots-clefs : linux minitel serie terminal raspbian raspberrypi mgetty crosscompilation crossdev arm

Maintenant que j'ai cette magnifique petite machine à 35 USD sous la main, pourquoi pas essayer de brancher le Minitel dessus, comme sur un PC classique ?

Ce post est la suite de l'article Minitel comme terminal Linux, et je vous invite à y jeter un coup d'œil avant de continuer. Il expliquera comment tester rapidement le Minitel, puis les aspects qui diffèrent par rapport à un PC classique sous Linux. Enfin, il expliquera dans les grandes lignes comment cross-compiler minicurses sur Gentoo pour Raspberry Pi.

Raspberry Pi

Le matériel

Il vous faut :

  • Un Raspberry Pi et un OS (j'utilise Raspian ici) ;
  • Le câble série nécessaire, qui est toujours le même que celui pour PC ;
  • Un convertisseur USB-série compatible avec le driver pl2303 sous Linux (c'est-à-dire à peu près n'importe quel câble trouvable à une dizaine d'euros rue Montgallet).

Nous n'aborderons pas la fabrication du câble série, qui est expliquée en détail dans l'article précédent.

Un petit test

Rien de tel qu'un petit test avant de passer à la suite :

$ stty -F /dev/ttyUSB0 1200 istrip cs7 parenb -parodd brkint \
    ignpar icrnl ixon ixany opost onlcr cread hupcl isig icanon \
    echo echoe echok
$ echo 'bonjour Minitel !' > /dev/ttyUSB0

Bonjour Minitel !

Ça, ça marche bien, et c'est plutôt rassurant.

Compiler mgetty comme il faut

Pour faire fonctionner un terminal Minitel sur le Raspberry Pi, les instructions d'origine peuvent être suivies si on souhaite se contenter d'un agetty et d'un prompt de login pas vraiment joli à voir. oui Pour y remédier, il faudra procéder comme dans mon article d'origine, c'est-à-dire appliquer un patch pour utiliser /etc/gettydefs pour que le prompt de login s'affiche correctement. C'est pourquoi nous serons toujours amenés à compiler mgetty depuis les sources, plutôt que d'installer le paquet binaire.

Nous procéderons à la compilation de mgetty directement sur le Raspberry Pi par souci de simplicité, mais il va de soi que ce sera certainement plus rapide de le cross-compiler depuis une machine plus grosse.

Ajouter d'abord une ligne deb-src dans /etc/apt/sources.list identique à celle-ci :

deb-src http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib rpi

puis

$ mkdir src; cd src
$ sudo apt-get source mgetty

Maintenant que nous avons récupéré les sources et les patchs Debian pour mgetty, appliquer celui pour utiliser gettydefs :

$ wget http://x0r.fr/blogstuff/mgetty-use-gettydefs.patch
$ patch -d mgetty-1.1.36 -p1 < mgetty-use-gettydefs.patch

Installer ensuite les dépendances nécessaires à la compilation :

$ sudo apt-get build-dep mgetty

Prendre un café.

$ cd mgetty-1.1.36
$ dpkg-buildpackage -rfakeroot -uc -b

Prendre un deuxième café, et regretter amèrement de ne pas avoir pris le temps de regarder comment cross-compiler cet outil.

Une fois que c'est terminé, remontez dans le répertoire parent, et admirez la flopée de nouveaux fichiers .deb. Bien entendu, nous allons installer mgetty.

$ cd ..
$ sudo dpkg -i mgetty_1.1.36-1.6_armhf.deb

L'instant de vérité : mgetty ne marche pas ! (mais getty, oui)

L'identifiant T0 est déjà utilisé pour le port série intégré au SoC du Raspberry Pi, donc nos ajouts à /etc/inittab portent l'identifiant T1.

Et donc, pour une raison étrange, mgetty ne marche pas. En effet, en essayant de mettre une ligne comme celle-ci dans /etc/inittab, comme cela aurait été d'usage :

T1:23:respawn:/sbin/mgetty -br ttyUSB0 4800v23 -i /etc/issue.mgetty

alors, rien n'apparaît à l'écran. Après avoir lâché strace, il semble que mgetty ouvre correctement le port série, que les appels système write(2) fonctionnent, mais qu'il se bloque sur le read(2) du login. Cependant, en utilisant le getty traditionnel, avec la ligne

T1:23:respawn:/sbin/getty -L ttyUSB0 4800 minitel1b-80

moyennant le prompt de login hideux, cela fonctionne parfaitement.

Il faudrait donc que je détermine exactement pourquoi je n'ai aucun affichage sur le Minitel avec mgetty, alors que getty fonctionne.

Cross-compiler minicurses pour Raspberry Pi

Bien évidemment, je ne pouvais pas m'arrêter là, et j'étais curieux de savoir si ma bibliothèque minicurses fonctionne bien. Cette fois, je l'ai cross-compilée à l'aide d'un crossdev configuré pour Raspberry Pi. J'aurais aussi pu compiler minicurses directement sur le Raspberry, mais pour des bibliothèques plus conséquentes, cela devient assez vite fastidieux.

Je vous invite à lire le Gentoo Embedded Handbook afin de comprendre un peu mieux ce qui se passe.

D'abord, il faut installer les bibliothèques qui vont bien. Si on utilise crossdev pour la première fois, le Embedded Handbook précise qu'il ne faut pas oublier de lancer la commande

# emerge-wrapper --init

Ma bibliothèque a pour dépendance la bibliothèque netpbm. Cependant, le packaging a l'air d'avoir été fait comme un pied, et pkg-config donne quelques problèmes.

Pour que la compilation de netpbm fonctionne :

# armv6j-hardfloat-linux-gnueabi-emerge -va libpng libxml2
# vi /usr/armv6j-hardfloat-linux-gnueabi/usr/lib/pkgconfig/libpng.pc

Changer ensuite prefix en /usr/armv6j-hardfloat-linux-gnueabi/usr. Faire de même avec libxml2.pc, puis :

# armv6j-hardfloat-linux-gnueabi-emerge -va netpbm

Avec autotools, cross-compiler, c'est magique. Une fois minicurses détaré :

$ LDFLAGS="-L/usr/armv6j-hardfloat-linux-gnueabi/usr/lib" \
    ./configure \
        --host=armv6j-hardfloat-linux-gnueabi \
        --prefix=/usr/armv6j-hardfloat-linux-gnueabi/

$ make 
$ file ./src/.libs/libminicurses.so.0.3.2 
./src/.libs/libminicurses.so.0.3.2: ELF 32-bit LSB shared object, ARM,
version 1 (SYSV), dynamically linked, not stripped

et pour les programmes d'exemple :

$ cd examples/
$ CC=armv6j-hardfloat-linux-gnueabi-gcc make

À présent, vous pourrez tester les programmes d'exemple pour voir que peu importe la taille de la bécane sur laquelle tourne minicurses, tant qu'il y a un Linux dessus, il n'y a aucun problème.

Conclusion

J'espère publier un tutoriel un peu plus compréhensible pour la compilation croisée de minicurses une fois que j'aurai fini de publier la version 0.4, qui devrait apparaître sous peu.

J'espère également que cet article ouvre, à terme, la voie de « hacks » à base de Minitel et de Raspberry Pi. On pourrait alors, par exemple, envisager un projet de domotique avec des appareils contrôlés avec un Raspberry Pi, et fournissant une interface d'administration par Minitel. Ce serait une belle façon de recycler ces terminaux qui, pour certains, ont déjà fêté leur 30e anniversaire.

Bloquer les bots hébergés sur Amazon AWS

Auteur :  x0r Publié le   Nombre de commentaires : 0
Mots-clefs : securite web nginx

Au fur et à mesure que je surveille mes logs avec logwatch, awstats et un bon vieux tail, je me rends compte que mes "ennemis" ne sont pas forcément les script kiddies ou les spambots (qui, d'ailleurs, s'empalent magnifiquement alors que j'ai pris des mesures qui me semblent parfaitement contournables), mais qu'il y a aussi des boîtes qui s'invitent sur ce site avec comme seul but de vendre leur outil de SEO dont je n'ai rien à battre, du style AhrefsBot ou sistrix.

Comme certains d'entre eux se cachent dans le cloud Amazon EC2 et que je vois aussi moult posts dans des forums divers et variés se plaignant de bots soupçonnés d'être malveillants provenant de ce cloud, on peut se proposer de les bloquer en récupérant les plages d'adresses IP, puis de passer un petit coup de awk dessus.

Pour ce faire, consultez le forum Amazon AWS, puis ouvrez le topic Amazon EC2 Public IP Ranges.

Lancez ce script:

sort -n | awk '/^[1-9]/ { print "deny", $1 ";" }' > ban-amazon-aws.conf

puis copiez-collez le contenu du post dedans. Ceci générera le bout de fichier de configuration nécessaire pour nginx. Pour Apache, c'est ce script-là qu'il faudra utiliser :

sort -n | awk '/^[1-9]/ { print "Deny from", $1 }' > .htaccess

Plus qu'à include le fichier au bon endroit (ou mettre le .htaccess au bon endroit), et ça marche. On notera qu'il n'y a que des plages IPv4, le cloud d'Amazon ne prenant pas (encore) en charge IPv6.

Cela dit, le seul inconvénient est que certaines personnes (et non des bots) pourraient visiter un site en passant par une machine de ce cloud, via un tunnel SSH par exemple. Comme pour le moment, les seules entités impactées par ce genre de mesures semblent être des bots, ça me va.