PROJET AUTOBLOG


Le blog de Seboss666

Site original : Le blog de Seboss666

⇐ retour index

Haproxy : OpenVPN ou SSH ?

vendredi 17 avril 2020 à 18:30

Je n’utilise pas du tout Haproxy à titre personnel, mes contacts n’ont été que professionnels, et principalement pour du load-balancing HTTP/HTTPS. Mais il est tout à fait possible de s’en servir pour d’autres usages, en mode TCP, c’est à dire en mode « brut ». Et là, ça permet de faire des choses de tarés, et l’astuce d’aujourd’hui en est une, partager le port 443 pour faire soit du SSH, soit de l’OpenVPN. Z’êtes prêts ?

Le concept

Oui parce que l’idée ne sort pas de nulle part non plus. Sur le papier déjà, il faut savoir que n’importe quel port peut être utilisé pour n’importe quel protocole. Ça n’empêche pas les RFC de définir des ports par défaut, qui sont la plupart du temps respectés, et qu’on doit laisser passer pour faire un peu de Web et d’Internet, sinon ça n’aurait pas grand intérêt : 53 pour le DNS, 80 et 443 pour HTTP et HTTPS, 22 pour SSH, vous en connaissez surement plusieurs dans ce cas.

Mais dans la pratique, et dans beaucoup de réseaux publics notamment, mais aussi des réseaux d’entreprise, avoir droit à autre chose que du 80 et du 443, c’est pas toujours évident (oui parfois même le DNS public est bloqué, et on doit passer par le point d’accès pour ça –quelle horreur…). Et il n’y a rien de plus frustrant de se retrouver coincé sur un réseau qui n’autorise pas à faire de l’Internet, seulement du Web. Et pour ceux qui ont du mal, prenez quelques instants pour me relire ce billet, et reviendez après.

Donc, pour faire de l’internet sur les réseaux qui ne veulent pas, il est intéressant de faire croire qu’on va faire du Web, soit port 443 en mode TCP, mais d’y héberger notre service qui n’est pas du Web. Le problème qui survient très vite dans ce cas, c’est qu’en théorie, on ne peut exposer qu’un seul service à la fois sur un port donné. C’est là qu’Haproxy va nous aider.

La trousse à outils du load-balancing, et bien plus

J’ai déjà eu l’occasion de parler d’Haproxy par le passé, mais c’était à chaque fois pour évoquer des usages Web. Et il le fait très bien, c’est ce qu’on utilise en général sur les pare-feux « netfilter » qu’on déploie sur des plateformes VMware entre autres, mais c’est aussi le moteur qui est exploité au sein d’NSX Edge, la passerelle virtuelle de VMware pour ses solutions de clustering. À part que dans ce cas, on vous colle devant une interface aussi merdique que possible, où appliquer une configuration relève du miracle tellement tout est contre-intuitif. À tel point que l’astuce que je vous présente aujourd’hui n’est peut-être pas applicable sur NSX, alors que la technologie sous-jacente le permet, c’est dire.

Tout ça pour dire que l’application de load-balancing sait en faire beaucoup plus, notamment grâce au mode TCP, qui permet de traiter les paquets de manière un peu moins spécifique. Encore que là, on va le voir, il est possible d’appliquer des règles en fonction de l’analyse du contenus des paquets. C’est pas du DPI encore à ce niveau, on cherche pas à déchiffrer le contenu, juste les entêtes pour agir en conséquence.

Architecture

L’exemple d’aujourd’hui se base sur une configuration qui peut être simple, à savoir que tout tient sur le même serveur, mais ce n’est pas obligatoire. On a donc trois services, paramétrés de cette manière :

Sur la machine, seul le port 443 est ouvert au monde évidemment, ce qui permet de brouiller les pistes. Celui qui va vouloir scanner les ports pensera tomber sur un serveur web, et aura quelques difficultés. Et le comportement sera un peu bizarre s’il tente une connexion HTTPS classique, au mieux la session TLS va quand même démarrer (sauf si la connexion VPN repose sur un certificat client), au pire il aura une réponse étrange voire une simple déconnexion (RST).

Comme j’ai dit, c’est pour l’exemple, les services en question peuvent tout à fait se trouver sur d’autres machines sur un réseau privé par exemple. Et je ne vais pas plus que ça détailler la configuration de ces services, c’est très facile de trouver des ressources même en français.

Alors oui, je préviens, je déconseille du coup d’utiliser cette configuration pour ajouter aussi le support d’un serveur web. Déjà parce que la connexion TLS est déjà filtrée pour la partie OpenVPN, donc il faudrait encore creuser pour qualifier la différence entre les deux, mais surtout parce qu’en mode TCP, haproxy va certes renvoyer les paquets vers le serveur web, mais du coup ce dernier verra l’adresse IP d’haproxy en tant que source, et plus l’ip du client. Et comme haproxy ne fait pas la terminaison, il n’y a pas d’ajout d’entête HTTP X-Forwarded-For puisque le protocole est toujours chiffré à ce moment-là. Il y a potentiellement moyen de s’en sortir avec le TPROXY, mais ça sort du cadre de l’expérimentation. Vous êtes prévenu, attaquons les choses sérieuses.

La configuration

Pour la mise en place, ça va « simplement » reposer sur un frontend, celui qui écoutera sur le port 443, et deux backends, un pour ssh, un pour openvpn. Là encore, pas la peine de s’attarder sur la configuration des backends, car toute la beauté du fonctionnement réside dans le frontend, et de plusieurs concepts, dont les acl et l’analyse de contenus des paquets. On va y aller étape par étape avec une explication à chaque fois.

On commence par une détection d’une connexion TLS :

frontend 443
  tcp-request inspect-delay 15s
  tcp-request content accept if { req.ssl_hello_type 1 }

