Daily - GuiGui's Showhttps://shaarli.guiguishow.info/Daily shared linksen-enhttps://shaarli.guiguishow.info/ GuiGui's Show - Sunday 25 April 2021 https://shaarli.guiguishow.info/?do=daily&day=20210425 https://shaarli.guiguishow.info/?do=daily&day=20210425 Sun, 25 Apr 2021 00:00:00 +0200 sleepd : exécuter une action (ex : éteindre) après un délai d'inactivité utilisateur sur un parc Ubuntu 20.04 Sun Apr 25 15:02:49 2021 -
http://shaarli.guiguishow.info/?ohmhqg


Nous avons plusieurs centaines de machines Ubuntu 20.04 qui ne sont pas attribuées à un utilisateur précis.

**Nous voulons éteindre automatiquement ces machines après une période d'inactivité**.

Critères :
  * Je parle d'inactivité "tout court", pas inactivité sur batterie ;
<br />
  * Logiciel sans interface graphique doté d'un fichier de configuration (que l'on peut donc modifier avec Puppet).

<br />
### sleepd

**`sleepd` est packagé dans Debian GNU/Linux, mais il ne l'est plus dans Ubuntu** après la version 14.04.

**Le paquet Debian fonctionne très bien sur Ubuntu** :
  * `apt download sleepd` depuis une machine Debian ;
<br />
  * `apt install libx86-1 pm-utils vbetool` sur une machine Ubuntu afin d'installer les dépendances ;
<br />
  * `dpkg -i sleepd_2.10_amd64.deb` ;
<br />
  * Ajouter les options que l'on veut dans `/etc/default/sleepd` : « -u » pour le délai avant action ; « -s /sbin/poweroff » pour éteindre la machine au lieu de la mettre en veille ; **« -w » pour comptabiliser également l'activité sur d'éventuelles sessions SSH** ;
<br />
  * `systemctl restart sleepd`.

<br />
### Alternatives

**[autopoweroff](https://github.com/deragon/autopoweroff/)**. Trop complet pour notre usage (**il peut vérifier la consommation CPU et la joignabiltié de machines** dont celle-ci dépend avant d'exécuter une action) donc fichier de configuration plus touffu.

CRON. Au début, je voulais écrire une tâche planifiée qui aurait tourné toutes les heures non-ouvrées et qui aurait utilisé la commande `w` pour déterminer si des utilisateurs ont eu une activité récente avant d'éteindre. Deux inconvénients : 1) pourquoi réinventer la roue ? ; 2) si l'on veut désactiver l'arrêt automatique lors d'une maintenance, il faut commenter le contenu d'un fichier, ce qui est moins pratique que `systemctl stop sleepd`.


]]>
GuiGui's Show - Saturday 24 April 2021 https://shaarli.guiguishow.info/?do=daily&day=20210424 https://shaarli.guiguishow.info/?do=daily&day=20210424 Sat, 24 Apr 2021 00:00:00 +0200 Can't access SMB file server - Windows Server | Microsoft Docs Sat Apr 24 19:41:07 2021 -
https://docs.microsoft.com/en-US/troubleshoot/windows-server/networking/dns-cname-alias-cannot-access-smb-file-server-share


Le protocole SMB version 1 utilisé au sein d'un domaine winwin (donc Kerberos) ne gère pas nativement les alias DNS (CNAME), il faut ajouter une clé de registre sur le serveur de fichiers ou enregistrer l'alias comme nom de service (SPN) Kerberos.

L'absence de prise en charge des alias DNS se constate aussi avec un client winwin 7 / 10 qui tente, en vain, de monter, en SMBv3, un partage CIFS exporté par un NAS Dell EMC Unity qui est membre d'un domaine Samba AD DC. Dans ce cas, impossible d'ajouter une clé de registre puisque le serveur de fichiers est le NAS Unity (et que la clé de registre fonctionne uniquement pour SMBv1). Il doit y avoir un moyen d'ajouter un Service Principal Name (SPN) Kerberos pour l'alias, mais nous n'avons pas creusé.


Suppression / copie récursive entraînant le gel d'un partage NFS = éventuel problème avec les options NFS rsize / wsize

Sat Apr 24 18:51:31 2021 -
http://shaarli.guiguishow.info/?mZYmag


**On peine à supprimer récursivement (`rm -r`) plusieurs arborescences plus ou moins touffues sur un partage NFS version 3**. Idem pour copier récursivement (`cp -a`) des arborescences. **La suppression ou la copie s'arrête sur un fichier, jamais le même** puisque plusieurs arborescences. Peu importe sa taille, ancienneté, etc., a priori. **Impossible dès lors d'utiliser le point de montage** (depuis la machine qui supprime / copie, bien entendu, pas depuis toute machine qui monte le partage). **Le problème se produit quasiment chaque jour**.

**Solution : monter le partage NFS en retirant les options `rsize=32768,wsize=32768`** et laisser agir la négociation automatique.

**Explication ? Aucune idée**.

On notera qu'**autofs est d'aucune utilité dans ce genre de blocage NFS**.

Plus de détails sur le contexte ? OK.

On utilisait ces options (et ces valeurs) avec nos anciens NAS (marques : NetApp et Nexenta). On ne les utilise plus sur notre NAS actuel (Dell EMC Unity) même si elles fonctionnaient durant nos tests.

Une machine physique Debian 7 montait un volume en ISCSI depuis notre ancien NAS Nexenta et elle l'exportait en CIFS (parce que le CIFS de notre NAS Nexenta ne fonctionnait pas, probablement car nous n'avions pas de contrôleur de domaine winwin ni Samba AD DC) et en NFSv3 vers une machine virtuelle d'administration du contenu du volume disque (l'usage d'ISCSI, qui exporte au niveau bloc, empêche, par nature, de monter le volume en NFS depuis le NAS). Cette VM d'administration montait le partage avec les options rsize et wsize sus-exposées. Aucun problème durant plus de 5 ans.

Nous avons cloné + virtualisé la machine physique Debian 7. Elle monte le même volume ISCSI, mais elle le monte depuis notre nouveau NAS Dell EMC, et elle l'exporte en CIFS (le temps de migrer nos utilisateurs, l'alias DNS avec lequel sont configurées les machines de nos utilisateurs ne pouvant être repris par notre nouveau NAS car [la négociation SMB échoue car le client Kerberos du NAS refuse l'incohérence entre l'alias et le nom réel du service SMB](/?wnkrlw), et l'ancien nom réel n'a plus de sens avec l'arrivée du nouveau NAS donc nous voulions pas le conserver) et en NFS à la même machine d'administration. Dès lors, cette machine d'administration a rencontré le problème sus-exposé. Le retrait des options entraîne une négociation automatique rsize=1048576,wsize=1048576 d'après `cat /proc/mounts`, soit bien plus que ce qu'on paramétrait à la main.

