<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
    <title>Selenith</title>
    <subtitle>Projets, mémos et reflexions personnelles</subtitle>
    <link href="https://www.selenith.org/atom.xml" rel="self" type="application/atom+xml"/>
    <link href="https://www.selenith.org"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-03-14T00:00:00+00:00</updated>
    <id>https://www.selenith.org/atom.xml</id>
    <entry xml:lang="fr">
        <title>Input remapper</title>
        <published>2026-03-14T00:00:00+00:00</published>
        <updated>2026-03-14T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/notes/input-remapper/" type="text/html"/>
        <id>https://www.selenith.org/notes/input-remapper/</id>
       
        <content type="html"><![CDATA[<p>J'ai récemment découvert l'existence de <a class="external-link" rel="noopener external" target="_blank" href="https://github.com/sezanzeb/input-remapper">input-remapper</a>. C'est un programme avec interface graphique qui permet de changer le comportement des touches de tout type de matériel. Pour les linuxien(ne)s qui comme moi ont du matériel Razer pour lesquels aucun programme n'existe pour mapper correctement ses souris et gamepads, c'est parfait.</p>
<p>Et le meilleur ? Ça fonctionne aussi avec le <a href="https://www.selenith.org/projets/nunstick/">Nunstick</a> 😍 !</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Human Slop</title>
        <published>2026-03-09T00:00:00+00:00</published>
        <updated>2026-03-09T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/notes/human-slop/" type="text/html"/>
        <id>https://www.selenith.org/notes/human-slop/</id>
       
        <content type="html"><![CDATA[<p>Ha ! l'<a class="external-link" rel="noopener external" target="_blank" href="https://unodieuxconnard.com/2026/03/09/human-slop/">Human-Slop</a> décrit chez l'Odieux Connard ! Excellent :'D</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Retour d’expérience sur un an de panneaux solaires</title>
        <published>2026-01-14T00:00:00+00:00</published>
        <updated>2026-01-14T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/retex-un-an-de-pannaux-solaires/" type="text/html"/>
        <id>https://www.selenith.org/articles/retex-un-an-de-pannaux-solaires/</id>
       
        <content type="html"><![CDATA[<p>Je vois beaucoup de n'importe quoi sur le solaire sur le net ces dernier temps, tant en bien qu'en mal. Entre ceux qui disent que c'est la panacée absolue et que tu vas être 100% autonome, que ça te sublimera d'une élongation karmique transcendantale et d'un retour d'affection instantanée et, d'autre part, ceux qui disent que ça va ruiner ta famille, sécher ton poisson rouge et que tes enfants te honniront même trente ans après, il est parfois compliqué de faire la part des choses.</p>
<p>Voici un petit RETEX sur mon installation solaire faite par moi même après un an de fonctionnement.</p>
<span id="continue-reading"></span><figure>
    
        <img src="https:&#x2F;&#x2F;www.selenith.org&#x2F;articles&#x2F;retex-un-an-de-pannaux-solaires&#x2F;conso.webp"  alt="Ma conso"  />
    
    <figcaption>
        <p>Image de ma conso 2025.</p>

    </figcaption>
</figure>
<!-- <hr />-->
<p>Je vais comparer deux périodes, 2024 et 2025, la première sans panneaux solaires et la deuxième avec. En faisant les calculs préliminaires à mon installation, j'avais fait plusieurs scénarios avec autoconsommation, revente, les deux, panneaux en toiture fait par des professionnels, installation faite par moi avec différentes puissance et les coûts en fonction de la législation (il faut une entreprise RGE si on veut revendre, Consuel si c'est sur le toit ou supérieur à une certaine puissance), aides de l'état si installé par un pro et j'en passe.
Il en est ressorti que le plus économique et le plus rentable semblait être une installation en plug and play d'au moins 2kW.
Mon objectif est de voir si ce type d'installation ultra basique permet d'avoir quelque chose d'intéressant financièrement sans avoir à faire des travaux trop lourds et compliqués ni d'y passer trop de temps.</p>
<h2 id="le-mode-de-consommation">Le mode de consommation</h2>
<p>Il s'agit d'une installation en autoconsommation de type plug and play au max de ce qui est possible sur le plan légal (3kW max). Ce n'est pas une installation sur un toit et elle n'est donc pas soumise à une validation par le Consuel ni par une déclaration quelconque. Il n'y a donc pas de frais supplémentaires cachés.</p>
<p>Cela implique que si l'installation produit plus que la maison ne consomme, personne ne rachète cette production, elle est renvoyée vers Enedis gratos pour eux et tant pis pour moi. D'un autre coté, je n'ai pas eu besoin de changer mon abonnement pour un autre plus cher, ni quoi que ce soit d'autre.</p>
<h2 id="warning-attention-la-securite-c-est-important-warning">⚠️ Attention : La sécurité c'est important ⚠️</h2>
<p>Même si elle n'a pas été faite par un pro, mon installation est conforme à la réglementation <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/NF_C_15-100">NF C 15-100</a>. Je précise que je n'ai pas de formation en électricité mais que comme pour tout, ce n'est pas très compliqué si on respecte le bon vieil adage : <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/RTFM_(expression)">RTFM</a>.</p>
<h2 id="le-contexte">Le contexte</h2>
<p>Voici un peu le contexte pré installation, sur l'année 2024.</p>
<h3 id="la-maison-et-son-dpe">La maison et son DPE</h3>
<p>Il s'agit d'une maison des années 60 d'environ 120 m² sans isolation des murs. C'est du parpaing avec enduit extérieur et plâtre à l’intérieur. Elle à été évaluée à D au DPE à l'époque de la vente. J'ai quand même isolé les combles en décembre 2023 avant la période de test.</p>
<p>La maison est située dans le sud de la France. Donc dans une région bien ensoleillée et où une bonne PAC air/eau permet de se chauffer (même avec une maison pas trop isolée).</p>
<h3 id="equipements-et-habitudes">Équipements et habitudes</h3>
<p>Presque tout est électrique : Four, chauffe eau classique à résistance et <a href="https://www.selenith.org/articles/economiser-15000-euros-pompe-a-chaleur/">pompe à chaleur air/eau</a> pour le chauffage. La clim est assurée en été par 2 pompes à chaleur air/air. J'ai installé une plaque à induction en début 2025. En 2024 j'avais donc en plus de l'électricité consommée une facture de gaz d'environ une dizaine d'euros par mois pour la cuisine.</p>
<p>Je travaille à la maison et je dois donc faire la cuisine tous les midis, maintenir le chauffage la journée et j'ai plusieurs pc allumés pour pouvoir faire le boulot. Avec les enfants c'est aussi une machine à laver par 1 jour et demi + sèche linge qui doivent tourner.</p>
<p>Pour le chauffage, la consigne est programmée pour 19 degrés en journée et 18 la nuit de 23H à 7H.</p>
<h3 id="consommation-de-base">Consommation de base</h3>
<p>Ce qui fait qu'en 2024 j'ai dépensé environ 3700 euros en électricité pour 11 950 kWh consommés.</p>
<h2 id="l-installation-solaire">L'installation solaire</h2>
<p>J'ai reçu mes panneaux solaire en fin  2024. L'installation à été mise en service juste avant janvier. J'ai donc un résultat sur une année complète de janvier à décembre 2025. Peu de temps après, j'ai équipé mon tableau électrique d'un module <a class="external-link" rel="noopener external" target="_blank" href="https://www.shelly.com/fr/products/shelly-3em">Shelly 3EM</a> et j'ai monté un home assistant sur un vieux raspberry qui m'a permis de mesurer ma consommation électrique et ma production solaire sur l'année. J'ai pris des micros onduleurs avec un firmware de type EZ1 - APsystems qui permettent d'être interrogés par API local. Je suis donc propriétaire de mes données et le système fonctionne encore même en cas de coupure internet.</p>
<h3 id="le-cout-de-l-installation">Le coût de l'installation</h3>
<p>Parlons un peu de l'installation.</p>
<ul>
<li>Les panneaux x 8 + micro onduleurs x 4 : 1100 euros (livraison comprise).</li>
<li>Les supports en acier : 280 euros (livraison comprise).</li>
<li>Le matériel pour raccorder au tableau électrique, comprenant interrupteur différentiel 63A et 2 disjoncteurs divisionnaire +  2 câbles 2.5mm² + 4 prises (2 par câble) + gaines: 250 euros.</li>
<li>le Shelly 3EM avec 3 pinces 120A (optionnel) : 70 euros.</li>
</ul>
<p>Soit au total environ 1700 euros TTC.</p>
<p>J'ai mis une bonne journée de travail pour installer les panneaux et faire le raccordement électrique au tableau.</p>
<p>Je pense qu'il est possible de trouver ou de bricoler des supports bien moins chers que ceux que j'ai acheté.</p>
<h3 id="la-consommation-sur-2025">La consommation sur 2025</h3>
<p>En 2025 j'ai consommé 9325 kWh sur le réseau électrique. J'ai eu une facture pour la période de 2550 euros environ. Presque tout Janvier est manquant sur mon screenshot car je n'avais pas encore le Shelly en service pour faire les mesures.</p>
<p>J'ai fait quelques ajustements progressivement grâce au monitoring de ma consommation. C'est important car il faut vraiment changer ses habitudes pour optimiser ses dépenses.</p>
<h3 id="quelques-points-particuliers">Quelques points particuliers</h3>
<p>Il est important de noter quelques points qui pourraient avoir une influence sur mes calculs.</p>
<p>Sur les 8 panneaux, un est arrivé cassé et j'ai du attendre début février pour recevoir son remplaçant. J'ai donc fait tout janvier avec seulement 7 panneaux sur les 8.</p>
<p>Le shelly m'a permis de monitorer, en plus de la consommation de base, la consommation spécifique de mon chauffe eau et de ma pompe a chaleur air/eau.
En voyant la consommation des différents postes j'ai fait des adaptations au fil du temps qui auraient été plus rentables plus tôt si j'y avait pensé dès le début.</p>
<p>Je me suis ainsi rendu compte que ma PAC tirait trop fort et faisait des cycles de chauffage trop court et trop intenses. J'ai donc regardé sa configuration et j'ai constaté que la loi d'eau n'était pas correctement configurée. J'ai fait la modif en début mars 2025. Sa consommation est depuis bien mieux répartie sur la totalité de la journée et donc <strong>d'avantage pendant les heures ou le soleil est là</strong>. J'ai donc au moins deux des mois les plus froids avec une PAC qui faisait des pic de consommation sur le réseau aux pires moments, le matin et le soir quand il n'y avait pas de soleil 😫 !</p>
<p>En <strong>mi avril seulement</strong> j'ai décidé de me servir du shelly pour remplacer le déclenchement de nuit de mon chauffe eau. Je l'ai programmé pour qu'il se déclenche au moment de la surproduction solaire pour absorber le surplus en journée. Ça m'a fait un sacré gain ! Entre 4 et 8 kWh par jour stockés dans le chauffe eau (selon la température de l'eau en entrée et la consommation du jour)! C'est rentable surtout les mois ou le chauffage est éteint, sinon le système ne se déclenche pas et la routine d'allumage nocturne prend le relais. J'aurais donc pu gagner pas mal plus la aussi 😢.</p>
<p>Je n'ai pas tout de suite pris l'habitude de lancer les machines gourmandes en décalé au moment ou il y a du soleil. Il m'est très souvent arrivé de lancer un sèche linge ou une machine à laver au moment de faire la cuisine le midi 🫢.</p>
<p>J'ai isolé par l'intérieur un quart de la maison en décembre 2025. Et pour voir l'impact (et parce que j'en avais marre de me peler !) j'ai augmenté le chauffage à 20 degrés en journée. Malgré cela, j'ai quand même moins consommé sur le réseau, 1450kWh au lieu de 1798kWh. L'isolation m'a permis de chauffer plus pour moins cher. L'augmentation du chauffage n'a donc pas eu d'impact négatif sur la consommation et le test reste donc valide.</p>
<p>Les minimales de températures ont été plus basses en novembre 2025 qu'en 2024, mais légèrement plus hautes en décembre 2025. Par contre très peu d'ensoleillement en décembre chez moi. Les informations sur le site <a class="external-link" rel="noopener external" target="_blank" href="https://infoclimat.fr">infoclimat</a> sont top pour ajuster les comparaisons en fonction des conditions extérieures.</p>
<p>Mes panneaux sont posés à même le sol et ils ne produisent rien avant 10h le matin et après la fin d'après midi vers 16h quand on est près du solstice d'hivers à cause de divers obstacles (haie et arbres).</p>
<h2 id="la-rentabilite-et-le-confort">La rentabilité et le confort</h2>
<p>Bon malgré tous les ajustements un peu tardifs, les points qui pourraient êtres améliorés et l'augmentation de la consommation à cause du froid++ en 2025 j'ai quand même fait une économie de 1270 euros (3700+120 de gaz - 2550) la première année !
Il est donc possible d'amortir ses panneaux (+ son installation électrique dédiée) en moins d'un an et demi en réfléchissant un peu (même en étant un peu lent à la détente sur les habitudes).</p>
<p>Je précise aussi que même avec ces ajustements, j'ai quand même eu des périodes de surproductions, surtout en été. Ceci dit l'avantage en été c'est qu'il fait chaud, j'ai donc pu absorber le surplus en augmentant la climatisation. C'est donc, sans être un gain financier, un sacré gain de confort. Parce que pouvoir se refroidir en pleine canicule gratuitement aux heures les plus chaudes ce n'est pas négligeable.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Les panneaux solaires sont donc particulièrement rentables dans les conditions de mon test et au final très rapidement ( moins de 1.5 an). Il faut cependant garder à l'esprit les quelques points suivants :</p>
<ul>
<li>Faire l'installation soi même si possible, c'est ce qui permet de faire une <strong>énorme économie</strong>. Plus qu'en payant un pro avec des aides de l'état.</li>
<li>Changer ses habitudes et répartir les consommations sur la journée et non plus la nuit.</li>
<li>Utiliser son chauffe eau comme batterie c'est une bonne idée.</li>
<li>Ne pas chercher à être 100% autonome. Les batteries sont trop chères et font exploser les coûts, surtout qu'il faut augmenter la surface de panneaux pour les charger.</li>
<li>Trouver l'équilibre pour la rentabilité n'est pas toujours simple et ça peut être très différent entre deux foyers.</li>
<li>L'isolation c'est important !</li>
</ul>
<p>J'espère en tout cas que ça t'auras donné envie de tenter l'aventure. Si tu veux échanger sur le sujet, n'hésite pas.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Créer une DMZ complète sous linux</title>
        <published>2025-11-02T00:00:00+00:00</published>
        <updated>2025-11-02T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/creer-une-dmz-complete-sous-linux/" type="text/html"/>
        <id>https://www.selenith.org/articles/creer-une-dmz-complete-sous-linux/</id>
       
        <content type="html"><![CDATA[<p>Bon, la ça ne rigole plus, maintenant que <a href="https://www.selenith.org/articles/creer-un-routeur-statique-sous-linux/">t'as les bases</a> pour créer un routeur avec un vieux grille pain, nous allons voir comment créer une DMZ avec plusieurs zones et ainsi ne plus risquer se faire pwned par tes nouvelles toilettes connectés dont l'app est reliée à un cloud chinois piraté depuis 2002.</p>
<span id="continue-reading"></span><figure>
    
        <img src="https:&#x2F;&#x2F;www.selenith.org&#x2F;articles&#x2F;creer-une-dmz-complete-sous-linux&#x2F;Demilitarized_Zone_Diagram.png"  alt="DMZ par Benj"  />
    
    <figcaption>
        <p>DMZ par  <a class="external-link" rel="noopener external" target="_blank" href="http://www.grassouille.org/docs/index.en.html">Benj</a>,  Domaine public pour <a class="external-link" rel="noopener external" target="_blank" href="https://commons.wikimedia.org/w/index.php?curid=802830">wikimedia</a></p>

    </figcaption>
</figure>
<!-- <hr />-->
<p>Cet article est assez technique et il faut avoir au moins connaissance de comment fonctionnent les réseaux IP et du principe des <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Sous-r%C3%A9seau">masques de sous-réseau</a> pour pouvoir tout comprendre. Contrairement aux articles qu'on trouve souvent sur les DMZ, nous allons en créer une en dual stack IPv4/IPv6 avec des outils plus modernes et faciles à maintenir que les classique iptables, bind9, etc.</p>
<h2 id="une-dmz">Une DMZ ?</h2>
<p>DMZ veut dire DeMilitarized Zone ou encore Zone démilitarisée en français. A la base, cela consiste à créer une zone dans notre réseau contenant des machines accessibles par internet mais distincte de notre réseau local (domestique ou d'entreprise). Le tout est géré par un pare-feu qui va s'occuper du routage et de la segmentation les différentes zones réseaux en permettant seulement aux flux légitimes de passer d'une zone à l'autre.</p>
<p>Aujourd'hui c'est aussi le seul moyen d'héberger chez soi des sites en IPv6 sans avoir tout son réseau accessible depuis internet. La plupart des fournisseurs d'accès à internet (FAI) ne proposent pas d'interface de configuration du pare-feu en IPv6. C'est tout ouvert ou tout fermé.</p>
<h2 id="une-dmz-ok-mais-avec-quoi">Une DMZ ok mais avec quoi ?</h2>
<p>Depuis le temps, tu dois commencer à me connaître et tu sais qu'on va la faire avec presque rien. Parce que presque rien c'est bien, comme ça tu choisis ton système d'exploitation et tu peux recycler du vieux materiel. C'est donc pas cher à l'achat et il n'y a pas de licence à payer régulièrement.</p>
<h3 id="le-materiel">Le materiel</h3>
<p>En terme de matériel, on utilisera le même type que pour faire un <a href="https://www.selenith.org/articles/creer-un-routeur-statique-sous-linux/">routeur statique</a> décrit dans mon précédent article.
En résumé, un vieux PC avec des cartes réseaux additionnelles, un minipc noname <a class="external-link" rel="noopener external" target="_blank" href="https://duckduckgo.com/?q=mini+pc+firewall">vendu sous l’appellation firewall</a>, un <a class="external-link" rel="noopener external" target="_blank" href="https://www.banana-pi.org/en/bananapi-router/201.html">banana pi</a> ou encore un <a class="external-link" rel="noopener external" target="_blank" href="https://www.hardkernel.com/shop/odroid-h4/">odroid h4</a> avec une carte d'extension réseau si tu veux le top du top en terme de rapport coût/performance/efficience énergétique. C'est comme tu préfères.</p>
<h3 id="le-systeme-d-exploitation">Le système d'exploitation</h3>
<p>Perso j'aime bien Archlinux mais pour commencer simple on va faire ça sous Debian 13 (Trixie) avec uniquement une configuration du kernel qui va bien et quelques outils. Nous ne verrons pas ici l'installation de Debian 13 car il y a de très bon tutos pour ça sur internet ainsi que le <a class="external-link" rel="noopener external" target="_blank" href="https://www.debian.org/releases/forky/amd64/index.fr.html">manuel officiel</a>.</p>
<h2 id="les-pre-requis">Les pré-requis</h2>
<p>Pour qu'une dmz fonctionne bien et pour ne pas multiplier les machines, on va installer ou activer sur notre machine pare-feu/routeur les fonctionnalités suivantes :</p>
<ul>
<li>Le transfert de paquets d'une interface réseaux à une autre (forwarding).</li>
<li>Un firewall avec nftables (la base).</li>
<li>Un service de DHCP pour que les machines en IPv4 puissent acquérir une adresse IPv4 automatiquement.</li>
<li>Un service de Router Advertisement pour que les machines en IPv6 puisse acquérir une adresse IPv6 automatiquement.</li>
<li>un service de DNS pour pouvoir accéder à nos autres machines via un nom de domaine local (optionnel).</li>
</ul>
<p>Après avoir installé Debian 13, installons les paquets nécessaires pour pouvoir commencer (en root).</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">apt</span><span style="color: light-dark(#032F62, #9ECBFF);"> update</span></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">apt</span><span style="color: light-dark(#032F62, #9ECBFF);"> install</span><span style="color: light-dark(#032F62, #9ECBFF);"> systemd-resolved</span><span style="color: light-dark(#032F62, #9ECBFF);"> kea</span><span style="color: light-dark(#032F62, #9ECBFF);"> nftables</span></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> enable</span><span style="color: light-dark(#032F62, #9ECBFF);"> systemd-networkd</span></span></code></pre><h2 id="le-reseau">Le réseau</h2>
<h3 id="definir-le-plan-d-adressage">Définir le plan d'adressage</h3>
<p>Il va falloir choisir quels sous-réseaux vont être utilisés pour les différentes zone. Pour l'IPv4, vu qu'on est sur des adresses privées, on peut donc choisir ce qu'on veut dans la <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Classe_d%27adresse_IP">classe C</a>. Pour l'IPv6, il va falloir voir quels sont les réseaux mis à disposition par ton FAI. En général les FAI en donnent 5 ou 6 et ils sont en masque sur 64 bits (ou encore en /64 en notation CIDR).</p>
<p>Pour pouvoir les connaître il faut se connecter à l'interface de gestion de sa box.</p>
<figure>
    
        <img src="https:&#x2F;&#x2F;www.selenith.org&#x2F;articles&#x2F;creer-une-dmz-complete-sous-linux&#x2F;net_fai.png"  alt="Interface de gestion montrant 6 sous-réseaux en &#x2F;64 allant de 2001:db8:1:10::&#x2F;64 à 2001:db8:1:15::&#x2F;64"  />
    
    <figcaption>
        <p>Exemple avec mon interface de gestion chez Free</p>

    </figcaption>
</figure>
<!-- <hr />-->
<p>Ensuite il va falloir définir les IP des différentes interfaces de la machine qui va être notre routeur/firewall. Tout doit être définit en statique. On ne veut pas que ses IP changent à chaque redémarrage et que ça ne perturbe toute la config.</p>
<p>On partira du principe que j'ai les sous-réseaux IPv6 suivants donnés par mon FAI (comme sur l'image d'exemple ci-dessus). On va les utiliser de la manière suivante :</p>
<ul>
<li>2001:db8:1:10::/64 sera le réseau d'interconnexion entre la box et le routeur, nommé "wan".</li>
<li>2001:db8:1:11::/64 sera le réseau nommé "lan" sur lequel on aura les PC standarts de connecté.</li>
<li>2001:db8:1:12::/64 sera le réseau nomé "dmz" sur lequel sera raccordé les machines qui devront être accessible depuis internet.</li>
</ul>
<p>Pour ce tuto je vais choisir les IPs définies ci-dessous.</p>
<p>Pour l'interface <strong>wan</strong> :</p>
<ul>
<li>IPv6 publique :  2001:db8:1:10::1ce:face/64</li>
<li>IPv6 locale : fe80::1ce:face/64</li>
<li>IPv4 : 192.168.0.100/24</li>
</ul>
<p>Pour l'interface <strong>lan</strong> :</p>
<ul>
<li>IPv6 publique :  2001:db8:1:11::1ce:cafe/64</li>
<li>IPv6 locale : fe80::1ce:cafe/64</li>
<li>IPv4 : 192.168.1.1/24</li>
</ul>
<p>Pour l'interface <strong>dmz</strong> :</p>
<ul>
<li>IPv6 publique :  2001:db8:1:12::1ce:beef/64</li>
<li>IPv6 locale : fe80::1ce:beef/64</li>
<li>IPv4 : 192.168.2.1/24</li>
</ul>
<h3 id="nommage-des-interfaces-reseau">Nommage des interfaces réseau</h3>
<p>Première étape si on ne veux pas s'emmêler les pinceaux : nommer ses interfaces réseau.
Il va falloir activer systemd-networkd et configurer au moins trois interfaces : wan, lan et dmz.
Pour cela il va te falloir faire un petit tour sur <a href="https://www.selenith.org/articles/nommer-ses-interfaces-reseau/">mon article sur le nommage des interfaces</a>.</p>
<p>Une fois le service systemd-networkd activé, les fichiers .link créés et la machine redémarrée, on va pouvoir passer à la suite.</p>
<h3 id="configuration-des-interfaces-reseau">Configuration des interfaces réseau</h3>
<p>Ci dessous, les fichiers des configuration des 3 interfaces à placer dans /etc/systemd/network/.</p>
<p>Pour le fichier <strong>10-wan.network</strong> :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Match]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>wan</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Network]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">DHCP</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">no</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">IPv6AcceptRA</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">false</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">LinkLocalAddressing</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">no</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">KeepConfiguration</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">yes</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Route]</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># IPv6 du lien local de la box internet</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Gateway</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>fe80::aa:bb:cc:dd</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">GatewayOnLink</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">yes</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Route]</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># IPv4 de la box internet</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Gateway</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>192.168.0.254</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">GatewayOnLink</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">yes</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Address]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Address</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>192.168.0.100/24</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Address]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Address</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">2001</span><span>:db8:1:10::1ce:face/64</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Address]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Address</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>fe80::1ce:face/64 </span></span>
<span class="giallo-l"></span></code></pre>
<p>Pour le fichier <strong>11-lan.network</strong> :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Match]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>lan</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Network]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">DHCP</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">no</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">IPv6AcceptRA</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">false</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">LinkLocalAddressing</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">no</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Address]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Address</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>192.168.1.1/24</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Address]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Address</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">2001</span><span>:db8:1:11::1ce:cafe/64</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Address]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Address</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>fe80::1ce:cafe/64 </span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span></code></pre>
<p>Pour le fichier <strong>12-dmz.network</strong> :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Match]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>dmz</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Network]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">DHCP</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">no</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">IPv6AcceptRA</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">false</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">LinkLocalAddressing</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">no</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Address]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Address</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>192.168.2.1/24</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Address]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Address</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">2001</span><span>:db8:1:12::1ce:beef/64</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Address]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Address</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>fe80::1ce:beef/64 </span></span>
<span class="giallo-l"></span></code></pre><h3 id="activation-du-transfert-de-paquets">Activation du transfert de paquets</h3>
<p>Pour permettre à une machine linux de transférer les paquets d'une interface à l'autre il faut activer l'option de forwarding dans la config du systeme.</p>
<p>Ca se fait via le fichier /etc/sysctl.d/sysctl.conf. Il va falloir dé-commenter (ou ajouter) les lignes suivant:</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">net.ipv4.ip_forward</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">1</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">net.ipv6.conf.all.forwarding</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">1</span></span></code></pre><aside class=indice>
<p class=centre>⚠️ Attention ⚠️</p>
<p>Avant de faire la suite il va falloir redémarrer la machine. Ça permettra d'activer les changements au niveau de l’adressage et du forwarding.
Vérifiez bien que tout est OK avant de continuer.
Pour le forwarding, la commande "sysctl -p" permet de voir les paramètres modifiés actifs.</p>

