Simon Vieille


CTO at Like-inn Développement, casual worker at IUT-BM, symfony expert and debian addict

Remote i3-wm WS : ma télécommande pour bureau Debian GNU/Linux

Il m'arrive d'avoir besoin de prendre le contrôle de ma machine via mon Android (bouger la souris, scroller et taper du texte).

J'ai quasiment toujours utilisé l'application Pointer Host. elle s'appuie sur un serveur Java lancé sur ma machine. Pour bouger la souris et générer des cliques, elle est très efficace. Cependant, l'écriture de caractères a toujours posé problème (chiffres et lettres accentuées erronés).

Depuis quelques semaines, j'ai envie de jouer avec les websockets et réécrire une appli du genre m'a semblé être un bon exercice.

Ce que je vais vous présenter est une POC. Cette application n'est pas sécurisée et est orientée pour mes besoins. Il est cependant très simple de la faire évoluer.

Voici mon cahier des charges :

  1. aucune application ne doit être installée sur mon téléphone
  2. utilisation du navigateur web pour le pilotage
  3. pouvoir bouger la souris
  4. pouvoir générer des cliques
  5. pouvoir scroller
  6. pouvoir taper des mots
  7. pouvoir lancer des raccouris claviers
  8. pouvoir gérer le volume du son
  9. pour Spotify : lancer et mettre en pause la musique, avancer et reculer dans la playlist en cours de lecture
  10. pouvoir changer de workspace dans mon gestionnaire de fenêtres i3-wm

Les outils pour scripter tout ça sont connus :

  • xdotool pour simuler un clavier et une souris (3, 4, 5, 6, 7) :
    • xdotool type "ceci va être tapé"
    • xdotool key Enter (touche Entrée)
    • xdotool click 1 (clique gauche)
  • amixer pour gérer le volume (8) :
    • amixer set Master 50% (volume à 50%)
  • playerctl pour piloter Spotify (9) :
    • playerctl -p spotify next (titre suivant)
  • i3-msg pour piloter i3-wm (10) :
    • i3-msg 'workspace "Foo"' (affichage du workspace Foo)

Websocket est un protocole réseau issu du web qui permet de créer un canal full-duplex entre un client et un serveur. Ils peuvent donc communiquer en temps réel dans une connexion TCP.

Comme à mon habitude et par esprit de contradiction (pas de NodeJS), j'ai décidé d'écrire la partie serveur en PHP 7. La partie cliente est en HTML 5 avec un peu de javascript.

Entre le serveur et le client, ce sont des messages textes qui sont échangés. J'ai décidé de les formater en JSON et seul le client va en envoyer. Ils sont toujours sous cette forme : {"type":"un type de message", [données complémentaires]}. Voici quelques exemples :

  • {"type":"workspace","value":"1. IRC"}
  • {"type":"pointer","click":"left"}
  • {"type":"media","value":"next"}
  • {"type":"volume","value":"down"}
  • {"type":"scroll","value":"up"}
  • {"type":"pointer","x":"-2","y":"3"}
  • {"type":"text","value":"Un texte"}

On peut aussi envoyer plusieurs messages dans un seul. Voici un exemple qui va permettre d'ouvrir urxvt via dmenu que je lance avec win+d :

{"type":"messages","value":[{"type":"keys","value":"win,d"},{"type":"text","value":"urxvt"},{"type":"key","value":"enter"}]}

Ces messages sont générés par le client et sont interprétés par des messageHandler une fois transmis au serveur. En voici un exemple :

Le code source de l'application est disponible sur deblan/remote-i3wm-ws et la procédure d'installation est simple :

Pour lancer le serveur websocket, il faut exécuter server/server start (@see restart et stop). Le serveur va écouter sur le port 14598. Concernant la partie cliente, vous pouvez créer un vhost Apache/Nginx qui pointera sur client/ ou lancer le serveur web built-in de PHP via php -S 0.0.0.0:15000 -t client/. Il faudra à présent vous connecter au serveur web depuis un navigateur.

Quelques captures de la partie cliente :

Remote i3-wm WS: keyboardRemote i3-wm WS: i3Remote i3-wm WS: mouseRemote i3-wm WS: media

Je vais essayer de faire une vidéo de démonstration. Depuis mon Samsung S8, ça fonctionne du feu de dieu et sur un petit Iphone 4S, c'est tout aussi fonctionnel (à part l'interface web un peu étriquée).

Edit 1

  • dbus-send a été remplacé par playerctl (merci Thomas L)
  • le type messages a été ajouté et permet d'envoyer plusieurs messages (cf l'exemple avec urxvt) et les mises à jour du code

Edit 2

  • Le code PHP du serveur a été déplacé dans server/src/resource/server.php
  • server/server est à présent un script shell et permet de lancer, relancer et stopper le serveur websocket (server/server start|restart|stop)

Monitordisplay : gérer ses dispositions d'écrans

Je branche très souvent des écrans externes à mon laptop et je suis un peu lassé de bidouiller xrandr. En effet, ses instructions sont simples mais assez longues et pénibles à écrire.

Ainsi, j'ai décidé de me faire un outil pour pouvoir configurer des modes d'affichage, pouvoir ajouter plusieurs dispositions et les activer rapidement.

Comme à mon habitude, c'est un outil en ligne de commande. J'ai décidé d'utiliser PHP pour une question de pratique pour moi.

Installation de monitordisplay

Il faut installer l'interpréteur PHP (5 ou 7) :

Maintenant que PHP est installé, il faut récupérer le projet :

Configuration