Deux changements entre avant et après : virtualisation de l'exportateur NFS et changement de l'initiateur ISCSI (de NAS, quoi). La logique impose de suspecter plutôt le deuxième. D'autant que nous n'utilisons plus rsize/wsize pour monter du NFS directement depuis notre nouveau NAS. On peut supposer qu'un enchaînement rsize/wsize fixées à 32 k + ISCSI ne convient pas à notre NAS Dell Unity.


]]>
GuiGui's Show - Thursday 22 April 2021 https://shaarli.guiguishow.info/?do=daily&day=20210422 https://shaarli.guiguishow.info/?do=daily&day=20210422 Thu, 22 Apr 2021 00:00:00 +0200 sql - Save PL/pgSQL output from PostgreSQL to a CSV file - Stack Overflow Thu Apr 22 22:48:46 2021 -
https://stackoverflow.com/questions/1517635/save-pl-pgsql-output-from-postgresql-to-a-csv-file


Exporter le résultat d'une requête SQL dans un fichier CSV avec PostgreSQL : `Copy (<REQUÊTE_SQL>) To '/tmp/<FICHIER_SORTIE>.csv' With CSV DELIMITER ',' HEADER;` depuis `psql`.


]]>
GuiGui's Show - Sunday 18 April 2021 https://shaarli.guiguishow.info/?do=daily&day=20210418 https://shaarli.guiguishow.info/?do=daily&day=20210418 Sun, 18 Apr 2021 00:00:00 +0200 Redémarrer automatiquement un démon sysvinit crashé avec systemd Sun Apr 18 20:29:30 2021 -
http://shaarli.guiguishow.info/?T1E7vA


Depuis quelques mois, nous avons un serveur coturn installé depuis les dépôts Debian GNU/Linux. Implémentation de [TURN](https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT), l'un des nombreux palliatifs pour tenter de faire fonctionner des logiciels multimédias pair-à-pair avec du NAT au milieu.

**Ce service se vautre plusieurs fois par semaine**. Évidemment, rien dans son journal. Sauf aujourd'hui : segfault. Mes recherches sur le web retournent rien (ou des paths vieux de 5-7 ans, qui ont donc été intégré depuis, en ce qui concerne l'erreur de segmentation). On pourrait lancer coturn en mode ultra-verbeux (« -V »), sortir `gdb` (pour la segfault), etc. Mais en attendant ?

Pour ces cas-là, **systemd propose `Restart=on-failure`, c'est-à-dire redémarrer un service à chaque fois qu'il crashe**.

J'utilise ça dans des units systemd [depuis plus de 5 ans](https://gitlab.netlib.re/arn/arn-confs/-/blob/master/routing/looking-glass/bird-lg-proxy.service). Mais, dans Debian, **coturn est livré avec un script sysv qui utilise `start-stop-daemon`. Est-ce que ça fonctionne ? Oui**.

Utiliser la commande `systemctl edit coturn.service`.

Saisir :

    [Service]
    RemainAfterExit=no
    Restart=on-failure
    RestartSec=10s

Enregistrer.

Désormais, **`systemctl status coturn` affiche deux lignes supplémentaires : « Drop-In: /etc/systemd/system/coturn.service.d / override.conf »**.

**« RemainAfterExit » est nécessaire**, sinon systemd ne fait pas le job.

« RestartSec » n'est pas nécessaire mais laisse un peu de répit à coturn pour démarrer et éviter une boucle de redémarrage (systemd essaye de faire redémarrer un service en boucle, jusqu'à une limite pré-définie et surchargeable, après quoi il laisse le service HS, ce que je ne veux pas).

Si l'on veut **tester, on remplace « on-failure » par « always » puis `killall coturn`**.


Ubuntu GNU/Linux : ajouter des utilisateurs LDAP / Samba 4 AD DC à un groupe local

Sun Apr 18 19:44:03 2021 -
http://shaarli.guiguishow.info/?OUGfLg


**Sur notre parc Ubuntu GNU/Linux, l'authentification des utilisateurs pour l'ouverture de session se fait auprès de notre domaine Samba 4 AD DC** (et sur un OpenLDAP auparavant).