</aside><h2 id="le-dhcp">Le DHCP</h2>
<p>Le DHCP est un protocole permettant l'attribution automatique d'une IPv4 à une machine qui se connecte sur un réseau. Pour que ça fonctionne on doit avoir un serveur DHCP qui répond aux sollicitations des machines.
On va utiliser <strong>Kea DHCP</strong> qui est le remplaçant du vénérable <strong>ISC DHCP</strong>.</p>
<p>On n'utilisera pas le DHCPv6 car il y a encore (trop) de machines qui ne respectent pas ce standard voir même qui, comme les smartphones android, n'implémentent même pas de quoi communiquer avec le serveur.</p>
<p>Le fichier de configuration de Kea <strong>/etc/kea/kea-dhcp4.conf</strong> est assez verbeux et contient pas mal d'indications. Les sections qui vont nous intéresser sont les suivantes.</p>
<p>Au début du fichier, on déclare sur quelles interfaces on sert le service DHCPv4 :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="json"><span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">Dhcp4</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>: </span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);"> Add names of your network interfaces to listen on.</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">    &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">interfaces-config</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span> {</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        //</span><span style="color: light-dark(#6A737D, #6A737D);"> See section 8.2.4 for more details. You probably want to add just</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        //</span><span style="color: light-dark(#6A737D, #6A737D);"> interface name (e.g. &quot;eth0&quot; or specific IPv4 address on that</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        //</span><span style="color: light-dark(#6A737D, #6A737D);"> interface name (e.g. &quot;eth0/192.0.2.1&quot;).</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">        &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">interfaces</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span> [</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">lan</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">dmz</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>]</span><span style="color: light-dark(#6A737D, #6A737D);"> //</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;--- Modifier ICI </span></span>
<span class="giallo-l"><span>    </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        //</span><span style="color: light-dark(#6A737D, #6A737D);"> Kea DHCPv4 server by default listens using raw sockets. This ensures</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        //</span><span style="color: light-dark(#6A737D, #6A737D);"> all packets, including those sent by directly connected clients</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        //</span><span style="color: light-dark(#6A737D, #6A737D);"> that don&#39;t have IPv4 address yet, are received. However, if your</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        //</span><span style="color: light-dark(#6A737D, #6A737D);"> traffic is always relayed, it is often better to use regular</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        //</span><span style="color: light-dark(#6A737D, #6A737D);"> UDP sockets. If you want to do that, uncomment this line:</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        //</span><span style="color: light-dark(#6A737D, #6A737D);"> &quot;dhcp-socket-type&quot;: &quot;udp&quot;</span></span>
<span class="giallo-l"><span>    }</span><span>,</span><span>  </span></span>
<span class="giallo-l"><span>    </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);">....... Reste du fichier</span></span>
<span class="giallo-l"><span>}</span></span></code></pre>
<p>Puis on declare la config des sous réseaux lan et dmz dans la section <strong>subnet4</strong>:</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="json"><span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">Dhcp4</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>: </span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);">....... Début du fichier</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">     &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">subnet4</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span> [</span></span>
<span class="giallo-l"><span>        {</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">id</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> 1</span><span>,</span></span>
<span class="giallo-l"><span>           </span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">subnet</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">192.168.1.0/24</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">interface</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">lan</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">            //</span><span style="color: light-dark(#6A737D, #6A737D);"> Plage d&#39;adresse dynamique à alouer.</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">pools</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span> [</span><span> {</span><span style="color: light-dark(#005CC5, #79B8FF);"> &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">pool</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">192.168.1.2 - 192.168.1.200</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span> }</span><span> ]</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">option-data</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span> [</span></span>
<span class="giallo-l"><span>                {</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                    &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">name</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">routers</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                    &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">data</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">192.168.1.1</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#6A737D, #6A737D);">  //</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;--- ICI mettre l&#39;IP de l&#39;interface lan.</span></span>
<span class="giallo-l"><span>                }</span><span>,</span></span>
<span class="giallo-l"><span>                {</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                        &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">name</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">domain-name-servers</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span><span style="color: light-dark(#6A737D, #6A737D);"> //</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;--- ICI mettre votre DNS. </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">                        //</span><span style="color: light-dark(#6A737D, #6A737D);"> Si vous faites la partie optionnelle de ce tuto mettre l&#39;IP de l&#39;interface lan</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">                        //</span><span style="color: light-dark(#6A737D, #6A737D);"> Sinon mettre l&#39;IP de votre box (ex 192.168.0.254) ou du DNS de votre choix (ex : DNS4EU en 86.54.11.1)</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                        &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">data</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">192.168.1.1</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span></span>
<span class="giallo-l"><span>                }</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>            ]</span><span>,</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">            //</span><span style="color: light-dark(#6A737D, #6A737D);"> Si vous voulez que certaines machines aient toujours la même ip c&#39;est dans cette section qu&#39;on le déclare</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">reservations</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span> [</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">                        //</span><span style="color: light-dark(#6A737D, #6A737D);">exemple avec une machine</span></span>
<span class="giallo-l"><span>                        {</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                                &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">hw-address</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">11:22:33:44:55:66</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span><span style="color: light-dark(#6A737D, #6A737D);"> //</span><span style="color: light-dark(#6A737D, #6A737D);"> L&#39;adresse MAC de la machine</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                                &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">ip-address</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">192.168.1.201</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span><span style="color: light-dark(#6A737D, #6A737D);"> //</span><span style="color: light-dark(#6A737D, #6A737D);"> L&#39;adresse IP souhaitées. Doit être en dehors de la plage dynamique.</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                                &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">hostname</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">PC_bureau</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span></span>
<span class="giallo-l"><span>                        }</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">                        //</span><span style="color: light-dark(#6A737D, #6A737D);"> exemple avec une seconde machine. N&#39;oubliez pas la virgule entre les deux.</span></span>
<span class="giallo-l"><span>                        {</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                                &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">hw-address</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">11:22:33:44:dd:ff</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> L&#39;adresse MAC de la machine</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                                &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">ip-address</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">192.168.69.202</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                                &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">hostname</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">PC_portable_2</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span></span>
<span class="giallo-l"><span>                        }</span></span>
<span class="giallo-l"><span>            ]</span></span>
<span class="giallo-l"><span>        }</span><span>,</span></span>
<span class="giallo-l"><span>        {</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">id</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> 2</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">subnet</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">192.168.2.0/24</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">interface</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">dmz</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">            //</span><span style="color: light-dark(#6A737D, #6A737D);"> Ici on définit un pool plus restreint. La plupart des IP seront configurées en fixe directement sur les machines.</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">pools</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span> [</span><span> {</span><span style="color: light-dark(#005CC5, #79B8FF);"> &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">pool</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">192.168.2.2 - 192.168.2.100</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span> }</span><span> ]</span><span>,</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">option-data</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span> [</span></span>
<span class="giallo-l"><span>                {</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                    &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">name</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">routers</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                    &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">data</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">192.168.2.1</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#6A737D, #6A737D);"> //</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;--- ICI mettre l&#39;IP de l&#39;interface dmz.</span></span>
<span class="giallo-l"><span>                }</span><span>,</span></span>
<span class="giallo-l"><span>                {</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                        &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">name</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">domain-name-servers</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                        &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">data</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">192.168.2.1</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;--- ICI mettre votre DNS. </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">                        //</span><span style="color: light-dark(#6A737D, #6A737D);"> Si vous faites la partie optionnelle de ce tuto mettre l&#39;IP de l&#39;interface wan</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">                        //</span><span style="color: light-dark(#6A737D, #6A737D);"> Sinon mettre l&#39;IP de votre box (ex 192.168.0.254) ou du DNS de votre choix (ex : DNS4EU en 86.54.11.1)</span></span>
<span class="giallo-l"><span>                }</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>            ]</span><span>,</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">reservations</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span> [</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">                 //</span><span style="color: light-dark(#6A737D, #6A737D);">exemple avec une machine</span></span>
<span class="giallo-l"><span>                        {</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                                &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">hw-address</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">aa:bb:cc:44:55:66</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span><span style="color: light-dark(#6A737D, #6A737D);"> //</span><span style="color: light-dark(#6A737D, #6A737D);"> L&#39;adresse MAC de la machine</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                                &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">ip-address</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">192.168.2.101</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span><span style="color: light-dark(#6A737D, #6A737D);"> //</span><span style="color: light-dark(#6A737D, #6A737D);"> L&#39;adresse IP souhaitées. Doit être en dehors de la plage dynamique.</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">                                &quot;</span><span style="color: light-dark(#005CC5, #79B8FF);">hostname</span><span style="color: light-dark(#005CC5, #79B8FF);">&quot;</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">server_mail</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span></span>
<span class="giallo-l"><span>                        }</span></span>
<span class="giallo-l"><span>            ]</span></span>
<span class="giallo-l"><span>        }</span></span>
<span class="giallo-l"><span>    ]</span><span>,</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);">....... Reste du fichier</span></span>
<span class="giallo-l"><span>}</span></span></code></pre>
<p>Puis on n'oublie pas de recharger la config de Kea.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> restart</span><span style="color: light-dark(#032F62, #9ECBFF);"> kea-dhcp4-server.service</span><span> </span></span></code></pre><h2 id="le-routing-advertisement">Le routing advertisement</h2>
<p>C'est un peu le même principe que pour le DCHP. En prefix on met le réseau correspondant à l'interface et en RDNSS l'adress IPv6 du DNS.
Si tu fais la partie du tuto optionnelle sur le DNS, il faut mettre l'IP de l'interface elle même. Sinon tu peux utiliser un résolveur public (ex : DNS4EU en 2a13:1001::86:54:11:1)</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="nginx"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">interface</span><span> lan_bridge {</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">   AdvSendAdvert</span><span style="color: light-dark(#005CC5, #79B8FF);"> on</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">   prefix</span><span> 2001:db8:1:11::/64</span></span>
<span class="giallo-l"><span>   {</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">      AdvOnLink</span><span style="color: light-dark(#005CC5, #79B8FF);"> on</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">      AdvAutonomous</span><span style="color: light-dark(#005CC5, #79B8FF);"> on</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">      AdvRouterAddr</span><span style="color: light-dark(#005CC5, #79B8FF);"> on</span><span>;</span></span>
<span class="giallo-l"><span>   }</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">   RDNSS</span><span> 2001:db8:1:11::1ce:cafe {}</span><span>;</span></span>
<span class="giallo-l"><span>};</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">interface</span><span> dmz {</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">   AdvSendAdvert</span><span style="color: light-dark(#005CC5, #79B8FF);"> on</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">   prefix</span><span> 2001:db8:1:12::/64</span></span>
<span class="giallo-l"><span>   {</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">      AdvOnLink</span><span style="color: light-dark(#005CC5, #79B8FF);"> on</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">      AdvAutonomous</span><span style="color: light-dark(#005CC5, #79B8FF);"> on</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">      AdvRouterAddr</span><span style="color: light-dark(#005CC5, #79B8FF);"> on</span><span>;</span></span>
<span class="giallo-l"><span>   }</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">   RDNSS</span><span> 2001:db8:1:12::1ce:beef {}</span><span>;</span></span>
<span class="giallo-l"><span>};</span></span></code></pre>
<p>Puis on n'oublie pas de recharger la config.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> reload</span><span style="color: light-dark(#032F62, #9ECBFF);"> radvd.service</span><span> </span></span></code></pre><h2 id="le-pare-feu">Le pare-feu</h2>
<p>Là on attaque la partie la plus complexe.</p>
<p>Pour schématiser, le pare-feu applique les règles en fonction du sens des paquets IP :</p>
<ul>
<li>Inbound : les paquets qui arrivent par une interface réseau et à destination d'une des IP de cette machine.</li>
<li>Output : Les paquets emis par cette machine et qui sortent par une interface.</li>
<li>Forward : les paquetes qui arrive par une interface réseau et qui ne sont pas à destination d'une IP de cette machine. Ils doivent la traverser pour en atteindre une autre.</li>
</ul>
<p>En plus des fonctionnalités de filtrage il va falloir utiliser du <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Network_address_translation">NAT</a>. En effet, notre DMZ est capable de router le trafic vers la Box internet en IPv4 et IPv6, mais les box des FAIs n'ont presque jamais la possibilité de configurer des routes statiques en IPv4. Il faut donc ruser avec du NAT.</p>
<p>Un schéma récapitulatif du comportement de nftable est dispo sur le site officiel :</p>
<figure>
    
        <img src="https:&#x2F;&#x2F;www.selenith.org&#x2F;articles&#x2F;creer-une-dmz-complete-sous-linux&#x2F;nf-hooks.svg"  alt="nft hooks"  />
    
    <figcaption>
        <p>© nft hooks par  <a class="external-link" rel="noopener external" target="_blank" href="https://people.netfilter.org/pablo/">Pablo Neira Ayuso</a></p>

    </figcaption>