tcp-request permet de spécifier dans quel mode on bosse, et surtout comment on analyse les paquets (TCP et pas HTTPS directement), ici on laisse passer les paquets TLS de type « client hello » (type 1, si vous voulez laisser passer un paquet entrant de type « server hello » — c’est bizarre mais passons –, c’est type 2), et de ce que j’ai compris le délai permet d’éviter de confondre OpenVPN et HTTPS. Cette première étape est nécessaire pour pouvoir ensuite filter les paquets OpenVPN spécifiquement :

acl acl_proto_openvpn payload(0,2) -m bin 003c
  tcp-request content accept if acl_proto_openvpn

On retrouve ici la déclaration d’une ACL, comme on l’a fait par le passé, mais cette fois, le critère est assez velu. On analyse le contenu brut d’un paquet pour faire correspondre une séquence binaire au début du paquet. En effet, la charge d’un paquet TCP commence par un code qui correspond au type de protocole, 003c correspondant donc ici à OpenVPN.

Je vous l’ai dit, c’est velu. Fort heureusement, la détection d’OpenSSH est plus simple. Si vous avez déjà fait un coup de telnet sur un serveur OpenSSH, vous avez déjà vu que l’annonce du serveur est en clair, et il y a un élément facilement identifiable, qui est la version du protocole SSH. On peut dès lors non pas taper sur de la reconnaissance binaire, mais du plus humain avec une chaine de caractères :

acl acl_proto_ssh payload(0,7) -m str SSH-2.0
  tcp-request content accept if acl_proto_ssh

Et c’est tout. Pour chaque protocole on a défini un filtre avec l’ACL sur le contenu du paquet, et on force Haproxy à n’accepter que ce type de paquet avec tcp-request content accept. Ne reste plus qu’à « router » vers le service concerné :

use_backend host_ssh if acl_proto_ssh
  use_backend openvpn if acl_proto_openvpn

Et voilà, vous avez votre routeur maison de protocole pour contourner les limitations un peu pénibles de certains réseaux.

Je vous remet la configuration complète ici, pour que ce soit plus digeste si vous voulez copier/coller :

frontend 443
  #ssl client hello
  tcp-request inspect-delay 15s
  tcp-request content accept if { req.ssl_hello_type 1 }
  #OpenVPN
  acl acl_proto_openvpn payload(0,2) -m bin 003c
  tcp-request content accept if acl_proto_openvpn
  #OpenSSH
  acl acl_proto_ssh payload(0,7) -m str SSH-2.0
  tcp-request content accept if acl_proto_ssh

L’alternative SSLH

J’ai présenté haproxy parce que je le connais bien, et que j’ai kiffé quand un collègue m’a expliqué qu’il faisait ça sur son serveur. Alors évidemment avec mon organisation, j’ai mis plus de trois mois pour vous rédiger tout ça, mais voilà, c’est fait. Mais Haproxy n’est pas seul à permettre ce multiplexage de protocole.

Pour faire du SSH et du HTTPS, il y a SSLH, contraction d’SSL (nom original d’un protocole qui s’appelle désormais TLS, à la base du chiffrement d’HTTPS et d’OpenVPN) et d’SSH, pour l’ouverture sécurisée d’un shell. Et cerise sur le gâteau, chose que je ne savais pas avant d’avoir pratiquement fini d’écrire cet article, il semble qu’il supporte désormais aussi OpenVPN et même plusieurs autres protocoles. J’ai pas creusé, du coup, je vous laisse découvrir, mais pour des accès à une infra derrière une livebox, ça pourrait être plus intéressant que de multiplier les ouvertures de ports et les solutions type rebond/bastion. Reste qu’avec le HTTPS il y a toujours ces questions d’adresses IP source dans les logs, et de ce que j’ai lu, SSLH traite le problème de la même façon qu’Haproxy, à savoir TPROXY.

Vous l’avez peut-être déjà utilisé, ou alors, si vous le mettez en place, n’hésitez pas à partager vos retours, que ce soit ici en commentaire ou votre propre espace d’expression, c’est toujours sympa à voir en français 🙂

Gérer plusieurs versions de certains outils en ligne de commande

mercredi 15 avril 2020 à 18:30

C’est un problème qu’on rencontre pas forcément quand on gère que du perso, mais quand on bosse sur une quantité importante de projets clients, il arrive qu’on doive jongler, pour différentes raisons, avec plusieurs versions différentes d’outils divers et variés. Et souvent les « procédures d’installation » (télécharger, copier dans /usr/local/bin, j’appelle pas ça une procédure), ne prennent pas ce cas d’usage en compte. je vais donc faire un inventaire de ce que j’ai pu faire et que je fais encore aujourd’hui pour gérer ça.

Les utilitaires que je manipule ces derniers mois ne sont pas obscurs : terraform, ansible, git, kubernetes, helm, pour ne citer qu’eux, évoluent constamment, et apportent toujours plus de nouvelles possibilités. Sauf que ces outils ne servent qu’à exécuter du code qui a été écrit à un instant T, donc avec la version disponible alors. Ou pas, j’ai eu à bosser sur un projet terraform dont certains modules étaient encore figés à la syntaxe 0.11, donc pas le choix, sauf qu’en parallèle, un projet interne utilisait la syntaxe 0.12. Il a donc fallu trouver une solution simple.

Vous avez donc maintenant une meilleure idée, et quand le problème s’est reproduit pour d’autres outils, j’ai cherché et trouvé d’autres solutions.

Terraform : tfenv

C’est en effet probablement le premier pour lequel j’ai eu à chercher une solution qui n’était pas utilisable nativement, comme on le verra avec Ansible plus tard. Quand vous regardez la doc, c’est « téléchargez, copiez dans un dossier du PATH, enjoy ». Et démerdez vous avec ça. Remarquez qu’on trouve beaucoup trop cette solution basique avec les outils développés en Go, qui effectivement ne s’embarrassent pas trop de bibliothèques partagées car ils sont majoritairement compilés en statique, donc avec tout ce dont ils ont besoin. Ça vous fait un fichier binaire de plus de 100Mo, mais on va dire que c’est un détail (regardez pas de trop près les providers terraform, vous allez vite vous pendre).