**On voudrait ajouter tous les utilisateurs du domaine à des groupes locaux** (qui n'existent pas dans notre domaine). On ne peut donc pas utiliser `/etc/group` puisque l'utilisateur est enregistré dans une autre base de données.

Quel intérêt de faire ça ? **Permettre à nos utilisateurs d'utiliser des logiciels qui réclament l'appartenance à un groupe local**. Exemple : **il faut être membre du groupe « vboxusers » pour avoir le droit de connecter des périphériques USB** (clé USB, webcam, etc.) **à une machine virtuelle VirtualBox**. On n'a **pas envie de pourrir notre domaine avec des goupes**, sans compter que **VirtualBox réclame une appartenance au groupe « vboxusers », pas au groupe « vboxusers@domaine.monorganisation.example »**).

Comme d'hab, **PAM vient à notre rescousse avec son [module pam_group](https://linux.die.net/man/5/group.conf)**.

D'abord, **on ajoute une ligne** `*;*;*;Al0000-2400;vboxusers` **dans le fichier `/etc/security/group.conf`**. On peut restreindre l'application de la règle à certains services PAM (sshd, par exemple), c'est le premier champ. Ou à certains terminaux (deuxième champ). Ou à certains utilisateurs / groupes d'utilisateurs (troisième champ). Que à certains horaires (quatrième champ), ici tous les jours (« Al »), de 0 h à 24 h (0000-2400).

Ensuite, il faut **ajouter pam_group à la liste des modules PAM exécutés sur le système**. Par défaut, il est appelé depuis le fichier `/etc/pam.d/login` donc l'ajout de groupes fonctionne depuis les tty (ctrl+alt+Fx), mais pas sur une connexion SSH ou depuis un émulateur de terminaux lancé depuis l'interface graphique (gnome-terminal, etc.). Pour corriger cela, **j'ajoute une ligne `auth optional pam_group.so » à la fin de `/etc/pam.d/common-auth`**. Attention : si tu utilises pam_script, qui permet de lancer un script lors de l'authentification, de l'ouverture / fermeture de session, **il faut que pam_group soit appelé avant pam_script sinon l'utilisateur ne sera pas ajouté aux groupes**.

**Il faut redémarrer le système pour que la modification devienne effective**. Fermer la session ne suffit pas. Redémarrer le gestionnaire d'affichage (gdm3, dans mon cas) ne suffit pas.

Note : [un bug dans systemd empêchait l'ajout de groupes par pam_group lors d'une ouverture de session graphique](https://bugs.launchpad.net/systemd/+bug/1762391). Il est corrigé depuis longtemps, y compris dans Ubuntu 20.04.

Merci Alex d'avoir mis ça en prod'.


Commande mysql sur un serveur avec plusieurs instances MariaDB : préciser le port avec « -P » ne suffit pas pour se connecter à la bonne instance

Sun Apr 18 18:34:14 2021 -
http://shaarli.guiguishow.info/?BklOtw


Nous avons **un serveur avec plusieurs instances de MariaDB. Une instance = un processus**, un port TCP, un fichier de configuration dédié, etc.

Sur ce serveur, si l'on tape la commande `mysql -P <numéro_port_instance> -u <user> -p <nom_bdd>`, MariaDB nous retourne l'erreur « ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory" ».

Si l'instance par défaut (celle qui écoute sur tcp/3306 / /var/run/mysqld/mysqld.sock) est toujours active, l'erreur est, en toute logique, « ERROR 1045 (28000): Access denied for user `<user>'@'localhost' (using password: YES) », car on tente de se connecter à l'instance par défaut.

**Le paramètre « -P », qui permet de préciser le port TCP à utiliser, ne se suffit pas à lui-même : il faut ajouter `--protocol=tcp`**.

**Ou utiliser la socket UNIX de l'instance** à laquelle on veut accéder avec `-S /var/run/mysqld/<socket>`.


Interface FOG lente lors d'un déploiement ? « Storage node » rémanent ?

Sun Apr 18 18:14:44 2021 -
http://shaarli.guiguishow.info/?qoFpnA


Quand on crée une tâche de déploiement d'une image disque (sur une seule machine, en unicast, ou sur une partie du parc, en multicast, même combat), l'interface web de notre serveur [FOG](https://fogproject.org/) (Free and Opensource Ghost), met énormément de temps (> 30 secs) à répondre pour annoncer que la tâche est créée.

Si l'on n'attend pas, que l'on va dans l'onglet « Tasks », on voit que la tâche est créée.

Origine du problème : **un « storage node » apparaît toujours dans la liste alors qu'il n'existe plus**. L'image disque que l'on veut déployer ne dépend pas de ce serveur, mais sa suppression depuis l'interface web de FOG résout la lenteur de celle-ci.


Comment le mode promiscuous d'une carte réseau est activé par Linux ?

Sun Apr 18 17:06:58 2021 -
http://shaarli.guiguishow.info/?uTSqHg


Après avoir voulu me remémorer [comment fonctionne une capture réseau du point de vue du noyau Linux](/?mJuAfA), je me suis interrogé sur l'activation, en détail, du mode promiscuous.

### Définition

**Une carte réseau Ethernet fait remonter au système d'exploitation uniquement les trames Ethernet qui lui sont destinées. Le tri est opéré sur l'adresse MAC de destination**. Sont conservés les paquets dont l'adresse MAC est celle de la carte réseau, l'adresse broadcast (FF:FF:FF:FF:FF:FF), ou l'une des adresses multicast (01:00:5E:XX:XX:XX pour IPv4, 33:33:XX:XX:XX:XX pour IPv6).

**Ce filtrage est effectué matériellement par la carte réseau**.

**Le mode promiscuous permet de retirer ce filtrage**, donc d'écouter tout ce qui passe sur le réseau.

Bon, il faut relativiser :
  * **À l'époque des réseaux équipés avec des hubs ou avec une topologie en bus, on recevait tout le trafic** réseau de toutes les machines du réseau.
<br />
  * **Sur les réseaux d'aujourd'hui, équipés avec des switchs, on reçoit uniquement le trafic destiné à la machine, broadcast, multicast** ou autre (01:80:C2:XX:XX:FF pour LLDP / STP / IEEE1905, etc.). Le seul moment où un switch fait fuiter du trafic unicast, c'est quand il ne connaît pas l'association entre une adresse MAC et un port ou quand sa table de correspondance est pleine.


<br />
### Pratique

**Le mode promiscuous est global à une interface réseau** : exécuter un `tcpdump -p` (on demande à ne pas activer le mode promiscuous) à côté d'un `tcpdump` (mode promiscuous activé) est vain : quel que soit l'ordre de lancement des commandes, le `tcpdump -p` verra les paquets qui ne sont pas destinés à la machine tant que le `tcpdump` (promiscuous) est en cours d'exécution.

**Voir si l'une des interfaces réseau du système est en mode promiscuous** : `ip -d l sh | grep -B 1 promiscuity`. Si le nombre affiché est supérieur à 1, alors plusieurs applications (+ le noyau voir ligne suivante) ont activé le mode promiscuous.

**Activer le mode promiscuous sans passer par libpcap** : `sudo ip l set promisc on dev <INTERFACE>`. Pour le désactiver : `sudo ip l set promisc off dev <INTERFACE>`.


<br />
### Promiscuous ne voit pas tout

**Le mode promiscuous ne permet pas de voir TOUT le trafic réseau adressé à la machine. Une carte réseau peut filtrer matériellement le trafic qu'elle juge invalide** : [toute trame 802.1Q quand aucun VLAN est configuré sur le système](https://unix.stackexchange.com/questions/353097/network-interface-receives-no-frames-unless-in-promiscuous-mode), [trames réseaux trop courtes](https://isc.sans.edu/forums/diary/Not+all+Ethernet+NICs+are+Created+Equal+Trying+to+Capture+Invalid+Ethernet+Frames/25896/) ou dont la somme de contrôle est incorrecte, etc.


<br />
### Linux filtre aussi

**Tous les paquets qui arrivent sur une interface configurée en mode promiscuous ne parviendront pas jusqu'aux logiciels "serveurs" en écoute, car le noyau fait le tri**.

Le tri le plus simple à mettre en évidence est que, si le transfert de paquets IP n'est pas activé (/proc/sys/net/ipv4/ip_forward = 0), alors tous les paquets IP dont l'adresse IP de destination n'est pas l'une des IPs de la machine (multicast inclus) seront détruits. Ils n'arriveront même pas jusqu'à la chaîne FORWARD de Netfilter/iptables. Il doit exister d'autres filtrages.


<br />
### Et donc, comment le mode promiscuous est activé par la libpcap ?

Si l'on regarde le [code](https://github.com/the-tcpdump-group/libpcap/blob/master/pcap-linux.c#L2529), la libpcap (utilisée par `tcpdump`, `wireshark`, etc.) utilise la fonction système `setsockopt()` pour positionner l'option. Il ne reste plus qu'à remonter le code de Linux.
  * `setsockopt()` est une fonction implémentée pour chaque famille/protocole. [Une socket libpcap est de type AF_PACKET / PF_PACKET](/?mJuAfA), donc c'est la fonction `packet_setsockopt()` située dans le fichier net/packet/af_packet.c qui est utilisée. Elle appelle `packet_mc_add()` qui appelle `packet_dev_mc()`, toujours dans af_packet.c.
    * `dev_set_promiscuity()` dans net/core/dev.c est appelée et elle appelle **`__dev_set_promiscuity()` toujours dans net/core/dev.c. On notera que c'est cette fonction qui journalise « device XXXX entered promiscuous mode » dans kern.log**.
      * `__dev_set_promiscuity()` appelle `dev_change_rx_flags()` (toujours dans net/core/dev.c) qui appelle `ndo_change_rx_flags`. Le pilote peut implémenter une fonction (ou non) pour remplacer celle par défaut et l'enregistrer dans la structure netdev_ops de la structure net_device. Exemple : le pilote e1000e n'implémente pas cette fonction.
<br />
      * `__dev_set_promiscuity()` appelle `dev_set_rx_mode()` (toujours dans net/core/dev.c) qui appelle `ndo_set_rx_mode()`. Le pilote e1000e la remplace avec `e1000e_set_rx_mode()` (« .ndo_set_rx_mode = e1000e_set_rx_mode, ») dont le commentaire indique « e1000e_set_rx_mode - secondary unicast, Multicast and Promiscuous mode ». Cette fonction met à jour les registres de la carte réseau et, surtout, restaure+écrit les adresses multicast et unicast quand on sort du mode promiscuous.


Comment fonctionne une capture réseau dans le noyau Linux ? À quel endroit du noyau le trafic est-il capturé par la libpcap ?

Sun Apr 18 16:26:08 2021 -
http://shaarli.guiguishow.info/?mJuAfA


Je ne me souvenais plus : comment fonctionne une capture réseau avec la libpcap (`tcpdump`, `wireshark`, etc.) dans le noyau Linux ? À quel endroit du noyau le trafic est-il capturé par la libpcap ?

**Explication concise dans les [pages 10-12 de ce document](https://linuxplumbersconf.org/event/4/contributions/489/attachments/242/423/bpf-packet-capture.pdf)** que l'on peut recouper avec le [code Linux de la libpcap](https://github.com/the-tcpdump-group/libpcap/blob/master/pcap-linux.c).

En gros :
  * **Création d'une socket de type RAW** (entête Ethernet conservé), famille d'adresses **AF/PF_PACKET** (contournement de la partie TCP/IP de la pile réseau), **protocole ETH_P_ALL** (tous les protocoles). Dans le noyau (Linux), **le protocole PF_PACKET, en tant que protocole générique, est traité très tôt par la pile réseau, après que le pilote de la carte réseau ait copié le paquet en RAM, et bien avant la couche IP** ([schéma](https://www.linuxjournal.com/article/5617)) et [Netfilter](https://superuser.com/questions/925286/does-tcpdump-bypass-iptables) (le pare-feu de Linux). On voit la socket dans `/proc/<PID_tcpdump>/fd` ;

    * Détails : la carte réseau émet une [IRQ](https://fr.wikipedia.org/wiki/Interruption_mat%C3%A9rielle) matérielle. Son pilote la traite en créant un espace mémoire de type sk_buff (réprésentation noyau d'un paquet réseau), en copiant le paquet depuis le tampon de la carte réseau vers l'espace mémoire, et en appelant netif_rx(), la fonction noyau générique de réception d'un paquet réseau. Cette dernière gère la congestion (celle liée aux IRQ, pas la congestion TCP), met le traitement du paquet dans la file d'attente d'un CPU, et génère une IRQ logicielle (soft IRQ). La fonction net_rx_action() traite les IRQ logicielles liées au réseau. Entre autres, elle appelle la fonction qui permet de traiter le protocole niveau 3 (IP, IPX, etc.). ("Récemment", c'est aussi elle qui peut se retrouver à déclencher la fonction poll() de récupération d'un paquet dans le tampon d'une carte réseau.) En tant que protocole générique, PF_PACKET est traité ici et prioritairement par la fonction packet_rcv()… qui duplique le paquet (si un filtre ne le supprime pas avant) afin qu'il soit aussi traité par le "vrai" gestionnaire du protocole réseau de niveau 3 (majoritairement IP donc ip_rcv() ‒ dont la fin d'exécution déclenche le prerouting de Netfilter ‒). [Source 1](http://gauss.ececs.uc.edu/Courses/c4029/labs/netif_rx.html). [Source 2](http://www.embeddedlinux.org.cn/linux_net/0596002556/understandlni-CHP-10-SECT-7.html).

  * **Association de la socket à une interface réseau** (bind()) ;
<br />
  * Activation éventuelle du [mode promiscuous](/?uTSqHg). `tcpdump -p` permet de ne pas l'activer ;
<br />
  * Application d'un éventuel filtre BPF/LSF (kernel-land) sur la socket. `tcpdump -d` affiche le bytecode BPF ;
<br />
  * Activation d'un espace mémoire partagé kernel/user-land afin d'éviter des copies inutiles du paquet. [Détails](http://paul.chavent.free.fr/packet_mmap.html) ;
<br />
  * Lire les paquets reçus.


]]>
GuiGui's Show - Saturday 10 April 2021 https://shaarli.guiguishow.info/?do=daily&day=20210410 https://shaarli.guiguishow.info/?do=daily&day=20210410 Sat, 10 Apr 2021 00:00:00 +0200 Proxmox : bridge + politique de filtrage REJECT côté hyperviseur + VM à faible trafic = « connection refused » Sat Apr 10 23:05:00 2021 -
http://shaarli.guiguishow.info/?yIX2dA


**Résumé** : si tu utilises le **pare-feu proposé par la [solution de virtualisation Proxmox](https://www.proxmox.com/en/proxmox-ve)** (c'est juste une surcouche à Netfilter / iptables) avec une **politique "REJECT"** (jeter les paquets non désirés en prévenant leur émetteur), que tes **VMs accèdent au réseau via un bridge** GNU/Linux et que, **par intermittence, tes tentatives de connexion** (SSH, par exemple) **à une machine virtuelle à très faible trafic se terminent** sans raison apparente en **« connection refused »**, il est possible que **le filtrage Proxmox activé sur une autre VM rejette la connexion** à cause d'un bridge qui n'a plus la VM légitime dans sa table de commutation (le trafic est alors dupliqué, par le bridge, à l'ensemble des VMs, et le pare-feu côté hyperviseur rejette illégitimement la connexion entrante).

C'est l'occasion de réviser les bases : table ARP, **table de commutation, durées de rétention des entrées de chaque table** (ARP Linux = potentiellement plusieurs heures), **comportement d'un switch / bridge quand sa table MAC est incomplète**, rappel que **toute machine peut clôturer une connexion qui ne lui est pas destinée mais qui lui parvient**, etc.

**Solutions possibles : politique de filtrage "DROP"** (par défaut dans Proxmox) ou harmoniser la durée de rétention des tables ARP et MAC (si on le peut, car un switch physique n'est pas forcément paramétrable) ou fournir aux VMs **un accès au réseau via un routage IP** / niveau 3 (plus de bridge / niveau 2) ou ajouter un filtrage niveau 2 (`ebtables`) complexe.


<br />
**Soit un serveur dans une machine virtuelle sur un hyperviseur Proxmox. Depuis une machine distante, on supervise son port SSH** avec [Picomon, un outil de supervision léger](https://gitlab.netlib.re/arn/picomon) qui utilise lui-même check_ssh de nagios/monitoring-plugins, une valeur sûre. Une vérification tous les quarts d'heure.

Surprise : **parfois, la vérification retourne une erreur « connection refused »**. Lancé sur la machine de supervision, `tcpdump` voit un paquet TCP avec le drapeau RST en réponse au SYN initial. Ça ne devrait pas puisqu'il n'y a aucun changement côté serveur (sshd est toujours lancé) ni aucun filtrage temporaire de type fail2ban ni cookies TCP (activés par Linux quand il y a trop de paquets TCP avec le drapeau SYN qui entrent sur la machine, car c'est le signe d'une potentielle attaque par saturation des états TCP) ni…

Même s'il y a une grande part d'aléatoire (en apparence…), **le problème est reproductible** avec le client OpenSSH (`ssh` sous GNU/Linux et \*BSD) et `telnet`. **Depuis plusieurs points du réseau**, tous chez des Fournisseurs d'Accès à Internet différents. **Le problème est donc du côté de la destination, du serveur**.

Le problème est toujours le même : **parfois, un `telnet` / `ssh` termine en « connection refused » puis toutes les tentatives suivantes sont fructueuses… jusqu'à temps que le problème revienne**. Nous avons même réussi à enchaîner 6 « connection refused » avant d'établir une connexion. Mais c'est arrivé une seule fois, donc il ne faut pas trop en tenir compte.

Côté machine virtuelle, un `tcpdump` capture un SYN entrant sur la VM et des SYN+ACK sortants. **Ce n'est donc pas la VM légitime qui émet le TCP RST reçu par le client** (Picomon).


<br />
### Le NAT ?

**L'hyperviseur se trouvant derrière un accès à Internet de particulier, la première piste est un NAT / pare-feu trop agressif** qui ferme prématurément les états liés à la connexion. **Nous n'y croyons pas**, car on parle de connexions pas encore établies. Même incrédulité concernant une éventuelle utilisation  du port de NAT entrant par d'autres usages : il y a très très très très peu de trafic sur cet accès à Internet donc plein de ports libres pour NAT-er les connexions sortantes (SNAT, Source NAT). Même pas de torrent au moment des faits !

De plus, **la configuration du DNAT** (Destination NAT, NAT entrant) **est correcte** : une seule règle concernant ce port + règle qui ne varie pas dans le temps + une seule adresse IP définie comme destination finale / IP à substituer à l'IP de destination.


<br />
### Le filtrage Proxmox ?

**[Proxmox propose des fonctions de filtrage réseau](https://pve.proxmox.com/wiki/Firewall)**. Ce filtrage est effectué sur l'hyperviseur (les interfaces TAP de la VM filtrée sont ajoutées à un nouveau bridge, qui est lui-même connecté au bridge principal des VM de l'hyperviseur via une paire d'interfaces de type veth). Le filtrage est appliqué sur la veth côté bridge principal. **Il y a aucun règle de filtrage définies pour cette machine virtuelle**, mais nous choisissons de **désactiver le filtrage côté Proxmox et de redémarrer la VM. Le problème persiste**.


<br />
###  Qu'est-ce qui est susceptible de bagoter (flapper) ?

**Le routage IP ? Il n'y a pas de routage à l'intérieur du réseau local** : le routeur du réseau est dans le même réseau que la machine virtuelle. Dans le même segment réseau.

<br />
**La résolution ARP (IP vers MAC) ? Le routeur du réseau est un OpenWRT. L'observation de la sortie d'un `arp -an` ne montre rien de suspect**. Enfin, si : elle montre plusieurs adresses IPs pour une même adresse MAC, ce qui fera douter l'un de nous. Mais **plusieurs adresses IP associées à une même adresse MAC, donc à une même machine, c'est parfaitement normal**. Ce qui a semé le doute, c'est que l'IP supplémentaire n'est pas censée être affectée à qui que ce soit, et qu'elle est passée d'une adresse MAC à une autre au cours de nos observations. Probablement une personne disposant d'une machine virtuelle sur l'hyperviseur qui jouait pendant qu'on observait.

Cette obversation de la table ARP du routeur permet également d'**invalider notre deuxième hypothèse : un conflit d'adresse IP** ou d'adresse MAC. Deux VMs utilisant la même IP / MAC, l'une sans démon SSH en cours d'exécution, l'autre avec, provoquerait aussi ce comportement.

<br />
**La table de commutation du bridge ? Sur l'hyperviseur, les machines virtuelles accèdent à Internet via un bridge. Un bridge GNU/Linux, c'est un commutateur virtuel minimaliste. Il a donc une table de commutation** qui dit sur quel port (donc à quelle VM) il doit envoyer le trafic destiné à telle adresse MAC. Pour la visualiser : `brctl showmacs <NOM_BRIDGE>`.

Hum… **À chaque fois que le problème se produit, la table MACs ne contient pas l'adresse MAC de la VM de destination**.

**À chaque fois que l'on [vide la table de commutation du bridge](/?jFWaLw) à la mano, on reproduit le problème**.

Cool, on passe d'un problème pseudo-aléatoire à un problème reproductible à la demande, c'est un pas essentiel. \o/


<br />
### Politique de filtrage

Mais… **D'où l'absence d'une correspondance MAC / port sur un switch génère un paquet TCP RST ?! Cette histoire devrait terminer en timeout** (+ réémission des SYN / SYN+ACK).

Sauf que…  **Que fait un switch quand il n'a pas d'association entre une MAC et un port ? Il émet le paquet sur tous ses ports**. Dans le cas présent, toutes les machines virtuelles de l'hyperviseur reçoivent le TCP SYN initial.

Oui, et alors ? **Puisqu'il n'y a pas leur adresse MAC (ni celle de broadcast ni celles normalisées pour le multicast) dans le champ destination de la trame ethernet, la carte réseau de chaque machine virtuelle va ignorer le paquet, sauf la machine légitime, qui va y répondre et re-peupler ainsi la table de commutation**. Ce n'est pas aussi simple que cela, nous y reviendrons à la fin, mais **cette subtilité n'est pas le sujet** pour l'instant.

**Si le pare-feu """"Proxmox"""" est désactivé pour la VM problématique, il ne l'est pas pour les autres VMs**, dont, pour rappel du paragraphe précédent, leur interface réseau côté hyperviseur reçoit le trafic émis par le bridge sur tous ses ports. Nous regardons la liste des règles de filtrage : **si aucune n'est déclenchée, une règle jette les paquets en prévenant l'émetteur** (« REJECT» dans la terminologie Netfilter / iptables). Cette politique est notre choix (Proxmox propose toutes celles de Netfilter / iptables).

Après vérification, **nous avons une seule VM filtrée sur cet hyperviseur. `tcpdump` sur l'une de ses interfaces veth nous confirme que c'est bien la règle de filtrage sur cette interface qui génère un paquet TCP RST**. \o/

**Nous remplaçons « REJECT» par « DROP »** (jeter les paquets sans prévenir l'émetteur) dans la politique de filtrage. **Plus moyen d'avoir l'erreur à la main, et plus d'alerte Picomon** durant quelques cycles. Puis, à nouveau, « connection refused ».

Mince. **On n'a donc pas identifié l'origine de la panne**, pense l'un de nous. L'autre dit "nan mais c'est normal. **Y'a un switch physique entre le routeur du réseau et les hyperviseurs, donc lui aussi il diffuse sur tous ses ports** une fois l'association périmée à son niveau, et, **sur l'autre hyperviseur, il y a aussi un bridge et des VMs avec des règles de filtrage similaires**". C'est donc le même problème. **On change la politique de sécurité** (REJECT -> DROP) **sur TOUTES les autres VM filtrées** du cluster Proxmox. **On attend 24 h : pas d'alertes Picomon** et impossible de reproduire le problème à la main. \o/


<br />
### Et du coup, y'a quoi comme solutions ?

**Changer la politique de filtrage Proxmox** de « REJECT » à « DROP ».

**Harmoniser la durée de rétention d'une entrée dans la table MAC des switchs avec celle d'une entrée dans la table ARP** du (ou des) routeur. Dans notre cas, cela signifie augmenter la durée de rétention d'une entrée dans la table de commutation d'un bridge GNU/Linux. Cela se fait dans `/sys/class/net/<NOM_BRIDGE>/bridge/ageing_time` + configuration `sysctl` pour rendre le changement permanent.

Fournir aux VMs un **accès au réseau via du routage IP / niveau 3. Plus de bridge / de niveau 2**.

**Filtrer ce qui entre sur la VM au niveau 2** (`ebtables`) afin que le paquet envoyé à toutes les VMs par le switch atteigne jamais `iptables`. Mais c'est pénible : "si l'adresse MAC de destination n'est ni celle de broadcast ni celle de la VM, alors filtrer", cela fait deux règles par VM sans compter ce qu'on n'a pas identifié, c'est relou.


<br />
### Explications complémentaires

Forcément, on se pose des questions.

<br />
"Nan mais normalement, **quand le routeur du réseau reçoit le premier paquet SYN, il effectue une résolution ARP. La réponse de la VM met à jour la table de commutation des switchs** sur le chemin donc notre problème ne devrait pas arriver".

Oui… **Sauf si le routeur a encore la réponse, datant d'un précédent échange, dans sa table ARP**.

D'un côté, **la durée de vie par défaut d'une entrée dans la table MAC d'un bridge GNU/Linux est de 5 minutes**. C'est le [manuel](https://manpages.debian.org/testing/bridge-utils/bridge-utils-interfaces.5.en.html) qui le dit et cela se vérifie avec `cat /sys/class/net/<NOM_BRIDGE>/bridge/ageing_time`. Nous n'avons pas trouvé l'info dans la datasheet du switch physique, mais nos observations laissent supposer une durée de vie de 5 à 10 minutes.

D'un autre côté, **la durée de vie d'une entrée dans la table ARP de Linux est… un vrai bordel à déterminer.** Après un délai pseudo-aléatoire (borné par les calculs `/proc/sys/net/ipv4/neigh/default/base_reachable_time / 2` et `3 * (/proc/sys/net/ipv4/neigh/default/base_reachable_time /2)`, l'état de l'entrée passe de « REACHABLE » à « STALE ». **Une entrée ARP dans l'état « STALE » est toujours utilisable** (Linux pourra confirmer l'association en effectuant une résolution ARP après-coup ou en se contentant d'avoir reçu du trafic provenant de la machine). **Pour sortir de cet état « STALE » (donc pour disparaître), l'entrée doit remplir quatre conditions cumulatives** :
  * 1) ne pas être utilisée dans la table de routage et que le garbage collector de ladite table soit passé (sa fréquence est définie dans `/proc/sys/net/ipv4/route/gc_timeout`) ;
<br />
  * 2) que le nombre d'entrées de la table dépasse un seuil (`/proc/sys/net/ipv4/neigh/default/gc_thresh1`). **Sur un tout petit réseau, ce seuil, de 128 entrées par défaut, est jamais atteint** ;
<br />
  * 3) que le timeout de l'entrée ait expiré (`/proc/sys/net/ipv4/neigh/default/gc_stale_time`) ;
<br />
  * 4) que le délai avant passage du garbage collector soit écoulé (fréquence définie dans `/proc/sys/net/ipv4/neigh/default/gc_interval`).

**D'après nos observations, une entrée ARP non utilisée existe encore une heure après son ajout automatique. Soit bien au-delà des 5 à 10 minutes de la purge de la table MAC de nos switchs** (physiques ou virtuels).

Sources de tout ce paragraphe : [1](https://support.cumulusnetworks.com/hc/en-us/articles/202012933-Changing-ARP-timers-in-Cumulus-Linux), [2](https://stackoverflow.com/questions/15372011/configuring-arp-age-timeout) (cette source parle du cache de la table de routage IPv4 de Linux… [qui n'existe plus](https://vincent.bernat.ch/fr/blog/2017-ipv4-table-routage-linux) mais la structure de données perdure donc la réflexion semble rester pertinente).

Donc, **si, c'est parfaitement crédible que le routeur n'effectue pas une résolution ARP préalable**.  

**Les switchs sur le chemin  qui "oublient" l'existence de la VM est tout aussi crédible : 1) il s'agit d'un serveur** (donc absence de trafic parasite permanent que l'on retrouve sur une station de travail type mDNS, SMB, etc.) ; 2) **il s'agit d'un bastion SSH, ce qui occasionne très très peu de trafic**, d'autant qu'il est accessible sur le net via un port non-standard et qu'un fail2ban rode.


<br />
"Nan mais **la VM légitime répond TCP SYN+ACK donc le TCP RST illégitime ne devrait pas être pris en compte par le client SSH**.

Oui, mais non. Si le SYN+ACK parvient au client avant le RST, l'implémentation TCP va incrémenter ses compteurs internes et générer le dernier ACK de la [poignée de main TCP](https://fr.wikipedia.org/wiki/Acquittement_(informatique). Le RST reçu après sera invalide car son numéro de séquence ne correspondra pas au compteur interne, donc, en effet, il sera ignoré et la connexion ne sera pas interrompue.

Mais, **le pare-feu qui émet le RST est sur l'hyperviseur, pas dans une VM. Sa réponse parvient forcément plus rapidement au client que celle que la VM légitime** (moins d'empilement de couches, de copies dans des structures de données, de timers, etc.). De plus, **le RST ferme les états dans les pare-feux et NAT situés entre le serveur et le client**, donc les SYN+ACK émis (et réémis) par la VM légitime arriveront jamais jusqu'au client SSH.


<br />
"Nan mais notre diagnostic est incorrect, car, s'il était vrai, **cela signifie qu'un pare-feu configuré avec une politique « REJECT » dans une VM chez n'importe quel hébergeur provoquerait ce genre d'effet secondaire sur des clients à faible trafic**".

**Normalement, le pilote de la carte réseau transmet au système uniquement les trames ethernet dont l'adresse MAC de destination correspond à la sienne. Sauf quand la carte réseau est en [mode promiscuous](https://fr.wikipedia.org/wiki/Promiscuous_mode)**. Donc **un pare-feu à l'intérieur d'une VM ne verrait pas les paquets qu'un switch aurait diffusé sur tous ses ports et n'enverrait donc pas de TCP RST** en retour.
  * Ça, c'est la théorie. Durant nos tests, un `tcpdump -p` (`-p` = désactivation du mode promiscuous, ce que /var/log/kern.log confirme) lancé dans une VM capture les paquets que le switch diffuse à toutes les VMs. En revanche, une règle de filtrage sur ces paquets ne produit aucun effet (compteurs `iptables -L -n -v` toujours à zéro). D'après notre test, il s'agit du comportement du pilote virtio_net. Le pilote e1000e ne fait pas remonter les paquets tant qu'on n'active pas le mode promiscuous.

Ensuite, **la latence causée par la remontée du paquet jusqu'à la VM puis la descente du TCP RST entrerait en compétition ardue avec la réponse légitime**. Dans notre cas, la réponse illégitime gagne la course car la compétition se joue entre un pare-feu sur l'hyperviseur et une réponse émise par un noyau Linux dans une VM.

Enfin, **il faut remplir plusieurs conditions pour déclencher ce bazar, dont certaines sont peu communes chez les hébergeurs** justement conscients des risques : **VMs raccordées au réseau via un bridge** (très peu courant) + filtrage sur l'hyperviseur + **politique de filtrage de type rejet en prévenant l'émetteur** (dite « REJECT ») alors que les préconisations sont de jeter silencieusement les paquets venant de l'extérieur afin de donner le moins d'indices possibles à un attaquant (c'est d'ailleurs la politique par défaut proposée par Proxmox) + durée de la rétention ARP supérieure à la durée de rétention de la table de commutation des switchs sur le chemin (alors que les hébergeurs ont plutôt du matos aux durées de rétention harmonisées plutôt qu'un routeur logiciel GNU/Linux) + machine émettant et recevant peu de trafic.


<br />
Debug et écriture de ce shaarli en collaboration avec [Johndescs](https://jonathan.michalon.eu/shaarli/).


]]>
GuiGui's Show - Friday 9 April 2021 https://shaarli.guiguishow.info/?do=daily&day=20210409 https://shaarli.guiguishow.info/?do=daily&day=20210409 Fri, 09 Apr 2021 00:00:00 +0200 GNU/Linux : vider / purger / flush / clear la table MAC / table de commutation d'un bridge Fri Apr 9 17:17:18 2021 -
http://shaarli.guiguishow.info/?jFWaLw


Sur un système GNU/Linux, **un bridge, c'est un commutateur / switch virtuel minimaliste**.

Il a donc une table de commutation / table MAC.

Pour la lire, c'est facile : `brctl showmacs <NOM_BRIDGE>`.

Pour la vider intégralement / flush / clear, `brctl` ne propose pas d'outil. On peut passer par sysfs : `echo 1 | sudo tee /sys/class/net/<NOM_BRIDGE>/bridge/flush` pour vider toute la table du bridge ou `echo 1 | sudo tee /sys/class/net/<NOM_BRIDGE>/brif/<NOM_INTERFACE>/flush` pour purger les seules entrées relatives à une interface membre du bridge. [Source](https://lists.linuxfoundation.org/pipermail/bridge/2007-September/005562.html).


]]>
GuiGui's Show - Thursday 1 April 2021 https://shaarli.guiguishow.info/?do=daily&day=20210401 https://shaarli.guiguishow.info/?do=daily&day=20210401 Thu, 01 Apr 2021 00:00:00 +0200 Sauver le monde de Teams en utilisant Zoom ou le non-sens de nos vies Thu Apr 1 14:41:41 2021 -
http://shaarli.guiguishow.info/?_w2-MQ


Soit **un événement professionnel annuel avec des conférences**. Chaque année, une organisation de la communauté se porte volontaire pour organiser cet événement.

Forcément, **cette année, il sera dématérialisé. L'organisateur choisi d'utiliser Microsoft Teams et Google YouTube**.

**Notre [DSI](https://fr.wiktionary.org/wiki/DSI) insiste pour qu'on mette à disposition de l'organisateur notre plate-forme [BBB](https://fr.wikipedia.org/wiki/BigBlueButton)**, notre plate-forme [Pod](https://github.com/EsupPortail/Esup-Pod), notre [Rocket Chat](https://github.com/RocketChat/Rocket.Chat), etc. **Deux arguments : Teams c'est le Mal ; Mettre en avant notre savoir-faire BBB+Pod+Rocket (ce qui se reformule en : "protéger mon cul de DSI** en montrant que notre taff n'est pas vain et que ma décision passée de ne pas externaliser est la bonne").

Personnellement, **je trouve déplacé le comportement de notre DSI. Autant que celui du libriste moyen qui va promouvoir et proposer avec insistance** d'utiliser OSM, Mastodon, GNU/Linux, Framabidule, etc. **Habituellement, cette personne-là se fait rembarrer en mode "occupe-toi de ton cul, j'utilise ce que je veux !"** (j'ai de l'expérience en la matière :) ). Pourquoi ce qui est vrai à l'échelle individuelle ne le serait pas à l'échelle d'organisations ? Ainsi, **je pense que nous avons dû passer pour des relous et des prétentieux** (ces temps-ci, nous n’avons pas été les seuls à monter des infrastructures BBB, Pod, etc.). D'autant qu'**avec nous dans ses pattes, l'organisateur a forcément plus de boulot** (il va devoir nous causer, organiser son projet avec nous en plus, coordonner encore plus de personnes, vérifier qu'on livre bien ce qu'on a promis à la date convenue, effectuer des allers-retours techniques si la livraison ne convient pas ou s'il y a des bugs, etc.).

**Notre plateforme Pod a jamais été vraiment utilisée par nos usagers** et nous n'avons pas effectué de tests de charge. J'ai insisté pour qu'on en fasse, pour qu'on étudie a minima le passage à l'échelle : le temps m'a jamais été débloqué. Comme d'habitude, **il faut faire les choses à moitié et laisser tout en plan… On nomme ça le pragmatisme. On a fait des trucs sans savoir pourquoi, sans usage concret derrière, et vu que c'est bâclé, notre savoir-faire est minimal et ma frustration est maximale**. Vu l'absence d'usage de notre Pod, il aurait été plus profitable de faire péter un coup les chefs de nos usagers et de rien mettre en place.

**Il est décidé d'aller consulter les gus qui ont codé Pod**. C'est bien connu qu'un gus qui ne connaît pas les spécifications de notre infrastructure (nombre de serveurs, CPU, RAM) ni la configuration des différents composants logiciels (nginx, ffmpeg, django, etc.) pourra affirmer avec certitude combien de visionneurs nous pourrons avoir sur notre plateforme. :)))) On n'est plus à une incohérence près.

Là où ça devient comique : **ce blabla est prévu sur… Zoom ! Donc, on veut sauver l'événement des griffes de Microsoft Teams en organisant (une partie de) la contre-offensive sur Zoom ! Genius!** FA-BU-LEUX. Nous sommes de « [classe mondiale, peut-être même les champions du monde !](https://www.allocine.fr/film/fichefilm_gen_cfilm=16731.html) ». C'est désespérant.

Comme d'habitude, **cette énième incohérence, ce non-sens avec les idées que l'on porte (ou que l'on prétend porter) ne semble pas déranger mes collègues. C'est ce qui arrive quand on réfléchit tout, y compris sa propre vie, en mode projet : il faut juste abattre du travail, atteindre des jalons, peu importe comment on les atteint**. Tout est une tâche comme une autre. Il faut l'achever le plus simplement possible sans trop se poser de questions afin de justifier son salaire. Où est le sens ?! On s'en moque. C'est désespérant… Mais chacun fait bien ce qu'il veut de sa vie.

Je n'ai pas participé à la petite causerie sur Zoom. La sauterie se fera sûrement sans moi. Merci bien.


]]>
GuiGui's Show - Sunday 28 March 2021 https://shaarli.guiguishow.info/?do=daily&day=20210328 https://shaarli.guiguishow.info/?do=daily&day=20210328 Sun, 28 Mar 2021 00:00:00 +0100 Service public ? Quel service public ?! Sun Mar 28 13:31:40 2021 -
http://shaarli.guiguishow.info/?VMpDMw


J'ai déjà déblatéré sur **[La Poste qui paume 10 % des accusés de réception](/?jgDzAA) des LRAR que j'envoie ou qui met 3-4 semaines pour me retourner ledit carton**, mais il y a pire (quand il s'agit de faire toujours plus de merde, l'humain se surpasse toujours).

Parlons hôpital public.

À la demande d'un médecin, **je prends rdv pour une IRM dans un hôpital public**. Pour prendre le rdv, **il faut téléphoner, insister, encore et encore, des jours durant, à toute heure ouvrée** (en supposant que le site web de l'hosto est à jour), **car personne décroche**. Ça fait **plus de 6 mois que c'est comme ça**.

J'obtiens finalement un rdv 2 mois plus tard. **Il faut le confirmer 3 jours avant**. Je tente de le faire mais… personne décroche ! J'ai essayé chaque jour. À toutes les heures ouvrées. Impossible. **Qui a donné cette consigne idiote de confirmer le rdv alors que le secrétariat n'arrive déjà pas à gérer la prise de rdv ?! Qui sont ces secrétaires qui appliquent des consignes qu'elles savent idiotes et intenables ?!** Elles sont fonctionnaires, donc inamovibles en cas d'insubordination !

Je me rends au rdv.

Il n'était pas utile de le confirmer. **Les fameuses règles qui changent tous les deux jours, putain que c'est relou**.

On me dit que ce rdv n'était pas à 18 h 15 mais à 17 h 15. Je suis sûr d'avoir noté correctement l'horaire, d'autant que la secrétaire m'avait téléphoné pour me proposer un créneau plus proche (que j'ai refusé car j'ai estimé de pas être dans une situation critique), donc on avait re-échangé l'horaire.

On me dit que l'on va me donner le numéro de téléphone pour que je prenne rdv car **le secrétariat ferme à 17 h. Pourquoi es-tu physiquement dans le local nommé « secrétariat », alors, connasse ?!** Ça te coûterait quoi de noter un rdv ?!

J'expose que j'ai pu joindre personne par téléphone les 3 derniers jours afin de confirmer mon rdv donc que c'est cocasse de me demander de reprendre rdv par téléphone. **Elle me coupe la parole pour me dire « et ça sonnait occupé, hum, désolée »**. Le ton était celui du jemenfoutisme, comme celui d'un psy ou d'un politicien, **ce ton qui veut dire "je vois, je vois, c'est ballot, mais c'est comme ça, ça arrive, on peut rien faire, ces choses-là sont immuables"**. Et, non, ça ne sonnait pas occupé, ça sonnait jemenfoutisme, ça sonnait dans le vide, connasse !

Dans l'ascenseur retour, il y a une [**affiche de la FHF « Si vous attendez, c'est qu'on préfère regarder des photos »**](https://www.fhf.fr/Presse-Communication/Supports-de-communication-FHF/Des-affiches-pour-faire-face-aux-violences). À cet instant précis, la moutarde m'est montée au nez : **j'ai jamais autant souhaité la disparition du service public !** Je suis vos règles à la con, je n'ai pas ce que je désire, vous vous moquez de moi avec vos réponses en carton, et en plus vous me narguez ?! **Pour qui vous prenez-vous, enfoirés ?!**

**Cette anecdote date de plus d'un mois. Je n'ai pas repris rdv. Je ne le ferai pas : marre de me faire maltraiter**. Quand mon problème sera sérieux, le médecin prescripteur me fera un mot pour griller la file d'attente, puis, en regardant l'IRM, il me dira « aïe, il aurait fallu agir plus tôt ». Monde de crevures.

Pour ceux qui se demandent pourquoi je n'ai pas confirmé le rdv par email : l'hôpital utilise le service antispam de Mailcontrol et le service emails de Microsoft. Non merci. Sans compter que si les secrétaires ne répondent pas au téléphone, j'imagine que les emails doivent aussi passer à la trappe.


]]>