</figure>
<!-- <hr />-->
<h3 id="la-config">La config</h3>
<p>On va configurer nftable via le fichier /etc/nftables.conf.
L'avantage de nftable sur iptables (à part qu'il est son successeur et que iptables est censé ne plus être utilisé hein), c'est qu'on peut définir des variables et des tableaux. C'est donc bien plus facile à maintenir et à comprendre. On verra dans la section suivante comment se servir des compteurs.</p>
<p>Pour l'exemple on va dire qu'on a deux serveurs dans la zone DMZ, un serveur web et un serveur de mail. Les explications sont dans les commentaires du fichier. Le fichier étant un peu larges, tu peux utiliser shift+molette de souris pour déplacer le texte latéralement dans le bloc ci-dessous.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="nginx"><span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#!/usr/sbin/nft -f</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># On nettoie tout avant d’appliquer la config</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">flush</span><span> ruleset</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># ---- Variables du réseau ----</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># Nom de l&#39;interface lan. </span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">define</span><span> DEV_LAN = </span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">lan</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># Nom de l&#39;interface wan</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">define</span><span> DEV_WAN = </span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">wan</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># Nom de l&#39;interface dmz</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">define</span><span> DEV_DMZ = </span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">dmz</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># Declaration des subnets locaux</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">define</span><span> NET_DMZ = 192.168.2.0/24</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">define</span><span> NET_LAN = 192.168.1.0/24</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">define</span><span> NET_IPV6_LAN = 2001:db8:1:11::/64</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># Déclaration des IP spécifiques</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">define</span><span> INT_WAN_IP = 192.168.0.100</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">define</span><span> IPV6_SERVEUR_mail = 2001:db8:1:12::dad:c0de</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">define</span><span> IPV4_SERVEUR_mail = 192.168.2.101</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">define</span><span> IPV6_SERVEUR_web = 2001:db8:1:12::dad:cafe</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">define</span><span> IPV4_SERVEUR_web = 192.168.2.102</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">table</span><span> inet global {</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# --------------------- Chaines d&#39;aiguillage -----------------------</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Point d&#39;entrée principal pour tout le traffic (non source-naté) IPv4 et ipv6 à destination de cette machine</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Cette règle va aiguiller les décisions vers les blocs (chains) inbound correspondants.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	chain</span><span> inbound {</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		type</span><span> filter hook input priority </span><span style="color: light-dark(#005CC5, #79B8FF);">0</span><span>;</span><span style="color: light-dark(#D73A49, #F97583);"> policy</span><span> drop</span><span>;</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Allow traffic from established and related packets, drop invalid</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		ct</span><span> state vmap { established : accept, related : accept, invalid : drop }</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# allow loopback traffic, anything else jump to chain for further evaluation</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		iif</span><span> vmap { lo : accept, </span><span>$</span><span>DEV_WAN</span><span> : jump inbound_wan, </span><span>$</span><span>DEV_DMZ</span><span> : jump inbound_dmz, </span><span>$</span><span>DEV_LAN_BRIDGE</span><span> : jump inbound_lan}</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# On revient ici après les aiguillages (jump) si le paquet n&#39;a pas été accepté. </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Et si on arrive ici, le paquet est detruit par la policy drop en debut de bloc.</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# point d&#39;entrée principale pour tout le traffic ipv4 et ipv6 qui est routé au travers de cette machine</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Cette règle va aiguiller les décisions vers les blocs (chains) forward correspondants.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	chain</span><span> forward {</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		type</span><span> filter hook forward priority </span><span style="color: light-dark(#005CC5, #79B8FF);">0</span><span>;</span><span style="color: light-dark(#D73A49, #F97583);"> policy</span><span> drop</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# accepte de forward depuis la loopback</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		iif</span><span> lo counter accept</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Allow traffic from established and related packets, drop invalid</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		ct</span><span> state invalid counter drop</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		ct</span><span> state { established, related } counter accept</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Accepte de transferer le trafic depuis le LAN </span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		iif</span><span> $</span><span>DEV_LAN_BRIDGE</span><span> counter accept</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Le traffic venant du WAN va être évalué.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		iif</span><span> $</span><span>DEV_WAN</span><span> counter jump forward_from_wan</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Le traffic venant de la DMZ va être évalué.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		iif</span><span> $</span><span>DEV_DMZ</span><span> counter jump forward_from_dmz</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# On revient ici après les aiguillages (jump) si le paquet n&#39;a pas été accepté. </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Et si on arrive ici, le paquet est detruit par la policy drop en debut de bloc</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# On met un petit compteur au besoin pour voir ce qui est drop.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		counter</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"><span>	</span></span>
<span class="giallo-l"><span>	</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Sortie. Pas de filtre. Cette machine est considéré de confiance.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	chain</span><span> output {</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		type</span><span> filter hook output priority </span><span style="color: light-dark(#005CC5, #79B8FF);">0</span><span>;</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# --------------------- fin : Chaines d&#39;aiguillage ----------------</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# --------------------- Chaines de décision -----------------------</span></span>
<span class="giallo-l"><span>	</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Ici c&#39;est la chaîne de décision pour les paquets qui viennent du WAN (d&#39;internet) à destination de cette machine</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# On bloque tout sauf l&#39;ICMPv6 nécessaire au routage.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	chain</span><span> inbound_wan {</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# On accepte les paquets IPv6 permettant à notre routeur de communiquer avec les autres.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# On limite cependant a 10 requêtes par seconde pour eviter de se faire flooder la machine </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# par une machine malveillante depuis internet</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		icmpv6</span><span> type {echo-request,nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert,mld-listener-query,destination-unreachable,packet-too-big,time-exceeded,parameter-problem} limit rate 10/second accept		</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Ce qui est bloqué est noté dans un compteur nommé.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		counter</span><span> name dropped_from_wan</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Ici c&#39;est la chaîne décision pour les paquets qui viennent du LAN a destination de cette machine</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Les utilisateurs du LAN sont considérés de confiance. On permet l&#39;accès a cette machine (pour le SSH, le DHCP, </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# les requêtes DNS si vous faites la partie optionnel du tuto, etc).</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	chain</span><span> inbound_lan {</span></span>
<span class="giallo-l"><span>	</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		ip6</span><span> saddr </span><span>$</span><span>NET_IPV6_LAN</span><span> accept </span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		ip</span><span> saddr </span><span>$</span><span>NET_LAN</span><span> accept</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Ici c&#39;est la chaîne de décision pour les paquets qui viennent de la zone DMZ a destination de cette machine</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Les machines de la DMZ sont considérées comme potentiellement compromises. On permet l&#39;accès </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# à cette machine pour certains services légitimes, mais on bloque tout le reste.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	chain</span><span> inbound_dmz {</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Comme pour la chaine inbound_wan au dessus, on accepte l&#39;ICMPv6 mais en limitant pour éviter le flooding.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		icmpv6</span><span> type {echo-request,nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert,mld-listener-query,destination-unreachable,packet-too-big,time-exceeded,parameter-problem} limit rate 10/second counter accept</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# On accepte également le ping ipv4 de manière limité afin de permettre le bon fonctionnement (ex : packet too big) et l&#39;éventuel debugging des serveurs.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		icmp</span><span> type echo-request limit rate 10/second counter accept</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Communication entrante avec le routeur (cette machine)</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# On accepte le DHCP</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		udp</span><span> dport </span><span style="color: light-dark(#005CC5, #79B8FF);">67</span><span> accept</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# On accepte le DNS</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		udp</span><span> dport </span><span style="color: light-dark(#005CC5, #79B8FF);">53</span><span> accept</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		tcp</span><span> dport </span><span style="color: light-dark(#005CC5, #79B8FF);">53</span><span> accept</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# On accepte le mdns (tu sais le truc avec avahi-daemon et les requêtes en .local)</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		udp</span><span> dport </span><span style="color: light-dark(#005CC5, #79B8FF);">5353</span><span> accept</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Ce qui est bloqué est noté dans un compteur nommé.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		counter</span><span> name dropped_from_dmz</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Décisions pour le trafic qui vient du WAN et traverse cette machine</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	chain</span><span> forward_from_wan {</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Comme pour la chaine inbound_wan au dessus, on accepte l&#39;ICMPv6 mais en limitant pour éviter le flooding.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		icmpv6</span><span> type {echo-request,nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert,mld-listener-query,destination-unreachable,packet-too-big,time-exceeded,parameter-problem} limit rate 10/second counter accept</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Pareil pour l&#39;ICMPv4</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		icmp</span><span> type echo-request limit rate 10/second counter accept</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Accepte HTTP/s vers le serveur web.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		ip6</span><span> daddr </span><span>$</span><span>IPV6_SERVEUR_web</span><span> tcp dport { http, https} counter accept</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		ip</span><span> daddr </span><span>$</span><span>IPV4_SERVEUR_web</span><span> tcp dport { http, https} counter accept</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Accepte les Mails vers le serveur mail (SMTP, IMAPS et submission).</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		ip6</span><span> daddr </span><span>$</span><span>IPV6_SERVEUR_mail</span><span> tcp dport { 25, 587, 993} counter accept</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		ip</span><span> daddr </span><span>$</span><span>IPV4_SERVEUR_mail</span><span> tcp dport { 25, 587, 993} counter accept</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Ce qui est bloqué est noté dans un compteur nommé.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		counter</span><span> name dropped_from_wan</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Décisions pour le trafic qui vient de la zone DMZ et traverse cette machine</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	chain</span><span> forward_from_dmz {</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Comme pour la chaine inbound_wan au dessus, on accepte l&#39;ICMPv6 mais en limitant pour éviter le flooding.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		icmpv6</span><span> type {echo-request,nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert,mld-listener-query,destination-unreachable,packet-too-big,time-exceeded,parameter-problem} limit rate 10/second counter accept</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Pareil pour l&#39;ICMPv4</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		icmp</span><span> type echo-request limit rate 10/second counter accept</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Vers le wan</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Http(s) utilisé pour mise a jours debian.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Port 25 utilisé pour envoyer des mail depuis le serveur mail</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		oif</span><span> $</span><span>DEV_WAN</span><span> tcp dport {25, http, https} counter accept</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# On accepte les requetes ntp vers le wan</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		oif</span><span> $</span><span>DEV_WAN</span><span> tcp dport </span><span style="color: light-dark(#005CC5, #79B8FF);">123</span><span> accept</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		oif</span><span> $</span><span>DEV_WAN</span><span> udp dport </span><span style="color: light-dark(#005CC5, #79B8FF);">123</span><span> accept</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# Ce qui est bloqué est noté dans un compteur local.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		counter</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# --------------------- fin : Chaines de décision -----------------</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# --------------------- Chaines de NAT ----------------------------</span></span>
<span class="giallo-l"><span>	</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Nat de l&#39;IPv4	en sortie (masquarade)</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	chain</span><span> postrouting {</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		type</span><span> nat hook postrouting priority </span><span style="color: light-dark(#005CC5, #79B8FF);">100</span><span>;</span><span style="color: light-dark(#D73A49, #F97583);"> policy</span><span> accept</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">		# masquerade private IP addresses</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		ip</span><span> saddr </span><span>$</span><span>NET_LAN</span><span> oif </span><span>$</span><span>DEV_WAN</span><span> masquerade</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		ip</span><span> saddr </span><span>$</span><span>NET_DMZ</span><span> oif </span><span>$</span><span>DEV_WAN</span><span> masquerade</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"><span>	</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# Nat de l&#39;IPv4 en entrée. Obligatoire car pas de routage possible sur la box internet</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	chain</span><span> prerouting {</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		type</span><span> nat hook prerouting priority -100</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		iif</span><span> $</span><span>DEV_WAN</span><span> ip daddr </span><span>$</span><span>INT_WAN_IP</span><span> tcp dport { 25, 143, 587, 993} counter dnat ip to </span><span>$</span><span>IPV4_SERVEUR_mail</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		iif</span><span> $</span><span>DEV_WAN</span><span> ip daddr </span><span>$</span><span>INT_WAN_IP</span><span> tcp dport { http, https} counter dnat ip to </span><span>$</span><span>IPV4_SERVEUR_web</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"><span>	</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # --------------------- fin : Chaines de NAT ----------------------</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# --------------------- Compteurs nommés --------------------------</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	counter</span><span> dropped_from_wan{</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		comment</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">paquets bloqués en entrée wan en direction du parefeu ou du réseau local</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	counter</span><span> dropped_from_dmz{</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		comment</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">paquets bloqués en entrée dmz en direction du parefeu, du réseau local ou du wan</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	# --------------------- fin : Compteurs nommés --------------------</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span></code></pre>
<p>Une fois la configuration écrite, on la recharge :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> reload</span><span style="color: light-dark(#032F62, #9ECBFF);"> nftables.service</span></span></code></pre><h3 id="les-commandes-utiles">Les commandes utiles</h3>
<p>Nftables permet de consulter les différents compteurs. C'est utile pour comprendre où sont bloqués les paquets en cas d'erreur de configuration. Ça permet aussi de vérifier que les blocages volontaires fonctionnent correctement.</p>
<p>Pour voir les compteurs nommés :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">nft</span><span style="color: light-dark(#032F62, #9ECBFF);"> list</span><span style="color: light-dark(#032F62, #9ECBFF);"> counters</span></span></code></pre>
<p>Pour voir les compteurs locaux d'une chaine. Exemple avec la chaine <strong>forward_from_wan</strong> :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">nft</span><span style="color: light-dark(#032F62, #9ECBFF);"> list</span><span style="color: light-dark(#032F62, #9ECBFF);"> chain</span><span style="color: light-dark(#032F62, #9ECBFF);"> inet</span><span style="color: light-dark(#032F62, #9ECBFF);"> global</span><span style="color: light-dark(#032F62, #9ECBFF);"> forward_from_wan</span></span></code></pre>
<p>Il aussi est possible de réinitialiser les compteurs sans redémarrer nftables :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">nft</span><span style="color: light-dark(#032F62, #9ECBFF);"> reset</span><span style="color: light-dark(#032F62, #9ECBFF);"> counters</span></span></code></pre><h2 id="optionnel-le-dns">(Optionnel) le DNS</h2>
<p>Cette partie optionnelle permet que toutes les requêtes DNS du LAN et de la DMZ passent par le routeur. Il se chargera ensuite d'envoyer les requêtes vers un résolveur de confiance en TLS, ce qui assurera un minimum de confidentialité.</p>
<p>Avoir un résolveur local permet aussi d'ajouter des noms d'hôte à ses propres machines, ce qui est plutôt pratique pour ne pas taper des IPv6 à rallonge pour se connecter aux serveurs de mail, nas, etc.</p>
<p>Commençons par installer le daemon qui va bien :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">apt</span><span style="color: light-dark(#032F62, #9ECBFF);"> install</span><span style="color: light-dark(#032F62, #9ECBFF);"> unbound</span></span></code></pre>
<p>Il suffit ensuite de créer un fichier de configuration de zone dans /etc/unbound/unbound.conf.d/ma_zone.conf</p>
<p>Puis de l'éditer de la manière suivante (les explications sont dans les commentaires) :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="yaml"><span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"># Simple recursive caching DNS</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"># unbound.conf -- https://DNSwatch.COM</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">s</span><span style="color: light-dark(#22863A, #85E89D);">erver</span><span>:</span></span>
<span class="giallo-l"><span>	</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> verbosity number, 0 is least verbose. 1 is default.</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        v</span><span style="color: light-dark(#22863A, #85E89D);">erbosity</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> 1</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> number of threads to create. 1 disables threading.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> num-threads: 1</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> the amount of memory to use for the RRset cache.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        #</span><span style="color: light-dark(#6A737D, #6A737D);"> plain value in bytes or you can append k, m or G. default is &quot;4Mb&quot;.</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        r</span><span style="color: light-dark(#22863A, #85E89D);">rset-cache-size</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 1</span><span style="color: light-dark(#032F62, #9ECBFF);">28m</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> the amount of memory to use for the message cache.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        #</span><span style="color: light-dark(#6A737D, #6A737D);"> plain value in bytes or you can append k, m or G. default is &quot;4Mb&quot;.</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        m</span><span style="color: light-dark(#22863A, #85E89D);">sg-cache-size</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 6</span><span style="color: light-dark(#032F62, #9ECBFF);">4m</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> Enforce privacy of these addresses. Strips them away from answers.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        #</span><span style="color: light-dark(#6A737D, #6A737D);"> It may cause DNSSEC validation to additionally mark it as bogus.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        #</span><span style="color: light-dark(#6A737D, #6A737D);"> Protects against &#39;DNS Rebinding&#39; (uses browser as network proxy).</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        #</span><span style="color: light-dark(#6A737D, #6A737D);"> Only &#39;private-domain&#39; and &#39;local-data&#39; names are allowed to have</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        #</span><span style="color: light-dark(#6A737D, #6A737D);"> these private addresses. No default.</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        p</span><span style="color: light-dark(#22863A, #85E89D);">rivate-address</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 1</span><span style="color: light-dark(#032F62, #9ECBFF);">0.0.0.0/8</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        p</span><span style="color: light-dark(#22863A, #85E89D);">rivate-address</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 1</span><span style="color: light-dark(#032F62, #9ECBFF);">72.16.0.0/12</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        p</span><span style="color: light-dark(#22863A, #85E89D);">rivate-address</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 1</span><span style="color: light-dark(#032F62, #9ECBFF);">92.168.0.0/16</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        p</span><span style="color: light-dark(#22863A, #85E89D);">rivate-address</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 1</span><span style="color: light-dark(#032F62, #9ECBFF);">69.254.0.0/16</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        p</span><span style="color: light-dark(#22863A, #85E89D);">rivate-address</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> f</span><span style="color: light-dark(#032F62, #9ECBFF);">d00::/8</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        p</span><span style="color: light-dark(#22863A, #85E89D);">rivate-address</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> f</span><span style="color: light-dark(#032F62, #9ECBFF);">e80::/10</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        p</span><span style="color: light-dark(#22863A, #85E89D);">rivate-address</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> ::</span><span style="color: light-dark(#032F62, #9ECBFF);">ffff:0:0/96</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        #</span><span style="color: light-dark(#6A737D, #6A737D);"> ---vvvvvv---  ICI on ajoute les réseaux IPv6 sur lesquels on veut définir des noms d&#39;hôtes. ---vvvvvvvvvv---</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        p</span><span style="color: light-dark(#22863A, #85E89D);">rivate-address</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 2</span><span style="color: light-dark(#032F62, #9ECBFF);">001:db8:1:12::/64</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;---- ICI exemple avec réseau DMZ dans lequel on va déclarer un nas</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> Allow the domain (and its subdomains) to contain private addresses.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        #</span><span style="color: light-dark(#6A737D, #6A737D);"> local-data statements are allowed to contain private addresses too.</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        p</span><span style="color: light-dark(#22863A, #85E89D);">rivate-domain</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">maison</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);">  &lt;---- ICI le domaine de premier niveau qu&#39;on veut déclarer</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> a number of locally served zones can be configured.</span></span>
<span class="giallo-l"><span>	# 	</span><span style="color: light-dark(#22863A, #85E89D);">l</span><span style="color: light-dark(#22863A, #85E89D);">ocal-zone</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &lt;</span><span style="color: light-dark(#032F62, #9ECBFF);">zone&gt; &lt;type&gt;</span></span>
<span class="giallo-l"><span>	# 	</span><span style="color: light-dark(#22863A, #85E89D);">l</span><span style="color: light-dark(#22863A, #85E89D);">ocal-data</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">&lt;resource record string&gt;</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o deny serves local data (if any), else, drops queries.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o refuse serves local data (if any), else, replies with error.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o static serves local data, else, nxdomain or nodata answer.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o transparent gives local data, but resolves normally for other names</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o redirect serves the zone data for any subdomain in the zone.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o nodefault can be used to normally resolve AS112 zones.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o typetransparent resolves normally for other types and other names</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o inform acts like transparent, but logs client IP address</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o inform_deny drops queries and logs client IP address</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o inform_redirect redirects queries and logs client IP address</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o always_transparent, always_refuse, always_nxdomain, always_nodata,</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);">   always_deny resolve in that way but ignore local data for</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);">   that name</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o always_null returns 0.0.0.0 or ::0 for any name in the zone.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> o noview breaks out of that view towards global local-zones.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> defaults are localhost address, reverse for 127.0.0.1 and ::1</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> and nxdomain for AS112 zones. If you configure one of these zones</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> the default content is omitted, or you can omit it with &#39;nodefault&#39;.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> If you configure local-data without specifying local-zone, by</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> default a transparent local-zone is created for the data.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> You can add locally served data with</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> local-zone: &quot;local.&quot; static</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> local-data: &quot;mycomputer.local. IN A 192.0.2.51&quot;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> local-data: &#39;mytext.local TXT &quot;content of text record&quot;&#39;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> note : les CNAMEs ne fonctionnent pas en local-data et local-zone</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	l</span><span style="color: light-dark(#22863A, #85E89D);">ocal-zone</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">maison.</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);"> s</span><span style="color: light-dark(#032F62, #9ECBFF);">tatic</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	l</span><span style="color: light-dark(#22863A, #85E89D);">ocal-data</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">nas.maison.       IN A    192.168.2.250</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);">  &lt;---- ICI l&#39;IPv4 de la machine d&#39;exemple</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	l</span><span style="color: light-dark(#22863A, #85E89D);">ocal-data</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">nas.maison.       IN AAAA 2001:db8:1:12::250</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);">  &lt;---- ICI l&#39;IPv6 de la machine d&#39;exemple</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> specify the interfaces to answer queries from by ip-address.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> The default is to listen to localhost (127.0.0.1 and ::1).</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> specify 0.0.0.0 and ::0 to bind to all available interfaces.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> specify every interface[@port] on a new &#39;interface:&#39; labelled line.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> The listen interfaces are not changed on reload, only on restart.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> interface: 192.0.2.153</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	i</span><span style="color: light-dark(#22863A, #85E89D);">nterface</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> 127.0.0.1</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	i</span><span style="color: light-dark(#22863A, #85E89D);">nterface</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> ::</span><span style="color: light-dark(#032F62, #9ECBFF);">1</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	i</span><span style="color: light-dark(#22863A, #85E89D);">nterface</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> 192.168.1.1</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on ajoute l&#39;IPv4 de l&#39;interface LAN</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	i</span><span style="color: light-dark(#22863A, #85E89D);">nterface</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 2</span><span style="color: light-dark(#032F62, #9ECBFF);">001:db8:1:11::1ce:cafe</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on ajoute l&#39;IPv6 de l&#39;interface LAN</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	i</span><span style="color: light-dark(#22863A, #85E89D);">nterface</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> 192.168.2.1</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on ajoute l&#39;IPv4 de l&#39;interface DMZ</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	i</span><span style="color: light-dark(#22863A, #85E89D);">nterface</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 2</span><span style="color: light-dark(#032F62, #9ECBFF);">001:db8:1:12::1ce:beef</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on ajoute l&#39;IPv6 de l&#39;interface DMZ</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> specify the interfaces to send outgoing queries to authoritative</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> server from by ip-address. If none, the default (all) interface</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> is used. Specify every interface on a &#39;outgoing-interface:&#39; line.</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	i</span><span style="color: light-dark(#22863A, #85E89D);">p-freebind</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> yes</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	o</span><span style="color: light-dark(#22863A, #85E89D);">utgoing-interface</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> 192.168.0.100</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on ajoute l&#39;IPv4 de l&#39;interface WAN</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	o</span><span style="color: light-dark(#22863A, #85E89D);">utgoing-interface</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 2</span><span style="color: light-dark(#032F62, #9ECBFF);">001:db8:1:10::1ce:face</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on ajoute l&#39;IPv6 de l&#39;interface WAN</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);">prefer-ip6: yes</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> control which clients are allowed to make (recursive) queries</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> to this server. Specify classless netblocks with /size and action.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> By default everything is refused, except for localhost.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> Choose deny (drop message), refuse (polite error reply),</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> allow (recursive ok), allow_setrd (recursive ok, rd bit is forced on),</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> allow_snoop (recursive and nonrecursive ok)</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> deny_non_local (drop queries unless can be answered from local-data)</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> refuse_non_local (like deny_non_local but polite error reply).</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	a</span><span style="color: light-dark(#22863A, #85E89D);">ccess-control</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 1</span><span style="color: light-dark(#032F62, #9ECBFF);">27.0.0.0/8 allow</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	a</span><span style="color: light-dark(#22863A, #85E89D);">ccess-control</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> ::</span><span style="color: light-dark(#032F62, #9ECBFF);">1 allow</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	a</span><span style="color: light-dark(#22863A, #85E89D);">ccess-control</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 1</span><span style="color: light-dark(#032F62, #9ECBFF);">92.168.1.0/24 allow</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on ajoute la zone LAN en IPv4</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	a</span><span style="color: light-dark(#22863A, #85E89D);">ccess-control</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 2</span><span style="color: light-dark(#032F62, #9ECBFF);">001:db8:1:11::::/64 allow</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on ajoute la zone LAN en IPv6</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	a</span><span style="color: light-dark(#22863A, #85E89D);">ccess-control</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 1</span><span style="color: light-dark(#032F62, #9ECBFF);">92.168.2.0/24 allow</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on ajoute la zone DMZ en IPv4</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	a</span><span style="color: light-dark(#22863A, #85E89D);">ccess-control</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 2</span><span style="color: light-dark(#032F62, #9ECBFF);">001:db8:1:12::/64 allow</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on ajoute la zone DMZ en IPv6</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> enable to not answer id.server and hostname.bind queries.</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        h</span><span style="color: light-dark(#22863A, #85E89D);">ide-identity</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> yes</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        #</span><span style="color: light-dark(#6A737D, #6A737D);"> enable to not answer version.server and version.bind queries.</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">        h</span><span style="color: light-dark(#22863A, #85E89D);">ide-version</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> yes</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> request upstream over TLS (with plain DNS inside the TLS stream).</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> Default is no.  Can be turned on and off with unbound-control.</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	t</span><span style="color: light-dark(#22863A, #85E89D);">ls-upstream</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> no</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> Forward zones</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> Create entries like below, to make all queries for &#39;example.com&#39; and</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> &#39;example.org&#39; go to the given list of servers. These servers have to handle</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> recursion to other nameservers. List zero or more nameservers by hostname</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> or by ipaddress. Use an entry with name &quot;.&quot; to forward all queries.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> If you enable forward-first, it attempts without the forward if it fails.</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">f</span><span style="color: light-dark(#22863A, #85E89D);">orward-zone</span><span>:</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	n</span><span style="color: light-dark(#22863A, #85E89D);">ame</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	f</span><span style="color: light-dark(#22863A, #85E89D);">orward-tls-upstream</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> yes</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on indique que les requêtes sortantes sont en TLS.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	#</span><span style="color: light-dark(#6A737D, #6A737D);"> Résolveurs DNS4EU</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	f</span><span style="color: light-dark(#22863A, #85E89D);">orward-addr</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 2</span><span style="color: light-dark(#032F62, #9ECBFF);">a13:1001::86:54:11:1@853</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on ajoute le résolveur de notre choix </span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	f</span><span style="color: light-dark(#22863A, #85E89D);">orward-addr</span><span>:</span><span style="color: light-dark(#032F62, #9ECBFF);"> 2</span><span style="color: light-dark(#032F62, #9ECBFF);">a13:1001::86:54:11:201@853</span><span style="color: light-dark(#6A737D, #6A737D);"> #</span><span style="color: light-dark(#6A737D, #6A737D);"> &lt;------- ICI on peut en mettre un autre </span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">	f</span><span style="color: light-dark(#22863A, #85E89D);">orward-first</span><span>:</span><span style="color: light-dark(#005CC5, #79B8FF);"> no</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span></code></pre>
<p>Une fois la configuration terminée, il faut la recharger.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> reload</span><span style="color: light-dark(#032F62, #9ECBFF);"> unbound.service</span><span> </span></span></code></pre>
<p>Avec cet exemple un "ping nas.maison" fonctionnera depuis une machine connecté dans les zone DMZ et/ou LAN.
Et par la magie du domaine privé, le raccourcis "ping nas" devrait fonctionner aussi.</p>
<h2 id="la-box-internet">La box internet</h2>
<p>A partir d'ici, tu vas pouvoir déplacer tout ce qui est branché à la box vers les bonnes interfaces du routeur. S'il y a plus d'une machine sur une zone il faudra utiliser un Switch.</p>
<p>Selon ton FAI tu vas pouvoir :</p>
<ul>
<li>Désactiver la fonction firewall IPv6.</li>
<li>Activer la fonction DMZ IPV4 en indiquant en destination l'adresse IPv4 de l'interface WAN (optionnel, ici 192.168.0.100).</li>
<li>Changer les éventuelles règles de NAT qu'il y avait déjà, en direction de l'IPv4 de l'interface WAN (toujours 192.168.0.100 dans ce tuto) si tu n'as pas activé la fonction DMZ.</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>Nous avons vu comment créer une bulle isolée dans ton réseau qui a accès à internet mais seulement vers les ports autorisés et qui ne peut pas initier de connections vers ton LAN.
Cette bulle qu'on a nommé DMZ permet d'y déployer des serveurs qu'on peut rendre accessibles avec les règles appropriées depuis l’extérieur.</p>
<p>Tu peux également ajouter autant de zones du même type tant que tu disposes d'interfaces réseaux supplémentaires. Il peut être intéressant justement de créer une bulle spéciale pour les objets connecté pour lesquels tu ne peux avoir aucune certitude sur <a class="external-link" rel="noopener external" target="_blank" href="https://www.numerama.com/cyberguerre/2103247-le-jour-ou-mon-aspirateur-intelligent-sest-retourne-contre-moi-un-developpeur-raconte-comment-un-produit-bon-marche-a-cartographie-son-domicile.html">ce qu'ils font sur ton réseau</a>.</p>
<p>Nous verrons dans de prochains articles comment ajouter une liste noire d'IP malveillantes dans notre pare-feu et aussi comment intégrer une antenne wifi, dans une des zones, directement sur le routeur.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>selenith.org</title>
        <published>2025-11-01T00:00:00+00:00</published>
        <updated>2025-11-01T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/notes/selenith-org/" type="text/html"/>
        <id>https://www.selenith.org/notes/selenith-org/</id>
       
        <content type="html"><![CDATA[<p>Nouveau domaine pour mon site. Je me suis pris un domaine de premier niveau en .org. C'est plus propre et en plus j'ai même mis un prefix en www histoire de normaliser l'acces au serveur web. Normalement vous devriez être redirigé correctement depuis l'ancien domaine ;)</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Thèmes sombre et clair</title>
        <published>2025-06-17T00:00:00+00:00</published>
        <updated>2025-06-17T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/notes/themes-sombre-et-clair/" type="text/html"/>
        <id>https://www.selenith.org/notes/themes-sombre-et-clair/</id>
       
        <content type="html"><![CDATA[<p>Un petit coup de CSS pour adapter le thème du site à ce que ton navigateur demande. Tu peux maintenant le consulter en version claire ou sombre !</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Tuto I2P sur std.rocks</title>
        <published>2025-06-12T00:00:00+00:00</published>
        <updated>2025-06-12T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/notes/tuto-i2p-sur-std-rocks/" type="text/html"/>
        <id>https://www.selenith.org/notes/tuto-i2p-sur-std-rocks/</id>
       
        <content type="html"><![CDATA[<p>Je viens de voir qu'il y a des supers tutoriels sur la suite logicielle <a class="external-link" rel="noopener external" target="_blank" href="https://geti2p.net/fr/">Invisible Internet Project</a> (i2p) sur le site <a class="external-link" rel="noopener external" target="_blank" href="https://std.rocks">std.rocks</a>. L'un pour <a class="external-link" rel="noopener external" target="_blank" href="https://std.rocks/fr/p2p_i2p_windows11.html">l'installation</a> et le deuxieme pour le <a class="external-link" rel="noopener external" target="_blank" href="https://std.rocks/fr/p2p_i2p_torrent.html">partage de fichiers</a> anonyme en p2p. Les tutos sont pour windows mais il y a aussi plein d'infos utiles valables pour linux.</p>
<p>Pour ceux qui ne connaissent pas, I2P est un <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/R%C3%A9seau_superpos%C3%A9">réseau superposé</a> et décentralisé qui anonymise le trafic au travers d'une couche dédiée par dessus internet.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>apn free mobile</title>
        <published>2025-06-11T00:00:00+00:00</published>
        <updated>2025-06-11T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/notes/apn-free-mobile/" type="text/html"/>
        <id>https://www.selenith.org/notes/apn-free-mobile/</id>
       
        <content type="html"><![CDATA[<p>Tiens je viens de me rendre compte que l'autoconfiguration de l'APN de free Mobile se met en IPv4 par défaut (en tout cas sur le téléphone que j'ai pu voir). Si on veut de l'IPv6 en réseau 4G et 5G, il faut penser à l'activer manuellement.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Nouvelles sections : les notes et les liens</title>
        <published>2025-06-09T00:00:00+00:00</published>
        <updated>2025-06-09T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/notes/nouvelle-section-les-notes/" type="text/html"/>
        <id>https://www.selenith.org/notes/nouvelle-section-les-notes/</id>
       
        <content type="html"><![CDATA[<p>J'inaugure deux nouvelles sections.</p>
<p>J'avais envie de partager quelques sites comme on faisait avant les réseaux sociaux. J'ai donc mis une sections <a href="https://www.selenith.org/liens/">liens</a>. J'ai déja mis quelques sites que j'aime bien et j'en rajouterai au fil de mes decouvertes.</p>
<p>La deuxieme section du site, les <a href="https://www.selenith.org/notes/">notes</a> me permettront d'y mettre des articles moins fouillés et plus liés à des reflexions personnelles ou à des news dont j'ai envie de parler.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Créer un routeur statique sous linux (debian 12)</title>
        <published>2025-06-07T00:00:00+00:00</published>
        <updated>2025-06-07T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/creer-un-routeur-statique-sous-linux/" type="text/html"/>
        <id>https://www.selenith.org/articles/creer-un-routeur-statique-sous-linux/</id>
       
        <content type="html"><![CDATA[<p>Bon, tu as envie de t'amuser avec le routage pour ton réseau perso ou pour monter un lab mais tu n'as pas envie de vendre ta maison pour te payer un routeur ? Et bien reste donc et installe toi confortablement, nous allons voir comment faire ça en ipv4 et ipv6 avec des technos récentes et le tout avec des outils de base en ligne de commande.</p>
<span id="continue-reading"></span><figure>
    
        <img src="https:&#x2F;&#x2F;www.selenith.org&#x2F;articles&#x2F;creer-un-routeur-statique-sous-linux&#x2F;router.svg"  alt="Illustration d&#x27;un routeur"  />
    
    <figcaption>
        <p>Icone d'un routeur utilisé dans les schémas réseaux <a class="external-link" rel="noopener external" target="_blank" href="https://creativecommons.org/publicdomain/zero/1.0/">licence CC0 1.0 Universal</a>.</p>

    </figcaption>
</figure>
<!-- <hr />-->
<h2 id="un-peu-de-contexte">Un peu de contexte</h2>
<h3 id="le-routage-ca-sert-a-quoi">Le routage, ça sert à quoi ?</h3>
<p>Pour simplifier, le principe du routage c'est d'acheminer les paquets d'un réseau qui est géré par quelqu'un au réseau géré par quelqu'un d'autre. Les réseaux peuvent être connecté directement ou passer par d'autres réseaux intermédiaires. Il faut donc pourvoir aiguiller les paquets à chaque interconnexion vers les bons chemins. Les routeurs sont donc l’équivalent des carrefours avec des panneaux qui indiquent quel chemin prendre pour aller ou on veut (village A, village B, toute directions, etc).</p>
<h3 id="pourquoi-faire-un-routeur-soi-meme">Pourquoi faire un routeur soi-même ?</h3>
<p>Comme je l'ai dit dans l'intro, ça n'est pas toujours intéressant d'acheter un vrai routeur du commerce si c'est juste pour simuler plusieurs petits réseaux dans le cas d'un labo. Même principe pour un réseau domestique. Les routeurs avec lesquels on peut faire des configs avancées coûtent cher. Et en plus le choix du hardware est ultra limité.</p>
<p>Avec ce tuto tu pourra utiliser un vieux PC auquel tu auras ajouté une carte réseau à moindre coût, voir même des adaptateurs USB vers ethernet pour environ 10 euros. Tu peux meme utiliser un <a class="external-link" rel="noopener external" target="_blank" href="https://www.hardkernel.com/shop/odroid-h4/">odroid type H4</a> avec une carte d’extension 4 ports si vraiment t'aime la performance et l'efficience en terme de consommation électrique.
Peut importe du moment que c'est un truc sur lequel tu peux installer une distribution linux et qu'il y a au moins 2 interfaces réseau.</p>
<p>A oui et je précise aussi que ce type de config fonctionne avec des machines virtuelles. Il est donc possible de créer des réseaus complexes dans des truc basiques comme <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Oracle_VM_VirtualBox">virtualbox</a>. C'est d’ailleurs ce que j'ai fait lors de l’écriture de cet article pour être certain que je ne te raconte pas de dinguerie.</p>
<h3 id="du-routage-mais-pas-trop-hardcore">Du routage mais pas trop hardcore</h3>
<p>On va voir comment faire du routage statique. Il serait tout à fait possible de faire du routage dynamique avec BGP, de l'OSPF, voir même du RIP pour le fun (les trois sont des protocoles de communication inter-routeurs), mais on va commencer par quelque chose de plus accessible. Je rappelle que le but c'est de faire une routeur domestique, de labo ou de petite entreprise. Il n'y en aura normalement qu'un ou deux max sur un tel réseau.</p>
<h2 id="c-est-parti">C'est parti !</h2>
<h3 id="prerequis">Prérequis</h3>
<p>C'est mieux si tu connais au moins vaguement le principe des <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Internet_Protocol">réseaux IP</a> et des <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Sous-r%C3%A9seau">sous-réseaux</a>.</p>
<p>Il va falloir activer le service systemd-networkd.service et nommer tes interfaces réseau. Si tu ne sais pas comment faire tu va devoir <a href="https://www.selenith.org/articles/nommer-ses-interfaces-reseau/">lire un autre des mes articles</a> (ça me fait aussi un prétexte pour que tu reste un peu plus dans le coin 😁 ).</p>
<p>Comme d'habitude les commande sont à taper en <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Utilisateur_root">root</a>.</p>
<h3 id="ce-qu-on-va-faire">Ce qu'on va faire</h3>
<p>Le routeur va permettre aux machines du réseau lan_bureaux de communiquer avec celles du réseau lan_serveurs.
Les interfaces Ethernets du routeur seront nommées en fonction du réseau sur lequel chacune d'elle est raccordée. Ça sera plus simple et on évitera les confusions pendant la config (c'est pour ca qu'il faut les nommer correctement !).</p>
<p>Voila le shéma :</p>
<figure>
    
        <img src="https:&#x2F;&#x2F;www.selenith.org&#x2F;articles&#x2F;creer-un-routeur-statique-sous-linux&#x2F;diagramme_network.webp"  alt="Schéma du réseau fait à la main et sans IA !"  />
    
    <figcaption>
        <p>Source : moi. <a class="external-link" rel="noopener external" target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/">licence CC BY-SA 4.0</a>.</p>

    </figcaption>
</figure>
<!-- <hr />-->
<h4 id="reseau-lan-serveurs">Réseau lan_serveurs</h4>
<p>Ce réseau aura comme plage d'adresses :</p>
<ul>
<li>ipv4 : 192.168.111.0/24</li>
<li>ipv6 : fd00:ace::/32</li>
</ul>
<p>L'interface "lan_serveurs" du routeur est connectée à un switch sur lequel sont raccordées les machines de ce réseau. Elle aura comme adresses :</p>
<ul>
<li>ipv4 : 192.168.111.1</li>
<li>ipv6 : fd00:ace::1</li>
</ul>
<h4 id="reseau-lan-bureaux">Réseau lan_bureaux</h4>
<p>Ce réseau aura comme plage d'adresses :</p>
<ul>
<li>ipv4 : 192.168.222.0/24</li>
<li>ipv6 : fd00:b0b::/32</li>
</ul>
<p>L'interface "lan_bureaux" du routeur est connectée à un switch sur lequel sont raccordées les machines de ce réseau. Elle aura comme adresses :</p>
<ul>
<li>ipv4 : 192.168.222.1</li>
<li>ipv6 : fd00:b0b::1</li>
</ul>
<h3 id="les-logiciels-utilises">Les logiciels utilisés</h3>
<p>Pas de choses complexes ici avec des interfaces graphiques ou web lourdes, uniquement de la ligne de commande et des programmes basiques disponibles sur presque toutes les distribution linux :</p>
<ul>
<li><strong>Systemd-networkd</strong> parce que c'est puissant et facile à configurer et déja préinstallé.</li>
<li>Le <strong>kernel linux</strong> parce que ça fait le boulot et que de toute façon il est déjà la.</li>
</ul>
<p>Voila c'est tout. Pas de framework à la noix ou d'interface web qui mange toutes les ressources.
La distribution linux que j'utilise pour faire mes routeurs est une Debian 12 mais ça marche aussi avec ce que tu veux du moment que tu peux installer Systemd-networkd.</p>
<h3 id="ip-forwarding">Ip forwarding</h3>
<p>Par défaut le système détruit les paquets qui arrivent et qui ne sont pas à destination de l'adresse IP d'une de ses propres interfaces. On va donc activer la fonction permettant de faire transiter les paquets d'une interface entrante à une autre sortante.</p>
<p>Il va falloir éditer le fichier de configuration utilisateur du kernel <strong>/etc/sysctl.d/99-sysctl.conf</strong>.
On va activer le forwarding de paquet pour l'ipv4 et l'ipv6 en décommentant les lignes suivantes :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="ini"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">net.ipv4.ip_forward</span><span>=</span><span>1</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">net.ipv6.conf.all.forwarding</span><span>=</span><span>1</span></span></code></pre>
<p>Puis on recharge la config pour prendre en compte les modifications :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">sysctl</span><span style="color: light-dark(#005CC5, #79B8FF);"> -</span><span style="color: light-dark(#005CC5, #79B8FF);">-system</span></span></code></pre><h3 id="configuration-des-interfaces">Configuration des interfaces</h3>
<h4 id="reseau-lan-serveurs-1">Réseau lan_serveurs</h4>
<p>Créer le fichier /etc/systemd/network/20-lan_serveurs.network qui contiendra :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="ini"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Match</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Name</span><span>=</span><span>lan_serveurs</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Network</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> Désactivation de l&#39;autoconfig</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">DHCP</span><span>=</span><span>no</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">IPv6AcceptRA</span><span>=</span><span>false</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">LinkLocalAddressing</span><span>=</span><span>no</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Address</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Address</span><span>=</span><span>192.168.111.1/24</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Address</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Address</span><span>=</span><span>fd00:ace::1/32</span></span></code></pre><h4 id="reseau-lan-bureaux-1">Réseau lan_bureaux</h4>
<p>Créer le fichier /etc/systemd/network/20-lan_serveurs.network qui contiendra :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="ini"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Match</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Name</span><span>=</span><span>lan_bureaux</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Network</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> Désactivation de l&#39;autoconfig</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">DHCP</span><span>=</span><span>no</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">IPv6AcceptRA</span><span>=</span><span>false</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">LinkLocalAddressing</span><span>=</span><span>no</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Address</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Address</span><span>=</span><span>192.168.222.1/24</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Address</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Address</span><span>=</span><span>fd00:b0b::1/32</span></span></code></pre><h4 id="activation-de-la-conf">Activation de la conf</h4>
<p>Une fois les fichiers édités, recharger la configuration réseau :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> reload</span><span style="color: light-dark(#032F62, #9ECBFF);"> systemd-networkd</span></span></code></pre>
<p>Controler la conf avec la commande suivante :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">ip</span><span style="color: light-dark(#032F62, #9ECBFF);"> address</span></span></code></pre>
<p>Ce qui doit donner :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>3: lan_serveurs: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc fq_codel state UP group default qlen 1000</span></span>
<span class="giallo-l"><span>    link/ether 08:00:27:3c:d3:d9 brd ff:ff:ff:ff:ff:ff</span></span>
<span class="giallo-l"><span>    inet 192.168.111.1/24 brd 192.168.111.255 scope global lan_serveurs</span></span>
<span class="giallo-l"><span>       valid_lft forever preferred_lft forever</span></span>
<span class="giallo-l"><span>    inet6 fd00:ace::1/16 scope global </span></span>
<span class="giallo-l"><span>       valid_lft forever preferred_lft forever</span></span>
<span class="giallo-l"><span>4: lan_bureaux: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc fq_codel state UP group default qlen 1000</span></span>
<span class="giallo-l"><span>    link/ether 08:00:27:85:07:1c brd ff:ff:ff:ff:ff:ff</span></span>
<span class="giallo-l"><span>    inet 192.168.222.1/24 brd 192.168.222.255 scope global lan_bureaux</span></span>
<span class="giallo-l"><span>       valid_lft forever preferred_lft forever</span></span>
<span class="giallo-l"><span>    inet6 fd00:b0b::1/16 scope global </span></span>
<span class="giallo-l"><span>       valid_lft forever preferred_lft forever</span></span></code></pre><h3 id="routage">Routage</h3>
<p>Cette partie va être très simple puisque systemd-networkd ajoute automatiquement à la table de routage principale de la machine les réseaux dans lesquels se trouvent les interfaces configurées par son biais.</p>
<p>Il faut juste verifier que les routes sont bien apparues (pour l'ipv4):</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">ip</span><span style="color: light-dark(#032F62, #9ECBFF);"> route</span></span></code></pre>
<p>ce qui doit donner :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>192.168.111.0/24 dev lan_serveurs proto kernel scope link src 192.168.111.1 </span></span>
<span class="giallo-l"><span>192.168.222.0/24 dev lan_bureaux proto kernel scope link src 192.168.222.1 </span></span></code></pre>
<p>Et pour ipv6</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">ip</span><span style="color: light-dark(#005CC5, #79B8FF);"> -</span><span style="color: light-dark(#005CC5, #79B8FF);">6</span><span style="color: light-dark(#032F62, #9ECBFF);"> route</span></span></code></pre><pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>fd00:ace::/32 dev lan_serveurs proto kernel metric 256 pref medium</span></span>
<span class="giallo-l"><span>fd00:b0b::/32 dev lan_bureaux proto kernel metric 256 pref medium</span></span></code></pre><h2 id="tests-de-bon-fonctionnement">Tests de bon fonctionnement</h2>
<h3 id="verifications">Verifications</h3>
<p>Dans le Réseau lan_bureaux on a une machine configurée comme ceci :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="ini"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Match</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Name</span><span>=</span><span>enp0s3</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Address</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Address</span><span>=</span><span>192.168.222.10/24</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Address</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Address</span><span>=</span><span>fd00:b0b::10/32</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Route</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Gateway</span><span>=</span><span>fd00:b0b::1</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Route</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Gateway</span><span>=</span><span>192.168.222.1</span></span></code></pre>
<p>Et dans le réseau lan_serveurs on a un serveur configurée comme ceci :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="ini"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Match</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Name</span><span>=</span><span>lan</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Address</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Address</span><span>=</span><span>192.168.111.50/24</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Address</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Address</span><span>=</span><span>fd00:ace::50/32</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Route</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Gateway</span><span>=</span><span>92.168.111.1</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Route</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Gateway</span><span>=</span><span>fd00:ace::1</span></span></code></pre>
<p>Depuis la machine dans le lan_bureaux on peut tester :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">ping</span><span style="color: light-dark(#005CC5, #79B8FF);"> 192.168.111.50</span></span></code></pre>
<p>Ce qui donne :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>PING 192.168.111.50 (192.168.111.50) 56(84) bytes of data.</span></span>
<span class="giallo-l"><span>64 bytes from 192.168.111.50: icmp_seq=1 ttl=63 time=0.322 ms</span></span>
<span class="giallo-l"><span>64 bytes from 192.168.111.50: icmp_seq=2 ttl=63 time=0.462 ms</span></span></code></pre>
<p>Ca fonctionne en ipv4.</p>
<p>Et en ipv6 :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">ping</span><span style="color: light-dark(#005CC5, #79B8FF);"> -</span><span style="color: light-dark(#005CC5, #79B8FF);">6</span><span style="color: light-dark(#032F62, #9ECBFF);"> fd00:ace::50</span></span></code></pre>
<p>Ce qui donne :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>PING fd00:ace::50(fd00:ace::50) 56 data bytes</span></span>
<span class="giallo-l"><span>64 bytes from fd00:ace::50: icmp_seq=1 ttl=63 time=0.510 ms</span></span>
<span class="giallo-l"><span>64 bytes from fd00:ace::50: icmp_seq=2 ttl=63 time=0.593 ms</span></span></code></pre>
<p>A ce stade tout est bon.</p>
<h3 id="explications">Explications</h3>
<p>L'ajout d'une section [Route] dans un fichier systemd-networkd sans préciser de réseau de Destination est l'équivalent d'un panneau "toutes directions". Cela indique à la machine sur laquelle est configurée cette interface que si elle ne connait pas le réseau de destination, elle envoie par defaut les paquets à l'adresse pointée en gateway. Pour un pc sur réseau domestique (celui que tu as probablement chez toi) il s'agit de l'adresse de la box internet.</p>
<p>Si on voulait router du traffic vers un réseau spécifique précis on pourrrait le faire par exemple comme ceci :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="ini"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Match</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Name</span><span>=</span><span>enp0s3</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Address</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Address</span><span>=</span><span>192.168.222.10/24</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Address</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Address</span><span>=</span><span>fd00:b0b::10/32</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Route</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Gateway</span><span>=</span><span>fd00:b0b::1</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Route</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Gateway</span><span>=</span><span>192.168.222.1</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[</span><span style="color: light-dark(#6F42C1, #B392F0);">Route</span><span style="color: light-dark(#6F42C1, #B392F0);">]</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> Route vers un VPN monté localement en 10.8.0.1</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Gateway</span><span>=</span><span>10.8.0.1</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">Destination</span><span>=</span><span>192.168.50.0/24</span></span>
<span class="giallo-l"></span></code></pre>
<p>C'est ce qu'on ferait dans le cas d'un VPN installé sur la machine de bureau, par exemple, qui n'aspirerait que les flux relatifs à un réseau (ici 192.168.50.0/24) qui est à l'autre bout du tunnel VPN.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Et voila, tu as pu voir comment transformer n'importe quelle machine linux en routeur en modifiant seulement quelques fichiers de config déja présents sur le système.
Avec quelques règles de pare-feu on pourrait même facilement transformer une machine comme notre routeur en <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Zone_d%C3%A9militaris%C3%A9e_(informatique)">DMZ</a>.</p>
<p>Pour info aussi, avec ce type de config, j'ai fabriqué des switchs et des routeurs qui fonctionnent jusqu'à 100Gbps sur 6 interfaces avec des chassis de serveurs DELL et juste une Debian.</p>
<p>Mais ne me crois pas sur parole, teste par toi même. Et surtout amuse toi bien ;)</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>L&#x27;art du hacking : Les shellcodes</title>
        <published>2024-12-20T00:00:00+00:00</published>
        <updated>2024-12-20T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/l-art-du-hacking-les-chellcodes/" type="text/html"/>
        <id>https://www.selenith.org/articles/l-art-du-hacking-les-chellcodes/</id>
       
        <content type="html"><![CDATA[<p>Aujourd'hui je vais te parler d'un voyage que j'ai entrepris, le temps d'une lecture, en parcourant les pages du livre "<a class="external-link" rel="noopener external" target="_blank" href="https://shop.arsouyes.org/l-art-du-hacking/10-les-shellcodes-volume-1.html">L'art du hacking : Les shellcodes</a>" des <a class="external-link" rel="noopener external" target="_blank" href="https://www.arsouyes.org/">arsouyes</a>.</p>
<span id="continue-reading"></span>
<p><img src="https://www.selenith.org/articles/l-art-du-hacking-les-chellcodes/les_shellcodes.png" alt="Illustration du livre Les shellcodes" /></p>
<h2 id="le-sujet">Le sujet</h2>
<p>Comme tu peux t'en douter il s'agit avant tout d'un livre sur les shellcodes, mais pas uniquement. C'est aussi l'occasion de revoir ou d'approfondir tes connaissances en systèmes (Linux et Windows), en réseau, en assembleur, en language C et en bien d'autres domaines.</p>
<h2 id="niveau-requis">Niveau requis</h2>
<p>C'est vraiment fait pour tous les niveaux du moment qu'on a quelques notions en ligne de commande windows ou linux et qu'on sait vaguement ce qu'est le système hexadecimal. Connaitre au moins un language de developpement et un peu le réseau est un plus, mais même sans, cela reste très accessible. La decouverte est progressive et les petits programmes que tu vas pouvoir créer vont évoluer tout au long de ta lecture.</p>
<h2 id="particularite">Particularité</h2>
<p>Contrairement à la pupart des explications et des tutos qu'on trouve en ligne actuellement sur le sujet, les techniques présentées sont à jour et modernes. Les communications réseaux sont etablies en IPv4 ET en IPv6 et les commandes systemes appelées sont fonctionnelles pour des processeurs 32 ET 64 bits, le tout sur des versions de systèmes d'exploitation récents. Les shellcodes créés sont modulables et avec les explications données il est possible de les adapter et de fabriquer facilement de nouvelles fonctionnalités selon ses propres besoins.</p>
<h2 id="mon-avis">Mon avis</h2>
<p>Si tu connais les arsouyes et leurs publications, tu ne seras pas dépaysé. La lecture est agréable et toujours emprunte d'une pointe d'humour et de quelques easter-eggs qui, si tu es de nature curieuse, t'emmenerons dans quelques <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wiktionary.org/wiki/rabbit_hole">trous de lapin</a>.</p>
<p>J'ai aimé le coté exploration, où on arpenterait une terra icognita avec une vieille carte sur laquelle se trouverait de nombreuses annotations des explorateurs et des exploratrices qui nous auraient précédés. Ici est indiqué comment il a fallu faire de l'ingenieurie inverse sur un systeme propriétaire. Là se trouve une note sur comment on pourrait obfusquer tel appel systeme. Ou encore comment en <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/RTFM_%28expression%29">lisant le putain de manuel</a>, on peut se rendre compte du nombre de choses qu'on peut faire mais qui nous est masqué par des programmes et des libs de plus haut niveau (utilisés pour se simplifier la vie la plupart du temps).</p>
<p>J'ai trouvé amusant de tester chaque ligne de code présents dans le livre et je me suis pris au jeu d'en faire parfois quelques variantes pour vérifer certains comportement du systèmes. Je dois dire, sans spoiler, qu'il y a  aussi une technique en particulier qui m'a vraiment surpris. Je me souviens encore m'être dit quelque chose comme ça :</p>
<p>Mais c'est une dinguerie ! Ce n'est pas possible qu'on puisse VRAIMENT faire faire ça au systeme ! Aucunes des libs ni aucuns des langages de programmation que je connais n'authorise ce genre de chose ! ... Ah ben si ça marche 🤯 !</p>
<p>Et pourtant je pensais m'y connaitre franchement pas mal, que ce soit en système, en prog ou en réseau.</p>
<p>Pour conclure, je dirais que tu ne perdras rien à le lire, bien au contraire et je pense que c'est tout à fait le genre de bouquin qui a sa place dans toutes les bibliothèques des entreprises et des institutions qui font de l'informatique leur metier.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Comment j&#x27;ai gagné 15000 euros en 4 heures en réparant ma pompe à chaleur</title>
        <published>2024-05-01T00:00:00+00:00</published>
        <updated>2024-05-01T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/economiser-15000-euros-pompe-a-chaleur/" type="text/html"/>
        <id>https://www.selenith.org/articles/economiser-15000-euros-pompe-a-chaleur/</id>
       
        <content type="html"><![CDATA[<p>Oui je sais, le titre de cet article ressemble au début d'une mauvaise réclame. Ne partez pas tout de suite, ça pourrait VRAIMENT vous être utile si vous avez une pompe à chaleur air/eau.</p>
<p>SPOILER : Il existe une pièce d'usure qu'il faut changer tous les 7 ans environ et que les spécialistes ne semblent pas <del>vouloir</del> connaître.</p>
<span id="continue-reading"></span><figure>
    
        <img src="https:&#x2F;&#x2F;www.selenith.org&#x2F;articles&#x2F;economiser-15000-euros-pompe-a-chaleur&#x2F;pac.jpg"  alt="PAC par Kristoferb"  />
    
    <figcaption>
        <p>Heat pump par <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Pompe_%C3%A0_chaleur#/media/Fichier:Heat_Pump.jpg">Kristoferb</a></p>

    </figcaption>
</figure>
<!-- <hr />-->
<h2 id="le-contexte">Le contexte</h2>
<p>Nous avons acheté une maison il y a presque 2 ans maintenant. Il s'agit d'une maison des années 60 qui, à une époque, devait être plutôt chouette. Je dis à une époque car rien n'a été correctement entretenu et TOUT nous a laché dans la première année et demi. Et je parle des choses qui fonctionnaient encore quand nous avons emménagé car la moitié des équipements étaient HS.</p>
<p>Mais je m'égare, car il n'est pas question ici de me plaindre, je savais (plus ou moins) à quoi m'en tenir lorsque nous l'avons acheté. Il est plutôt question de partager le résultat de réparations que j'ai faites et pour lesquelles j'ai trouvé assez peu d'informations, autant sur le net que de la part des professionnels avec qui j'ai pu interagir.</p>
<h2 id="le-probleme-de-base">Le problème de base</h2>
<p>La maison a été équipée il y a environ 14 ans d'une pompe à chaleur (PAC) air/eau, c'est a dire qu'il y a un gros radiateur avec ventilateur dehors pour collecter la chaleur de l'air extérieur et un module intérieur qui chauffe de l'eau et la fait circuler dans des radiateurs en fonte. C'est comme un gros frigo mais à l'envers, ca chauffe dedans et ça refroidi dehors, le tout grâce à un compresseur et un système de détente de gaz.</p>
<p>En emménageant nous avons testé cet équipement et tout semblait bien se passer :</p>
<ul>
<li>Le circulateur faisait bien circuler l'eau dans les radiateurs intérieurs.</li>
<li>Le compresseur go brrr ! ok ça compressait bien.</li>
<li>Il faisait froid devant le radiateur externe, chaud dans les radiateurs intérieurs.</li>
<li>La pression de l'eau semblait constante.</li>
</ul>
<p>Maiiiiiis une fois l'hiver arrivé, c'est la que ça à commencé à mal se passer. Ça chauffait bien, mais seulement lors de la première chauffe de la journée et après plus du tout, et la pression de l'eau tombait a 0.2~0.3 bar alors qu'elle était à 1 bar avant la chauffe.</p>
<p>Du coup je remets de l'eau pour remonter la pression à 1 bar et ça chauffe de nouveau.</p>
<p>Je vérifie alors TOUS les tuyaux, même ceux dans le vide sanitaire (ce passage pourrait faire l'objet d'une histoire entière avec des os de rats, des araignées inconnues, une invasion d'escargots lubriques et un cadavre de chat momifié D:) pour être sûr qu'il n'y avait pas de fuite dans le circuit et tout était OK.</p>
<p>Seul truc un peu étrange, c'est qu'il semblait y avoir un peu plus d'eau sur le sol au niveau de l’évacuation extérieure. Mais elle était aussi relié en amont au groupe de sécurité du ballon d'eau chaude, ça ne paraissait pas forcement incongru, surtout en hiver.</p>
<p>En observant minutieusement la pression de l'eau pendant la chauffe je vois qu'elle n'est pas constante elle monte tout doucement jusqu’à 3 bar et ensuite elle descend rapidement à 0.3 bar.</p>
<p>On a donc la séquence suivante :</p>
<ul>
<li>Eau à 1 bar</li>
<li>Mise en chauffe ok</li>
<li>Eau qui monte à 3 bar</li>
<li>Pression qui diminue d'un coup à moins d'un bar</li>
<li>Chauffe qui ne marche presque plus.</li>
</ul>
<p>Je me dis : j'y connais rien en plomberie ni en pompe à chaleur, mais ça ressemble quand même beaucoup à un système de sécurité qui se serait mis en route pour éviter une surpression. Ce qui expliquerait aussi l’afflux d'eau sur le sol à l’extérieur.
Mais ce que j'ignorais à ce moment c'est pourquoi la pression augmentait dans mon circuit d'eau chaude alors qu'elle aurait dû être stable.</p>
<h2 id="premiere-approche-echec-appeler-un-professionnel">Première approche (échec) : appeler un professionnel</h2>
<p>Et là j'ai eu de tout, des pros très sympa mais pas disponibles avant l'an prochain, des moins sympa qui ne s'occupent pas de PACs qu'ils n'ont pas installé eux même et des carrément azimutés qui m'ont indiqué que au delà de 10 ans il fallait tout changer et qu'il n'ouvriraient même pas le bloc intérieur pour faire un diagnostic.</p>
<p>La dernière catégorie a été la plus représentée, soit 4 sur l’échantillon de 7 professionnels contactés.</p>
<h2 id="deuxieme-approche-succes-se-debrouiller">Deuxième approche (succès) : se débrouiller</h2>
<p>A ce stade, je n'avais pas grand chose à perdre et je me suis dit que ça ne devait pas être si compliqué de tenter un truc moi même. Après tout, je passe mes journées à devoir fabriquer des trucs sur des technos pour lesquelles je n'ai pas forcément toujours des connaissances de base.</p>
<h3 id="trouver-les-informations">Trouver les informations</h3>
<p>Bon là, pas de secret, il fallait chercher sur internet si quelqu'un aurait eu une pompe à chaleur qui présentait les mêmes symptômes que la mienne.
Et après avoir écumé plein de sites de bricoleurs avec des réponses allant de "change tout" à "fait cette invocation de réparation quantique en araméen" j'ai fini par tomber sur une vidéo d'un type qui décrivait le changement d'un vase d'expansion d'une PAC air/eau. Il indiquait que le changement était nécessaire dans le cadre d'un problème similaire au mien.</p>
<p>C'est la que j'ai eu l'illumination : <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/RTFM_(expression)">RTFM</a>.</p>
<p>Je ne sais pas pourquoi je n'ai pas eu l'idée avant, mais je suis allé sur le site du fabriquant et bien qu’étant un ancien modèle j'ai pu retrouver le manuel d'installation et d'utilisation de ma PAC.
On y voyait une vue éclatée du bloc intérieur avec les différentes pièces décrites. Celle qui a attiré mon attention a été le fameux vase d'expansion intégré, chargé de réguler la pression lorsque l'eau chauffe et augmente de volume !
Dans le manuel, c’était bien précisé qu'il fallait changer cette pièce tous les 7 ans car la membrane élastique à l’intérieur <strong>s'usait et que C'ETAIT NORMAL</strong> !</p>
<h3 id="agir">Agir</h3>
<p>A partir de la il ne m'a pas été difficile de trouver la référence de la pièce sur le manuel, de la commander sur un site de pièces détachées (pour 270 euros + un joint fibre à 0.10 euros) et de la changer en démontant et en remontant le tout avec un simple jeux de clés plates.</p>
<p>Voila à quoi ressemble le bloc intérieur :</p>
<p><img src="https://www.selenith.org/articles/economiser-15000-euros-pompe-a-chaleur/entier.jpg" alt="bloc intérieur monté" /></p>
<p>Pour les curieuses et les curieux, j'ai procédé comme ceci :</p>
<ul>
<li>
<p>Etape 1 : Couper l'alimentation électrique des bloc intérieur et extérieur via les différentiels présent sur votre tableau électrique.</p>
</li>
<li>
<p>Etape 2 : démonter les caches du bazar :</p>
</li>
</ul>
<p><img src="https://www.selenith.org/articles/economiser-15000-euros-pompe-a-chaleur/sans_cache.jpg" alt="bloc interieur démonté" /></p>
<ul>
<li>Etape 3 : démonter la plaque de protection latérale :</li>
</ul>
<p><img src="https://www.selenith.org/articles/economiser-15000-euros-pompe-a-chaleur/sans_cache_vue_laterale.jpg" alt="vue latérale" /></p>
<p><img src="https://www.selenith.org/articles/economiser-15000-euros-pompe-a-chaleur/vase_vue_laterale.jpg" alt="vue latérale sans plaque de protection" /></p>
<ul>
<li>Etape 4 : démonter le vieux vase d'expansion.
Attention, prévoir quelque chose pour collecter l'eau qui va couler du tuyau démonté. Selon l'installation il peut y avoir plusieurs litres d'eau qui vont s’écouler.</li>
</ul>
<p><img src="https://www.selenith.org/articles/economiser-15000-euros-pompe-a-chaleur/vase_demonte.jpg" alt="vue latérale avec vase démonté" /></p>
<ul>
<li>
<p>Etape 5 : Faire toutes les étapes précédentes en sens inverse une fois le nouveau vase installé ( Penser à changer l'ancien joint au niveau du raccord à visser).</p>
</li>
<li>
<p>Etape 6 : Rajouter de l'eau dans le circuit de chauffage grâce au robinet dédié jusqu’à 1 bar.</p>
</li>
<li>
<p>Etape 7 : Rallumer le tout et savourer.</p>
</li>
</ul>
<h3 id="mais-rager-quand-meme-un-peu">Mais rager quand même un peu</h3>
<p>Apres la remise en fonctionnement me sont venus des sentiments contradictoire qui pourraient se résumer à :</p>
<ul>
<li>Haha !! Je viens de m’éviter un remplacement complet ! Je viens d’économiser plus d'une dizaine de milliers d'euros !!!</li>
<li>Mais en fait, c’était super clair et commun mon problème.... pourquoi les artisans qui pouvaient intervenir m’ont tous proposé un remplacement complet ?</li>
<li>Ahhhhh ! mais les chacals, il n'y a que deux explications : la nullité ou la fourberie !</li>
</ul>
<p>Bon en vrai, je ne veux pas mettre tous les artisans dans le même sac, j'imagine que ceux qui étaient bons et qui auraient pu me dépanner honnêtement étaient ceux qui avaient l'agenda rempli jusqu'à l'année d’après...
Mais quand même, autant de nuls ou d'escrocs, ca fait quand même chier 😤 !</p>
<p>Car pour information, la PAC vient de passer son second hiver et elle ronronne toujours parfaitement. Le tout avec une pression stable.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Total de l'opération :</p>
<ul>
<li>En excluant le temps passé à contacter des artisans, 3 heures de recherches et de lectures techniques, 15 minutes pour commander le vase d'expansion et 45 minutes pour le changer (alors que je n'avais jamais démonté une PAC).</li>
<li>270 euros et des poussières au lieu de 13 à 18 milles euros pour une installation de ce type.</li>
</ul>
<p>Moralité, quand on a besoin d'un professionnel, si on ne s'est pas renseigné un peu avant sur le sujet, on peut quand même bien se faire rouler dans la farine. Que ça soit par incompétence ou par malice le résultat reste le même, on peut perdre beaucoup d'argent.</p>
<p>Ah oui et on ne le dira jamais assez : <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/RTFM_(expression)">RTFM</a> !</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Créer un switch administrable sous Linux</title>
        <published>2024-03-03T00:00:00+00:00</published>
        <updated>2024-03-03T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/creer-un-switch-administrable-sous-linux/" type="text/html"/>
        <id>https://www.selenith.org/articles/creer-un-switch-administrable-sous-linux/</id>
       
        <content type="html"><![CDATA[<p>Les switch du commerce sont très bien tant qu'on n'a pas besoin de fonctionnalités particulières. Mais dès lors qu'on veut faire quelque chose d'un peu poussé, on est vite limité. Nous allons donc voir comment transformer un pc en switch administrable.</p>
<span id="continue-reading"></span><h2 id="l-interet">L'interet</h2>
<p>Avec un switch administrable et évolutif on peut imaginer faire pas mal de choses tel que :</p>
<ul>
<li>Monitorer du trafic et faire des captures réseau.</li>
<li>Copier le trafic et le renvoyer vers une interface sur laquelle est branchée une sonde de detection de menace (IDS) type suricata.</li>
<li>Avoir un point d'arrivée ou de depart d'un tunnel VPN.</li>
<li>Gérer son propre hardware wifi et installer des <a class="external-link" rel="noopener external" target="_blank" href="https://www.alfa.com.tw/products/awus036ac_1">cartes externes</a> très performantes.</li>
<li>Faire un répéteur wifi.</li>
<li>Faire du filtrage complexe avec nftables (seul moyen actuel de faire du filtrage fin en IPv6 à la maison).</li>
<li>Gérer son propre DNS intégré.</li>
<li>Gérer son propre DHCP intégré.</li>
<li>Activer l'IP forwarding et faire du routage !</li>
</ul>
<h2 id="le-materiel">Le matériel</h2>
<p>Dans ce domaine, le choix est assez vaste. Il est possible d'utiliser un vieux PC de récup auquel on va ajouter une ou deux carte réseaux (1, 2 ou 4 ports Ethernet). Il existe aussi des machines vendues en ligne sous la dénomination <a class="external-link" rel="noopener external" target="_blank" href="https://duckduckgo.com/?q=mini+pc+firewall">mini PC firewall</a> qui sont parfaites pour ça. Ces dernières ont ma préférence car leur refroidissement est passif et avec un <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/SSD">SSD</a> elles sont parfaitement silencieuses.</p>
<h2 id="la-config">La config</h2>
<p>L'idée de base est de permettre le trafic à travers toutes les interfaces réseau de la machine. Une adresse IP sera disponible sur une interface virtuelle afin d'être disponible depuis n'importe laquelle des interfaces physiques.</p>
<h3 id="schema-d-exemple">Schema D'exemple</h3>
<p>Ci-dessous, un exemple un peu plus visuel.</p>
<p><img src="https://www.selenith.org/articles/creer-un-switch-administrable-sous-linux/switch_linux.png" alt="Schéma montrant un bridge fait entre 3 interfaces réseau physiques et une interface virtuelle portant une IP" /></p>
<p>L'idée est de pouvoir accéder à l'interface virtuelle de la machine via son ip depuis n'importe quelle interface physique intégrée au bridge.</p>
<h3 id="interface-bridge">Interface bridge</h3>
<p>C'est l'interface virtuelle qui va nous permettre de lier les interfaces physique ensemble et d'avoir un point pour attribuer une IP.</p>
<p>On va créer un fichier .netdev nommé 05-lan_bridge.netdev contenant :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[NetDev]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>lan_bridge</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Kind</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>bridge</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># Si boucles dans le réseau, activer le spanning tree </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># en décommentant les lignes ci dessous.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#[BRIDGE]</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#STP=yes</span></span></code></pre>
<p>Ce fichier permet de creer l'interface.</p>
<p>Ensuite, on va pouvoir lui attribuer la config liée à notre réseau.</p>
<p>Dans cet exemple le switch dispose d'une adresse ip V4 et d'une V6. Il est donc important de définir les gateway pour les deux réseaux.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Match]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>lan_bridge</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Network]</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># 3 parametres ci dessous utilisés car on attribue ici une ip fixe</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">DHCP</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">no</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">IPv6AcceptRA</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">false</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">LinkLocalAddressing</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">no</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">DNS</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>10.8.0.252 #optionnel</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Address]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Address</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>10.8.0.1/24</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Address]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Address</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>fe80::1ce:cafe/64 </span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Route]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Gateway</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>fe80::e69e:12ff:fe0b:653a</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">GatewayOnLink</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">yes</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Route]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Gateway</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>10.8.0.254</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">GatewayOnLink</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">yes</span></span>
<span class="giallo-l"></span></code></pre><h3 id="interfaces-physiques">Interfaces physiques</h3>
<p>Les fichiers <strong>.network</strong> indiquent à quel bridge ces interfaces sont attachées.
L'interface bridge contiendra les paramètres réseaux de <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Mod%C3%A8le_OSI">niveau 3</a>, donc pas besoin de préciser plus de parametres ici.
Pour plus de detail sur la configuration des interfaces et leur nommage tu peux voir <a href="https://www.selenith.org/articles/nommer-ses-interfaces-reseau/">mon article à ce sujet</a>.</p>
<h4 id="exemple-interface-1">Exemple : interface 1</h4>
<p>Fichier 10-lan_1.link :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Match]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">MACAddress</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">08</span><span>:00:27:3c:d3:10</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Link]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Description</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>Interface vers maison</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>lan_1</span></span></code></pre>
<p>Fichier 10-lan_1.network :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Match]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>lan_1</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Network]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Bridge</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>lan_bridge</span></span>
<span class="giallo-l"></span></code></pre><h4 id="exemple-interface-2">Exemple : interface 2</h4>
<p>Fichier 20-lan_2.link :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Match]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">MACAddress</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">08</span><span>:00:27:3c:d3:d9</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Link]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Description</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>Interface vers labo</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>lan_2</span></span></code></pre>
<p>Fichier 20-lan_2.network :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Match]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>lan_2</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Network]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Bridge</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>lan_bridge</span></span>
<span class="giallo-l"></span></code></pre><h2 id="activation-de-la-config">Activation de la config</h2>
<p>N'oublie pas de redémarrer le service <strong>systemd-networkd.service</strong> pour activer la configuration.</p>
<p>Une fois la config rechargée, la machine se comportera comme un switch réseau au niveau du groupe d'interfaces liées par un bridge. De plus, une autre machine connectée à n'importe quelle interfaces physique de notre switch pourra le pinger (ou s'y connecter en SSH, etc) via l'IP unique du Bridge.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Histone PHP Database</title>
        <published>2024-01-20T00:00:00+00:00</published>
        <updated>2024-01-20T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/projets/histone-php-database/" type="text/html"/>
        <id>https://www.selenith.org/projets/histone-php-database/</id>
       
        <content type="html"><![CDATA[<p>Histone est un système de gestion de base de donnée rustique sous forme de fichiers que j'ai créé à l'origine pour être intégré dans le <a href="https://www.selenith.org/projets/plasmide/">CMS Plasmide</a>.
Intégralement ecrit en PHP, il ne nécessite pas de module ou de lib externe.</p>
<p>Depuis le temps que je m'en sers pour tout un tas de projets, je me suis dit que ça pourrait être utile à d'autres allergiques au SQL 😁. Histone est donc disponible en license libre (GNU AGPLv3) .</p>
<span id="continue-reading"></span>
<p><img src="https://www.selenith.org/projets/histone-php-database/histone.png" alt="Logo Histone" /></p>
<h2 id="le-projet">Le projet</h2>
<h3 id="la-genese">La génèse</h3>
<p>Histone a été developpé à ses débuts en 2008 pour fonctionner sur un serveur NAS DNS-313 de D-Link modifié (CPU 300 MHz, 64Mo de RAM, le tout sous debian 4). Il fait moins de 20 Ko. Il est donc concu pour être trés économe en ressource et peut fonctionner sur des petits systèmes embarqués.</p>
<p>Il est vrai qu'a l'ère du tout centralisé et du cloud, il peut paraitre étonnant de concevoir un système de persistance sous forme de fichiers un peu "à l'ancienne". Il y a deux raison a cela.</p>
<p>La premiere est que j'utilise pour la plupart de mes projet des petites machine, qui bien que performantes, n'ont pas les capacités des gros serveurs dédiés à des taches d'hébergement. Un systeme de gestion de base de données (SGBD) tel que MySQL est trop gourmand pour de telles configurations.</p>
<p>La seconde vient du fait que j'ai pu observé que la plupart du temps, lorqu'un SGBD est installé sur une machine, il ne sert que pour l'unique site web hebergé <strong>sur la même machine</strong>.</p>
<p>Malgres mes recherches, je n'ai trouvé, à l'époque, aucun systeme de persistances des données suffisamment optimisé pour de telles contraintes. Il existait bien quelques bibliotheques PHP pour manipuler des fichiers XML, mais les temps d'acces explosaient quand il commençait à y avoir plusieurs milliers d'enregistrements.</p>
<h3 id="les-caracteristiques">Les caractéristiques</h3>
<p>Histone fonctionne sur quelques principes simples :</p>
<ul>
<li>Que du PHP "vanilla", pas de lib externe, ni de module, ni de <del>ces abominations de</del> frameworks.</li>
<li>Pas de langage de requêtes compliqué, type SQL, tout se fait en orienté objet.</li>
<li>Les données sont stockées dans des fichiers PHP natif, pour profiter de la gestion du cache du Zend Engine.</li>
<li>Un champ "id" en clé primaire par table qui est un nombre (Integer) et auto incrémental. Et c'est tout.</li>
<li>Autant de clé étrangères qu'on veut, déclarées dans un fichier "structure.php" dédié à chaque table.</li>
<li>Les modules de cache de type APCu sont géré automatiquement, ce qui augmente encore les perfs en lecture.</li>
<li>Pas de jointure ou de vues. La logique est a implémenter dans le code applicatif.</li>
</ul>
<p>Pour donner une idée de ses performances, il a servi de base de donnée à plusieurs sites sur ce fameux DNS-313 cité plus haut pendants plusieurs années (avant que le raspberry pi n'existe), dont un des site contenait un forum avec plusieurs milliers de posts. Les temps de réponses ne depassaient jamais les 300 millisecondes.</p>
<p>Envie de tester ? C'est parti !</p>
<h2 id="telecharger">Télécharger</h2>
<p>Voici le lien de téléchargement : <a href="https://www.selenith.org/projets/histone-php-database/histone.zip">Histone</a></p>
<h2 id="installation">Installation</h2>
<h3 id="decompression">Décompression</h3>
<p>Apres avoir téléchargé le fichier ZIP, décompresse le à la racine de ton site. Tu peux ensuite supprimer le fichier ZIP,  il ne sera plus utile.
Une fois décompréssé tu dois avoir une arboresence comme celle ci :</p>
<ul>
<li>core
<ul>
<li>model
<ul>
<li>Archivable.php</li>
<li>Archivist.php</li>
<li>Cache_helper.php</li>
<li>Ribosome.php</li>
</ul>
</li>
</ul>
</li>
<li>local
<ul>
<li>data</li>
</ul>
</li>
</ul>
<h3 id="creation-de-la-base">Création de la base</h3>
<p>Pour creer une nouvelle table dans la base de donnée, il suffit simplement de créer un dossier portant le nom voulu dans le dossier data. Dans ce dossier il faut creer un fichier <strong>structure.php</strong> qui permet de renseigner les éventuelles clé étrangères. Toutes les tables ont automatiquement un champ ID qui est auto incrémental.</p>
<h3 id="exemple-avec-cas-d-usage-livres-et-bibliotheques">Exemple avec cas d'usage : livres et bibliothèques</h3>
<p>Je veux créer la table Livre et la table Bibliothèque.</p>
<p>On aura donc :</p>
<ul>
<li>core
<ul>
<li>model
<ul>
<li>Archivable.php</li>
<li>Archivist.php</li>
<li>Cache_helper.php</li>
<li>Ribosome.php</li>
</ul>
</li>
</ul>
</li>
<li>local
<ul>
<li>data
<ul>
<li>Livre
<ul>
<li>strucure.php</li>
</ul>
</li>
<li>Bibilotheque
<ul>
<li>structure.php</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Un livre appartient à une seule bibliothèque, mais une bibliothèque peut contenir plusieurs livres. On aura donc une relation de 1-n, matérialisée par une clé étrangère dans la table livre que j'appelerais <strong>id_bibliotheque</strong>.</p>
<p>Une fois n'est pas coutume, modélisé en UML ca nous donne  :</p>
<p><img src="https://www.selenith.org/projets/histone-php-database/histone_exemple.png" alt="Exemple UML" /></p>
<p>Une fois les deux dossier créés, édite les fichiers structures pour configurer les clés étrangères.</p>
<p>Pour Livre :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"><span>	$</span><span>structure</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> [</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">id_bibliotheque</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre>
<p>Pour Bibliotheque :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"><span>	$</span><span>structure</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> [</span><span>]</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre>
<p>Le fichier est obligatoire, même si la table n'a pas de clé étrangères.</p>
<p>Le nom des clé étrangèress est libre. La declaration des clé étrangères de cette facon permet d'optimiser drastiquement les acces aux données.</p>
<h2 id="utilisation">Utilisation</h2>
<h3 id="importation-des-ressouces">Importation des ressouces</h3>
<p>Tout d'abord il faut importer les differents fichiers :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">include</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">core/model/Cache_helper.php</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">include</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">core/model/Ribosome.php</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">include</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">core/model/Archivist.php</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">include</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">core/model/Archivable.php</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre>
<p>Ensuite il faut créé un objet d'acces à la base de donnée</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivist</span><span>(</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre>
<p>Pour finir il faut creer un objet qui va representer une entrée dans la base de donnée. Il est imperatif de préciser le nom de la table lorsque l'on créée un Archivable.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre>
<p>Maintenant que tu as les bases, passons aux choses serieuses : les requetes dans la base de donnée.</p>
<h3 id="insertion">Insertion</h3>
<p>On commence par renseigner les attributs à sauvegarder, cela se fait par la méthode <strong>set(String nomAttribut, String/int valeurAttribut)</strong> de l'objet Archivable. Puis on l'ajout à la base de donnée avec la methode <strong>archive(Archivable object)</strong> de l'Archiviste.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"><span>$</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivist</span><span>(</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">titre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">De la brièveté de la vie</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Sénèque</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>id</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">archive</span><span>(</span><span>$</span><span>livre</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">echo</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre ajoué avec l</span><span style="color: light-dark(#005CC5, #79B8FF);">\&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">id : </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>id</span><span> )</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> on peut en ajouter un autre en creant un nouveau Archivable de type livre</span></span>
<span class="giallo-l"><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">titre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">De la vie heureuse</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Sénèque</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">archive</span><span>(</span><span>$</span><span>livre</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre>
<p>Simple non ?</p>
<p>Petite précision, les champs/colonnes d'une table sont créé <strong>dynamiquement</strong> en fonction des objets qui sont ajoutés ou supprimés. Toutes les tables disposent en outre d'un identifiant unique 'id' par enregistrement, mais pas besoin de te tracasser avec sa gestion, il est créé et auto incrémenté lors de l'insertion d'une nouvelle entrée.</p>
<h3 id="selection">Selection</h3>
<p>Ce coup ci on va utiliser la methode <strong>restore(Archivable $archivable)</strong> de l'Archiviste. Cette methode renvoi un tableau contenant les entrées trouvés ou un tableau vide si rien ne correspont.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);">Création d&#39;un objet Archivable qui va permettre de requeter la table Livre</span></span>
<span class="giallo-l"><span>$</span><span>livres_à_trouver</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);">Je vais récuperer tous les livres dont l&#39;auteur s&#39;appelle exactement Sénèque</span></span>
<span class="giallo-l"><span>$</span><span>livres_à_trouver</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Sénèque</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);">les objets trouvés sont renvoyé sous forme d&#39;un tableau d&#39;Archivables</span></span>
<span class="giallo-l"><span>$</span><span>livres_trouvés</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">restore</span><span>(</span><span>$</span><span>livres_à_trouver</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> on peut verifier qu&#39;on a bien trouvé des livres. Comme ceci par ex:</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">if</span><span>(</span><span style="color: light-dark(#005CC5, #79B8FF);">empty</span><span>(</span><span>$</span><span>livres_trouvés</span><span>)</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	//</span><span style="color: light-dark(#6A737D, #6A737D);">si la liste est vide on l&#39;indique</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">	echo</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">aucun livre trouvé.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	//</span><span style="color: light-dark(#6A737D, #6A737D);">et on quitte qvant d&#39;executer la boucle qui suit (à replacer par un return dans une fonction).</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	exit</span><span>(</span><span style="color: light-dark(#005CC5, #79B8FF);">0</span><span>)</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> on peut afficher les archivables trouvé de cette manière </span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">foreach</span><span>(</span><span>$</span><span>livres_trouvés</span><span style="color: light-dark(#D73A49, #F97583);"> as</span><span> $</span><span>livre</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">	echo</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);"> Livre trouvé : </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">get</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">titre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);"> écrit par </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">get</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);"> avec id automatique : </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">get</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">id</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre>
<p>Pour faire un recherche approximative maintenant, on va plutot utiliser la methode <strong>search(Archivable $archivable)</strong></p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"><span>	</span></span>
<span class="giallo-l"><span>$</span><span>livres_à_trouver</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livres_à_trouver</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">titre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">la vie</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livres_trouvés</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">search</span><span>(</span><span>$</span><span>livres_à_trouver</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> Et on affiche les livres trouvés</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">foreach</span><span>(</span><span>$</span><span>livres_trouvés</span><span style="color: light-dark(#D73A49, #F97583);"> as</span><span> $</span><span>livre</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">	echo</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);"> Livre trouvé : </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">get</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">titre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);"> écrit par </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">get</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre><h3 id="modification">Modification</h3>
<p>Pour faire une modification, on utilise deux objets Arhivable. Le premier sert à faire une recherche, de la même manière que la fonction restore. Le deuxieme contient les attributs à modifier ou à ajouter.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"><span>$</span><span>livres_à_trouver</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livres_à_trouver</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Sénèque</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>livre_modifié</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livre_modifié</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Lucius Annaeus Seneca</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">update</span><span>(</span><span>$</span><span>livres_à_trouver</span><span>,</span><span> $</span><span>livre_modifié</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre><h3 id="suppression">Suppression</h3>
<p>Pour faire une suppression, le principe et le même que pour une selection.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> pour supprimer tous les livres dont l&#39;auteur est Sénèque</span></span>
<span class="giallo-l"><span>$</span><span>livres_à_supprimer</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livres_à_supprimer</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Sénèque</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">delete</span><span>(</span><span>$</span><span>livres_à_supprimer</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> Pour supprimer Le livre dont l&#39;id est 1</span></span>
<span class="giallo-l"><span>$</span><span>livre_à_supprimer</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livre_à_supprimer</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">id</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> 1</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">delete</span><span>(</span><span>$</span><span>livre_à_supprimer</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre><h2 id="les-petits-plus-histone">Les petits plus Histone</h2>
<h3 id="le-tri">Le tri</h3>
<p>Il est possible également de demander à l'archiviste de trier les donnée avant de les afficher:</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> On récupere tous les livres</span></span>
<span class="giallo-l"><span>$</span><span>livres_à_trouver</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>liste_livres</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">restore</span><span>(</span><span>$</span><span>livres_à_trouver</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);">  Trie les livre par titre et par ordre alphabetique avec le troisième argument à true</span></span>
<span class="giallo-l"><span>$</span><span>liste_livres</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">sort</span><span>(</span><span>$</span><span>liste_livres</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">titre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> true</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);">  Trie les livre par auteur et par ordre alphabetique inverse avec le troisième argument à false</span></span>
<span class="giallo-l"><span>$</span><span>liste_livres</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">sort</span><span>(</span><span>$</span><span>liste_livres</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> false</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> Et on affiche les livres trouvés et triés</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">foreach</span><span>(</span><span>$</span><span>liste_livres</span><span style="color: light-dark(#D73A49, #F97583);"> as</span><span> $</span><span>livre</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">	echo</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);"> Livre trouvé : </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">get</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">titre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);"> écrit par </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>livre</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">get</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre><h3 id="l-implementation-de-arrayaccess">L'implementation de ArrayAccess</h3>
<p>Les objets archivable implementent l'interface ArrayAccess. Il est donc possible de les utiliser comme un tableau à une dimension.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>livre_à_trouver</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livre_à_trouver</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Sénèque</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livre_à_trouver</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">titre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">De la vie heureuse</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>liste_livres</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">restore</span><span>(</span><span>$</span><span>livres_à_trouver</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> Et on affiche les livres trouvés et triés</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">foreach</span><span>(</span><span>$</span><span>liste_livres</span><span style="color: light-dark(#D73A49, #F97583);"> as</span><span> $</span><span>livre</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">	echo</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);"> Livre trouvé : </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>livre</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">titre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);"> écrit par </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>livre</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre>
<p>Le but est d'alleger un peu le code de l'accès aux attributs des objets archivables.</p>
<h3 id="la-recherche-unique">La recherche unique</h3>
<p>Il est possible de recuperer seulement le premier Archivable qui correspond à un critère précis. C'est utile lors d'une requete sur un objet qu'on sait être unique.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>livre_à_trouver</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Livre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>livre_à_trouver</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">id</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> 1</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>livre_trouvé</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">restore_first</span><span>(</span><span>$</span><span>livres_à_trouver</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> on peut verifier qu&#39;on a bien trouvé des livres. Comme ceci par ex:</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">if</span><span>(</span><span style="color: light-dark(#005CC5, #79B8FF);">empty</span><span>(</span><span>$</span><span>livre_trouvé</span><span>)</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	//</span><span style="color: light-dark(#6A737D, #6A737D);">si livre_trouvé est vide ou égale à NULL ou à false .</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">	echo</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">aucun livre trouvé.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	//</span><span style="color: light-dark(#6A737D, #6A737D);">et on quitte qvant d&#39;executer la suite (à replacer par un return dans une fonction)</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	exit</span><span>(</span><span style="color: light-dark(#005CC5, #79B8FF);">0</span><span>)</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> ici on s&#39;évite une boucle fastidieuse</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">echo</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);"> Livre trouvé : </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>livre_trouvé</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">titre</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);"> écrit par </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>livre_trouvé</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">auteur</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre><h2 id="contribuer">Contribuer</h2>
<p>Tu peux contribuer à l'amélioration d'Histone en m'envoyant des patch/diff, il est open source (license AGPLv3).</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Nommer ses interfaces réseau</title>
        <published>2024-01-16T00:00:00+00:00</published>
        <updated>2024-01-16T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/nommer-ses-interfaces-reseau/" type="text/html"/>
        <id>https://www.selenith.org/articles/nommer-ses-interfaces-reseau/</id>
       
        <content type="html"><![CDATA[<p>Bon, aujourd'hui un article qui denonce grave. Avoir un serveur avec plus d'une interface réseau et ne pas les nommer correctement c'est vilain. Ne soit pas vilain (ou vilaine) et nomme tes interfaces réseaux. Et plus d'excuse pour ne pas le faire après avoir lu cet article, parce que tu vas voir comment configurer ça en 10 minutes avec systemd-networkd.</p>
<span id="continue-reading"></span><figure>
    
        <img src="https:&#x2F;&#x2F;www.selenith.org&#x2F;articles&#x2F;nommer-ses-interfaces-reseau&#x2F;bandeau_ia.jpeg"  alt="Image générée par IA (Bing) d&#x27;une façade de serveur avec moults cables réseaux branchés. Les boutons paraissent fondus"  title="Les boutonns coulennnnnt !"  />
    
    <figcaption>
        <p>Image générée avec le Créateur d’image Bing pour le fun.</p>

    </figcaption>
</figure>
<!-- <hr />-->
<h2 id="prerequis">Prérequis</h2>
<h3 id="l-environnement-de-base">L'environnement de base</h3>
<p>Nous allons voir comment faire ce type de configuration sur un serveur de type Debian 10, 11 ou 12 <strong>sans interface graphique</strong>.</p>
<p>Sous Debian, le réseau est géré par défaut par le service networking, tu peux le vérifier en tappant la commande :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> status</span><span style="color: light-dark(#032F62, #9ECBFF);"> networking.service</span></span></code></pre>
<p>Ca doit donner un truc comme ca :</p>
<p><img src="https://www.selenith.org/articles/nommer-ses-interfaces-reseau/networking.png" alt="Image du service networking en fonctionnement" /></p>
<h3 id="la-config-par-defaut">La config par defaut</h3>
<p>Le système de nommage par défaut doit donner quelque chose comme ceci avec la commande "ip link" :</p>
<p><img src="https://www.selenith.org/articles/nommer-ses-interfaces-reseau/interfaces_base.png" alt="Image du résultat de la commande ip link. Les interfaces ont des noms aléatoires" /></p>
<p>On ne va pas se mentir, ici impossible de savoir qu'est ce qui est branché à quoi sans un plan d'adressage noté quelque part.</p>
<p>Par défaut, le daemon systemd-networkd doit être présent mais désactivé.</p>
<p>Pour s'en assurer :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> status</span><span style="color: light-dark(#032F62, #9ECBFF);"> systemd-networkd</span></span></code></pre>
<p>Ce qui doit te donner :</p>
<p><img src="https://www.selenith.org/articles/nommer-ses-interfaces-reseau/networkd_eteint.png" alt="Image du résultat de la commande systemctl status systemd-networkd. Le daemon est présent mais inactif" /></p>
<h2 id="nouvelle-configuration">Nouvelle configuration</h2>
<p>On va procéder en deux parties, d'abord activer les daemons nécessaires puis configurer les interfaces.
A partir d'ici toutes les commandes sont à tapper en tant que <strong>root</strong> (ou en prefixant tout avec <a class="external-link" rel="noopener external" target="_blank" href="https://wiki.debian.org/fr/sudo">sudo</a>, c'est comme tu veux).</p>
<h3 id="activation-de-systemd-networkd">Activation de systemd-networkd</h3>
<p>On va d'abord activer le lancement de systemd-neworkd au démarrage.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> enable</span><span style="color: light-dark(#032F62, #9ECBFF);"> systemd-networkd</span></span></code></pre>
<p>Ce qui nous donne :</p>
<p><img src="https://www.selenith.org/articles/nommer-ses-interfaces-reseau/activer_networkd.png" alt="Image du résultat de la commande systemctl enable systemd-networkd. Le daemon s&#39;active." /></p>
<p>Le daemon se lancera au boot mais il n'est pas encore démarré. Ca tombe bien, ca va te permettre de configurer les interfaces.
A ce stade tes interfaces réseaux sont probablement configurées dans  <strong>/etc/network/interfaces</strong>. Pour éviter les conflits de configuration entre les services systemd-networkd et networking, commente tout ce qui concerne tes interfaces, loopback compris.</p>
<p>Une fois terminé, tu devrais avoir un fichier qui ressemble à ceci :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> This file describes the network interfaces available on your system</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> and how to activate them. For more information, see interfaces(5).</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">source</span><span style="color: light-dark(#032F62, #9ECBFF);"> /etc/network/interfaces.d/</span><span style="color: light-dark(#005CC5, #79B8FF);">*</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> The loopback network interface</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);">auto lo</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);">iface lo inet loopback</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> The primary network interface</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);">allow-hotplug enp0s3</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);">iface enp0s3 inet dhcp</span></span>
<span class="giallo-l"></span></code></pre><h3 id="activation-de-systemd-resolved-optionnel">Activation de systemd-resolved (optionnel)</h3>
<p>Si tu as besoin que ta machine puisse configurer automatiquement l'adresse de son DNS via DHCP (on va y revenir plus bas) il va te falloir activer le daemon systemd-resolved.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">apt</span><span style="color: light-dark(#032F62, #9ECBFF);"> install</span><span style="color: light-dark(#032F62, #9ECBFF);"> systemd-resolved</span></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> enable</span><span style="color: light-dark(#032F62, #9ECBFF);"> systemd-resolved</span></span></code></pre>
<p>Sans cela seul l'autoconfig de l'IP fonctionnera via DHCP. Il te faudra donc configurer l'adresse du DNS de la machine à la main dans <a class="external-link" rel="noopener external" target="_blank" href="https://wiki.debian.org/resolv.conf">/etc/resov.conf</a>.</p>
<h3 id="configuration-des-interfaces">Configuration des interfaces</h3>
<p>Pour chaque interface il va y avoir 2 fichiers. Un pour définir le nom de l'interface et le deuxieme pour appliquer la config réseau que tu veux.
Ces fichiers doivent se placer dans  <strong>/etc/systemd/network/</strong>.</p>
<aside class=attention>
<p class=centre>⚠️ Attention ⚠️</p>
<p>Il y a une fourberie avec systemd-networkd. Il existe un fichier par défaut situé à l'emplacement <strong>/usr/lib/systemd/network/99-default.link</strong>. Ce fichier est prévu pour pouvoir s'appliquer à toutes les interfaces non configurées et les nommer.</p>
<p>Le truc c'est que tous les fichiers de config d'un meme type (.link et .network) sont executés par ordre alphabétique et c'est le premier dont la section <strong>Match</strong> correspond à une interface qui est appliqué. Il faut donc nommer tes fichiers de config avec un préfix inferieur à <strong>99</strong> (ex : 01, 10, 21, 97, etc).</p>

</aside>
<p>Pour chaque interface, tu vas devoir créer un fichier <strong>[nombre inferieur à 99]-[nom que tu veux].link</strong> puis un fichier <strong>[nombre inferieur à 99]-[nom que tu veux].network</strong>.</p>
<h4 id="exemple-avec-une-interface-wan">Exemple avec une interface "wan"</h4>
<p>Le fichier de nommage <strong>/etc/systemd/network/10-wan.link</strong> :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Match]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">MACAddress</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">08</span><span>:00:27:1f:</span><span style="color: light-dark(#005CC5, #79B8FF);">0d</span><span>:02</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Link]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Description</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>Interface vers box internet</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>wan</span></span></code></pre>
<p>Puis un fichier portant le même nom ".network". Il n'est pas obligatoire que le nom soit le même mais c'est plus cohérent.</p>
<p>Le contenu de <strong>/etc/systemd/network/10-wan.network</strong> pour une config automatique via DHCP :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Match]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>wan</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Network]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">DHCP</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">yes</span></span></code></pre>
<p><em>DHCP=yes</em> permet de requêter ton DHCP local (en general la box internet si c'est à la maison) afin de récuperer :</p>
<ul>
<li>Une IP pour l'interface.</li>
<li>La gateway du sous réseau.</li>
<li>L'adresse du DNS associé.</li>
</ul>
<p>Si tu veux que la partie DNS fonctionne avec ce type de config n'oublie pas d'installer le daemon systemd-resolved.</p>
<h4 id="exemple-avec-une-interface-lan-serveurs">Exemple avec une interface "lan_serveurs"</h4>
<p>Le fichier de nommage  <strong>/etc/systemd/network/20-lan_serveurs.link</strong> :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Match]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">MACAddress</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">08</span><span>:00:27:3c:d3:d9</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Link]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Description</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>Interface vers lan serveurs</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>lan_serveurs</span></span></code></pre>
<p>Le fichier <strong>/etc/systemd/network/20-lan_serveurs.network</strong>  pour une config en IP statique:</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Match]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Name</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>lan_serveurs</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Network]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Address</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>10.8.0.15/24</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Gateway</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>10.8.0.254/24 #optionnel</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">DNS</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>10.8.0.252 #optionnel</span></span></code></pre><h2 id="desactivation-du-service-networking">Désactivation du service networking</h2>
<p>Maintenant que systemd-networkd.service est configuré, on va désactiver le service networking.service qui ne sert plus a rien.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> disable</span><span style="color: light-dark(#032F62, #9ECBFF);"> networking.service</span></span></code></pre><h2 id="redemarrage">Redémarrage</h2>
<p>Pour valider tous les changements, il faut redémarrer la machine :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">reboot</span></span></code></pre><h2 id="resultat-de-la-manip">Résultat de la manip</h2>
<p>Une fois toutes tes interfaces renommées et configurées, un "ip link" doit donner quelque chose comme ceci :</p>
<p><img src="https://www.selenith.org/articles/nommer-ses-interfaces-reseau/interfaces_nommes.png" alt="Résultat de la commande &quot;ip link&quot; qui affiche des jolies interfaces bien nommées" /></p>
<p>Et voila ! La c'est propre ! Et quand il faudra configurer le pare-feu de la machine, ça sera quand même plus simple 😎.</p>
<h2 id="aller-plus-loin">Aller plus loin</h2>
<p>L'exellent article sur le <a class="external-link" rel="noopener external" target="_blank" href="https://wiki.archlinux.org/title/Systemd-networkd_(Fran%C3%A7ais)">wiki d'archlinux</a> est assez complet et il y a pas mal d'exemples pour des configurations plus complexe.</p>
<p>Dans cet <a href="https://www.selenith.org/articles/creer-un-switch-administrable-sous-linux/">article</a> tu peux aussi voir comment, à partir de cette configuration, il est possible de transformer une machine sous debian équipé de plusieurs interfaces réseau en switch manageable.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Utiliser le code 444 avec nginx</title>
        <published>2024-01-06T00:00:00+00:00</published>
        <updated>2024-01-06T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/erreur-444/" type="text/html"/>
        <id>https://www.selenith.org/articles/erreur-444/</id>
       
        <content type="html"><![CDATA[<p>Si tu héberges tes sites et applications web sur un serveur dédié sous nginx et que comme moi, tu en as marre qu'il se fasse manger des ressources par des scripts kiddies et des scanners réseaux à la noix, j'ai un truc pour toi : le code 444 !</p>
<span id="continue-reading"></span>
<p><img src="https://www.selenith.org/articles/erreur-444/444.png" alt="Image de panneau sens interdit portant l&#39;inscription &quot;erreur 444&quot; " /></p>
<h2 id="le-contexte">Le contexte</h2>
<p>Comme tu le sais probablement déjà, lorqu'on expose un truc sur internet, il ne faut pas attendre longtemps avant que des bots ou des idiots tombent sur ta plage d'adresse IP et se mettent à tout scanner pour trouver une faille à exploiter.</p>
<p>On ne va pas parler ici de sécurité mais plutôt de performance. Il y a d'autres outils dédiés de pour faire la sécu.</p>
<p>Cela étant dit, chaque fois qu'un serveur reçoit une requête, il doit l'interpréter, traiter la demande, éventuellement faire de la redirection et réécriture d'URL, chercher les fichiers sur le disque et faire une réponse en bonne et due forme. Tout ceci à pour conséquence de consommer des ressources en CPU, RAM, et temps d'acces disque. Ce n'est pas un problème quand ce sont des visiteuses et visiteurs amicaux mais c'est franchement inutile lorqu'il s'agit d'un blaireau qui cherche à nuire à ta machine.</p>
<h2 id="la-methode">La méthode</h2>
<p>On va simplement configurer nginx pour couper avec dedain toutes les connexions entrantes qui ne sont pas à destination d'un nom de domaine déclaré (ex : https://site-qui-rox.net/). Ca parait basique, mais ca permet de ne pas traiter une proportion assez élevée de requêtes inutiles.</p>
<p>Chose importante, on va partir du principe que <strong>personne</strong> n'a besoin de venir se connecter sur ton site web via son ip (ex : https://10.10.0.8/). Ceux qui font ça ne méritent pas de lire le contenu de ton site de toute façon.</p>
<p>Précision quand même : si tu veux pouvoir acceder à ton site malgré tout par son IP (sur un LAN sans DNS par exemple), tu peux toujours utiliser ton fichier <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Hosts">hosts</a> pour déclarer un nom local.</p>
<h3 id="configuration-de-nginx">Configuration de Nginx</h3>
<p>Sous debian, il suffit de créer (ou de remplacer) le fichier <strong>/etc/nginx/sites-enabled/default.conf</strong> et de le configurer comme ceci :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="nginx"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">server</span><span> {</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">  # On écoute sur les ports HTTP et HTTPS</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">  # default_server permet d&#39;aspirer les requetes vers des server_name non déclarés</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  listen</span><span style="color: light-dark(#005CC5, #79B8FF);"> 80</span><span style="color: light-dark(#005CC5, #79B8FF);"> default_server</span><span>;</span><span style="color: light-dark(#6A737D, #6A737D);"> ## ecoute en ipv4, port 80</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  listen</span><span> [::]:80 </span><span style="color: light-dark(#005CC5, #79B8FF);">default_server</span><span>;</span><span style="color: light-dark(#6A737D, #6A737D);"> ## ecoute en ipv6, port 80</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  listen</span><span style="color: light-dark(#005CC5, #79B8FF);"> 443</span><span style="color: light-dark(#005CC5, #79B8FF);"> default_server</span><span>;</span><span style="color: light-dark(#6A737D, #6A737D);"> ## ecoute en ipv4, port 443 sans ssl</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  listen</span><span> [::]:443 </span><span style="color: light-dark(#005CC5, #79B8FF);">default_server</span><span>;</span><span style="color: light-dark(#6A737D, #6A737D);"> ## ecoute en ipv6, port 443 sans ssl</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">  # Rejet des connexions SSL. On n&#39;est pas pas pour servir un café !</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">  # Ce paramètre est impératif pour pouvoir traiter le port 443</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">  # dans le même bloc &quot;serveur&quot; que le port 80.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  ssl_</span><span style="color: light-dark(#D73A49, #F97583);">reject_handshake</span><span style="color: light-dark(#005CC5, #79B8FF);"> on</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  server_</span><span style="color: light-dark(#D73A49, #F97583);">name</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">  # Les petits fichiers de logs qui permettent de voir tout ce qui est drop</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  access_log</span><span> /var/log/nginx/default-access.log</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  error_</span><span style="color: light-dark(#D73A49, #F97583);">log</span><span> /var/log/nginx/default-error.log </span><span style="color: light-dark(#005CC5, #79B8FF);">error</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">  # Le mot magique. </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">  # return 444 indique à nginx de couper la connexion TCP</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">  # sans autre forme de procès</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  return</span><span style="color: light-dark(#005CC5, #79B8FF);"> 444</span><span>;</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span></code></pre>
<p>Je donne ci dessous un exemple de config d'un site qui serait accessible via l'adresse https://sitequirox.net et hébergé sur le même serveur :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="nginx"><span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># Ce bloc sert à rediriger le traffic http vers https</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">server</span><span> {</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  listen</span><span style="color: light-dark(#005CC5, #79B8FF);">   80</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  listen</span><span>   [::]:80</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  server_</span><span style="color: light-dark(#D73A49, #F97583);">name</span><span> sitequirox.net</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  access_log</span><span> /var/log/nginx/sitequirox-access.log</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  error_</span><span style="color: light-dark(#D73A49, #F97583);">log</span><span> /var/log/nginx/sitequirox-error.log </span><span style="color: light-dark(#005CC5, #79B8FF);">error</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  return</span><span style="color: light-dark(#005CC5, #79B8FF);"> 301</span><span> https://</span><span>$</span><span>host</span><span>$</span><span>request_uri</span><span>;</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># bloc HTTPS</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">server</span><span> {</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  listen</span><span style="color: light-dark(#005CC5, #79B8FF);">  443</span><span> ssl</span><span>;</span><span> </span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  listen</span><span> [::]:443 ssl</span><span>;</span></span>
<span class="giallo-l"><span>	</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  server_</span><span style="color: light-dark(#D73A49, #F97583);">name</span><span> sitequirox.net</span><span>;</span></span>
<span class="giallo-l"><span>  </span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  access_log</span><span> /var/log/nginx/sitequirox-access.log</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  error_</span><span style="color: light-dark(#D73A49, #F97583);">log</span><span> /var/log/nginx/sitequirox-error.log </span><span style="color: light-dark(#005CC5, #79B8FF);">error</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  ssl_</span><span style="color: light-dark(#D73A49, #F97583);">certificate</span><span> /etc/letsencrypt/live/sitequirox.net/fullchain.pem</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  ssl_</span><span style="color: light-dark(#D73A49, #F97583);">certificate_key</span><span> /etc/letsencrypt/live/sitequirox.net/privkey.pem</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  root</span><span> /srv/www/sitequirox.net/</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  index</span><span> index.html</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">  location</span><span style="color: light-dark(#6F42C1, #B392F0);"> / </span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # First attempt to serve request as file, then</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # as directory, then fall back to displaying a 404.</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    try_files</span><span> $</span><span>uri</span><span> $</span><span>uri</span><span>/ </span><span style="color: light-dark(#005CC5, #79B8FF);">=404</span><span>;</span><span>	</span></span>
<span class="giallo-l"><span>  }</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span></code></pre>
<p>Et n'oublie pas de recharger la conf de nginx après l'avoir modifié.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> reload</span><span style="color: light-dark(#032F62, #9ECBFF);"> nginx</span></span></code></pre><h2 id="conclusion">Conclusion</h2>
<p>Cette méthode permet, de manière très simple, d'économiser les ressources du serveur en ne traitant pas les requêtes inutiles.</p>
<p>Le second avantage avec la configuration que j'ai donné est que tu pourras voir toutes les requêtes non légitimes dans un fichier de log dédié. La récupération des IP malveillantes provenant d'attaques non ciblées en devient simplifiée.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Se connecter avec un certificat TLS à son application web</title>
        <published>2023-12-20T00:00:00+00:00</published>
        <updated>2023-12-20T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/connexion-appli-web-avec-cle-tls/" type="text/html"/>
        <id>https://www.selenith.org/articles/connexion-appli-web-avec-cle-tls/</id>
       
        <content type="html"><![CDATA[<p>Les mots de passe c'est chiant. Personne ne les aime. A part en informatique, on n'utilise presque jamais des mots de passe. Imaginez ouvrir votre maison ou votre voiture en tapant un mot de passe sur un clavier (ou en déverrouillant un cadenas à code, c'est la même chose) et pensez à tous les problèmes qui peuvent en découler. Voila, les mots de passe c'est nul. Dans la vrai vie on utilise des clés.</p>
<p>Je vais vous parler de l'utilisation des certificats TLS, qui vont se comporter exactement comme des clés, pour vous identifier dans vos application. Nous allons voir comment mettre en place une authentification de ce type avec un cas pratique en utilisant php et nginx sur un serveur linux débian.</p>
<span id="continue-reading"></span>
<p><img src="https://www.selenith.org/articles/connexion-appli-web-avec-cle-tls/clef.jpg" alt="clé TLS" /></p>
<h2 id="avant-de-commencer">Avant de commencer</h2>
<p>Autant le dire tout de suite, cet article va être assez technique et probablement un peu long. Mais ne vous inquiétez pas,  en suivant bien pas à pas les différentes sections, vous serez en mesure d'implémenter un système d'authentification par certificats TLS dans n'importe quelle application web basée sur PHP.</p>
<p>Nous n'utiliserons ici que des fonctions disponible en PHP "vanilla". Seules des connaissances basiques en administration système linux et en développement PHP seront donc nécessaires.</p>
<h3 id="un-certificat-tls-mais-qu-est-ce-donc">Un certificat TLS ? Mais qu'est ce donc ?</h3>
<p>Pour simplifier, c'est un fichier qui va permettre de crypter (ou chiffrer) des trucs qui peuvent être aussi bien des connections réseau que des fichiers. Ce fichier peut contenir des informations sur l'entité a qui il appartient, tel qu'un pseudo ou une adresse mail par exemple pour un utilisateur, ou bien un nom de domaine pour un serveur. C'est le cas par exemple des certificats fournis par les sites accessibles en HTTPS.</p>
<h3 id="pourquoi-utiliser-un-certificat">Pourquoi utiliser un certificat ?</h3>
<p>L'intérêt d'un certificat c'est qu'il peut être signé (marqué et validé en quelque sorte) par un autre certificat auquel on fait confiance. Ce qui permettra par la suite que lorsqu'un utilisateur vous présentera son certificat, vous pourrez vérifier s'il a bien été validé par le votre.</p>
<p>En HTTPS il est possible au serveur web de demander au navigateur de lui transmettre le certificat personnel d'un utilisateur pour son domaine.</p>
<p>Ce certificat personnel sera donc à enregistrer dans le navigateur de l'utilisateur et sera transmis automatiquement, à chaque fois qu'il se connectera au serveur correspondant disposant du certificat de confiance.</p>
<p>Nous aurons donc tous les avantages d'une connexion HTTPS, avec en plus :</p>
<ul>
<li>
<p>Plus besoin de taper de mot de passe pour s'authentifier.</p>
</li>
<li>
<p>Plus jamais de perte de session. L'authentification est permanente.</p>
</li>
<li>
<p>Plus besoin d'utiliser des sessions PHP coté serveur.</p>
</li>
<li>
<p>Plus besoin d'utiliser des cookies pour conserver l'authentification pendant la navigation.</p>
</li>
<li>
<p>Et la cerise sur le gâteau : Plusieurs certificats peuvent êtres associés à un même utilisateur.</p>
</li>
</ul>
<p>Le dernier point est important. Un utilisateur pourra disposer de plusieurs certificats. Il pourra donc en avoir un sur son PC portable et un autre, différent, sur sont PC de bureau. Dans le cas ou son PC portable serait volé ou compromis, il suffira dans l'application de désactiver la clé correspondante. L'utilisateur pourra donc continuer a se connecter depuis sont PC de bureau tout en empêchant toute connexion depuis son PC portable devenu non légitime.</p>
<h2 id="nginx-et-php">Nginx et php</h2>
<p>Nginx est le serveur web qui va permettre de servir les pages de votre application/site web. C'est lui qui va recevoir les requêtes du navigateur du client. Il va servir les fichier statiques et rediriger les requêtes à destination des fichiers PHP via le processus php-fpm.</p>
<h3 id="installation">Installation</h3>
<p>Installer le tout avec apt de manière classique (en root):</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">apt</span><span style="color: light-dark(#032F62, #9ECBFF);"> update</span></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">apt</span><span style="color: light-dark(#032F62, #9ECBFF);"> install</span><span style="color: light-dark(#032F62, #9ECBFF);"> openssl</span><span style="color: light-dark(#032F62, #9ECBFF);"> nginx</span><span style="color: light-dark(#032F62, #9ECBFF);"> php-fpm</span></span></code></pre><h2 id="nginx-configuration">Nginx : configuration</h2>
<p>C'est nginx qui va servir de point d'arrivé pour la connexion TLS. Il va donc être en charge de vérifier si le client connecté en HTTPS utilise un certificat approuvé et connu. Si c'est le cas, il va falloir qu'il transmette les informations contenues dans le certificat à PHP. Si ce n'est pas le cas, il doit pouvoir quand meme servir des pages HTTPS et c'est l'application PHP qui se chargera de présenter un mode "déconnecté".</p>
<p>Pour l'exemple, notre site sera accessible à l'adresse <strong>https://mon-site-web.net</strong> et ses fichiers seront stockés à l'emplacement <strong>/srv/www/mon-site-web.net</strong> dans la machine qui l'héberge. Si vous voulez tester ca chez vous, pensez à creer une entrée DNS sur votre domaine ou à renseigner dans votre fichier <strong>hosts</strong>   local (présent sur <a class="external-link" rel="noopener external" target="_blank" href="https://www.commentcamarche.net/maison/reseau-wifi/1129-modifier-le-fichier-hosts/">windows</a> et sur <a class="external-link" rel="noopener external" target="_blank" href="https://www.malekal.com/modifier-fichier-etc-hosts-linux/">linux</a>) l'ip de votre serveur, afin de pouvoir joindre votre site avec son nom de domaine.</p>
<p>Voici comment configurer NGINX (prenez le temps de lire les commentaires):</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="nginx"><span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># Ce bloc sert à rediriger les connexions entrantes HTTP </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># vers les memes URL mais en HTTPS</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">server</span><span> {</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        listen</span><span style="color: light-dark(#005CC5, #79B8FF);"> 80</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        listen</span><span> [::]:80</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        server_</span><span style="color: light-dark(#D73A49, #F97583);">name</span><span> mon-site-web.net</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        return</span><span style="color: light-dark(#005CC5, #79B8FF);"> 301</span><span> https://</span><span>$</span><span>host</span><span>$</span><span>request_uri</span><span>;</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">server</span><span> {</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # SSL configuration</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    listen</span><span style="color: light-dark(#005CC5, #79B8FF);"> 443</span><span> ssl</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    listen</span><span> [::]:443 ssl</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # Certificat publique et clé privée du serveur.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # Necessaire pour etablir des connexion TLS (HTTPS).</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # Peuvent etre générés gratuitement avec let&#39;s encrypt par exemple</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    ssl_</span><span style="color: light-dark(#D73A49, #F97583);">certificate</span><span> /etc/letsencrypt/live/mon-site-web.net/fullchain.pem</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    ssl_</span><span style="color: light-dark(#D73A49, #F97583);">certificate_key</span><span> /etc/letsencrypt/live/mon-site-web.net/privkey.pem</span><span>;</span></span>
<span class="giallo-l"><span>    </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # Certificat de confiance de ce serveur. Il va servir a vérifier</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # que le certificat envoyé par le navigateur client est authentique.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # Il n&#39;y a aucun lien avec le certificat HTTPS ci dessus.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    #</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # L&#39;option ssl_verify_client permet de demander au client s&#39;il a un certificat valide.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # Le mode &quot;optional&quot; permet au client ne présentant pas de certificat valide, ou n&#39;en possedant</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # pas, de quand meme de naviguer en https sur notre site.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    #</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # Tant qu&#39;on a pas encore générer le certificat de confiance de notre</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # application on laisse les deux lignes en commentaire.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    #ssl_client_certificate /srv/www/mon-site-web.net/local/certs/server.pem;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    #ssl_verify_client optional;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    root</span><span> /srv/www/mon-site-web.net</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    index</span><span> index.php</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    server_</span><span style="color: light-dark(#D73A49, #F97583);">name</span><span> mon-site.net</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    # On sert les fichiers statiques</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    location</span><span style="color: light-dark(#6F42C1, #B392F0);"> / </span><span>{</span><span>    </span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        try_files</span><span> $</span><span>uri</span><span> $</span><span>uri</span><span>/ </span><span style="color: light-dark(#005CC5, #79B8FF);">=404</span><span>;</span></span>
<span class="giallo-l"><span>    }</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    #on sert les fichiers dynamiques</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    location</span><span style="color: light-dark(#D73A49, #F97583);"> ~</span><span style="color: light-dark(#032F62, #DBEDFF);"> \.php$ </span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        include</span><span> snippets/fastcgi-php.conf</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        fastcgi_</span><span style="color: light-dark(#D73A49, #F97583);">pass</span><span> unix:/var/run/php/php-fpm.sock</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        # /!\ Variables SSL a déclarer absolument pour que Nginx puisse</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        # extraire les information du certificat client et les transmettre</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        # à notre application en PHP</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        fastcgi_</span><span style="color: light-dark(#D73A49, #F97583);">param</span><span> SSL_CLIENT_VERIFY </span><span>$</span><span>ssl_client_verify</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        fastcgi_</span><span style="color: light-dark(#D73A49, #F97583);">param</span><span> SSL_CLIENT_I_DN </span><span>$</span><span>ssl_client_i_dn</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        fastcgi_</span><span style="color: light-dark(#D73A49, #F97583);">param</span><span> SSL_CLIENT_S_DN </span><span>$</span><span>ssl_client_s_dn</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        fastcgi_</span><span style="color: light-dark(#D73A49, #F97583);">param</span><span> SSL_CLIENT_M_SERIAL </span><span>$</span><span>ssl_client_serial</span><span>;</span></span>
<span class="giallo-l"><span>    }</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>}</span></span></code></pre>
<p>Cette configuration est à placer dans /etc/nginx/site-enabled/mon-site-web.net.</p>
<p>Redemarrer ensuite nginx :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> restart</span><span style="color: light-dark(#032F62, #9ECBFF);"> nginx</span></span></code></pre><h2 id="php">PHP</h2>
<p>Cette partie va etre un peu plus longue. PHP va devoir gérer les points suivants :</p>
<ul>
<li>La génération du certificat de confiance maître utilisé par nginx.</li>
<li>La base des utilisateurs avec leur niveau de droits eventuel.</li>
<li>La generation des certificats des utilisateurs.</li>
<li>La correspondance entre les certificats et les utilisateur.</li>
<li>La signature (marquage comme valide) des certificats des utilisateurs par le certificat de confiance maître.</li>
</ul>
<h3 id="generation-du-certificat-de-confiance-maitre">Génération du certificat de confiance maître.</h3>
<p>Cette action est à effectuer une seule fois. Typiquement lors d'un processus d'installation de votre application/site web.
Nous allons generer un certificat publique et une clé secrete qui servira à signer (rendre valide) les certificats des utilisateurs.</p>
<p>Afin d'éviter que la clé secrete ne puisse être lue par tout le monde, nous allons l'enregistrer en tant que variable dans un fichier PHP.
De cette manière, même si quelqu'un fait une requete sur le fichier de clé secrete, le fichier sera executé en tant que PHP et n'affichera qu'une page blanche.
Cette clé secrete sera en plus sécurisée par un password qu'on enregistrera dans un fichier de config.</p>
<p>Un exemple de code permettant de generer le certificat publique, la clé secrete et son password :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">/**</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> * Classe gerant l&#39;acces et la sauvegarde de la configuration</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">*/</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">class</span><span style="color: light-dark(#6F42C1, #B392F0);"> Config</span><span>{</span></span>
<span class="giallo-l"><span>    </span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    private</span><span style="color: light-dark(#D73A49, #F97583);"> static</span><span> $</span><span>conf_file</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">local/config.php</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	private</span><span> $</span><span>conf</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	public</span><span style="color: light-dark(#D73A49, #F97583);"> function</span><span style="color: light-dark(#005CC5, #79B8FF);"> __construct</span><span>(</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        if</span><span>(</span><span style="color: light-dark(#D73A49, #F97583);">!</span><span style="color: light-dark(#005CC5, #79B8FF);">file_exists</span><span>(</span><span style="color: light-dark(#D73A49, #F97583);">self</span><span style="color: light-dark(#D73A49, #F97583);">::</span><span>$</span><span>conf_file</span><span>)</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">            $</span><span style="color: light-dark(#005CC5, #79B8FF);">this</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span>conf</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> [</span><span>]</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">            return</span><span>;</span></span>
<span class="giallo-l"><span>        }</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		include</span><span>(</span><span style="color: light-dark(#D73A49, #F97583);">self</span><span style="color: light-dark(#D73A49, #F97583);">::</span><span>$</span><span>conf_file</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">		$</span><span style="color: light-dark(#005CC5, #79B8FF);">this</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span>conf</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>config</span><span>;</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>        </span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	public</span><span style="color: light-dark(#D73A49, #F97583);"> function</span><span style="color: light-dark(#6F42C1, #B392F0);"> get</span><span>(</span><span>$</span><span>field</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		if</span><span>(</span><span style="color: light-dark(#D73A49, #F97583);">!</span><span style="color: light-dark(#005CC5, #79B8FF);">isset</span><span>(</span><span style="color: light-dark(#005CC5, #79B8FF);">$</span><span style="color: light-dark(#005CC5, #79B8FF);">this</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span>conf</span><span>[</span><span>$</span><span>field</span><span>]</span><span>)</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">			return</span><span style="color: light-dark(#005CC5, #79B8FF);"> false</span><span>;</span></span>
<span class="giallo-l"><span>		}</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		return</span><span style="color: light-dark(#005CC5, #79B8FF);"> $</span><span style="color: light-dark(#005CC5, #79B8FF);">this</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span>conf</span><span>[</span><span>$</span><span>field</span><span>]</span><span>;</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	public</span><span style="color: light-dark(#D73A49, #F97583);"> function</span><span style="color: light-dark(#6F42C1, #B392F0);"> set</span><span>(</span><span>$</span><span>field</span><span>,</span><span> $</span><span>valeur</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">		$</span><span style="color: light-dark(#005CC5, #79B8FF);">this</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span>conf</span><span>[</span><span>$</span><span>field</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>valeur</span><span>;</span><span>		</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	public</span><span style="color: light-dark(#D73A49, #F97583);"> function</span><span style="color: light-dark(#6F42C1, #B392F0);"> save</span><span>(</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>		$</span><span>contenuFicher</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">&lt;?php</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#005CC5, #79B8FF);">PHP_EOL</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">$config = </span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#005CC5, #79B8FF);">var_export</span><span>(</span><span style="color: light-dark(#005CC5, #79B8FF);">$</span><span style="color: light-dark(#005CC5, #79B8FF);">this</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span>conf</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> true</span><span>)</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">;</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#005CC5, #79B8FF);">PHP_EOL</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">?&gt;</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>;</span><span>				</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">		file_put_contents</span><span>(</span><span style="color: light-dark(#D73A49, #F97583);">self</span><span style="color: light-dark(#D73A49, #F97583);">::</span><span>$</span><span>conf_file</span><span>,</span><span> $</span><span>contenuFicher</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> LOCK_EX</span><span>)</span><span>;</span><span>	</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">/**</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> * Genere un password aléatoire.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> * </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> * </span><span style="color: light-dark(#D73A49, #F97583);">@return</span><span style="color: light-dark(#D73A49, #F97583);"> string</span><span style="color: light-dark(#6A737D, #6A737D);"> Le password généré.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> */</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">function</span><span style="color: light-dark(#6F42C1, #B392F0);"> generate_ca_pass</span><span>(</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    return</span><span> $</span><span>string</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> substr</span><span>(</span><span style="color: light-dark(#005CC5, #79B8FF);">str_replace</span><span>(</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">+</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">/</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">=</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> base64_encode</span><span>(</span><span style="color: light-dark(#6F42C1, #B392F0);">random_bytes</span><span>(</span><span style="color: light-dark(#005CC5, #79B8FF);">32</span><span>)</span><span>)</span><span>)</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> 0</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> 32</span><span>)</span><span>;</span><span> </span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">/**</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> * Generation de la paire de clés.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> * </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> * </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> * </span><span style="color: light-dark(#D73A49, #F97583);">@param</span><span style="color: light-dark(#D73A49, #F97583);"> string</span><span style="color: light-dark(#6A737D, #6A737D);"> $CN 		FQDN du site. Ex : mon-site-web.net</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> * </span><span style="color: light-dark(#D73A49, #F97583);">@param</span><span style="color: light-dark(#D73A49, #F97583);"> string</span><span style="color: light-dark(#6A737D, #6A737D);"> $OU 		Le nom de l&#39;organisation. Ex : mon-super-site ou super-site</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> * </span><span style="color: light-dark(#D73A49, #F97583);">@param</span><span style="color: light-dark(#D73A49, #F97583);"> string</span><span style="color: light-dark(#6A737D, #6A737D);"> $country 	Le code du pays en 2 lettres. Ex : FR</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">*/</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">function</span><span style="color: light-dark(#6F42C1, #B392F0);"> generate_root_ca_keypair</span><span>(</span><span>$</span><span>CN</span><span>,</span><span> $</span><span>OU</span><span>,</span><span> $</span><span>country</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>    $</span><span>subject</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> array</span><span>(</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">commonName</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span> $</span><span>CN</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">countryName</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span>  $</span><span>country</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">organizationalUnitName</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span> $</span><span>OU</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">organizationName</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span> $</span><span>CN</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">stateOrProvinceName</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span> $</span><span>OU</span><span>,</span></span>
<span class="giallo-l"><span>    )</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);"> Génère le password de la clé privée.</span></span>
<span class="giallo-l"><span>    $</span><span>ca_password</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#6F42C1, #B392F0);"> generate_ca_pass</span><span>(</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);">Sauvegarde la clé dans la config.</span></span>
<span class="giallo-l"><span>    $</span><span>config</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Config</span><span>(</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>    $</span><span>config</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">cert_pass</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span> $</span><span>ca_password</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>    $</span><span>config</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">save</span><span>(</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>    </span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);"> Génère une nouvelle de clé privée RSA 2048 bits</span></span>
<span class="giallo-l"><span>    $</span><span>private_key</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> openssl_pkey_new</span><span>(</span><span style="color: light-dark(#005CC5, #79B8FF);">array</span><span>(</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">private_key_type</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span style="color: light-dark(#005CC5, #79B8FF);"> OPENSSL_KEYTYPE_RSA</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">private_key_bits</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span style="color: light-dark(#005CC5, #79B8FF);"> 2048</span></span>
<span class="giallo-l"><span>    )</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);"> Génère une requête de signature de certificat</span></span>
<span class="giallo-l"><span>    $</span><span>csr</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> openssl_csr_new</span><span>(</span><span>$</span><span>subject</span><span>,</span><span> $</span><span>private_key</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> array</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">digest_alg</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">sha256</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);"> Génère un certificat autosigné et l&#39;enregistre dans un fichier</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);"> on indique 1000 ans de validié ($days=365000), histoire d&#39;avoir un peu de marge ^_^</span></span>
<span class="giallo-l"><span>    $</span><span>x509</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> openssl_csr_sign</span><span>(</span><span>$</span><span>csr</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> null</span><span>,</span><span> $</span><span>private_key</span><span>,</span><span> $</span><span>days</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">365000</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> array</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">digest_alg</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">sha256</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">    openssl_x509_export_to_file</span><span>(</span><span>$</span><span>x509</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">local/certs/server.pem</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);">Prépare la clé sous forme exportable en lui assignant le mot de passe généré.</span></span>
<span class="giallo-l"><span>    $</span><span>ecc_private</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">    openssl_pkey_export</span><span>(</span><span>$</span><span>private_key</span><span>,</span><span> $</span><span>ecc_private</span><span>,</span><span> $</span><span>ca_password</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);">Ecrit la clé privée dans un fichier</span></span>
<span class="giallo-l"><span>    $</span><span>contenuFicher</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">&lt;?php</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#005CC5, #79B8FF);">PHP_EOL</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">$privkey=</span><span style="color: light-dark(#005CC5, #79B8FF);">\&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>ecc_private</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#005CC5, #79B8FF);">\&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#005CC5, #79B8FF);">PHP_EOL</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">?&gt;</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">    file_put_contents</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">local/certs/server.key.php</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span> $</span><span>contenuFicher</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> LOCK_EX</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> ==================== main =========================</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);">creations des dossiers </span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">if</span><span>(</span><span style="color: light-dark(#D73A49, #F97583);">!</span><span style="color: light-dark(#005CC5, #79B8FF);">file_exists</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">local</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">    mkdir</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">local</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">if</span><span>(</span><span style="color: light-dark(#D73A49, #F97583);">!</span><span style="color: light-dark(#005CC5, #79B8FF);">file_exists</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">local/certs</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">    mkdir</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">local/certs</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> Génération du certificat maitre et de sa clé privée.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">generate_root_ca_keypair</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">mon-site-web.net</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">super-site</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">FR</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre>
<p>Collez le code ci dessus dans un fichier (ex : install.php), puis faire une requête vers votre site pour generer la config et certificat racine de confiance. (ex https://mon-site-web.net/install.php).</p>
<p>Prenez garde à n'éxecuter qu'une fois cette requete car à chaque nouvelle execution, un nouveau certificat racine sera générer. Il vous faudra donc supprimer ou trouver un moyen de désactiver ce fichier apres son exacution.</p>
<p>A partir d'ici, vous devez décommenter les lignes concernant <strong>ssl_client_certificate</strong> et <strong>ssl_verify_client</strong> dans le fichier de configuration de Nginx.
Redemarrer nginx pour prendre en compte la nouvelle configuration et ainsi activer la lecture du certificat client.</p>
<h3 id="generation-du-certificat-des-utilisateur">Génération du certificat des utilisateur.</h3>
<p>Dans cette section nous ne verrons pas comment creer des utilisateurs pour votre site, ni comment utiliser une eventuelle base de donner pour le faire. Le choix vous appartient. Je pars du principe qu'un utilisateur doit disposer d'un identifiant numérique unique dans votre base de données.</p>
<p>Les certificats que nous allons générer pour les utilisateur ne contiendront donc que 2 élément :</p>
<ul>
<li>l'ID de l'utilisateur qui devra correspondre à un ID dans votre base de donnée.</li>
<li>L'ID du certificat lui meme, car un utilisateur doit pouvoir posseder plusieurs certificats. On utilisera le champ x500uid du certificat.</li>
<li>Optionnel : le nom de l'utilisateur ou son pseudo.</li>
</ul>
<p>Il vous appartiendra de creer des tables dans votre base de donnée comme ceci :</p>
<ul>
<li>Table User : clé primaire <strong>id</strong>, Pseudo, etc.</li>
<li>Table Certificat : clé primaire <strong>x500uid</strong>, clé étrangere <strong>id_certificat</strong>.</li>
</ul>
<p>Les certificats des utilisateurs seront générés au format P12. C'est un format pratique qui contient le certificat et la clé privé en un seul fichier, le tout protéger par un mot de passe. Le mot de passe s'utilise seulement la première fois au moment d'importer le certificat dans votre navigateur.</p>
<p>Un exemple de code permettant de generer une certificats pour un utilisateur et lancant un téléchargement pour le récuperer :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> Attention !!! </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> Coller ou inclure ici le code de la classe Config donnée plus haut dans cet article.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> Ca va permettre de récuperer le password du certificat racine pour pouvoir signer le certificat du client.</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">function</span><span style="color: light-dark(#6F42C1, #B392F0);"> generate_user_cert</span><span>(</span><span>$</span><span>username</span><span>,</span><span> $</span><span>password</span><span>,</span><span> $</span><span>user_id</span><span>,</span><span> $</span><span>x500uid</span><span>,</span><span> $</span><span>country</span><span>,</span><span> $</span><span>site_CN</span><span>,</span><span> $</span><span>site_OU</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>    $</span><span>cacert</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">file://certs/server.pem</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    include</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">certs/server.key.php</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>    $</span><span>config</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Config</span><span>(</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>    $</span><span>ca_pass</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>config</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">get</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">cert_pass</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>    $</span><span>ca_private_key</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> array</span><span>(</span><span>$</span><span>privkey</span><span>,</span><span> $</span><span>ca_pass</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>    </span></span>
<span class="giallo-l"><span>    </span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>    $</span><span>subject</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> array</span><span>(</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">commonName</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span> $</span><span>username</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">countryName</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span> $</span><span>country</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">organizationalUnitName</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span> $</span><span>site_OU</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">x500UniqueIdentifier</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span> $</span><span>x500uid</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">organizationName</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span> $</span><span>site_CN</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">stateOrProvinceName</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span> $</span><span>site_OU</span><span>,</span></span>
<span class="giallo-l"><span>    )</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);"> Génère une nouvelle paire de clés privée (et publique)</span></span>
<span class="giallo-l"><span>    $</span><span>private_key</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> openssl_pkey_new</span><span>(</span><span style="color: light-dark(#005CC5, #79B8FF);">array</span><span>(</span></span>
<span class="giallo-l"><span>       </span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">private_key_type</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span style="color: light-dark(#005CC5, #79B8FF);"> OPENSSL_KEYTYPE_RSA</span><span>,</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">        &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">private_key_bits</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span style="color: light-dark(#005CC5, #79B8FF);"> 2048</span></span>
<span class="giallo-l"><span>    )</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>    $</span><span>csr</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> openssl_csr_new</span><span>(</span><span>$</span><span>subject</span><span>,</span><span> $</span><span>private_key</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> array</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">digest_alg</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">sha256</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);"> Génère une requête de signature de certificat</span></span>
<span class="giallo-l"><span>    $</span><span>configArgs</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> array</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">x509_extensions</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">v3_req</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">digest_alg</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">sha256</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#032F62, #9ECBFF);">	&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">basicConstraints</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> =&gt;</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">critical,CA:FALSE</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>    $</span><span>serial</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>user_id</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);"> on indique 1000 ans de validié ($days=365000), histoire d&#39;avoir un peu de marge ^_^</span></span>
<span class="giallo-l"><span>    $</span><span>x509</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> openssl_csr_sign</span><span>(</span><span>$</span><span>csr</span><span>,</span><span> $</span><span>cacert</span><span>,</span><span> $</span><span>ca_private_key</span><span>,</span><span> $</span><span>days</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">365000</span><span>,</span><span> $</span><span>configArgs</span><span>,</span><span> $</span><span>serial</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>    </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">    //</span><span style="color: light-dark(#6A737D, #6A737D);"> Génère un certificat PKCS12 contenant la chaine de validation + le certificat x509 + la clé privée</span></span>
<span class="giallo-l"><span>    $</span><span>p12</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">    openssl_pkcs12_export</span><span>(</span><span>$</span><span>x509</span><span>,</span><span> $</span><span>p12</span><span>,</span><span>$</span><span>private_key</span><span>,</span><span> $</span><span>password</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">    return</span><span> $</span><span>p12</span><span>;</span></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> ==================== main =========================</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> A vous de creer un utilisateur dans votre base et de fournir les variables suivantes :</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> $username et $user_id</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> A vous de creer une entrée certificat valide dans votre base et de fournir la variable $x500uid</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> A vous de demander a l&#39;utilisateur quel password il veut pour sont certificat et de fournir la variabre $password.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> Attention : $password ne doit pas etre enregistré dans votre base. </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> Il sera intégré dans le certificat et n&#39;est pas necessaire coté serveur pour l&#39;authentification.</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>country</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">FR</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>site_CN</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">mon-site-web.net</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>;</span></span>
<span class="giallo-l"><span>$</span><span>site_OU</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">super-site</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span> ;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>$</span><span>p12</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#6F42C1, #B392F0);"> generate_user_cert</span><span>(</span><span>$</span><span>username</span><span>,</span><span> $</span><span>password</span><span>,</span><span> $</span><span>user_id</span><span>,</span><span> $</span><span>x500uid</span><span>,</span><span> $</span><span>country</span><span>,</span><span> $</span><span>site_CN</span><span>,</span><span> $</span><span>site_OU</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> on indique au navigateur client qu&#39;un fichier p12 va lui etre envoyé.</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">header</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Content-Type: application/pkcs-12</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">header</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Content-Disposition: attachment; filename=&quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span>$</span><span>username</span><span style="color: light-dark(#D73A49, #F97583);">.</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">.p12&quot;;</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">//</span><span style="color: light-dark(#6A737D, #6A737D);"> lancement du telechargement du fichier.</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">echo</span><span>(</span><span>$</span><span>p12</span><span>)</span><span>;</span><span>	</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre>
<p>Une fois ce code executé vous devriez avoir récupéré un fichier P12 au nom de l'utilisateur.</p>
<p>Vous allez pouvoir l'integrer à votre navigateur qui le présentera automatiquement à chaque requete vers votre site.
Pour installer le certificat dans votre navigateur, aller dans <strong>Paramètres</strong> ➡️ <strong>confidentialité/vie privée et sécurité</strong> ➡️ <strong>Sécurité</strong> ➡️ <strong>Voir/Afficher les certificats</strong>. Cliquer sur le bouton <strong>Importer</strong> et entrer votre password. Une fois l'importation terminée, fermer et réouvrir votre navigateur.</p>
<h3 id="identifier-les-certificat-des-utilisateur-dans-votre-application-web">Identifier les certificat des utilisateur dans votre application web</h3>
<p>Voici un exemple de classe permettant de réaliser l'authentification des utilisateurs.</p>
<p>En plus d'indiquer si l'utilisateur est connecté, vous pouver également leur attribuer un niveau de droit d'acces à votre site (utilisateur, moderateur, admin, etc). Cette classe va etre chargée de récuperer les données décodées et transmises par nginx. Elle les comparera ensuite avec les données utilisateur enregistées en base de donnée.</p>
<p>Dans le code qui va suivre, les portions de code relatives aux classes <strong>Archivist</strong> et <strong>Archivable</strong> sont des abstractions perso que j'utilise pour acceder à la base de donnée. Je ne donne pas le code de ces classes ici pour eviter d'alourdir cet article déja très long. A vous de remplacer ces classes par votre propre systeme d'interrogation de base de donnée (PDO, mysql, etc).</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="php"><span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">&lt;</span><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#005CC5, #79B8FF);">php</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">class</span><span style="color: light-dark(#6F42C1, #B392F0);"> Identificator</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	public</span><span style="color: light-dark(#D73A49, #F97583);"> static</span><span> $</span><span>USER_PERM_ADMIN</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> 3</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	public</span><span style="color: light-dark(#D73A49, #F97583);"> static</span><span> $</span><span>USER_PERM_MODERATOR</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> 2</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	public</span><span style="color: light-dark(#D73A49, #F97583);"> static</span><span> $</span><span>USER_PERM_BASE</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> 1</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	public</span><span style="color: light-dark(#D73A49, #F97583);"> static</span><span> $</span><span>USER_PERM_NOTHING</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> 0</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>	</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	public</span><span style="color: light-dark(#D73A49, #F97583);"> static</span><span style="color: light-dark(#D73A49, #F97583);"> function</span><span style="color: light-dark(#6F42C1, #B392F0);"> get_user_profile</span><span>(</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>		$</span><span>user</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> [</span><span>]</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		if</span><span>(</span><span style="color: light-dark(#D73A49, #F97583);">self</span><span style="color: light-dark(#D73A49, #F97583);">::</span><span style="color: light-dark(#6F42C1, #B392F0);">is_user_certified</span><span>(</span><span>)</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>			</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">            //</span><span style="color: light-dark(#6A737D, #6A737D);"> Utilisation de hexdec  : les serials sont en hexadecimal dans les certificat, on doit les reconvertir en decimal. </span></span>
<span class="giallo-l"><span>			$</span><span>user_id</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> hexdec</span><span>(</span><span>$</span><span>_SERVER</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">SSL_CLIENT_M_SERIAL</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>			$</span><span>dn_list</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> self</span><span style="color: light-dark(#D73A49, #F97583);">::</span><span style="color: light-dark(#6F42C1, #B392F0);">load_user_distinguished_name</span><span>(</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>			</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">			if</span><span>(</span><span style="color: light-dark(#D73A49, #F97583);">!</span><span style="color: light-dark(#005CC5, #79B8FF);">isset</span><span>(</span><span>$</span><span>dn_list</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">x500UniqueIdentifier</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>)</span><span style="color: light-dark(#D73A49, #F97583);"> OR</span><span> $</span><span>dn_list</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">x500UniqueIdentifier</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);">==</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>				$</span><span>user</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">connected</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);"> false</span><span>;</span></span>
<span class="giallo-l"><span>			}</span><span style="color: light-dark(#D73A49, #F97583);">else</span><span>{</span></span>
<span class="giallo-l"><span>				$</span><span>user_found</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> self</span><span style="color: light-dark(#D73A49, #F97583);">::</span><span style="color: light-dark(#6F42C1, #B392F0);">get_user_from_database</span><span>(</span><span>$</span><span>user_id</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>				</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">				if</span><span>(</span><span>$</span><span>user_found</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>					$</span><span>x500uid_list</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);">  self</span><span style="color: light-dark(#D73A49, #F97583);">::</span><span style="color: light-dark(#6F42C1, #B392F0);">get_user_certificate_x500uid_list_from_database</span><span>(</span><span>$</span><span>user_id</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">					if</span><span>(</span><span style="color: light-dark(#005CC5, #79B8FF);">in_array</span><span>(</span><span>$</span><span>dn_list</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">x500UniqueIdentifier</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>,</span><span> $</span><span>x500uid_list</span><span>)</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>						$</span><span>user</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">connected</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);"> true</span><span>;</span></span>
<span class="giallo-l"><span>						$</span><span>user</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">id</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>(</span><span style="color: light-dark(#D73A49, #F97583);">int</span><span>)</span><span>$</span><span>user_id</span><span> ;</span><span>					</span></span>
<span class="giallo-l"><span>						$</span><span>user</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">name</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>$</span><span>dn_list</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">CN</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>;</span></span>
<span class="giallo-l"><span>						$</span><span>user</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">x500uid</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>$</span><span>dn_list</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">x500UniqueIdentifier</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>;</span></span>
<span class="giallo-l"><span>						$</span><span>user</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">permission_level</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>$</span><span>user_found</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">get</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">permission_level</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>					}</span><span style="color: light-dark(#D73A49, #F97583);">else</span><span>{</span></span>
<span class="giallo-l"><span>						$</span><span>user</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">connected</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);"> false</span><span>;</span></span>
<span class="giallo-l"><span>					}</span></span>
<span class="giallo-l"><span>			</span></span>
<span class="giallo-l"><span>				}</span><span style="color: light-dark(#D73A49, #F97583);">else</span><span>{</span></span>
<span class="giallo-l"><span>					$</span><span>user</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">connected</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);"> false</span><span>;</span></span>
<span class="giallo-l"><span>					</span></span>
<span class="giallo-l"><span>				}</span></span>
<span class="giallo-l"><span>			}</span></span>
<span class="giallo-l"><span>		}</span><span style="color: light-dark(#D73A49, #F97583);">else</span><span>{</span></span>
<span class="giallo-l"><span>			$</span><span>user</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">connected</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);"> false</span><span>;</span></span>
<span class="giallo-l"><span>		}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		return</span><span> $</span><span>user</span><span>;</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	private</span><span style="color: light-dark(#D73A49, #F97583);"> static</span><span style="color: light-dark(#D73A49, #F97583);"> function</span><span style="color: light-dark(#6F42C1, #B392F0);"> is_user_certified</span><span>(</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		if</span><span>(</span><span style="color: light-dark(#005CC5, #79B8FF);">	isset</span><span>(</span><span>$</span><span>_SERVER</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">SSL_CLIENT_VERIFY</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>)</span><span style="color: light-dark(#D73A49, #F97583);"> &amp;&amp;</span><span> </span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">			isset</span><span>(</span><span>$</span><span>_SERVER</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">SSL_CLIENT_M_SERIAL</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>)</span><span style="color: light-dark(#D73A49, #F97583);"> &amp;&amp;</span></span>
<span class="giallo-l"><span style="color: light-dark(#005CC5, #79B8FF);">			isset</span><span>(</span><span>$</span><span>_SERVER</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">SSL_CLIENT_S_DN</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>)</span><span style="color: light-dark(#D73A49, #F97583);"> &amp;&amp;</span></span>
<span class="giallo-l"><span>			$</span><span>_SERVER</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">SSL_CLIENT_VERIFY</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);"> ==</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">SUCCESS</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span></span>
<span class="giallo-l"><span>		)</span><span>{</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">			return</span><span style="color: light-dark(#005CC5, #79B8FF);"> true</span><span>;</span></span>
<span class="giallo-l"><span>		}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		return</span><span style="color: light-dark(#005CC5, #79B8FF);"> false</span><span>;</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	private</span><span style="color: light-dark(#D73A49, #F97583);"> static</span><span style="color: light-dark(#D73A49, #F97583);"> function</span><span style="color: light-dark(#6F42C1, #B392F0);"> load_user_distinguished_name</span><span>(</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>		$</span><span>DN</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>_SERVER</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">SSL_CLIENT_S_DN</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>		$</span><span>dn_pairs</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> explode</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">,</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span> $</span><span>DN</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>		$</span><span>dn_list</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> [</span><span>]</span><span>;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		foreach</span><span> (</span><span>$</span><span>dn_pairs</span><span style="color: light-dark(#D73A49, #F97583);"> as</span><span> $</span><span>pair</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>			$</span><span>key_value</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> explode</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">=</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span> $</span><span>pair</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>			$</span><span>dn_list</span><span>[</span><span>$</span><span>key_value</span><span>[</span><span style="color: light-dark(#005CC5, #79B8FF);">0</span><span>]</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>key_value</span><span>[</span><span style="color: light-dark(#005CC5, #79B8FF);">1</span><span>]</span><span>;</span></span>
<span class="giallo-l"><span>		}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		return</span><span> $</span><span>dn_list</span><span>;</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"><span>	</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	/**</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	* Return the user found in database.</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	*</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	* </span><span style="color: light-dark(#D73A49, #F97583);">@return</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span style="color: light-dark(#6A737D, #6A737D);"> user or false if not found</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">	*/</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	private</span><span style="color: light-dark(#D73A49, #F97583);"> static</span><span style="color: light-dark(#D73A49, #F97583);"> function</span><span style="color: light-dark(#6F42C1, #B392F0);"> get_user_from_database</span><span>(</span><span>$</span><span>user_id</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>		$</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivist</span><span>(</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>		$</span><span>user</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">User</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>		$</span><span>user</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">id</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span>  (</span><span style="color: light-dark(#D73A49, #F97583);">int</span><span>)</span><span>$</span><span>user_id</span><span> )</span><span>;</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span>		$</span><span>user_found</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">restore_first</span><span>(</span><span>$</span><span>user</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		return</span><span> $</span><span>user_found</span><span>;</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">	private</span><span style="color: light-dark(#D73A49, #F97583);"> static</span><span style="color: light-dark(#D73A49, #F97583);"> function</span><span style="color: light-dark(#6F42C1, #B392F0);"> get_user_certificate_x500uid_list_from_database</span><span>(</span><span>$</span><span>user_id</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span>		$</span><span>x500uid_list</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> [</span><span>]</span><span>;</span></span>
<span class="giallo-l"><span>		$</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivist</span><span>(</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>		$</span><span>certif_to_find</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#D73A49, #F97583);"> new</span><span style="color: light-dark(#005CC5, #79B8FF);"> Archivable</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Certificate</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>		$</span><span>certif_to_find</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">set</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">id_user</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span>  (</span><span style="color: light-dark(#D73A49, #F97583);">int</span><span>)</span><span>$</span><span>user_id</span><span> )</span><span>;</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span>		$</span><span>certifs_found</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>arch</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">restore</span><span>(</span><span>$</span><span>certif_to_find</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		foreach</span><span>(</span><span>$</span><span>certifs_found</span><span style="color: light-dark(#D73A49, #F97583);"> as</span><span> $</span><span>current_certif</span><span>)</span><span>{</span></span>
<span class="giallo-l"><span>			$</span><span>x500uid_list</span><span>[</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> $</span><span>current_certif</span><span style="color: light-dark(#D73A49, #F97583);">-&gt;</span><span style="color: light-dark(#6F42C1, #B392F0);">get</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">x500uid</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span><span>;</span></span>
<span class="giallo-l"><span>		}</span></span>
<span class="giallo-l"><span>		</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">		return</span><span> $</span><span>x500uid_list</span><span>;</span></span>
<span class="giallo-l"><span>	}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span>}</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> ==================== main =========================</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">/*</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">A utiliser dans votre application</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">Les variables associées à $USER sont :</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">$USER[&#39;connected&#39;] : boolean</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">=&gt; si connected == true</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">$USER[&#39;name&#39;] : String</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">$USER[&#39;id&#39;] : int</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">$USER[&#39;permission_level&#39;] : int</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">Permission level possible : </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> - Identifier::$USER_PERM_ADMIN = 3;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> - Identifier::$USER_PERM_MODERATOR = 2;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> - Identifier::$USER_PERM_BASE = 1;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"> - Identifier::$USER_PERM_NOTHING = 0;</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">*/</span></span>
<span class="giallo-l"><span>$</span><span>USER</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);">Identificator</span><span style="color: light-dark(#D73A49, #F97583);">::</span><span style="color: light-dark(#6F42C1, #B392F0);">get_user_profile</span><span>(</span><span>)</span><span>;</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">?</span><span style="color: light-dark(#D73A49, #F97583);">&gt;</span></span></code></pre>
<p>Si vous voulez désactiver le certificat d'un utilisateur, il vous suffit simplement de supprimer en base de donnée l'entrée avec le x500uid et l'id utilisateur correspondant. L'avantage de cette méthode c'est que vous n'aurez pas à gerer des liste de certificats révoqués (CRL).</p>
<h2 id="conclusion">Conclusion</h2>
<p>Et voila, vous venez de créer votre propre infrastructure de gestion des clés, certes rustique, mais autonome et automatisée. Il ne vous reste plus qu'a créer les conditionnelles necessaire pour afficher le bon états de votre application en fonction du niveau d'acces de l'utilisateur.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Systemd : Creer un daemon actix sous Debian</title>
        <published>2021-04-13T00:00:00+00:00</published>
        <updated>2021-04-13T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/rust-webserver-actix-systemd/" type="text/html"/>
        <id>https://www.selenith.org/articles/rust-webserver-actix-systemd/</id>
       
        <content type="html"><![CDATA[<p>Je trouve que Rust est un chouette langage. Et le truc encore plus chouette avec Rust c'est la quantité de libs cool qu'on trouve sur <a class="external-link" rel="noopener external" target="_blank" href="https://crates.io/">crates.io</a>.<br />
J'utilise pour plusieurs projets professionnels des back-end web écrits en Rust grace à la lib Actix. On va voir comment, en quelques minutes, on peut creer un daemon web actix grace à Systemd.</p>
<span id="continue-reading"></span>
<p><img src="https://www.selenith.org/articles/rust-webserver-actix-systemd/systemd-actix.png" alt="Systemd aime actix" /></p>
<h2 id="actix">Actix</h2>
<p>Actix est un serveur web capable, entre autre, d'interpreter des requetes HTTP et de les traiter. L'idée ici est d'utiliser actix pour effectuer en Rust les traitement qu'on ferait habituellement en PHP.</p>
<p>Actix fonctionne de manière un peu différente de PHP. Au lieu d'utiliser CGI (ou FastCGI), il va simplement ecouter sur un socket réseau.</p>
<p>La <a class="external-link" rel="noopener external" target="_blank" href="https://actix.rs/docs/getting-started/">documentation officielle</a> explique comment creer un serveur en Rust avec actix en moins de 5 minutes.</p>
<p>Ce qui m'interesse ici c'est d'etre capable de lancer le binaire du serveur grace à des commandes de systemd, du style <strong>systemctl restart ma-super-appli-web.service</strong>.</p>
<p>Le truc cool, c'est qu'Actix est deja en mesure d'interpreter les interruptions systemes classique.</p>
<h2 id="placer-le-binaire-au-bon-endroit">Placer le binaire au bon endroit</h2>
<p>Une fois le binaire compilé avec un bon <strong>cargo build --release</strong> il va falloir le copier dans un endroit approprié du systeme.</p>
<p>Admettons que votre projet s'appelle, avec beaucoup d'originalité, <strong>serveur-rust</strong> il vous faudra récuperer le binaire du meme nom se trouvant dans le dossier <em>target/release/</em> de votre projet.</p>
<p>On le placera par exemple dans /usr/local/sbin/ de manière à ce qu'il se trouve dans le PATH du systeme.</p>
<h2 id="creer-le-fichier-unit-pour-systemd">Creer le fichier Unit pour Systemd</h2>
<p>C'est presque le plus simple.</p>
<p>Il suffit de creer un fichier dans <em>/etc/systemd/system/</em> avec le nom de votre service et le contenu tel que decrit ci dessous.</p>
<p>Exemple avec un service qu'on va nommer <strong>serveur-rust</strong>. On creer le fichier /etc/systemd/system/serveur-rust.service (en root):</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="systemd"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Unit]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Description</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>Actix-web rust server app launcher</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">After</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>network.target</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Service]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">Type</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span style="color: light-dark(#005CC5, #79B8FF);">simple</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);"># Ici le chemin du binaire. A remplacer par le votre.</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">ExecStart</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>/usr/local/sbin/serveur-rust</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">[Install]</span></span>
<span class="giallo-l"><span style="color: light-dark(#22863A, #85E89D);">WantedBy</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>multi-user.target</span></span></code></pre>
<p>Il n'y a plus qu'a activer le service (en root):</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> enable</span><span style="color: light-dark(#032F62, #9ECBFF);"> serveur-rust.service</span></span></code></pre>
<p>Grace a cette commande, le serveur sera lancé au démarrage de la machine</p>
<h2 id="lancer-le-service">Lancer le service</h2>
<p>Pour démarrer le service immediatement :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> start</span><span style="color: light-dark(#032F62, #9ECBFF);"> serveur-rust.service</span></span></code></pre>
<p>Pour vérifier que le service fonctionne :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">systemctl</span><span style="color: light-dark(#032F62, #9ECBFF);"> status</span><span style="color: light-dark(#032F62, #9ECBFF);"> serveur-rust.service</span></span></code></pre>
<p>Et la, magie ! ca fonctionne.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Certificat client SSL et thunderbird</title>
        <published>2021-03-10T00:00:00+00:00</published>
        <updated>2021-03-10T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/certificat-client-ssl-thunderbird/" type="text/html"/>
        <id>https://www.selenith.org/articles/certificat-client-ssl-thunderbird/</id>
       
        <content type="html"><![CDATA[<p>Thunderbird permet, si le serveur mail l'exige, de présenter un certificat client pour la connexion SSL en imap.<br />
Le probleme c'est qu'a chaque démarrage, thunderbird redemande de selectionner un certificat, même lorsqu'on utilise la fonction "se souvenir de ce choix".</p>
<span id="continue-reading"></span>
<p><img src="https://www.selenith.org/articles/certificat-client-ssl-thunderbird/Mozilla_Thunderbird_logo.png" alt="Logo thunderbird" /></p>
<h2 id="le-contexte">Le contexte</h2>
<p>Cela fait deja plusieurs années que j'ai configuré mon serveur mail pour n'accepter
les connexion IMAP qu'a condition que le client présente un certificat généré par ma <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Infrastructure_%C3%A0_cl%C3%A9s_publiques">PKI</a>.
J'utilise thunderbird pour me connecter à ma boite mailn mais un bug persiste depuis quelques temps.</p>
<p>Lorsque thunderbird s'ouvre et se connecte à la boite mail, il demande quel certificat choisir. On peut donc choisir un certificat et
selectionner une option "se souvenir de ce choix" afin de ne plus etre importuné par ce popup a l'ouverture.
Le problème c'est que meme en cochant cette option, thunderbird redemande à chaque ouverture de sélectionner le bon certificat.</p>
<p>Quand on a pas mal de comptes et des agenda synchronisés, ca devient vite le clicodrome de l'enfer.</p>
<h2 id="la-methode-de-contournement">La méthode de contournement</h2>
<p>Voici donc une methode de contournement simple, mais efficace.</p>
<ul>
<li>Aller dans le menu "Tools|options"</li>
<li>Puis le sous menu "Advanced"</li>
<li>Selectionner "General"</li>
<li>Cliquer sur le bouton "Config Editor"</li>
<li>Chercher la propriété <strong>security.default_personal_cert</strong></li>
<li>La modifier de "Ask every time" en "Select Automatically" (sans les guillements et en respectant la casse)</li>
</ul>
<p>Et voila, fin des popups en pagaille au démarrage !</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Sed non glouton (non greedy)</title>
        <published>2020-11-07T00:00:00+00:00</published>
        <updated>2024-01-06T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/sed-non-glouton/" type="text/html"/>
        <id>https://www.selenith.org/articles/sed-non-glouton/</id>
       
        <content type="html"><![CDATA[<p><a class="external-link" rel="noopener external" target="_blank" href="https://www.shellunix.com/sed.html">Sed</a> est une commande unix bien pratique pour capturer une chaine de caractere dans un flux du texte. Nous allons voir comment effectuer une capture non gloutonne sans s'arracher les cheveux.</p>
<span id="continue-reading"></span>
<p><img src="https://www.selenith.org/articles/sed-non-glouton/pacman-min.png" alt="pacman" /></p>
<h2 id="le-cas-d-usage">Le cas d'usage</h2>
<p>Apres avoir implementé un <a href="https://www.selenith.org/articles/spf-killer-reject-on-none/">hack de spf-policyd</a> sur mon serveur de mail, j'ai voulu créé un filtre sur mes fichiers de log me permettant de savoir, en un coup d'oeil, quels sont les domaines rejetés par mon serveur.</p>
<h2 id="la-methode-usuelle">La méthode usuelle</h2>
<p>En general, on va avoir tendance a utiliser <strong>grep</strong> pour filter les lignes interessantes :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">grep</span><span style="color: light-dark(#032F62, #9ECBFF);"> NOQUEUE</span><span style="color: light-dark(#032F62, #9ECBFF);"> /var/log/mail.log</span></span></code></pre>
<p>Ce qui nous donne quelque chose comme ceci :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>Nov  7 05:48:02 raspberrypi postfix/smtpd[22342]: NOQUEUE: reject: RCPT from dynrak234g-10-10-67-105.inwitelecom.net[105.67.10.10]: 550 5.7.23 &lt;moi@mondomaine.fr&gt;: Recipient address rejected: Votre message est en etat &quot;rejected&quot; car la configuration SPF (Sender Policy Framework) de votre serveur mail est incorrecte. Votre message est donc considere comme un SPAM. Details technique : Message rejected due to: no SPF record. Please see http://www.open-spf.org/Why?s=helo;id=dynrak234g-195-129-67-105.inwitelecom.net;ip=105.67.10.10;r=&lt;UNKNOWN&gt;; from=&lt;heike.lindner@manos-immobilien.com&gt; to=&lt;moi@mondomaine.fr&gt; proto=ESMTP helo=&lt;dynrak234g-195-129-67-105.inwitelecom.net&gt;</span></span>
<span class="giallo-l"><span>Nov  7 07:59:24 raspberrypi postfix/smtpd[22972]: NOQUEUE: reject: RCPT from unknown[186.83.41.2]: 550 5.7.23 &lt;moi@mondomaine.fr&gt;: Recipient address rejected: Votre message est en etat &quot;rejected&quot; car la configuration SPF (Sender Policy Framework) de votre serveur mail est incorrecte. Votre message est donc considere comme un SPAM. Details technique : Message rejected due to: no SPF record. Please see http://www.open-spf.org/Why?s=helo;id=dynamic-ip-18683412.cable.net.co;ip=186.83.41.2;r=&lt;UNKNOWN&gt;; from=&lt;riskyesg@paraisodedonquijote.com&gt; to=&lt;moi@mondomaine.fr&gt; proto=ESMTP helo=&lt;dynamic-ip-18683412.cable.net.co&gt;</span></span>
<span class="giallo-l"><span>Nov  7 08:24:35 raspberrypi postfix/smtpd[23097]: NOQUEUE: reject: RCPT from unknown[45.64.236.77]: 550 5.7.23 &lt;moi@mondomaine.fr&gt;: Recipient address rejected: Votre message est en etat &quot;rejected&quot; car la configuration SPF (Sender Policy Framework) de votre serveur mail est incorrecte. Votre message est donc considere comme un SPAM. Details technique : Message rejected due to: no SPF record. Please see http://www.open-spf.org/Why?s=helo;id=node-45-64-236-77.alliancebroadband.in;ip=45.64.236.77;r=&lt;UNKNOWN&gt;; from=&lt;dgyks@sickel.com&gt; to=&lt;moi@mondomaine.fr&gt; proto=ESMTP helo=&lt;node-45-64-236-77.alliancebroadband.in&gt;</span></span>
<span class="giallo-l"><span>Nov  7 08:57:55 raspberrypi postfix/smtpd[23411]: NOQUEUE: reject: RCPT from unknown[176.216.115.26]: 550 5.7.23 &lt;moi@mondomaine.fr&gt;: Recipient address rejected: Votre message est en etat &quot;rejected&quot; car la configuration SPF (Sender Policy Framework) de votre serveur mail est incorrecte. Votre message est donc considere comme un SPAM. Details technique : Message rejected due to: no SPF record. Please see http://www.open-spf.org/Why?s=helo;id=[176.216.115.26];ip=176.216.115.26;r=&lt;UNKNOWN&gt;; from=&lt;jose.miguel.covelo.perez@inega.es&gt; to=&lt;moi@mondomaine.fr&gt; proto=ESMTP helo=&lt;[176.216.115.26]&gt;</span></span>
<span class="giallo-l"><span>Nov  7 09:29:19 raspberrypi postfix/smtpd[23601]: NOQUEUE: reject: RCPT from unknown[185.223.216.254]: 550 5.7.23 &lt;moi@mondomaine.fr&gt;: Recipient address rejected: Votre message est en etat &quot;rejected&quot; car la configuration SPF (Sender Policy Framework) de votre serveur mail est incorrecte. Votre message est donc considere comme un SPAM. Details technique : Message rejected due to: no SPF record. Please see http://www.open-spf.org/Why?s=helo;id=[185.223.216.254];ip=185.223.216.254;r=&lt;UNKNOWN&gt;; from=&lt;nishimura@jn-design.com&gt; to=&lt;moi@mondomaine.fr&gt; proto=ESMTP helo=&lt;[185.223.216.254]&gt;</span></span>
<span class="giallo-l"><span>Nov  7 10:01:55 raspberrypi postfix/smtpd[23714]: NOQUEUE: reject: RCPT from unknown[61.9.108.122]: 550 5.7.23 &lt;moi@mondomaine.fr&gt;: Recipient address rejected: Votre message est en etat &quot;rejected&quot; car la configuration SPF (Sender Policy Framework) de votre serveur mail est incorrecte. Votre message est donc considere comme un SPAM. Details technique : Message rejected due to: no SPF record. Please see http://www.open-spf.org/Why?s=helo;id=[61.9.108.122];ip=61.9.108.122;r=&lt;UNKNOWN&gt;; from=&lt;robin@fuchs5.com&gt; to=&lt;moi@mondomaine.fr&gt; proto=ESMTP helo=&lt;[61.9.108.122]&gt;</span></span>
<span class="giallo-l"><span>Nov  7 10:57:46 raspberrypi postfix/smtpd[24007]: NOQUEUE: reject: RCPT from unknown[59.91.247.194]: 550 5.7.23 &lt;moi@mondomaine.fr&gt;: Recipient address rejected: Votre message est en etat &quot;rejected&quot; car la configuration SPF (Sender Policy Framework) de votre serveur mail est incorrecte. Votre message est donc considere comme un SPAM. Details technique : Message rejected due to: no SPF record. Please see http://www.open-spf.org/Why?s=helo;id=[59.91.247.194];ip=59.91.247.194;r=&lt;UNKNOWN&gt;; from=&lt;lukasz@pakunova.pl&gt; to=&lt;moi@mondomaine.fr&gt; proto=ESMTP helo=&lt;[59.91.247.194]&gt;</span></span>
<span class="giallo-l"><span>Nov  7 11:32:26 raspberrypi postfix/smtpd[24233]: NOQUEUE: reject: RCPT from unknown[197.3.10.37]: 550 5.7.23 &lt;moi@mondomaine.fr&gt;: Recipient address rejected: Votre message est en etat &quot;rejected&quot; car la configuration SPF (Sender Policy Framework) de votre serveur mail est incorrecte. Votre message est donc considere comme un SPAM. Details technique : Message rejected due to: no SPF record. Please see http://www.open-spf.org/Why?s=helo;id=[197.3.10.37];ip=197.3.10.37;r=&lt;UNKNOWN&gt;; from=&lt;annadias@carbotrade-spa.com&gt; to=&lt;moi@mondomaine.fr&gt; proto=ESMTP helo=&lt;[197.3.10.37]&gt;</span></span>
<span class="giallo-l"><span>Nov  7 12:29:09 raspberrypi postfix/smtpd[24500]: NOQUEUE: reject: RCPT from unknown[182.186.12.201]: 550 5.7.23 &lt;moi@mondomaine.fr&gt;: Recipient address rejected: Votre message est en etat &quot;rejected&quot; car la configuration SPF (Sender Policy Framework) de votre serveur mail est incorrecte. Votre message est donc considere comme un SPAM. Details technique : Message rejected due to: no SPF record. Please see http://www.open-spf.org/Why?s=helo;id=[182.186.12.201];ip=182.186.12.201;r=&lt;UNKNOWN&gt;; from=&lt;eli@ifcship.com&gt; to=&lt;moi@mondomaine.fr&gt; proto=ESMTP helo=&lt;[182.186.12.201]&gt;</span></span>
<span class="giallo-l"><span>Nov  7 13:15:28 raspberrypi postfix/smtpd[24844]: NOQUEUE: reject: RCPT from unknown[190.244.85.167]: 550 5.7.23 &lt;moi@mondomaine.fr&gt;: Recipient address rejected: Votre message est en etat &quot;rejected&quot; car la configuration SPF (Sender Policy Framework) de votre serveur mail est incorrecte. Votre message est donc considere comme un SPAM. Details technique : Message rejected due to: no SPF record. Please see http://www.open-spf.org/Why?s=helo;id=167-85-244-190.fibertel.com.ar;ip=190.244.85.167;r=&lt;UNKNOWN&gt;; from=&lt;ricerx@punkass.com&gt; to=&lt;moi@mondomaine.fr&gt; proto=ESMTP helo=&lt;167-85-244-190.fibertel.com.ar&gt;</span></span>
<span class="giallo-l"><span>Nov  7 13:49:11 raspberrypi postfix/smtpd[24979]: NOQUEUE: reject: RCPT from adsl-73.37.6.210.tellas.gr[37.6.210.73]: 550 5.7.23 &lt;moi@mondomaine.fr&gt;: Recipient address rejected: Votre message est en etat &quot;rejected&quot; car la configuration SPF (Sender Policy Framework) de votre serveur mail est incorrecte. Votre message est donc considere comme un SPAM. Details technique : Message rejected due to: no SPF record. Please see http://www.open-spf.org/Why?s=helo;id=adsl-73.37.6.210.tellas.gr;ip=37.6.210.73;r=&lt;UNKNOWN&gt;; from=&lt;lyxbi@excite.fr&gt; to=&lt;moi@mondomaine.fr&gt; proto=ESMTP helo=&lt;adsl-73.37.6.210.tellas.gr&gt;</span></span>
<span class="giallo-l"><span>Nov  7 14:17:05 raspberrypi postfix/smtpd[25090]: NOQUEUE: reject: RCPT from unknown[154.160.11.112]: 550 5.7.23 &lt;moi@mondomaine.fr&gt;: Recipient address rejected: Votre message est en etat &quot;rejected&quot; car la configuration SPF (Sender Policy Framework) de votre serveur mail est incorrecte. Votre message est donc considere comme un SPAM. Details technique : Message rejected due to: no SPF record. Please see http://www.open-spf.org/Why?s=helo;id=[154.160.11.112];ip=154.160.11.112;r=&lt;UNKNOWN&gt;; from=&lt;prenault@lenko.com&gt; to=&lt;moi@mondomaine.fr&gt; proto=ESMTP helo=&lt;[154.160.11.112]&gt;</span></span>
<span class="giallo-l"><span>etc...</span></span></code></pre>
<p>Le résultat est pertinent, mais sa lecture est désagréable.<br />
C'est la que sed intervient.</p>
<h2 id="faire-du-menage">Faire du menage</h2>
<p>On va utiliser <strong>sed</strong> en mode substitution et avec la fonction de capture.</p>
<p>La syntaxe de base de la substitution est la suivante :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">sed</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">s/phrase a chercher/phrase de remplacement/</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span></span></code></pre>
<p>La phrase a chercher peut etre une <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Expression_r%C3%A9guli%C3%A8re">expression regulière</a>, aussi appelée regex.</p>
<p>La capture permet de récuperer une partie de la phrase a chercher. Il est possible d'afficher le résultat de la capture dans la phrase de remplacement avec la notation \&lt;numéro de la capture&gt;.<br />
Ex : <strong>\1</strong> ou <strong>\2</strong></p>
<p>la capture s'effectue avec les parenthèses <strong>(</strong> et <strong>)</strong>. Il faut cependant les echapper avec le symbole "<strong>\</strong>" pour indiquer à sed qu'on veut faire une capture et non chercher les caracteres "(" et ")".</p>
<p>Ex :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">sed</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">s/expression \(mot\) reste de l expression/capturé : \1/</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span></span></code></pre>
<p>Affichera :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>capturé : mot</span></span></code></pre><h2 id="t-en-a-trop-pris-gros">T'en a trop pris gros !</h2>
<p>Le probleme c'est que les regex de sed sont gloutonnes. Sed ne reconnait pas la notation <strong>+?</strong> ou <strong>*?</strong>.</p>
<p>Un exemple avec le fichier de log précédent. On souhaite extraire la valeur "<em>annadias@carbotrade-spa.com</em>" contenu dans les chevrons de "<em>from=&lt;annadias@carbotrade-spa.com&gt;</em>"</p>
<p>La commande :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">grep</span><span style="color: light-dark(#032F62, #9ECBFF);">  NOQUEUE</span><span style="color: light-dark(#032F62, #9ECBFF);"> /var/log/mail.log</span><span style="color: light-dark(#D73A49, #F97583);"> |</span><span style="color: light-dark(#6F42C1, #B392F0);"> sed</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">s/.*from=&lt;\(.*\)&gt;.*/\1/</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span></span></code></pre>
<p>Donne comme résultat :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>annadias@carbotrade-spa.com&gt; to=&lt;moi@mondomaine.fr</span></span></code></pre>
<p>Le soucis vient du fait que <strong>&lt;.*&gt;</strong> prend tous les caractères jusqu'au dernier "<strong>&gt;</strong>" rencontré, même si d'autres se trouvent sur le chemin.</p>
<h2 id="la-negation-et-la-solution">La négation et la solution</h2>
<p>L'astuce est donc d'utiliser la négation du caractere délimiteur pour etre certain de s'arreter au premier rencontré.</p>
<p>Ex :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>[^&gt;]</span></span></code></pre>
<p>Signifie : n'importe quel caractère qui n'est pas "<strong>&gt;</strong>".
On va donc pouvoir l'utiliser à la place du "<strong>.</strong>" de la manière suivante :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>[^&gt;]*</span></span></code></pre>
<p>L'expression a utiliser est donc la suivante :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">grep</span><span style="color: light-dark(#032F62, #9ECBFF);">  NOQUEUE</span><span style="color: light-dark(#032F62, #9ECBFF);"> /var/log/mail.log</span><span style="color: light-dark(#D73A49, #F97583);"> |</span><span style="color: light-dark(#6F42C1, #B392F0);"> sed</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">s/.*from=&lt;\([^&gt;]*\)&gt;.*/\1/</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span></span></code></pre>
<p>Qui nous donnera comme résultat :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>heike.lindner@manos-immobilien.com</span></span>
<span class="giallo-l"><span>riskyesg@paraisodedonquijote.com</span></span>
<span class="giallo-l"><span>dgyks@sickel.com</span></span>
<span class="giallo-l"><span>jose.miguel.covelo.perez@inega.es</span></span>
<span class="giallo-l"><span>nishimura@jn-design.com</span></span>
<span class="giallo-l"><span>robin@fuchs5.com</span></span>
<span class="giallo-l"><span>lukasz@pakunova.pl</span></span>
<span class="giallo-l"><span>annadias@carbotrade-spa.com</span></span>
<span class="giallo-l"><span>eli@ifcship.com</span></span>
<span class="giallo-l"><span>ricerx@punkass.com</span></span>
<span class="giallo-l"><span>lyxbi@excite.fr</span></span>
<span class="giallo-l"><span>prenault@lenko.com</span></span></code></pre><h2 id="bonus-un-peu-plus-de-detail">Bonus : un peu plus de détail</h2>
<p>En reprenant cette expression et en ajoutant une deuxieme capture, on peut egalement récupérer la date :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">grep</span><span style="color: light-dark(#032F62, #9ECBFF);">  NOQUEUE</span><span style="color: light-dark(#032F62, #9ECBFF);"> /var/log/mail.log</span><span style="color: light-dark(#D73A49, #F97583);"> |</span><span style="color: light-dark(#6F42C1, #B392F0);"> sed</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">s/\(.*\)raspberrypi.*from=&lt;\([^&gt;]*\)&gt;.*/\1: \2/</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span></span></code></pre>
<p>Résultat :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>Nov  7 05:48:02 : heike.lindner@manos-immobilien.com</span></span>
<span class="giallo-l"><span>Nov  7 07:59:24 : riskyesg@paraisodedonquijote.com</span></span>
<span class="giallo-l"><span>Nov  7 08:24:35 : dgyks@sickel.com</span></span>
<span class="giallo-l"><span>Nov  7 08:57:55 : jose.miguel.covelo.perez@inega.es</span></span>
<span class="giallo-l"><span>Nov  7 09:29:19 : nishimura@jn-design.com</span></span>
<span class="giallo-l"><span>Nov  7 10:01:55 : robin@fuchs5.com</span></span>
<span class="giallo-l"><span>Nov  7 10:57:46 : lukasz@pakunova.pl</span></span>
<span class="giallo-l"><span>Nov  7 11:32:26 : annadias@carbotrade-spa.com</span></span>
<span class="giallo-l"><span>Nov  7 12:29:09 : eli@ifcship.com</span></span>
<span class="giallo-l"><span>Nov  7 13:15:28 : ricerx@punkass.com</span></span>
<span class="giallo-l"><span>Nov  7 13:49:11 : lyxbi@excite.fr</span></span>
<span class="giallo-l"><span>Nov  7 14:17:05 : prenault@lenko.com</span></span></code></pre>
<p>En version hardcore avec mise en forme avec la commande <strong>column</strong> :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">grep</span><span style="color: light-dark(#032F62, #9ECBFF);"> NOQUEUE</span><span style="color: light-dark(#032F62, #9ECBFF);"> /var/log/mail.log</span><span style="color: light-dark(#D73A49, #F97583);"> |</span><span style="color: light-dark(#6F42C1, #B392F0);"> sed</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">s/\(.*\)raspberrypi.*from=&lt;\([^&gt;]*\)&gt;.*to=&lt;\([^&gt;]*\)&gt;.*helo=&lt;\([^&gt;]*\)&gt;.*/\1#\2#\4#\3/</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#D73A49, #F97583);"> |</span><span style="color: light-dark(#6F42C1, #B392F0);"> column</span><span style="color: light-dark(#005CC5, #79B8FF);"> -</span><span style="color: light-dark(#005CC5, #79B8FF);">t</span><span style="color: light-dark(#005CC5, #79B8FF);"> -</span><span style="color: light-dark(#005CC5, #79B8FF);">s</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">#</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span></span></code></pre>
<p>Ce qui va afficher les données de la manière suivant :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="plain"><span class="giallo-l"><span>date expediteur serveur_emetteur destinataire</span></span></code></pre>
<p>Grâce à cette ligne de commande, je peux avoir un rapport de tous les domaines pourris qui m'envoient des mail.<br />
Le cas échéant, je peux alors ajouter une exception dans mon filtrage SPF pour laisser passer un domaine mal configuré mais avec lequel j'ai besoin de communiquer par mail.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Atomisation des SPAM : Hack de spf-policyd (postfix)</title>
        <published>2020-10-31T00:00:00+00:00</published>
        <updated>2020-10-31T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/spf-killer-reject-on-none/" type="text/html"/>
        <id>https://www.selenith.org/articles/spf-killer-reject-on-none/</id>
       
        <content type="html"><![CDATA[<p>Administrer son serveur de messagerie, c'est cool. Se faire blinder ses boites mails de SPAM, ça l'est moins.
Il existe plein de methodes subtiles et inefficaces pour bloquer les SPAM tout en laissant passer les mail légitimes. Nous allons voir qu'avec un simple Hack de spf-policyd, la subtilité c'est pour les faibles et les couards !</p>
<span id="continue-reading"></span><figure>
    
        <img src="https:&#x2F;&#x2F;www.selenith.org&#x2F;articles&#x2F;spf-killer-reject-on-none&#x2F;spam-mail.jpg"  alt="Boite aux lettres avec inscription no junk mail"  />
    
    <figcaption>
        <p>Vous ne passerez paaaaaas !</p>

    </figcaption>
</figure>
<!-- <hr />-->
<h2 id="le-contexte">Le contexte</h2>
<p>Configurer un systeme anti-spam sous postfix est une vrai misère. Même s'il existe des tres bons tutos, ils impliquent tous de <a class="external-link" rel="noopener external" target="_blank" href="https://www.sidn.nl/en/news-and-blogs/hands-on-implementing-spf-dkim-and-dmarc-in-postfix">nombreuses étapes de configurations complexes</a>.
De plus, il est souvent nécessaire d'utiliser des services tiers pour qualifier le niveau de confiance du serveur émetteur.</p>
<h2 id="la-methode-usuelle">La methode usuelle</h2>
<p>L'idée est de se concentrer sur le SPF. Je pars du principe que si quelqu'un administre un serveur de mail il DOIT avoir correctement configuré au moins le champ SPF du DNS lié à son domaine.
C'est ultra basique et indispensable pour envoyer des mail vers des adresses gmail ou outlook.</p>
<p>La verification du SPF consiste à dire à votre serveur mail que lorsqu'il reçoit un mail, il doit verifier si l'IP du serveur émetteur correspond à l'IP du serveur officiellement déclaré de ce domaine.</p>
<p>Cette vérification peut être effectuée par un utilitaire nommé spf-policyd. Le problème c'est que cet utilitaire fonctionne uniquement si le domaine indiqué comme etant celui de l'émetteur déclare effectivement un champ SPF dans son DNS.
Dans le cas ou rien ne serait déclaré, spf-policyd laisse passer le mail. Un peu embettant non ?</p>
<p>Du coup il est normalement necessaire de coupler spf-policyd avec DKIM, DMARC et spamassasin pour etre certain de couvrir tous les cas possibles.</p>
<h2 id="le-hack">Le hack</h2>
<p>L'idée simple est de modifier spf-policyd pour qu'il rejette les mails si le SPF de l'emetteur n'existe pas (résultat "None"). La fonction de base, qui rejette le mail si le SPF ne correspond pas (résultat "Fail") continuera de fonctionner normalement.
On va simplement rendre spf-policyd un peut plus aggressif.</p>
<p>Sous Débian 10 et ubuntu 20.04, apres avoir <a class="external-link" rel="noopener external" target="_blank" href="https://help.ubuntu.com/community/Postfix/SPF">installé et configuré</a> le paquet <strong>postfix-policyd-spf-python</strong>,  il faut éditer le fichier /usr/lib/python3/dist-packages/spf_engine/__init__.py</p>
<p>A la ligne 159, sous le bloc suivant :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="python"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        if</span><span> mfrom_policy</span><span style="color: light-dark(#D73A49, #F97583);"> ==</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">SPF_Not_Pass</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>:</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">            try</span><span>:</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Fail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                actions</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>.</span><span>append</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Fail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Softfail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                actions</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>.</span><span>append</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Softfail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Neutral</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                actions</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>.</span><span>append</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Neutral</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">            except</span><span>:</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">                if</span><span> debugLevel</span><span style="color: light-dark(#D73A49, #F97583);"> &gt;=</span><span style="color: light-dark(#005CC5, #79B8FF);"> 2</span><span>:</span><span> syslog</span><span>.</span><span>syslog</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Configuration File parsing error: Mail_From_reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"></span></code></pre>
<p>Ajouter ces lignes suivantes apres "exept :, if debug...":</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="python"><span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        #</span><span style="color: light-dark(#6A737D, #6A737D);"> Hack de selenith</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        elif</span><span> mfrom_policy</span><span style="color: light-dark(#D73A49, #F97583);"> ==</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Cerbere</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>:</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">            try</span><span>:</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Fail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                actions</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>.</span><span>append</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Fail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Softfail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                actions</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>.</span><span>append</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Softfail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">None</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                actions</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>.</span><span>append</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">None</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">            except</span><span>:</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">                if</span><span> debugLevel</span><span style="color: light-dark(#D73A49, #F97583);"> &gt;=</span><span style="color: light-dark(#005CC5, #79B8FF);"> 2</span><span>:</span><span> syslog</span><span>.</span><span>syslog</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Configuration File parsing error: Mail_From_reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"></span></code></pre>
<p>La section devrait donc ressembler à ceci :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="python"><span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);"> if</span><span> scope</span><span style="color: light-dark(#D73A49, #F97583);"> ==</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">mfrom</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>:</span></span>
<span class="giallo-l"><span>        mfrom_policy</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> configData</span><span>.</span><span>get</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Mail_From_reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        if</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span style="color: light-dark(#032F62, #9ECBFF);">@</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span style="color: light-dark(#D73A49, #F97583);"> in</span><span> sender</span><span>:</span></span>
<span class="giallo-l"><span>            sender_domain</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span> sender</span><span>.</span><span>split</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">@</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>,</span><span style="color: light-dark(#005CC5, #79B8FF);"> 1</span><span>)</span><span>[</span><span style="color: light-dark(#005CC5, #79B8FF);">1</span><span>]</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        else</span><span>:</span></span>
<span class="giallo-l"><span>            sender_domain</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        if</span><span> spf</span><span>.</span><span>domainmatch</span><span>(</span><span>reject_domain_list</span><span>,</span><span> sender_domain</span><span>)</span><span>:</span></span>
<span class="giallo-l"><span>            mfrom_policy</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">SPF_Not_Pass</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span></span>
<span class="giallo-l"><span>            local</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">local_mfrom</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span style="color: light-dark(#D73A49, #F97583);"> =</span><span style="color: light-dark(#005CC5, #79B8FF);"> True</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        if</span><span> mfrom_policy</span><span style="color: light-dark(#D73A49, #F97583);"> ==</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">SPF_Not_Pass</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>:</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">            try</span><span>:</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Fail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                actions</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>.</span><span>append</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Fail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Softfail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                actions</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>.</span><span>append</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Softfail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Neutral</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                actions</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>.</span><span>append</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Neutral</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">            except</span><span>:</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">                if</span><span> debugLevel</span><span style="color: light-dark(#D73A49, #F97583);"> &gt;=</span><span style="color: light-dark(#005CC5, #79B8FF);"> 2</span><span>:</span><span> syslog</span><span>.</span><span>syslog</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Configuration File parsing error: Mail_From_reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">        #</span><span style="color: light-dark(#6A737D, #6A737D);"> Hack de selenith</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        elif</span><span> mfrom_policy</span><span style="color: light-dark(#D73A49, #F97583);"> ==</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Cerbere</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>:</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">            try</span><span>:</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Fail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                actions</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>.</span><span>append</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Fail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Softfail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                actions</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>.</span><span>append</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Softfail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">None</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span>                actions</span><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>]</span><span>.</span><span>append</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">None</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">            except</span><span>:</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">                if</span><span> debugLevel</span><span style="color: light-dark(#D73A49, #F97583);"> &gt;=</span><span style="color: light-dark(#005CC5, #79B8FF);"> 2</span><span>:</span><span> syslog</span><span>.</span><span>syslog</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Configuration File parsing error: Mail_From_reject</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">        elif</span><span> mfrom_policy</span><span style="color: light-dark(#D73A49, #F97583);"> ==</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Softfail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>:</span></span>
<span class="giallo-l"><span style="color: light-dark(#D73A49, #F97583);">            try</span><span>:</span></span>
<span class="giallo-l"><span>                unused_results</span><span>.</span><span>remove</span><span>(</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">Fail</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span><span>)</span></span></code></pre>
<p>Avec ce petit patch, il va être necessaire de mettre en liste blanche les domaines des serveurs mail émetteurs qu'on peut considérer comme sûrs, mais dont les champs SPF sont mal ou non configurés.</p>
<p>Pour cela on va éditer le fichier de config <strong>/etc/postfix-policyd-spf-python/policyd-spf.conf</strong></p>
<p>Ajouter en fin de fichier les lignes suivantes :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> Domaines des adresses emails emetteurs autorisés (mfrom) </span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> Valide seulement si le SPF du domaine est configuré. Si SPF : None =&gt; utiliser HELO_Whitelist</span></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">Domain_Whitelist</span><span style="color: light-dark(#032F62, #9ECBFF);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> freetelecom.fr,linuxfr.org,outlook.com,sfr.fr,orange.fr,google.com</span></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> Domaines des serveurs emetteurs autorisé (HELO)</span></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">HELO_Whitelist</span><span style="color: light-dark(#032F62, #9ECBFF);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);">   free.fr,freetelecom.fr,amazonses.com,gouv.fr,outlook.com,sfr.fr,orange.fr,google.com,linkedin.com</span></span></code></pre>
<p>Et pour finir on active notre patch en modifiant la valeur Mail_From_reject comme ceci :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);"> Mail_From_reject = Fail</span></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">Mail_From_reject</span><span style="color: light-dark(#032F62, #9ECBFF);"> =</span><span style="color: light-dark(#032F62, #9ECBFF);"> Cerbere</span></span></code></pre>
<p>En ayant appliqué le patch dans la section qu'on a nommé "Cerbere", on peut l'activer ou le désactiver à la volée en changeant la valeur de <strong>Mail_From_reject</strong> de <em>Fail</em> à <em>Cerbere</em>.</p>
<p>J'ai mis les principaux domaines avec lesquels j'ai déja rencontrés des soucis.</p>
<p>A vous de compléter ou de modifier avec les domaines que vous trouvez pertinent et dont les champs SPF sont mal configurés (oui c'est toi que je regarde, le site des impots).</p>
<h2 id="aller-plus-loin">Aller plus loin</h2>
<p>Une technique avec de la <a href="https://www.selenith.org/articles/sed-non-glouton/">regexp savoureuse</a> pour surveiller les domaines bloqués par notre spf-policyd cerbère sous stéroides.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Centralisation du web et site statique</title>
        <published>2020-10-19T00:00:00+00:00</published>
        <updated>2020-10-19T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/centralisation-et-site-statique/" type="text/html"/>
        <id>https://www.selenith.org/articles/centralisation-et-site-statique/</id>
       
        <content type="html"><![CDATA[<p>Les site dynamiques avec systeme de gestion de contenu (CMS), tel quel wordpress, drupal ou joomla sont faciles à installer et offrent quantité de fonctionnalités bien pratiques.
Alors pourquoi suis-je donc passé d'un site dynamique à un site statique en 2020 ?</p>
<span id="continue-reading"></span><figure>
    
        <img src="https:&#x2F;&#x2F;www.selenith.org&#x2F;articles&#x2F;centralisation-et-site-statique&#x2F;Ambre_Moustique.jpg"  alt="Moustique pris dans l&#x27;ambre"  />
    
    <figcaption>
        <p>Moustique pris dans l'ambre. Image issue d'une photo de <a class="external-link" rel="noopener external" target="_blank" href="https://fr.wikipedia.org/wiki/Ambre#/media/Fichier:Ambre_Moustique.jpg">Didier Desouens</a>.</p>

    </figcaption>
</figure>
<!-- <hr />-->
<h2 id="le-point-de-depart-les-commentaires">Le point de départ : les commentaires</h2>
<p>En voulant retaper un peu l'aspect graphique de mon site, je me suis fait la reflexion suivante : Il n'y a quasiment aucun commentaire sous mes articles.
C'etait pourtant la raison principale pour laquelle j'avais choisi de maintenir un site dynamique. Pour offrir une tribune aux visiteurs et ainsi permettre critique (constructive) et échanges autour des choses que je partage.
La raison de cette absence de commentaire est plutot simple, c'est dû à la centralisation des communication sur des plates formes dédiées.</p>
<h2 id="s-enfermer-pour-partager">S'enfermer pour partager</h2>
<p>Lorsqu'on veut partage une publication à des gens qu'on sait etre intéréssés pas le sujet, on a assez peu d'options.</p>
<p>La première, décentralisée, est aussi la moins pratique pour discuter à plusieurs. Il s'agit du bon vieux mail.
C'est un support qui est parfait pour un dialogue entre deux personnes. Mais dès qu'on commence à augmenter le nombres de participants, ca devient vite fouilli.
Sans compter qu'on a pas forcement envie d'avoir son adresse mail partagée, de maniere aléatoire avec 150 personnes, des qu'on veut faire un simple commentaire publique.</p>
<p>La deuxieme, décentralisée elle aussi, est le Flux Atom/RSS. Mais il ne permet en aucun cas le dialogue.</p>
<p>La troisième, centralisée, mais surtout la solution la plus utilisée, est le partage sur les réseaux sociaux. Pratique, rapide, non intrusif, ça parait être la solution idéale.
Mais il n'en est rien. Les discutions se font alors sous les posts de partage créés dans les réseaux sociaux, à l'endroit ou le lecteur est déja présent et connecté.
Et on ne peut pas le blamer, cela lui demande moins d'energie et de temps que d'aller sur le site d'origine, de taper son commentaire, un pseudo, ainsi que de valider un captcha <del>à la con sans lequel ton site se fait spammer par des bots de script kiddies</del>.
Le fossé se creuse d'autant plus s'il faut indiquer des infos supplémentaires, tel qu'une adresse mail, ou pire, devoir créer un compte.</p>
<p>Et c'est comme ça qu'on se retrouve avec un site usine à gaz permettant d'avoir des sections commentaires. Vides.</p>
<h2 id="la-dure-realite">La dure réalité</h2>
<p>Partant de ce constat, cela vaut il la peine de maintenir un site dynamique avec toute la gestion que ca implique derriere : La mise à jour du CMS lui même, des modules CGI (php, python ou que sais-je), de la base de donnée, etc.
Sans compter que tous ces services augmentent la surface d'attaque et donc la vulnérabilité votre serveur, qui ne manque pas de se faire scanner à longueur de journée.</p>
<p>Apres avoir passé des années à essayer de sensibiliser mon entourage aux dangers des services centralisés collecteurs de données, ainsi qu'aux vertus d'un internet décentralisé et fédéré, j'ai pu constaté avec bonheur que tout le monde s'en fout.
Ou en tout cas, que meme lorsque le sujet eveil un interet, les alternatives sont toujours moins sexy qu'un beau service gratuit, avec tout plein de fonctionnalité chatoyantes en échange de seulement <strong>toutes vos données</strong>.
Et franchement, meme chez les connaisseurs, peu ont envi de s'embeter la vie à monter sa propre instance mastodon, son blog perso auto hebergé, son serveur de mail et son serveur XMPP.
Et c'est normal. Cela demande du temps et des connaissances que tout le monde n'a pas.</p>
<h2 id="la-solution">La solution</h2>
<p>J'en suis donc arriver à cette conclusion. Un site pour blogguer oui, mais dynamique, aucun interet. De plus, il existe aujourd'hui des tonnes de générateurs de sites statiques bien fichus et open source.
La plupart proposent même deja une palanquée de templates prets à l'emploi.
Pour ma part, celui qui m'a le plus séduit est <a class="external-link" rel="noopener external" target="_blank" href="https://www.getzola.org/">Zola</a>.
On maitrise tout de A à Z, la génération du site est ultra rapide et la création d'articles est super intuitive, à partir de pages écrites en markdown.</p>
<p>Et pour les commentaires ? C'est simple : une expression régulière dans postfix. Il est possible de rediriger une infinité d'adresses mail vers une seule boite.
Ca permet de créer des liens de commentaires sous chaque article. Un commentaire posté de cette facon aterrit proprement dans un dossier dédié de ma boite mail.
Si le commentaire est pertinent, je mets à jour l'article lié en citant l'auteur du commentaire, s'il le souhaite.</p>
<p>Ce systeme hybride me simplifie la gestion du site, sa maintenance, ainsi que la modération des commentaires.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Pomodoro facile avec ubuntu</title>
        <published>2020-01-07T00:00:00+00:00</published>
        <updated>2020-01-07T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/pomodoro/" type="text/html"/>
        <id>https://www.selenith.org/articles/pomodoro/</id>
       
        <content type="html"><![CDATA[<p>En cherchant une application ubuntu pour structurer ma facon de travailler avec la technique pomodoro, je suis tombé sur le post de <a class="external-link" rel="noopener external" target="_blank" href="https://www.quora.com/Whats-the-best-Pomodoro-app-on-Ubuntu#">Rem's Lavedrine</a>.</p>
<p>J'ai trouvé sa solution tellement simple et elegante, que je me suis dit que j'allais la partager.</p>
<span id="continue-reading"></span><figure>
    
        <img src="https:&#x2F;&#x2F;www.selenith.org&#x2F;articles&#x2F;pomodoro&#x2F;Pomodoro_Technique.jpg"  alt="Pomodoro par vungoctho"  />
    
    <figcaption>
        <p>Pomodoro par <a class="external-link" rel="noopener external" target="_blank" href="https://commons.wikimedia.org/wiki/File:Pomodoro_Technique.jpg">vungoctho</a></p>

    </figcaption>
</figure>
<!-- <hr />-->
<p>L'idée est de faire un simple script, en bash, qui affiche une notification au bout de 25 minutes, pour indiquer qu'il est temps de faire une pause. J'ai amélioré un peu l'idée pour en faire une commande directement accessible depuis un terminal.</p>
<p>Voici donc les etapes.</p>
<p>Creer, si'l n'existe pas, le dossier <strong>/home/<soiMeme>/.local/bin/</strong></p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">mkdir</span><span style="color: light-dark(#005CC5, #79B8FF);"> -</span><span style="color: light-dark(#005CC5, #79B8FF);">p</span><span style="color: light-dark(#032F62, #9ECBFF);"> ~/.local/bin</span></span></code></pre>
<p>Creer le fichier de script contenant la commande. 1500 secondes correspondent à 25 minutes.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">cat</span><span style="color: light-dark(#D73A49, #F97583);"> &gt;</span><span style="color: light-dark(#032F62, #9ECBFF);"> ~/.local/bin/pomodoro.sh</span><span style="color: light-dark(#D73A49, #F97583);"> &lt;&lt;</span><span style="color: light-dark(#032F62, #9ECBFF);">EOF</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">notify-send &quot;Début de session Pomodoro.&quot;</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">sleep 1500 &amp;&amp; notify-send &quot;Votre session de pomodoro est terminée. Faites une pause.&quot; &amp;</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">EOF</span></span></code></pre>
<p>Rendez le executable.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">chmod</span><span style="color: light-dark(#032F62, #9ECBFF);"> +x</span><span style="color: light-dark(#032F62, #9ECBFF);"> ~/.local/bin/pomodoro.sh</span></span></code></pre>
<p>Vous n'avez plus qu'a executer la commande suivante depuis un terminal ouvert.</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">pomodoro.sh</span></span></code></pre>
<p><em>Note :</em> Comme le script se trouve dans .local/bin/ de votre /home, pas besoin d'utiliser le chemin complet pour l'appeler. Il est inclu dans votre PATH par défaut.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Nunstick</title>
        <published>2019-01-25T00:00:00+00:00</published>
        <updated>2024-02-25T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/projets/nunstick/" type="text/html"/>
        <id>https://www.selenith.org/projets/nunstick/</id>
       
        <content type="html"><![CDATA[<p>As-tu déjà révé d'avoir la précision de la souris et le confort de la manette ?
C'est maintenant possible avec le Nunsick !!!</p>
<span id="continue-reading"></span>
<p>Plus de détails sur les fonctionnalité sur le <a class="external-link" rel="noopener external" target="_blank" href="https://nunstick.madyweb.net">site de présentation</a>.</p>
<h2 id="la-genese-du-projet">La génèse du projet</h2>
<p>Etant un gros joueur de RPG et de MMORPG, je n'ai découvert que tardivement les FPS.
Je suis tombé dedans avec Skyrim, puis, plus tard, avec Overwatch. Et je dois dire qu'apres quelques heures de jeux, notamment sur Overwatch, une pensée me trottait dans la tete :</p>
<p><del>Pourquoi je n'arrive pas à toucher ce put*** de Genji alors que je suis juste à deux metres !!</del> Mais bon sang, c'est vraiment trop moisi les FPS au clavier ! Depuis le temps, personne n'a jamais eu l'idée de faire une manette pour la main gauche ?</p>
<p>Apres moulte recherches infructueuses, j'ai fini par me dire que ca ne devait pas etre si compliqué à faire une manette quand meme ! Et bien, à vrai dire, c'est effectivement plutot simple, surtout en utilisant un truc déja existant et bien fichu : un nunchuk. Mais il faut quand meme savoir ou on va.</p>
<h2 id="mais-arrete-de-causer-et-dit-nous-ou-on-peut-en-acheter-un">Mais arrete de causer et dit nous où on peut en acheter un !</h2>
<p>Cesse donc d'etre aggressif, vil(e) impatient(e) ! J'ai encore des choses à expliquer.</p>
<p>Jusqu'a il y a quelques mois, j'avais une petite structure légale qui me permettait d'en vendre.
Mais, meme si les Nunsticks se vendaient régulierement, le nombre n'etait pas suffisant pour absorber le montant exorbitant des taxes sur les entreprises.</p>
<p>Du coup, la réponse est à la fois simple et compliquée : Si tu en veux un, fabrique le toi meme !</p>
<p>Je m'en sers toujours quotidiennement, et je trouve dommage que le Nunstick meurt par manque de volume de production. J'ai donc décidé de mettre les ressources a disposition pour en fabriquer sous <a class="external-link" rel="noopener external" target="_blank" href="https://www.gnu.org/licenses/gpl-3.0.html">license GPL v3</a>.</p>
<h2 id="fabriquer-un-nunstick-ok-mais-comment">Fabriquer un Nunstick ? Ok... mais comment ?</h2>
<h3 id="le-materiel">Le materiel</h3>
<p>Alors deja il va falloir te procurer un <a class="external-link" rel="noopener external" target="_blank" href="https://store.arduino.cc/products/arduino-micro-without-headers">arduino micro atmega32u4</a>. N'achete pas ces mauvaises copies souvent nommées "Micro Pro". Ce sont des versions au rabais, les soudures des composants sont fragiles.</p>
<p>Si tu ne sais pas souder, tu peux utiliser la version avec les <a class="external-link" rel="noopener external" target="_blank" href="https://store.arduino.cc/products/arduino-micro">headers (broches) déja soudés</a>, ainsi que des connecteurs sans soudure type <a class="external-link" rel="noopener external" target="_blank" href="https://www.amazon.fr/AZDelivery-%E2%AD%90%E2%AD%90%E2%AD%90%E2%AD%90%E2%AD%90-Jumper-Cavalier-Arduino/dp/B07KYHBVR7">jumper</a>.</p>
<p>Ensuite il te faudra un <a class="external-link" rel="noopener external" target="_blank" href="https://fr.aliexpress.com/w/wholesale-nunchuck-i2c.html?spm=a2g0o.productlist.search.0">connecteur de nunchuck</a>.</p>
<p>J'ai la flemme de faire un shema, voici comment relier les deux :</p>
<p><img src="https://www.selenith.org/projets/nunstick/montage.jpg" alt="le montage" /></p>
<h3 id="le-logiciel">Le logiciel</h3>
<p>Il va te falloir installer le logiciel de developpement de l'arduino (Arduino IDE). Ca prend quelques minutes avec <a class="external-link" rel="noopener external" target="_blank" href="https://www.arduino-france.com/tutoriels/ide-arduino-installation-et-utilisation/">un bon tuto</a>.</p>
<p>Tout d'abord il va falloir décompresser <a href="https://www.selenith.org/projets/nunstick/ArduinoNunchuk.zip">le driver</a> dans le dossier <strong>libraries</strong> de l'arduino IDE</p>
<p>Puis telecharger et ouvrir le logiciel du <a href="https://www.selenith.org/projets/nunstick/nunstick.zip">Nunstick</a>.</p>
<p>Il ne restera plus qu'a l'uploader dans l'Arduino comme c'est decrit dans le tuto ci dessus.</p>
<h2 id="peaufiner-un-peu-le-tout">Peaufiner un peu le tout</h2>
<p>Pour faire un joli boitier, voici <a href="https://www.selenith.org/projets/nunstick/stl.zip">les fichiers .stl</a> à utiliser avec n'importe quelle imprimante 3D.</p>
<p>Pour info, j'utilise une imprimante type Prusa I3 et le logiciel ultimaker pour le pilotage de l'impression.</p>
<p>Attention, pour que ca rentre dans le boitier, il faut utiliser la version de l'arduino à souder sois meme. Ca ne rentrera pas avec les broches.
Il te faudra aussi souder les fils dans les trous de l'adaptateur du Nunchuck et couper les pins au raz de leur support en plastique noir.</p>
<p>Et voila un Nunstick tout neuf !</p>
<p><img src="https://www.selenith.org/projets/nunstick/3.jpg" alt="un nunstick" /></p>
<h2 id="mais-je-ne-sais-pas-faire-tout-ca-moi-et-j-en-veux-un-quand-meme">Mais Je ne sais pas faire tout ca moi et j'en veux un quand meme !</h2>
<p>Je t'invite à te rapprocher du Fablab le plus proche de chez toi. Tu y trouveras surement des gens sympa qui pourrons t'aider pour la soudure et l'impression 3D.</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Mapper une razer naga sous Linux</title>
        <published>2018-09-12T00:00:00+00:00</published>
        <updated>2018-09-12T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/articles/mapper-razer-naga-linux/" type="text/html"/>
        <id>https://www.selenith.org/articles/mapper-razer-naga-linux/</id>
       
        <content type="html"><![CDATA[<p>Si comme moi vous aimez bien les devices Razer et que vous jouez sous Linux, cet article est fait pour vous.</p>
<p>J'ai pendant longtemps cherché a changer le mappage par défaut de ma razer Naga Hex. Impossible de faire autre chose, sans les drivers razer, que les deux configuration de la souris activable par le bouton qui se trouve dessous.</p>
<span id="continue-reading"></span>
<p><img src="https://www.selenith.org/articles/mapper-razer-naga-linux/Razer-Naga-Hex.jpg" alt="Image de souris Razer naga Hex" /></p>
<p>J'etais donc condamné à devoir reconfigurer tous mes jeux pour utiliser soit les chiffres 123456 du clavier standard soit ceux clavier numérique.</p>
<p>Mais c'est alors que je suis tombé sur <a class="external-link" rel="noopener external" target="_blank" href="https://bbs.archlinux.org/viewtopic.php?id=145502%7Cce">cette page</a>.
Je test sur mon PC, un xubuntu 18.04 et la, ô joie, ca fonctionne !</p>
<p>Voila donc un script qui fonctionne sur les nagas Hex et les nagas Epic :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);">Récuperation du clavier ID généré par la Naga</span></span>
<span class="giallo-l"><span>remote_id</span><span style="color: light-dark(#D73A49, #F97583);">=</span><span>$(</span></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">  xinput</span><span style="color: light-dark(#032F62, #9ECBFF);"> list</span><span style="color: light-dark(#D73A49, #F97583);"> |</span></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">  sed</span><span style="color: light-dark(#005CC5, #79B8FF);"> -</span><span style="color: light-dark(#005CC5, #79B8FF);">n</span><span style="color: light-dark(#032F62, #9ECBFF);"> &#39;</span><span style="color: light-dark(#032F62, #9ECBFF);">s/.*Naga.*id=\([0-9]*\).*keyboard.*/\1/p</span><span style="color: light-dark(#032F62, #9ECBFF);">&#39;</span></span>
<span class="giallo-l"><span>)</span></span>
<span class="giallo-l"><span>[</span><span style="color: light-dark(#032F62, #9ECBFF);"> &quot;</span><span>$</span><span>remote_id</span><span style="color: light-dark(#032F62, #9ECBFF);">&quot;</span><span> ]</span><span style="color: light-dark(#D73A49, #F97583);"> |</span><span style="color: light-dark(#D73A49, #F97583);">|</span><span style="color: light-dark(#005CC5, #79B8FF);"> exit</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#6A737D, #6A737D);">#</span><span style="color: light-dark(#6A737D, #6A737D);">Creation du fichier de configuration des touches</span></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">mkdir</span><span style="color: light-dark(#005CC5, #79B8FF);"> -</span><span style="color: light-dark(#005CC5, #79B8FF);">p</span><span style="color: light-dark(#032F62, #9ECBFF);"> /tmp/xkb/symbols</span></span>
<span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">cat</span><span style="color: light-dark(#D73A49, #F97583);"> &gt;</span><span style="color: light-dark(#032F62, #9ECBFF);">/tmp/xkb/symbols/custom</span><span style="color: light-dark(#D73A49, #F97583);"> &lt;&lt;</span><span style="color: light-dark(#032F62, #9ECBFF);">\EOF</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">xkb_symbols &quot;remote&quot; {</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">    key &lt;AE01&gt;   { [Alt_L] };</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">    key &lt;AE02&gt;   { [e, E] };</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">    key &lt;AE03&gt;   { [a,  A] };</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">    key &lt;AE04&gt;   { [Control_L] };</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">    key &lt;AE05&gt;   { [Tab,  ISO_Left_Tab] };</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">    key &lt;AE06&gt;   { [c, C] };</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">    key &lt;AE07&gt;   { [F7, F7] };</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">    key &lt;AE08&gt;   { [F8, F8] };</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">    key &lt;AE09&gt;   { [F9, F9] };</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">    key &lt;AE10&gt;   { [F10, F10] };</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">    key &lt;AE11&gt;   { [F11, F11] };</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">    key &lt;AE12&gt;   { [F12, F12] };</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">};</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">EOF</span></span>
<span class="giallo-l"></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">#Injection de la nouvelle configuration</span></span>
<span class="giallo-l"><span style="color: light-dark(#032F62, #9ECBFF);">setxkbmap -device </span><span>$</span><span>remote_id</span><span style="color: light-dark(#032F62, #9ECBFF);"> -print | sed &#39;s/\(xkb_symbols.*\)&quot;/\1+custom(remote)&quot;/&#39; | xkbcomp -I/tmp/xkb -i </span><span>$</span><span>remote_id</span><span style="color: light-dark(#032F62, #9ECBFF);"> -synch - </span><span>$</span><span>DISPLAY</span><span style="color: light-dark(#032F62, #9ECBFF);"> 2&gt;/dev/null</span></span>
<span class="giallo-l"></span></code></pre>
<p>Vous pouvez le mettre dans un fichier appelé naga.sh et le rendre executable avec la commande :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">chmod</span><span style="color: light-dark(#032F62, #9ECBFF);"> +x</span><span style="color: light-dark(#032F62, #9ECBFF);"> naga.sh</span></span></code></pre>
<p>Il ne vous reste plus qu'a l'executer :</p>
<pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);"><code data-lang="shellscript"><span class="giallo-l"><span style="color: light-dark(#6F42C1, #B392F0);">./naga.sh</span></span></code></pre>
<p>La configuration ci dessus est celle que j'utilise pour Skyrim SE, lancé avec steam Play sous Linux. Pensez a executer script apres chaque nouveau demarrage.</p>
<p>Le gros avantage c'est que vous pouvez faire autant de scripts que vous avez de jeux. Vous aurez alors l'equivalents des profiles dans razer synapse.</p>
<p>Et noubliez pas que le <a class="external-link" rel="noopener external" target="_blank" href="https://nunstick.fr/">nunstick</a> est aussi compatible Linux ;D</p>
]]></content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Plasmide</title>
        <published>2014-10-05T00:00:00+00:00</published>
        <updated>2014-10-05T00:00:00+00:00</updated>
        <author>
          <name>Selenith</name>
        </author>
        <link rel="alternate" href="https://www.selenith.org/projets/plasmide/" type="text/html"/>
        <id>https://www.selenith.org/projets/plasmide/</id>
       
        <content type="html"><![CDATA[<p>Plasmide est un Systeme de Gestion de Contenu, ou encore Content Management System (CMS) créé, à l'origine, pour heberger un site de guilde. Il contient, entre autre, un forum, un raidplanneur et un moteur de site complet.</p>
<span id="continue-reading"></span>
<p><img src="https://www.selenith.org/projets/plasmide/plasmide.png" alt="Logo Plasmide" /></p>
<h2 id="le-projet">Le projet</h2>
<p>Integralement ecrit en PHP,javascript, HTML et CSS, il permet la mise en place et le maintient d'un site web dyanmique sans pré-requis de connaissance en developpement.</p>
<p>Plasmide a été developpé a l'origine pour fonctionner sur un serveur NAS DNS 313 de D-Link modifié, puis par la suite sur un raspberry-pi. Il est donc concu pour être econome en ressource et fonctionne avec une base de donnée embarquée.</p>
<h2 id="telecharger">Télécharger</h2>
<p>Voici les liens de téléchargement :</p>
<p><a href="https://www.selenith.org/projets/plasmide/plasmide.zip">Plasmide avec tous les modules</a></p>
<h2 id="contribuer">Contribuer</h2>
<p>Plasmide étant open source, vous pouvez contribuer a son évolution en m'envoyant des patch/diff.</p>
]]></content>
        
    </entry>
</feed>