Donc, pour pouvoir facilement switcher entre les versions de Terraform, et même gérer facilement les versions installées sur mon poste, j’ai découvert un petit utilitaire très pratique : tfenv. Il est utilisable sous Linux et Mac (et apparemment sous Windows, dans git-bash), et permet d’installer et de switcher facilement entre les versions de terraform. Le genre d’outil qu’on aurait aimé avoir en natif plutôt que du bête download de binaire, mais bon, on peut pas tout avoir.

Pour l’installation j’ai fait le feignant et je suis passé par yay sur Manjaro, mais les instructions disponibles sur le README sont faciles à suivre.

Ansible : les virtualenv à la rescousse !

Eh oui, Ansible est un outil écrit en Python, et j’avais parlé de comment utiliser les virtualenv très récemment pour utiliser youtube-dl sur le NAS de ma môman. Dans le cas d’Ansible, j’ai eu à jouer avec plus que la version, car là c’était en fonction de la version de Python directement que j’avais à switcher entre les virtualenv, certains modules utilisés n’étant compatibles qu’avec Python 2 (le mainteneur sait qu’il doit repasser dessus pour les passer en python 3, mais ça demande du temps qu’on facture pas au client, donc personne le fait – une sacrée connerie contre laquelle on se bat de plus en plus souvent…).

Sur une machine où vous avez les deux versions de Python d’installés, il faut donc vérifier si vous avez python2-virtualenv (souvent seulement appelé python-virtualenv) et python3-virtualenv, ou alors pour Python 3, reprendre la méthode avec le module intégré python3 -m venv.

~  .venv  ansible 
$ python --version
Python 3.8.2
 ~  .venv  ansible 