monitordisplay va essayer de charger 3 fichiers. Chaque fichier peut surcharger la configuration du précédent. Voici la liste :

  • /etc/monitordisplay/config.ini
  • $HOME/.config/monitordisplay/config.ini
  • $HOME/.monitordisplay

Je suis le seul utilisateur du laptop donc je vais juste créer le dernier.

Le fichier de configuration copié contient 2 écrans :

laptop et hdmi sont les identifiants "humains" sur lesquels je vais m'appuyer pour réaliser les dispositions. Le paramètre name contient l'identifiant technique passé à xrand. resolutionX et resolutionY indiquent la résolution de l'écran.

Il est possible de configurer plusieurs fois le même écran. Il suffit de modifier l'identifiant humain. Vous pouvez ainsi prévoir plusieurs résolutions.

Maintenant, il reste à renseigner des modes d'affichage. En voici trois exemples :

Tout comme un écran, le mode d'affichage porte un identifiant. Il possède également une liste de dispositions (config[]) et un indicateur (optionnel) d'écran principal (primary). L'ordre des identifiants définie la position, de gauche à droite, des écrans.

Utilisation

Pour activer un mode d'affichage (exemple : work), il suffit de lancer cette ligne de commande :

Le mode work contient deux dispositions. Pour passer à la seconde disposition, il suffit de lancer :

-t permet donc de passer successivement d'une disposition à une autre.

Quand monitordisplay charge un mode ou change de disposition, par défaut, il désactive les écrans non pris en charge. Si vous souhaitez outre-passer ce comportement, il suffit de passer l'argument -s. C'est assez pratique quand vous souhaitez initialiser une résolution sur un écran sans désactiver les autres.

Le code source est disponible sur gitnet et c'est open bar ;)


Let's Encrypt - Comment se faciliter la vie ?

Mon serveur web est composé d'un frontend nginx et d'un backend apache. L'ensemble de mes certificats (à l'exception du wildcard deblan.org) est géré par Let's Encrypt. Mon problème jusqu'à aujourd'hui était que lors de la création ou le renouvellement d'un certificat, mon service nginx devait être coupé pour réaliser l'authentification nécessaire à la validation faite par Let's Encrypt.

Le service nginx, tel que je l'ai configuré, possède un fichier de configuration unique qui écoute sur le port 80. Ce fichier permet :

  • d'indiquer mon backend apache
  • de gérer les problématiques de cache des assets (images, css, javascripts, etc.)

Vous pouvez remarquer l'include à la ligne 20. Voici le contenu du snippet :

Il identifie un répertoire unique où seront générés les fichiers d'authentification de Let's Encrypt. Il aura fallu créer ce répertoire au préalable (sudo mkdir -p /var/www/letsencrypt/).

Reste à présent 2 scripts :

  • celui qui permet de générer un certificat
  • celui qui permet de renouveler les certificats qui vont expirer

Pour la génération d'un certificat, j'ai souhaité une ligne de commande simple : le-get-certificate monsite.com www.monsite.com foo.monsite.com. Voici son contenu :

Edit : la commande cerbot renew fait le travail tout seul. L'intérêt de mon script pourrait d'ajouter rapidement des domaines à certifier en augmentant le CSR automatiquement.

Edit 2 : certbot renew --webroot -w /var/www/letsencrypt --agree-tos est sans doute la meilleurs manière de renouveler les certificats. J'ai rencontré quelques problèmes avec le script proposé ci-dessous.

Concernant le renouvellement, le script suivant s'appuie sur un fichier de configuration que vous devrez alimenter à chaque création de certificat. Il doit être créé à cet emplacement : /etc/letsencrypt/domains.conf. Voici à quoi il ressemble chez moi et j'ai ajouté la ligne nécessaire pour l'exemple de la commande de création :

Voici à présent le script que devra être exécuté périodiquement pour le renouvellement :

J'espère que cela pourra vous être utile et si vous avez des remarques, n'hésitez pas à m'en faire part :)


[livecoding] deblan/nginx-rtmp-auth: RTMP auth module (partie 1)

Je publie aujourd'hui une nouvelle vidéo issue du live réalisé sur la plateforme livecoding. Dans l'optique de réaliser une application d'authentification de stream (comme Twich ou Livecoding), je développe les outils pour valider l'utilisateur qui stream via une clé et le nom de sa chaîne. Il manque quelques minutes au début, je me suis rendu compte que je n'ai pas lancé l'enregistrement…L'ensemble du live est dipo sur livecoding et il manque l'installation de symfony et la configuration de Propel, les deux principaux outils sur lesquels je m'appuie.

J'en ai profité pour mettre en ligne un micro site web qui référence les vidéos. Ce n'est qu'une première ébauche mais vous y retrouverez l'ensemble des lives sans devoir fouiller sur YouTube. C'est par ici que ça se passe :)

Bon visionnage !


[livecoding] deblan/gist: issue #1

Voici la vidéo du live réalisée sur la plateforme livecoding. J'ai traité le premier ticket ouvert pour le projet Gist où il est question d'adapter la fonctionnalité de clonage pour un gist chiffré. Pour rappel, Gist est un service en ligne pour déposer du code (gist) qui peut-être modifié et versionné. L'outil intègre une solution pour chiffrer les contenus coté navigateur.

J'en profite pour vous informer qu'il y a quelques jours, j'ai publié la version 1.1.1 dans laquelle se trouvent un ou deux correctifs mais surtout la capacité d'affiner les accès à l'application (cf la documentation). Pour mettre à jour votre instance, il suffit de lancer la commande make update.

Bon visionnage !