$ ansible --version
ansible 2.8.10
  config file = None
  configured module search path = ['/home/seboss666/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/seboss666/.venv/ansible/lib/python3.8/site-packages/ansible
  executable location = /home/seboss666/.venv/ansible/bin/ansible
  python version = 3.8.2 (default, Feb 26 2020, 22:21:03) [GCC 9.2.1 20200130]
 ~  .venv  ansible 
$ deactivate
 ~  .venv 
$ python -m venv ansible29
 ~  .venv 
$ source ansible29/bin/activate
 ~  .venv  ansible29 
$ pip install --upgrade pip
Collecting pip
  Using cached https://files.pythonhosted.org/packages/54/0c/d01aa759fdc501a58f431eb594a17495f15b88da142ce14b5845662c13f3/pip-20.0.2-py2.py3-none-any.whl
Installing collected packages: pip
  Found existing installation: pip 19.2.3
    Uninstalling pip-19.2.3:
      Successfully uninstalled pip-19.2.3
Successfully installed pip-20.0.2
 ~  .venv  ansible29 
$ pip install ansible
Collecting ansible
  Downloading ansible-2.9.6.tar.gz (14.2 MB)
     |████████████████████████████████| 14.2 MB 9.1 MB/s 
Collecting jinja2
  Using cached Jinja2-2.11.1-py2.py3-none-any.whl (126 kB)
Collecting PyYAML
  Using cached PyYAML-5.3.1.tar.gz (269 kB)
Collecting cryptography
  Downloading cryptography-2.9-cp35-abi3-manylinux2010_x86_64.whl (2.7 MB)
     |████████████████████████████████| 2.7 MB 9.3 MB/s 
Collecting MarkupSafe>=0.23
  Using cached MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl (32 kB)
Collecting six>=1.4.1
  Using cached six-1.14.0-py2.py3-none-any.whl (10 kB)
Collecting cffi!=1.11.3,>=1.8
  Using cached cffi-1.14.0-cp38-cp38-manylinux1_x86_64.whl (409 kB)
Collecting pycparser
  Using cached pycparser-2.20-py2.py3-none-any.whl (112 kB)
Installing collected packages: MarkupSafe, jinja2, PyYAML, six, pycparser, cffi, cryptography, ansible
    Running setup.py install for PyYAML ... done
    Running setup.py install for ansible ... done
Successfully installed MarkupSafe-1.1.1 PyYAML-5.3.1 ansible-2.9.6 cffi-1.14.0 cryptography-2.9 jinja2-2.11.1 pycparser-2.20 six-1.14.0
 ~  .venv  ansible29 
$ ansible --version
ansible 2.9.6
  config file = None
  configured module search path = ['/home/seboss666/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/seboss666/.venv/ansible29/lib/python3.8/site-packages/ansible
  executable location = /home/seboss666/.venv/ansible29/bin/ansible
  python version = 3.8.2 (default, Feb 26 2020, 22:21:03) [GCC 9.2.1 20200130]

Pour certains projets, comme le code repose aussi sur des sdk de cloud provider, je crée un venv dédié qui embarque à la fois ansible et le sdk/cli concerné, aws et azure majoritairement pour l’instant (j’ai commencé à découvrir Google Cloud Platform très récemment, rien de transcendant). L’aspect paradoxal de tout ça c’est que je peux avoir plusieurs fois la même version d’Ansible d’installée, pour différentes versions de Python et des dépendances associées. Ça consomme plus de disque, mais bon, j’ai plus de Windows pour m’emmerder avec ça et le SSD est loin d’être saturé, le coût est donc plus que supportable.

Kubernetes/helm, j’ai sorti l’artillerie lourde

Pour Kubernetes et Helm, je n’ai pas trouvé de méthode maison ou un outil léger adapaté comme pour Terraform. Par contre, je suis tombé sur la rolls, de celles qui pourraient au final remplacer aussi tfenv pour terraform, car elle repose sur un système de plugins.

asdf Version Manager est cette rolls. Je vous laisse regarder la liste des plugins pour comprendre la palette de possibilités de gestion d’outils, j’ai donc pour ma part pour l’instant utilisé ceux de kubectl et d’helm. kubectl parce que l’utilitaire pour manipuler ses cluster Kubernetes a une palette certes large de compatibilité entre versions serveur et client, mais y’a des limites, et si vous avez un kubectl en 1.16.x, et que vous avez le malheur de devoir manipuler un cluster qui est encore installé en 1.12.x, vous vous engagez sur une pente plus que glissante, car la version 1.16 a mis à la retraite bon nombre d’API qui étaient en service sur l’ancien. Helm parce qu’entre la version 2 et la version 3 c’est le jour et la nuit sur le fonctionnement, et que des packages installés avec la version 2 ne peuvent pas être gérés simplement de manière transparente du jour au lendemain avec la version 3. D’autant plus quand vous utilisez le provider pour terraform.

~ 
$ asdf plugin-add kubectl
initializing plugin repository...
Clonage dans '/home/seboss666/.asdf/repository'...
remote: Enumerating objects: 96, done.
remote: Counting objects: 100% (96/96), done.
remote: Compressing objects: 100% (84/84), done.
remote: Total 1743 (delta 41), reused 38 (delta 12), pack-reused 1647
Réception d'objets: 100% (1743/1743), 393.01 Kio | 1.36 Mio/s, fait.
Résolution des deltas: 100% (760/760), fait.
 ~ 
$ asdf list-all
No plugin given
 ~  ✘ 1 
$ asdf list-all kubectl
1.14.10
1.15.7
1.15.8
1.15.9
1.15.10
1.15.11
1.16.3
1.16.4
1.16.5
1.16.6
1.16.7
1.16.8
1.17.0-rc.1
1.17.0-beta.2
1.17.0-rc.2
1.17.0
1.17.1
1.17.2
1.17.3
1.17.4
1.18.0-alpha.1
1.18.0-beta.1
1.18.0-rc.1
1.18.0-alpha.2
1.18.0-beta.2
1.18.0-alpha.3
1.18.0-alpha.5
1.18.0
1.18.1
1.19.0-alpha.1
 ~ 
$ asdf install kubectl 1.16.8
Downloading kubectl from https://storage.googleapis.com/kubernetes-release/release/v1.16.8/bin/linux/amd64/kubectl
 ~ 
$ asdf global kubectl 1.16.8
 ~ 
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.8", GitCommit:"ec6eb119b81be488b030e849b9e64fda4caaf33c", GitTreeState:"clean", BuildDate:"2020-03-12T21:00:06Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"}
The connection to the server localhost:8080 was refused - did you specify the right host or port?

Et ça ce ne sont que les utilitaires, mais dans les plugins vous pouvez aussi bosser carrément avec des versions différentes de langages de programmation, comme nodejs, ruby, et j’en passe, c’est donc très pratique dans un environnement de développement, et pour se passer de docker qui a ses propres contraintes. Attention toutefois, asdf est vraiment pensé pour un usage sur poste local, ce n’est pas un outil de déploiement en production, je recommande vivement soit de passer par Docker, soit d’adapter l’environnement pour votre application en installant plus proprement (idéalement via package manager pour gérer les mises à jour auto). Je pense par exemple aux software collections sur Redhat/CentOS qui permettent de multiplier les versions de certains langages (coucou PHP).

Bref, s’il ne devait en rester qu’un, ça serait probablement celui-là. Surtout que si le plugin dont vous auriez besoin n’existe pas encore, vous avez tout à fait la possibilité de l’écrire vous-même 🙂

Et vous, vous faites comment ?

Mon manager repose désormais exclusivement sur Docker pour ce genre de besoins. Il garde soigneusement quantité de containers et d’images qu’il redémarre à la volée quand il en a besoin, mais je trouve la solution plus lourde et moins naturelle par rapport au reste de l’usage du système.

Mais vous avez probablement vos propres routines pour ce genre de situation, je suis curieux de les découvrir, alors, comment ça jongle ?

PS : le très partageur Cascador, qui a fait un petit namedrop sur systemd-nspawn, sans préciser qu’il a carrément fait un article dessus 🙂

Quelques astuces diverses, dix-huitième

dimanche 12 avril 2020 à 10:30

Cela fait beaucoup trop longtemps que je n’ai pas sorti de nouvel épisode de ces astuces en tout genre (Novembre 2019 !). Mais elles existent toujours, et voilà enfin un nouvel épisode.

Un nmap fonctionnel sur WSL

J’en ai parlé, j’ai pas mal expérimenté avec le WSL 1 sur mon installation de Windows à destination du PC de jeu, pour limiter mon recours à une machine virtuelle Linux. Parmi les problèmes/limitations que j’ai pu rencontrer, il y a l’utilisation d’nmap. En effet, le binaire Linux m’a gratifié d’une palanquée de messages d’erreur bien salaces. Pas étonnant, il cherche à demander des infos bas niveau au noyau Linux, qui n’existe pas…

J’ai du coup découvert qu’on pouvait lancer des binaires Windows depuis le WSL, et donc, la solution recommandée dans ce cas est d’installer la version Windows d’nmap depuis le site officiel et seulement lui, qui elle va utiliser les sous-systèmes du noyal Windows pour faire son job, sans erreur donc. Pour l’appeler ensuite de manière transparente, un alias suffit dans votre environnement :

alias nmap='"/mnt/c/Program Files (x86)/Nmap/nmap.exe"'

Je vous laisse adapter le chemin si vous avez modifié les points de montages pour une utilisation de Docker.

Fermer la fenêtre principale de Steam sous Manjaro Linux

Si vous êtes aussi sous Manjaro et que vous utilisez Steam, vous aurez certainement remarqué un comportement par défaut plutôt pénible par rapport à Windows : malgré la présence de l’icône de notifications, fermer la fenêtre principale ne fait que la réduire.

C’est une mesure prise à cause de certains bureaux où l’icône déconne et laisse traîner un process zombie à la fin, ce qui empêche de relancer correctement le client derrière. Mais on peut modifier ce comportement avec une variable d’environnement, et je vous recommande de la mettre justement dans /etc/environment :

STEAM_FRAME_FORCE_CLOSE=1

Normalement ce comportement est spécifique à Manjaro, mais si d’aventure vous le rencontrez ailleurs, vous savez par où commencer.

Correctement utiliser l’accélération du décodage vidéo Intel avec VLC

J’ai passé un peu de temps à pester contre ça, d’autant que c’est beaucoup mieux géré sous Windows. En effet, je pensais avoir suivi les recommandations du Wiki Archlinux, j’avais, droit à ça :

$ vainfo
vaInitialize failed with error code -1 (unknown libva error),exit

Et quand on lance VLC, dans les messages on peut voir ça :

[00007f6c9c001f70] glconv_vaapi_x11 gl error: vaInitialize: unknown libva error
[00007f6c9c001f70] glconv_vaapi_drm gl error: vaInitialize: unknown libva error
libva error: va_getDriverName() failed with operation failed,driver_name=i965

Moralité la conso CPU est bien vénère avec un VLC qui mange facile les trois quarts du CPU au global pour la lecture d’une vidéo full HD.

La solution : la variable d’environnement. Il suffit d’ajouter le bon nom à la variable LIBVA_DRIVER_NAME, et le tour est joué :

$ LIBVA_DRIVER_NAME=iHD vainfo
vainfo: VA-API version: 1.5 (libva 2.5.0)
vainfo: Driver version: Intel iHD driver - 1.0.0
vainfo: Supported profile and entrypoints
(...)

Et quand on lance VLC avec :

[00007fe6e590ee90] avcodec decoder: Using Intel iHD driver - 1.0.0 for hardware decoding

Je recommande de la coller dans /etc/environment, ça permet d’être le plus large possible dans sa prise en compte. Voilà, personne est foutu de se parler correctement pour s’identifier afin d’être exploité comme il faut. C’est la magie du libre. Ah et non, ça suffit pas pour que ça fonctionne sous Firefox, là c’est encore pire en terme de conso CPU, et j’ai pas encore réussi malgré une fois encore la présence des paquets.

Git : cloner une seule branche (pour un test)

Quand on veut gagner un peu de temps sur un simple test rapide autour d’un code d’un dépôt git, et que ce code se trouve dans une branche spécifique, on peut directement cloner cette branche-là uniquement :

git clone -b my-dev-branch --single-branch https://gitforge.domain/user/my_super_repo

En l’occurrence, je testais la branche d’un mec qui cherchait à dockeriser son appli et qui rencontrait des problèmes au build sous Manjaro 🙂 (et moi une appli JS, en temps normal je m’en approche pas, donc pas besoin de récupérer tout le dépôt pour un simple test, surtout sur la petite connexion de ma petite sœur).

Une déconnexion automatique sur vos sessions SSH inactives

Découvert chez un client y’a pas longtemps, si vous laissez une connexion SSH ouverte sans rien en faire, elle est déconnectée automatiquement au bout d’un certain temps. J’ai cherché comment ils faisaient, c’est via une variable d’environnement, soit dans le /etc/profile pour l’appliquer de manière globale, soit dans votre bashrc, pour que ça ne concerne que l’utilisateur :

export readonly TMOUT=900

Le temps est en secondes. Au passage, double astuce puisqu’on voit ici qu’on définit la variable en lecture seule.

Mise à jour du paquet AUR ttf-sil-fonts sur ArchLinux/Manjaro

Ce paquet, qui avait été laissé à l’abandon, a été repris récemment par un autre mainteneur. Mais le format a changé, avant il se chargeait directement de l’installation, maintenant c’est un meta-paquet qui installe chaque police qui se trouve dans un paquet indépendant. Ce qui cause des conflits avec des polices déjà installées. La solution la plus simple c’est de désinstaller le paquet, et de le réinstaller dans la foulée :

yay -R ttf-sil-fonts
yay -S ttf-sil-fonts

Ça vous évitera comme moi de faire des trucs sales à base de déplacement des fichiers qui existent déjà dans les dossiers cible 😀

Worms WMD et ArchLinux/Manjaro, c’est compliqué (mais ça se soigne)

Le jeu est disponible nativement sous Linux mais la maintenance par Team17 n’est pas vraiment au beau fixe. En particulier, avec les évolutions permanentes d’ArchLinux, c’est simple, par défaut le jeu ne démarre pas. Pour corriger, il faut modifier le script de lancement, pour qu’il ressemble à ça :

#!/bin/bash

GAMEPATH="$(dirname "$(realpath $0)")"
export LC_ALL=C
export LD_LIBRARY_PATH="${GAMEPATH}/lib:${LD_LIBRARY_PATH}"
export DBUS_FATAL_WARNINGS=0

chmod a+x ./Worms\ W.M.Dx64
./Worms\ W.M.Dx64

C’est plus fourni et surtout ça permet d’utiliser les bibliothèques Steam plutôt que les bibliothèques natives. Dans tous les cas, n’espérez pas faire des parties classées en ligne, la connexion aux serveurs Team17 ne fonctionne pas. Heureusement le multijoueur avec des amis fonctionne quand même, ouf.

Franciser Sublime Text ? C’est possible

Bon personnellement, ça ne m’empêche pas de continuer à bosser en anglais, mais en effet, pour ceux qui s’en servent, un reproche qui lui est souvent fait est d’être « english centric ». Par chance, avec la façon dont est construite l’interface, elle est hautement personnalisable. Et pour ça, il suffit d’installer le paquet LocalizedMenu avec Package Manager, et sélectionner la langue via le menu Preferences, et voilà :

Pour le reste, je vous laisse regarder le dépôt Git.

Lancer une commande originale et pas son alias

Vous le savez j’adore les alias de bash, j’en utilise pas mal. Le problème c’est que parfois on aurait besoin de comparer avec la commande « brute », fort heureusement, il n’y a pas besoin de détruire l’alias, il suffit de préfixer la commande avec un antislash :

Ça permet de voir parfois les problèmes visuels que les personnalisations engendrent 🙂

Kubernetes, communications réseau inter-containers dans un même pod

Un collègue m’a posé la question récemment, et j’avais pas la réponse, alors j’ai cherché. Il expérimentait k3s, et voulait déployer un ethercalc, qui utilise une appli nodejs et un serveur redis pour le stockage des classeurs. Hors il a mis les deux containers dans le même pod, donc pas de service pour le redis :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: calc
spec:
  replicas: 1
  selector:
    matchLabels:
      app: calc
  template:
    metadata:
      labels:
        app: calc
    spec:
      containers:
        - name: ethercalc
          image: audreyt/ethercalc:latest
          ports:
            - containerPort: 8000
          env:
            - name: REDIS_PORT_6379_TCP_ADDR
              value: redis
            - name: REDIS_PORT_6379_TCP_PORT
              value: "6379"
          imagePullPolicy: Always
        - name: redis
          image: redis:latest
          volumeMounts:
            - name: redis-data
              mountPath: /data
          imagePullPolicy: Always

On voit qu’il tente de mettre le nom du container dans la variable REDIS_PORT_6379_TCP_ADDR, et ça ne fonctionne pas. Et bien j’ai appris que dans ce cas, Kubernetes place les deux containers dans le même réseau, ce qui veut dire qu’on peut contacter le container voisin sur son port en utilisant « localhost » directement !


Voilà, c’est tout pour aujourd’hui, vous l’aurez compris, j’abandonne pas la série mais faut pas s’attendre à voir un nouvel épisode dans moins d’un mois 😀

Powerline.bash, le retour !

lundi 30 mars 2020 à 18:30

Pour ceux qui lisent le blog depuis un moment, vous savez que j’utilise Powerline pour décorer mon shell, ainsi que celui de mes machines virtuelles à la maison. Dans l’ensemble j’en suis très content, mais le projet qui m’avait lancé sur la personnalisation de mon shell, powerline.bash, est revenu sous mes yeux, et oui, j’ai craqué, j’ai décidé de basculer dessus. Voyons donc pourquoi.

Si vous avez relu mon billet d’origine, l’installation de Powerline, notamment pour avoir un statut git assez visuel est assez lourde, en gros, en plus des paquets powerline et powerline-fonts, il me faut en plus un paquet pip et une configuration maison plutôt chargée à pousser. Autant dire que le contenu du playbook ansible pour déployer tout ça est assez fat, mais bon, c’est pas non plus la mort.

Powerline a ses propres problèmes, et certains m’avaient d’ailleurs été relevés. Le principal, c’est la latence. Il arrive parfois qu’il mette un temps visible à rendre la main, ouvrir un nouveau shell, et le problème empire quand votre CPU est déjà particulièrement chargé comme c’est souvent le cas dernièrement sur mon laptop du boulot. J’ai en plus eu des soucis à l’époque de la bascule Python 3.7 > 3.8 sous Manjaro, ce qui m’avait poussé à devoir tout refaire (en gros j’avais plus de prompt le temps que je corrige). Je n’ai jamais réussi non plus à l’avoir sur deux lignes, et plusieurs tentatives pour personnaliser plus avant se sont toujours soldées par des échecs. Je ne pense pas être plus bête qu’un autre, mais là quand même… Il y a certainement d’autres contrariétés qui ne me reviennent pas en tête là tout de suite, mais voilà, j’ai été donc frustré plus d’une fois avec son utilisation.

« Ha, ha, ha, ha, staying alive… »

Et au gré de mes flux RSS, Etienne Bersac, le développeur de powerline.bash, a fait un journal sur linuxfr pour discuter des mises à jour. C’était l’occasion de découvrir que contrairement à ce que je pensais, je n’avais pas activé les notifications sur le dépôt, ça m’apprendra à être plus vigilant. Donc, depuis le temps, il y a eu pas mal de petits raffinements et de corrections, de nouveaux segments, cvia des contributions externes, et celui sur git a bien évolué. C’est beaucoup plus intéressant désormais.

J’ai donc retesté le bousin, l’installation et la configuration sont toujours aussi simples, ça tient à un git clone et l’ajout de deux lignes dans le bash_aliases. Dans mon cas évidemment, ça demande aussi de virer/commenter les lignes nécessaires à Powerline.

Je vais la faire courte, j’ai tout de suite été conquis. Certes, les détails concernant le statut du dépôt git sont un peu moins fournies (j’avais le nombre de fichiers avec leur statut quand le dépôt n’était pas à jour, ainsi que le nombre de commits à pousser), mais c’est désormais plus parlant, les couleurs sont mieux choisies, on voit qu’on a des trucs à pousser, il y a le support de plus d’icônes. Et c’est finalement largement suffisant pour éviter de lancer des commandes sans avoir bien vérifié le statut du dépôt auparavant, ça économise pas mal de commandes git status, toujours bon à prendre.

Dossier, venv python, statut git, tout ce qu’il faut quoi 🙂

Quant à la vitesse de chargement et de réponse, c’est évidemment le jour et la nuit. J’ai donc entrepris de rebasculer mon profil dessus sur tous mes serveurs. l’occasion de reprendre mes playbooks pour les remettre au gout du jour, cela faisait un moment qu’ils n’avaient pas été lancés, et j’ai également découvert plusieurs manques ou faiblesses (genre le playbook qui supprime la ligne pour charger acme.sh sur le bastion…). Petite particularité par rapport à la doc, j’ai opté pour un déploiement du dépôt dans /opt, comme ça il n’est cloné qu’une fois pour tous les utilisateurs que je modifie. Le module git d’ansible se chargera des pull la prochaine fois, et voilà.

Et je pense que je vais envisager de le pousser aussi sur mes serveurs « publics », comme celui que j’utilise pour ce blog (qui va vraiment avoir besoin qu’on lui refasse une beauté, ça devient intenable).

En tout cas, c’est du beau boulot, encore merci à Etienne, ainsi qu’aux contributeurs qui sont mentionnés dans le README. Je ne dis pas que j’en ferai partie dans un futur proche, mais j’avais déjà participé à l’époque en terme de remontée de bug sur Ubuntu 16.04 – eh oui, tant qu’il est supporté, on doit le prendre en compte, même s’il sent vraiment la naphtaline maintenant-, et j’ai le segment Kubernetes à tester sur le pc du boulot (pas encore à la maison, je pense qu’en termes de priorité la VM du blog est prioritaire). Donc y’a peut⁻être encore des trucs à remonter ou contribuer 🙂

Youtube-dl sur un NAS Synology, c’est possible !

mercredi 25 mars 2020 à 18:30

En partant chez ma mère pour mieux vivre le confinement prolongé qui se profile devant nous, j’ai embarqué son NAS trop longtemps en maintenance avec un disque dur neuf pour le remettre en service. Et parmi ce que j’ai prévu de lui faire faire, il y a la même chose que chez moi, sauf que le Download Station embarqué ne sait plus récupérer les vidéos sur YouTube. Qu’à cela ne tienne il y a une solution !

Le NAS

Le NAS est un ancien Synology DS215j. C’est un modèle pouvant accueillir deux disques, avec un processeur Armada 375 plus que poussif, et un système d’exploitation basé sur Linux mais avec une interface web de gestion qui est d’une lenteur hallucinante. Je l’avais acheté après la mort de mon serveur perso monté avec des composants d’occasion qui est en fait toujours en vie, seulement un des disques était mort, mais je n’avais pas eu suffisamment confiance pour relancer cette machine dont la consommation ne me convenait plus.

Ce NAS était équipé de deux disques de 2To, configurés en SHR, parce que Synology ne pose pas la question à l’installation et utilise son RAID maison. Déjà ça m’avait gonflé, et à l’époque je n’avais pas plus creusé que ça et je l’avais laissé en l’état. Mais avec la saturation des disques, et leur âge grandissant couplé au bruit plus important de leur mécanique, je l’avais embarqué pour lui refaire une santé et une upgrade de disque.

Cette période de maintenance s’est donc terminée avec la remise en service sur un unique disque dur de 4To, le seul en état de marche à disposition, qui était destiné à mon propre NAS, qui pourra attendre pendant mon absence.

DSM 6 sur ce NAS, c’est l’enfer

Et c’est peu de le dire. Si visuellement peu de choses ont changé dans l’interface du système d’exploitation de Synology, la gourmandise en performance est là : la moindre action fait grimper le CPU dans les tours, un simple listing des trois pauvres dossiers partagés créés suffit, c’est bien simple, chaque action prend plusieurs secondes pour voir son résultat. Et ce n’est pas que côté serveur, le navigateur en prend aussi pour son grade, je ne sais pas avec quels pieds de lépreux l’interface a été codée, mais c’est une catastrophe.

Malgré tout, les fonctionnalités sont là, à part que le Download Station ne sait plus récupérer les vidéos YouTube. Apparemment il ne repose pas sur youtube-dl comme Takeasy sur Asustor (mais qui n’a pas été mis à jour depuis plus d’un mois, ce qui fait que certains sites auparavant supportés ne fonctionnent plus).

« Oh mais y’a Python 3 ! »

La lumière au bout du tunnel 🙂 En effet, dans le gestionnaire de paquets de DSM, il est possible d’installer Python 3, en pus de Python 2 qui est déjà installé. L’installation via l’interface est simple, comme n’importe quel paquet. Reste ensuite à activer SSH et les home directory, pour ensuite se connecter à son compte en ligne de commande.

Youtube-dl s’installe via pip. Mais par défaut, pip ne semble pas disponible. Arf. Mais c’est partiellement faux. De toute façon, pour tout projet qui nécessite d’utiliser pip, il est recommandé de passer par un virtualenv, un environnement virtuel adapté à un projet en particulier. Et ça tombe bien, python 3 permet d’en créer d’une manière particulièrement simple :

seboss666@Mariz_NAS:~$ python3 -m venv yt

Et hop, quelques longues secondes après, on a un dossier yt qui contient notre virtualenv :

seboss666@Mariz_NAS:~/yt$ ll
total 36
drwxr-xr-x 7 seboss666 users 4096 Mar 22 22:53 .
drwxr-xr-x 5 seboss666 users 4096 Mar 22 22:51 ..
drwxr-xr-x 2 seboss666 users 4096 Mar 22 22:53 bin
drwxr-xr-x 4 seboss666 users 4096 Mar 22 22:53 etc
drwxr-xr-x 2 seboss666 users 4096 Mar 22 22:51 include
drwxr-xr-x 3 seboss666 users 4096 Mar 22 22:51 lib
-rw-r--r-- 1 seboss666 users   61 Mar 22 22:52 pip-selfcheck.json
-rw-r--r-- 1 seboss666 users   75 Mar 22 22:51 pyvenv.cfg
drwxr-xr-x 4 seboss666 users 4096 Mar 22 22:53 share

Ensuite on l’active comme n’importe quel venv :

seboss666@Mariz_NAS:~/yt$ source bin/activate
(yt) seboss666@Mariz_NAS:~$ pip --version
pip 7.1.2 from /volume1/homes/seboss666/yt/lib/python3.5/site-packages (python 3.5)

Notez le petit (yt) qui permet de visualiser qu’on est dans un virtualenv python. Et surprise, pip est bien présent ! Par contre il sent fort la napthaline. On va donc en profiter pour le mettre à jour, et tenter d’installer youtube-dl :

(yt) seboss666@Mariz_NAS:~$ pip install --upgrade pip
Collecting pip
  Downloading https://files.pythonhosted.org/packages/54/0c/d01aa759fdc501a58f431eb594a17495f15b88da142ce14b5845662c13f3/pip-20.0.2-py2.py3-none-any.whl (1.4MB)
    100% |████████████████████████████████| 1.4MB 45kB/s 
Installing collected packages: pip
  Found existing installation: pip 7.1.2
    Uninstalling pip-7.1.2:
      Successfully uninstalled pip-7.1.2
Successfully installed pip-20.0.2
(yt) seboss666@Mariz_NAS:~$ pip install youtube-dl
Collecting youtube-dl
  Downloading youtube_dl-2020.3.8-py2.py3-none-any.whl (1.8 MB)
     |████████████████████████████████| 1.8 MB 3.7 MB/s 
Installing collected packages: youtube-dl
Successfully installed youtube-dl-2020.3.8

Eh ben, ça semble parfait ! Il faut juste s’assurer d’un dernier détail. En effet, sur plusieurs sites pratiquant le HLS ou le DASH, la vidéo et l’audio sont séparés en flux distincts, et youtube-dl a l’habitude d’utiliser ffmpeg pour recoller les morceaux :

(yt) seboss666@Mariz_NAS:~/yt$ which ffmpeg
/bin/ffmpeg

Cool 🙂 Je ne sais par contre pas si c’est installé de base sur le NAS, ou si ça provient d’un autre paquet comme le serveur multimédia, installé afin de fournir du DLNA au lecteur Bluray, et qui a une option de transcodage vidéo, d’où le recours potentiel à ffmpeg. Dans le doute, vous pourrez vérifier par vous-même, moi c’est déjà installé et configuré je touche plus à rien.

Le problème de l’indexation multimédia

Eh oui, si ce n’est pas une astuce en vrac, c’est pas juste pour pouvoir vous faire l’historique du NAS et une critique de ses performances, vous le voyez à la simplicité ça aurait pu tenir en un seul paragraphe ou presque. Quand on télécharge un fichier avec Download Station, ou qu’on pousse un fichier par SMB (le partage réseau), le fichier est presque immédiatement disponible pour le lecteur Bluray. Malheureusement, pour une raison que j’ignore, ce n’est pas le cas pour les vidéos récupérées par youtube-dl, et de mémoire les vidéos poussées via rsync/ssh non plus.

Il faut donc, dans ce cas, forcer une réindexation qui va prendre plus ou moins de temps en fonction de la taille de la bibliothèque, et qui se déclenche avec la commande suivante :

(yt) seboss666@Mariz_NAS:/volume1/Download$ sudo synoindex -R all

Bon après, l’interface du lecteur Bluray LG est une honte et le rafraîchissement provoque une erreur qui demande de retourner à l’accueil pour refaire tout le chemin vers le dossier voulu. Mais ça fonctionne 🙂

Les NAS maison me manquent (et les vrais lecteurs multimedia aussi)

J’avoue, entre la puissance famélique, l’indexation sélective, et l’interface pénible du bluray, je regrette vraiment OpenMediaVault, minidlna et Kodi. Disposer d’un lecteur Bluray disposant d’une interface aussi propre que Kodi est illusoire, ne serait-ce que parce que ce dernier ne dispose pas de toutes les technologies pour lire des bluray pourris par des DRM qui imposent de payer des licences à sept chiffres, dont on devrait pourtant avoir les clés pour des raisons d’interopérabilité. VLC s’y est cassé les dents, notamment grâce aux pressions de Sony qui se gave en licences, et rien n’a bougé depuis (il faut dire que le marché stagne, voire baisse quand la VOD en streaming explose, donc sont pas pressés de filer les clés de la bagnole). Mon raspberry Pi sous LibreELEC me donne toujours entière satisfaction, sauf pour le plugin YouTube qui m’a poussé à me tourner vers d’autres solutions.

Quant à Openmediavault, le projet est toujours maintenu et toujours aussi intéressant, le problème, c’est que le matériel pour le faire tourner sera forcément plus volumineux, consommateur de ressources, et potentiellement beaucoup plus cher. Même si en termes de consommation on sera proche avec mon microserveur, atteindre un tarif de 180€ pour la base sans les disques relève du miracle, puisque c’est juste le prix de la carte mère avec CPU soudé sans la RAM, sans le boitier, sans l’alimentation, autant d’éléments inclus pour le prix. Avec un CPU x86 toutefois, on aurait accès à beaucoup plus de puissance et d’usages, ce que j’avais fini par faire à l’époque sur mon NAS maison, avec l’ajout d’une machine virtuelle en plus du reste.La problématique du CPU dans les NAS a parfaitement été analysée par David, je vous laisse lire son dossier si vous souhaitez creuser le sujet. Minidlna fonctionne quelque soit la méthode pour ajouter un fichier, puisque c’est le noyau et uniquement lui qui prévenait de l’arrivée d’un fichier, peu importe qu’il soit déposé via une application, un partage réseau, un transfert SSH.

Bref, comme trop souvent avec l’informatique, la liberté et le confort ont un prix, et pour les usages de ma mère, la liberté et la performance ne sont pas des priorités absolues, donc on va s’en contenter. Par contre, son lecteur Bluray/home cinema donne quelques signes de fatigue, et ça coûte cher à remplacer, j’espère que ça tiendra encore quelques années.